LINUX.ORG.RU

Ответ на: комментарий от anonymous

Потому что у разработчиков не будет взрываться мозг

А мне кажется, что оформление файла (кодировка) и содержание литералов не должны зависеть друг от друга. Мне приходилось перекодировать файлы между koi-8, windows-1251 и utf-8 по ходу истории развития моих проектов. И что, при этом я должен ещё и подредактировать код, чтобы смысл не поменялся?

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Но у тебя скорее всего есть с этим проблемы, очень хочется услышать.

Иных проблем, кроме только что озвученной, нет.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Мне приходилось перекодировать файлы между koi-8, windows-1251 и utf-8

А яр это как решит? Байтики в сырцах то поменяются в любом случае.

anonymous
()
Ответ на: комментарий от den73

Кстати, юникодные строки в питоне, прекрасно переживают смену кодировки.

/tmp$ cat boo-cp1251.py | iconv -f cp1251
# -*- coding: cp1251 -*-
print u'ю'
/tmp$ python2 boo-cp1251.py 
ю
anonymous
()
Ответ на: комментарий от den73

ИМХО, самое правильное решение - все строки считать закодированными в UTF-8/UTF-16 (то есть кодировка, которая покрывает все потребности, какой-нибудь CP1251 не подойдёт). В памяти программы. При чтении исходника компилятор автоматически всё переводит в правильную кодировку (исходник может быть в любой кодировке). Все функции стандартной библиотеки работают именно над этими строками.

Нужна работа с другими кодировками? У строки есть конструктор, принимающий массив байт и название кодировки. А ещё есть метод, принимающий название кодировки и возвращающий массив байт. С помощью первого конвертируешь байтики в строку, с помощью второго обратно.

Так сделано во всех нормальных фреймворках и языках, назови хоть одно исключение. Не... по причинам legacy некоторые штуки поддерживают 2 типа строк - в однобайтовой кодировке и юникодовые. Но это сугубо наследие (когда-то в языке были только однобайтовые строки и сейчас многое на это завязано). Если без этого можно обойтись, то реализуют лишь юникодовые строки.

И ты не ответил на мой вопрос. В какой кодировке будет результат сложения двух строк, одна из которых в CP1251, а другая в CP866?

И ты реально собираешься писать для каждой кодировки, которую знаешь, полный набор строковых функций? А ещё полный набор функции перекодирования из каждой кодировки в каждую (зависимость количества функций от количества кодировок квадратическая)?

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 3)
Ответ на: комментарий от KivApple

зависимость количества функций от количества кодировок квадратическая

Нет, он выберет общую кодировку, которую поддерживает icu и прозреет)

anonymous
()
Ответ на: комментарий от anonymous

Байтики в сырцах то поменяются в любом случае.

Наверное, я не очень внятно объяснил.

Перекодирование в моём случае означало, что я перекодирую сам исходник и меняю в нём первую строчку с указанием кодировки. Либо меняю кодировку по умолчанию в среде.

Пока нет b"ю", то и проблемы никакой не будет: байтики в исходнике разные, а считаются они в букву «ю» во внутреннем представлении, принятом в данном образе (неважно, какое оно).

Если же ты сделал

# -*- coding: utf-8 -*-
a = b"ю"

а потом перекодировал исходник в koi-8r и поменял первую строчку

# -*- coding: koi-8r -*-
a = b"ю"
,

То переменная a получит разное значение. Понятно, что у этого есть use-case-ы. Но пока не вижу необходимости включать это в Яр. Моя задача сейчас - выработать минимальный синтаксис достаточный для жизнеспособности. Данная фича к абсолютно необходимым не относится.Если она потом понадобится, её можно включить в полный вариант «чстроку» в виде одного из атрибутов.

den73 ★★★★★
() автор топика
Ответ на: комментарий от KivApple

utf-8 - прекрасная кодировка. Даже нельзя получить букву из строки по номеру за время O(1).

den73 ★★★★★
() автор топика
Ответ на: комментарий от KivApple

И ты не ответил на мой вопрос.

Ты тоже не ответил на мои вопросы. Будем выяснять, кто первый начал не отвечать?

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Даже нельзя получить букву из строки по номеру за время O(1).

Вообще то, в общем случае, в юникоде нельзя в принципе получить буковку за константу. Есть только кодпойнты, которые часто совпадают с буковками. От кодировки это не зависит. Вот такой жестокий мир.

anonymous
()
Ответ на: комментарий от den73

Наверное, я не очень внятно объяснил.

Да, нет, я сразу тебя понял. В примере выше я это и сделал. В случае юникодных строк ничего не поменяется, в случае байтовых... ну автор такого кода ссзб. Можно простейшую защиту в виде data = u'ю'.encode('utf-8') сделать.

anonymous
()
Ответ на: комментарий от KivApple

Если тебе это не нравится

Конечно не нравится. И юникод вообще нужен не всегда. Есть (и всегда будут) машины с ограниченным объёмом памяти, а также задачи, где быстродействие важно, а наличие китайских иероглифов - нет.

в случае байтовых... ну автор такого кода ссзб

Не понял, почему не поменяется, если я поменяю utf-8 на utf-16. Байты в исходнике будут разные и b"ю" приведёт к разным результатам.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Именно этим и хорош UTF-8. Можно забить на то, что это юникод и работать с ним как с обычными ASCII строками. Разумеется, всякие иероглифы при этом пострадают, но они и не нужны там, где такие ограниченные ресурсы. А когда у нас много ресурсов и нужны иероглифы, то оверхед от использования UTF-8 не будет так заметен.

Да, русские буквы и любой другой национальный алфавит - такие же иероглифы. В каком-нибудь микроконтроллере не нужно ни то, ни другое, ASCII хватит всем.

KivApple ★★★★★
()
Ответ на: комментарий от KivApple

Да, русские буквы и любой другой национальный алфавит - такие же иероглифы. В каком-нибудь микроконтроллере не нужно ни то, ни другое, ASCII хватит всем.

Здесь я с тобой тоже не соглашусь, но это и не важно.

Промежуточные итоги темы: есть пример языков, где тип результата привязан к литералу (Python с b и u, а также MSVS с L). Есть ICU, о которой я не знал (впрочем, знание пока не пригодилось). Есть однобайтовые кодировки, в Яре не раскрыты, но и не надо пока - ведь если рантайм в десятки Мб, то это вряд ли микроконтроллер. Само по себе решение сделать много синтаксисов для строк не уникально, такое же есть в Питоне, Баше, Перле, ну и в Лиспе можно сделать разные строки и я для себя уже давно сделал. Так что считаю его правильным.

Задать тип литерала в Яре можно, хотя и неудобно (полный синтаксис строки). Задать его в коротком синтаксисе чс.*() тоже пока что есть место - остались незаняты все большие буквы и все цифры.

den73 ★★★★★
() автор топика
Ответ на: комментарий от hatefu1_dead

В контексте независимости - да. А вдруг это такая ценная вещь, что это важнее независимости от кодировки? Хотя пофиг - всё равно в Яре это можно будет сделать, если надо. Синтаксис позволяет.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Вопрос в том - нужен ли опасный?

Это даже не вопрос. Так как единственный способ исключить опасность — убрать байтовые строковые литералы, что естественно ересь.

anonymous
()
Ответ на: комментарий от den73

Смотри, в третьем питоне строки - это набор символов и операций с этим набором, а то, как они внутри представлены, пользователя языка не волнует, разве что в смысле эффективности этого представления и набора допустимых символов. Байтовый тип же - это набор байтов, и то, что твои настройки позволяют ввести или представить этот набор байтов по-разному, на содержание переменной не влияют, и наоборот, то, что представляется одним и тем же символом при разных настройках, может отвечать разному содержанию. Перекодировав файл, ты изменишь этот самый набор байтов, и соответственно содержание байтовой переменной. Кодировка строки - это способ байтового представления набора символов, и, например, при чтении файла строковые литералы преобразуются из указанной кодировки во внутреннее представление, таким образом оставляя символы неизменными. Может я ошибаюсь, но если ты в Яре хочешь посредством синтаксиса влиять именно на внутреннее представление строк, то я не вижу случаев, когда это может быть нужно и предполагаю множество проблем с реализацией операций над строками - либо писать n^2 функций для n кодировок, либо каждый раз перекодировать. А если же ты хочешь допустить возможность задания строк из байтовых представлений в различных кодировках, то представь, насколько неудобно будет править файл, где строки заданы то в utf-8, то windows-1251, то в koi8-r.

hatefu1_dead
()
Ответ на: комментарий от den73

b"ю" - это оксюморон и синтаксическая ошибка, потому что байтовый тип может содержать только литералы из ascii, правильно - b'\xd1\x8e', либо bytes([209, 131]).

hatefu1_dead
()
Ответ на: комментарий от hatefu1_dead

b"ю" - это оксюморон и синтаксическая ошибка

В Питоне - возможно. А так вообще это «грязный хак». То, что он грязен, не говорит о его безполезности. Например, препроцессор в С кто-то может считать грязным хаком, но он в реальности необходим. В общем-то b выходит за рамки данной темы и делать так я не собирался.

Может я ошибаюсь, но если ты в Яре хочешь посредством синтаксиса влиять именно на внутреннее представление строк

Я пока это обдумываю. Я только что нашёл вот что: https://ru.wikipedia.org/wiki/C++11#.D0.9D.D0.BE.D0.B2.D1.8B.D0.B5_.D1.81.D1....

Раз авторы С++ сочли это нужным, значит это нужно. Яр - не Питон, это более производительный язык, а значит, от работы с деталями реализации не уйти.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

В принципе, можно вообще взять за основу именно последние стандарты С++ - тогда слегка уменьшится порог вхождения и никто уже не сможет придраться к замудрёности - я его сразу смогу назвать неосилятором, потому что у последние стандарты С++ считаются удачными.

Но полностью взять за основу не получится, поскольку там всё основано на латинице. И там вроде нет вопросов про ресурсные файлы. Можно, во всяком случае, взять

R"(The String Data \ Stuff " )"
R"delimiter(The String Data \ Stuff " )delimiter"

den73 ★★★★★
() автор топика
Ответ на: комментарий от hatefu1_dead

Касаемо n^2 функций не соглашусь - далеко не все функции нужны. Иногда особое представление строк нужно только для FFI, для него не нужно ничего, кроме конструктора и возможности перекодировать в другую кодировку. Кроме того, в n^2 нет ничего особенно нового и страшного - С++ -ные шаблоны template<T1,T2> делают ровно то же самое, просто это лаконично записано. Это неизбежно - либо делаешь много функций, либо динамический вызов (компактно, но медленно).

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.