А разве в первом случае в JS не нужны другие кавычки тоже ?
В том и дело, что нет:
> var order = { id: 123 }, s = `order: ${order[`id`]}`; s
'order: 123'
Понятное дело, что и случаев таких в JS/TS меньше, потому что кавычки для форматирования - это не обычные одинарные и двойные, и потому что в "объекты-словари" можно ходить просто через точку (order.id).
Обратную косую черту можно обойти дополнительной переменной хотя конечно и не так удобно.
Понятно, что можно обойти. Но, если честно, в Python мне чаще, чем во многих других языках, приходится искать вот такие обходные пути. В треде выше вот огорчился, что нет встроенного find(iterable, predicate), тоже приходится как-то обходить.
Ваш первый вариант мне не нравится тем, что для меня ключевое слово break не несет смысл возврата значения. Если бы в вашем примере predicate не назывался так очевидно, я бы сначала подумал, что эта функция как-то меняет или потребляет значения из iterable, и возвращает флаг "дайте мне еще данных".
Наверное, это дело привычки. Я не привык писать на Python, поэтому паттерны с for-else не узнаю сразу.
В идеали, я бы хотел иметь find в стандартной библиотеке, работающий как more_itertools.first_true. И писал бы так:
x = find(iterable, predicate)
if x is None:
raise NotFoundException()
А из ваших вариантов мне ни один не нравится, что с for-else, что другие. Если выбирать только из существующих способов, сделал бы как-то так:
x = filter(predicate, iterable)
x = next(x, None)
if x is None:
raise NotFoundException()
Я не очень много пишу именно на Python, больше на JS/TS, в котором таких ограничений нет. Поэтому спотыкаюсь в простых случаях:
# здесь нужны другие кавычки
f"order id: {order["id"]}"
# здесь нельзя бекслеш
f"""
some header
{'\n'.join(rows)}
"""
Конечно, все это сразу же подсвечивается IDE и правится. А второй случай у меня чаще всего возникает в кустарных одноразовых скриптах, когда я мало забочусь о стиле кода, и нужно просто что-то быстро вывести в нужном формате. Но, тем не менее, немного раздражает.
Мне кажется, что это стоит решать скорее насаждением стиля кода в команде. А для самого языка лучше быть консистентным - допускать в них любые выражения, без произвольных ограничений.
Ограничения f-строк меня уже давно раздражали, если честно. Особенно невозможность использовать бекслеши, или одни и те же кавычки.
Я не пользуюсь Three.js напрямую, поэтому с кодом не знаком. Плюс, то, что я уже сделал, в целом, покрывает мои требования. Поэтому писать такой лоадер мне уже не очень интересно. Если будет интересно кому-то другому, то код открыт :)
Если вдруг есть потребность - мой код можно использовать как препроцессор, а загружать в Three.js уже полученный glTF.
для того, чтобы получить и обработать данные курса валют нужно можно знать синтаксис десятка разнородных программ обойтись парой инструментов, которые найдутся на любой системе. А еще делать это нужно можно в примитивной неудобной интерактивной командной строке на коленке, если нужен быстрый ответ на запрос, а не полноценная разработка.
В таком алгоритме я вижу некоторые проблемы. Главным образом, они связаны с тем, что UV-маппинг - насколько я понимаю - не обязан быть обратимым.
Несколько треугольников модели могут иметь одни и те же UV для одной текстуры, но разные для другой.
Не для всех треугольников, у которых есть маппинг в одну текстуру, есть маппинг в другую. Скорее всего, такое реализовано просто маппингом всего треугольника в одну точку на текстуре.
То есть, грубо говоря, вот этот шаг не будет работать:
Берём цвет и пишем его во вторую текстуру по другим uv координатам.
Нет разницы, как это называть, если эффект аналогичный. Представьте себе умножение не двух литералов, а двух переменных. Которое где-то в рантайме начинает внезапно выдавать в 10 раз больший результат.
Дайте мне superstrict, при котором бы на попытку 2 + '3' (или любое другое несоответствие) вылетало исключение
И потом пытаться по стектрейсу какой-нибудь sum() понять, откуда именно в нее пришла строка вместо числа? Вместо того, чтобы IDE сразу, ещё до запуска кода подсветила место, где я при рефакторинге забыл поменять тип поля.
Я правильно понимаю, что разработчик этой библиотеки - вы? Судя по репозиторию, это так, поэтому вопросы про интерфейс и реализацию буду задавать вам.
Самый главный вопрос: для чего такая абстракция? У localStorage и sessionStorage и так общий интерфейс. IndexedDB же обычно используется для других целей, чем Storage. Ограничения на значения и особенности их хранения у него, опять же, другие.
Мне кажется, можно было бы не изобретать свой интерфейс, а взять тот же самый Storage, и дописать для него нужные вам реализации (для Map, например).
Использование Proxy тоже выглядит не слишком оправданным. Например, из-за такого интерфейса, получается, в вашем хранилище нельзя сохнанить данные по ключу entries, раз он занят методом? Использование ключей, начинающихся с __ (вместо, например, приватных полей) тоже вызывает вопросы к тому, что возможны коллизии.
Плюс еще одна причина, почему мне не нравится такие интерфейсы - они ломают ожидания о производительности. Вряд ли многие программисты будут ожидать, что когда они будут просто читать поле объекта, это будет обращение к внешнему хранилищу.
Я, в целом, не начинал этот тред, чтобы спорить с вами :) Просто было странно, что в статье про NODE_PATH и симлинки, например, упомянули, а про эту фичу нет.
Но мне все ещё кажется, что сложность миграции на ESM вы, возможно, преувеличиваете.
Но вот проблему c тем, что везде, где подключается папка придется дописать /index, судя по всему не решается.
Просто по ещё одной автозамене на каждую папку, которая так импортировались.
И с ts-node и tsx как-то это все-равно не дружит из коробки.
С ts-node вроде все должно работать - типизация за счёт paths в tsconfig, сами импорты за счёт самой ноды. Разве нет?
С tsx дела не имел, про него не знаю.
Любой код из npm или свой, который что-то из этого использует придется переписывать или искать альтернативу.
По поводу кода из npm - неправда: ESM-модули могут импортировать CommonJS-модули.
По поводу своего кода: все отличия из вашего списка (при использовании TypeScript) либо решаются плюс-минус автозаменой (__filename и __dirname), либо очень редко встречаются в коде (require.extensions).
Для чистого JS - да, согласен, придется все экспорты на другой синтаксис переписывать.
С Jest - да, может быть проблема. Хотя я вроде не натыкался на баги, несмотря на экспериментальный статус.
У вас комменты для нейросети получились примерно такой же длины, как и сгенерированный ей код. А для запросов к базе понадобилось указывать дополнительный контекст - схему таблиц. В итоге у меня есть подозрение, что для данных примеров код проще будет все же написать руками.
В том и дело, что нет:
Понятное дело, что и случаев таких в JS/TS меньше, потому что кавычки для форматирования - это не обычные одинарные и двойные, и потому что в "объекты-словари" можно ходить просто через точку (
order.id).Понятно, что можно обойти. Но, если честно, в Python мне чаще, чем во многих других языках, приходится искать вот такие обходные пути. В треде выше вот огорчился, что нет встроенного
find(iterable, predicate), тоже приходится как-то обходить.Ваш первый вариант мне не нравится тем, что для меня ключевое слово
breakне несет смысл возврата значения. Если бы в вашем примереpredicateне назывался так очевидно, я бы сначала подумал, что эта функция как-то меняет или потребляет значения изiterable, и возвращает флаг "дайте мне еще данных".Наверное, это дело привычки. Я не привык писать на Python, поэтому паттерны с
for-elseне узнаю сразу.В идеали, я бы хотел иметь
findв стандартной библиотеке, работающий какmore_itertools.first_true. И писал бы так:А из ваших вариантов мне ни один не нравится, что с
for-else, что другие. Если выбирать только из существующих способов, сделал бы как-то так:Но все равно некрасиво.
Я не очень много пишу именно на Python, больше на JS/TS, в котором таких ограничений нет. Поэтому спотыкаюсь в простых случаях:
Конечно, все это сразу же подсвечивается IDE и правится. А второй случай у меня чаще всего возникает в кустарных одноразовых скриптах, когда я мало забочусь о стиле кода, и нужно просто что-то быстро вывести в нужном формате. Но, тем не менее, немного раздражает.
Иронично, что мы написали прям дословно одинаковый код в одновременных комментариях :)
Еще одно подтверждение тому, что такой вариант куда более интуитивен, чем
for-else.В вашем примере очень неочевидный control flow, из-за чего не сразу понятно, что он вообще делает. Мне кажется, вот так и короче, и понятнее:
Так что ваш пример получился не в пользу
for-else:)Мне кажется, что это стоит решать скорее насаждением стиля кода в команде. А для самого языка лучше быть консистентным - допускать в них любые выражения, без произвольных ограничений.
Ограничения f-строк меня уже давно раздражали, если честно. Особенно невозможность использовать бекслеши, или одни и те же кавычки.
Так наоборот же, в этом релизе многое стало проще:
убрали депрекейтнутые функции (unittest, webbrowser)
добавили более адекватный синтаксис (параметры дженериков, type, override)
убрали неочевидные ограничения, о которые все спотыкались (парсинг f-строк)
увеличили полезность сообщений об ошибках
Я не пользуюсь Three.js напрямую, поэтому с кодом не знаком. Плюс, то, что я уже сделал, в целом, покрывает мои требования. Поэтому писать такой лоадер мне уже не очень интересно. Если будет интересно кому-то другому, то код открыт :)
Если вдруг есть потребность - мой код можно использовать как препроцессор, а загружать в Three.js уже полученный glTF.
У вас неверный итог получился.
В таком алгоритме я вижу некоторые проблемы. Главным образом, они связаны с тем, что UV-маппинг - насколько я понимаю - не обязан быть обратимым.
Несколько треугольников модели могут иметь одни и те же UV для одной текстуры, но разные для другой.
Не для всех треугольников, у которых есть маппинг в одну текстуру, есть маппинг в другую. Скорее всего, такое реализовано просто маппингом всего треугольника в одну точку на текстуре.
То есть, грубо говоря, вот этот шаг не будет работать:
В таком случае, как мне кажется, лучше было бы переписать текст от третьего лица. Сейчас выглядит так, будто вы - представитель JetBrains.
(если это действительно так - то простите)
Попробуйте Ruffle. Учитывая возраст игры, думаю, он ее спокойно переварит. SWF-файл гуглится в интернете.
Честно говоря, я просто не разобрался в ее интерфейсе. Mecabricks в этом плане для меня оказался проще.
Нет разницы, как это называть, если эффект аналогичный. Представьте себе умножение не двух литералов, а двух переменных. Которое где-то в рантайме начинает внезапно выдавать в 10 раз больший результат.
И потом пытаться по стектрейсу какой-нибудь
sum()понять, откуда именно в нее пришла строка вместо числа? Вместо того, чтобы IDE сразу, ещё до запуска кода подсветила место, где я при рефакторинге забыл поменять тип поля.Вот я что-то не уверен, что в нем с этим строже.
Угадаете, где какой язык? :)
Я правильно понимаю, что разработчик этой библиотеки - вы? Судя по репозиторию, это так, поэтому вопросы про интерфейс и реализацию буду задавать вам.
Самый главный вопрос: для чего такая абстракция? У
localStorageиsessionStorageи так общий интерфейс. IndexedDB же обычно используется для других целей, чем Storage. Ограничения на значения и особенности их хранения у него, опять же, другие.Мне кажется, можно было бы не изобретать свой интерфейс, а взять тот же самый Storage, и дописать для него нужные вам реализации (для Map, например).
Использование Proxy тоже выглядит не слишком оправданным. Например, из-за такого интерфейса, получается, в вашем хранилище нельзя сохнанить данные по ключу
entries, раз он занят методом? Использование ключей, начинающихся с__(вместо, например, приватных полей) тоже вызывает вопросы к тому, что возможны коллизии.Плюс еще одна причина, почему мне не нравится такие интерфейсы - они ломают ожидания о производительности. Вряд ли многие программисты будут ожидать, что когда они будут просто читать поле объекта, это будет обращение к внешнему хранилищу.
Я, в целом, не начинал этот тред, чтобы спорить с вами :) Просто было странно, что в статье про NODE_PATH и симлинки, например, упомянули, а про эту фичу нет.
Но мне все ещё кажется, что сложность миграции на ESM вы, возможно, преувеличиваете.
Просто по ещё одной автозамене на каждую папку, которая так импортировались.
С ts-node вроде все должно работать - типизация за счёт paths в tsconfig, сами импорты за счёт самой ноды. Разве нет?
С tsx дела не имел, про него не знаю.
По поводу кода из npm - неправда: ESM-модули могут импортировать CommonJS-модули.
По поводу своего кода: все отличия из вашего списка (при использовании TypeScript) либо решаются плюс-минус автозаменой (
__filenameи__dirname), либо очень редко встречаются в коде (require.extensions).Для чистого JS - да, согласен, придется все экспорты на другой синтаксис переписывать.
С Jest - да, может быть проблема. Хотя я вроде не натыкался на баги, несмотря на экспериментальный статус.
У вас комменты для нейросети получились примерно такой же длины, как и сгенерированный ей код. А для запросов к базе понадобилось указывать дополнительный контекст - схему таблиц. В итоге у меня есть подозрение, что для данных примеров код проще будет все же написать руками.
Можно же настроить paths в tsconfig. Да и кроме того:
На самом деле, не уверен, что остались ещё случаи, где это не приемлемо. Сможете привести пример?