Потому что у разработчиков не будет взрываться мозг
А мне кажется, что оформление файла (кодировка) и содержание литералов не должны зависеть друг от друга. Мне приходилось перекодировать файлы между koi-8, windows-1251 и utf-8 по ходу истории развития моих проектов. И что, при этом я должен ещё и подредактировать код, чтобы смысл не поменялся?
ИМХО, самое правильное решение - все строки считать закодированными в UTF-8/UTF-16 (то есть кодировка, которая покрывает все потребности, какой-нибудь CP1251 не подойдёт). В памяти программы. При чтении исходника компилятор автоматически всё переводит в правильную кодировку (исходник может быть в любой кодировке). Все функции стандартной библиотеки работают именно над этими строками.
Нужна работа с другими кодировками? У строки есть конструктор, принимающий массив байт и название кодировки. А ещё есть метод, принимающий название кодировки и возвращающий массив байт. С помощью первого конвертируешь байтики в строку, с помощью второго обратно.
Так сделано во всех нормальных фреймворках и языках, назови хоть одно исключение. Не... по причинам legacy некоторые штуки поддерживают 2 типа строк - в однобайтовой кодировке и юникодовые. Но это сугубо наследие (когда-то в языке были только однобайтовые строки и сейчас многое на это завязано). Если без этого можно обойтись, то реализуют лишь юникодовые строки.
И ты не ответил на мой вопрос. В какой кодировке будет результат сложения двух строк, одна из которых в CP1251, а другая в CP866?
И ты реально собираешься писать для каждой кодировки, которую знаешь, полный набор строковых функций? А ещё полный набор функции перекодирования из каждой кодировки в каждую (зависимость количества функций от количества кодировок квадратическая)?
Перекодирование в моём случае означало, что я перекодирую сам исходник и меняю в нём первую строчку с указанием кодировки. Либо меняю кодировку по умолчанию в среде.
Пока нет b"ю", то и проблемы никакой не будет: байтики в исходнике разные, а считаются они в букву «ю» во внутреннем представлении, принятом в данном образе (неважно, какое оно).
Если же ты сделал
# -*- coding: utf-8 -*-
a = b"ю"
а потом перекодировал исходник в koi-8r и поменял первую строчку
# -*- coding: koi-8r -*-
a = b"ю"
,
То переменная a получит разное значение. Понятно, что у этого есть use-case-ы. Но пока не вижу необходимости включать это в Яр. Моя задача сейчас - выработать минимальный синтаксис достаточный для жизнеспособности. Данная фича к абсолютно необходимым не относится.Если она потом понадобится, её можно включить в полный вариант «чстроку» в виде одного из атрибутов.
Даже нельзя получить букву из строки по номеру за время O(1).
Вообще то, в общем случае, в юникоде нельзя в принципе получить буковку за константу. Есть только кодпойнты, которые часто совпадают с буковками. От кодировки это не зависит. Вот такой жестокий мир.
Да, нет, я сразу тебя понял. В примере выше я это и сделал. В случае юникодных строк ничего не поменяется, в случае байтовых... ну автор такого кода ссзб. Можно простейшую защиту в виде data = u'ю'.encode('utf-8') сделать.
Конечно не нравится. И юникод вообще нужен не всегда. Есть (и всегда будут) машины с ограниченным объёмом памяти, а также задачи, где быстродействие важно, а наличие китайских иероглифов - нет.
в случае байтовых... ну автор такого кода ссзб
Не понял, почему не поменяется, если я поменяю utf-8 на utf-16. Байты в исходнике будут разные и b"ю" приведёт к разным результатам.
Именно этим и хорош UTF-8. Можно забить на то, что это юникод и работать с ним как с обычными ASCII строками. Разумеется, всякие иероглифы при этом пострадают, но они и не нужны там, где такие ограниченные ресурсы. А когда у нас много ресурсов и нужны иероглифы, то оверхед от использования UTF-8 не будет так заметен.
Да, русские буквы и любой другой национальный алфавит - такие же иероглифы. В каком-нибудь микроконтроллере не нужно ни то, ни другое, ASCII хватит всем.
Да, русские буквы и любой другой национальный алфавит - такие же иероглифы. В каком-нибудь микроконтроллере не нужно ни то, ни другое, ASCII хватит всем.
Здесь я с тобой тоже не соглашусь, но это и не важно.
Промежуточные итоги темы: есть пример языков, где тип результата привязан к литералу (Python с b и u, а также MSVS с L). Есть ICU, о которой я не знал (впрочем, знание пока не пригодилось). Есть однобайтовые кодировки, в Яре не раскрыты, но и не надо пока - ведь если рантайм в десятки Мб, то это вряд ли микроконтроллер. Само по себе решение сделать много синтаксисов для строк не уникально, такое же есть в Питоне, Баше, Перле, ну и в Лиспе можно сделать разные строки и я для себя уже давно сделал. Так что считаю его правильным.
Задать тип литерала в Яре можно, хотя и неудобно (полный синтаксис строки). Задать его в коротком синтаксисе чс.*() тоже пока что есть место - остались незаняты все большие буквы и все цифры.
В контексте независимости - да. А вдруг это такая ценная вещь, что это важнее независимости от кодировки? Хотя пофиг - всё равно в Яре это можно будет сделать, если надо. Синтаксис позволяет.
Смотри, в третьем питоне строки - это набор символов и операций с этим набором, а то, как они внутри представлены, пользователя языка не волнует, разве что в смысле эффективности этого представления и набора допустимых символов. Байтовый тип же - это набор байтов, и то, что твои настройки позволяют ввести или представить этот набор байтов по-разному, на содержание переменной не влияют, и наоборот, то, что представляется одним и тем же символом при разных настройках, может отвечать разному содержанию. Перекодировав файл, ты изменишь этот самый набор байтов, и соответственно содержание байтовой переменной. Кодировка строки - это способ байтового представления набора символов, и, например, при чтении файла строковые литералы преобразуются из указанной кодировки во внутреннее представление, таким образом оставляя символы неизменными. Может я ошибаюсь, но если ты в Яре хочешь посредством синтаксиса влиять именно на внутреннее представление строк, то я не вижу случаев, когда это может быть нужно и предполагаю множество проблем с реализацией операций над строками - либо писать n^2 функций для n кодировок, либо каждый раз перекодировать. А если же ты хочешь допустить возможность задания строк из байтовых представлений в различных кодировках, то представь, насколько неудобно будет править файл, где строки заданы то в utf-8, то windows-1251, то в koi8-r.
b"ю" - это оксюморон и синтаксическая ошибка, потому что байтовый тип может содержать только литералы из ascii, правильно - b'\xd1\x8e', либо bytes([209, 131]).
В Питоне - возможно. А так вообще это «грязный хак». То, что он грязен, не говорит о его безполезности. Например, препроцессор в С кто-то может считать грязным хаком, но он в реальности необходим. В общем-то b выходит за рамки данной темы и делать так я не собирался.
Может я ошибаюсь, но если ты в Яре хочешь посредством синтаксиса влиять именно на внутреннее представление строк
В принципе, можно вообще взять за основу именно последние стандарты С++ - тогда слегка уменьшится порог вхождения и никто уже не сможет придраться к замудрёности - я его сразу смогу назвать неосилятором, потому что у последние стандарты С++ считаются удачными.
Но полностью взять за основу не получится, поскольку там всё основано на латинице. И там вроде нет вопросов про ресурсные файлы. Можно, во всяком случае, взять
R"(The String Data \ Stuff " )"
R"delimiter(The String Data \ Stuff " )delimiter"
Касаемо n^2 функций не соглашусь - далеко не все функции нужны. Иногда особое представление строк нужно только для FFI, для него не нужно ничего, кроме конструктора и возможности перекодировать в другую кодировку. Кроме того, в n^2 нет ничего особенно нового и страшного - С++ -ные шаблоны template<T1,T2> делают ровно то же самое, просто это лаконично записано. Это неизбежно - либо делаешь много функций, либо динамический вызов (компактно, но медленно).