Артём Кобзарь - Как и зачем я пишу свой статический типизатор
HTML-код
- Опубликовано: 12 сен 2024
- Ближайшая конференция - HolyJS 2024 Autumn, 7 ноября (online), 14-15 ноября (Санкт-Петербург + трансляция).
Подробности и билеты: jrg.su/K18Cxd
- -
. . Артём - приверженец следующего подхода: «Чтобы эффективно что-то использовать - нужно написать свой аналог». Он расскажет о том, как работают самые популярные на сегодняшний день решения для статической типизации и как он пишет свое собственное решение.
Не могу отделаться от ощущения что про статическую типизацию в JS мне рассказывает Лев Против >_
Господи как жизненно, тоже весь доклад на это отвлекался)))
На сегодня проект закрыт. Артём, спасибо за попытку сделать лучше 👍🏼
Отличный инженерный подход, красавчик !
Это было очень круто, спасибо!
Подписался, поддержу
доклад можно было переименовать: "До чего доводит flow"
Ссылка на полезные ссылки из доклада
github.com/JSMonk/hegel-literature
такие доклады очень круты - выявляют проблемные места распиареных технологий. не всё так гладко в мире TS.
Очень крутая идея! С интересом слежу за вашим проектом. Но до успеха ему, в лучшем случае, лет 4-5 нужно будет.
Как финансируется проект? Или это хобби проект на энтузиазме?
Если вы читаете .d.ts файлы - как обрабатываются их Typescript типы, например тот же any?
Здравствуйте. Финансируется - никак, у меня есть патреон, но это проект не ради «деняк», по большей части это хобби.
Типы поеобразуются в антологичный либо схожие, к примеру, any -> unknown (антологичный ts-ному unknown или mixed во Flow)
Крутой чувак . Смотрел стримы как он разрабатывал этот типизатор .
А как без проверки типов в рантайме валидировать/типизировать приходящие с сервера данные?
никак
По поводу ruclips.net/video/GIHrPm_YAIc/видео.html - в C# и Java также будет ошибка во время рантайма, смотри gist.github.com/KvanTTT/e3d75635d67620e5769a96376b597516 И там точно индекс 2 имелся в виду, а не 1? Если массивы индексируются от 0, то ошибка возникнет до проверки типов, индекс вне диапазона.
Так Java и C# вообще не эталон хорошей типизации)
Индекс вне диапазона в Java и С# т.к. массивы не динамические в статически типизированных ЯП, в отличии от JS.
Артём красава!
Сколько раз он выпил водички в конце?)))
31:40 - пошла жара. TS действительно имеет проблему, но она там взялась не из-за того, что авторы TS идиоты. Структурная типизация даёт множество фишек, а в замен даёт одну проблему. И из этого никак не следует, что решение плохое и его нужно поменять. Просто нужно добавить хинт.
Но, автор опять пытается всех обмануть. Его примитивная система типов не способна дать то, что может дать TS. И она попросту убога. Но что же он говорит? Он говорит, что так и нужно. Нужно убого. Он опять пытается выдать слабость за фичу.
32:10 - враньё переходит уже все границы. Автор показывает некую особенно TS и говорит "нельзя" и вы думаете, что действительно нельзя. Но всё можно - id(x: T) {return x;}. Причём это не является проблемой, потому как если функция будет объявлена в контексте, где уже описана её сигнатура - она возьмёт сигнатуру из контекста. А если ты вне контекста хочешь создать генерик-функцию - объяви это явно. Это поведение обусловлено совместимостью с js.
34:15 - это не зависимые типы. К тому же, сразу видно костыли убогой системы типов. Для получения каких-либо трансформаций типов убогой систему типов нужна магия. Нормальной же системе типов - нет. И лучше бы он нам показал как реализована его магия. Ну и по поводу TS - враньё - вот пруф: bit.ly/3ffQFzR
Проявлю небывалую академическую щедрость Вам, и, если Вам действительно интересно подискутировать на данную тему (систем типов и вывода типов) - напишите мне в тг @js_monk, и сможем подискутировать у нас на подкасте. Думаю, обсуждение с таким профаном как я, Вам может быть скучным, но сможете высказать свою позицию во всеуслышанье.
В общем, перед сном решил для протокола разобрать примеры автора - godbolt.org/z/NDLy1c Очевидно, что сравнения с растом не получилось - это дерьмо не может ни во что. Там я привёл пару пруфвов против тезисов автора(там на тему вывода типов в расте для лямбд). Этого будет достаточно. Посмотрим на ответы автора.
Красавчик) я что-то вроде того для себя попробовал) пришел к тому же выводу ) это хайп и деньги, братишка) Стив Жобс вей
Давайте не будем спорить. Лучше поговорим о типизации. Вы там хотели доказательств того, почему система типов раста говно - вот показываю пример, о котором я уже множество раз говорил. Берём кресты: godbolt.org/z/sRmWZv
Я даже не буду говорить о какой-то там выразительности и том, что это бездарное дерьмо никогда не сможет в подобное. Сейчас не об этом. Хотя выразительность в данном случае так же обусловлена системой типов и её мощностью, но то тоже ладно.
Проблема здесь следующая. С++ знает, что есть несколько типов трансформаций и несколько типов контейнеров. Вектор является RA-контейнером. Если мы применим к нему трансформацию, которая сохраняет RA - оно будет работать. transform - это ваш map.
А вот фильтр не сохраняет RA и после нельзя применить [], которые подразумевают RA. RA в данном случае - random access, т.е. доступ по индексу за O(1).
У вас была примитивная вариация такого подхода - это пример с model. Дак вот - раст в такое не может. Там нету вывода типов. И пародия на них в лябмдах никак не помогает, потому как это не С++/js-лямбды и их применение крайне ограничено. Да даже в C++ применение лямбд ограничено, как и в js.
Ах да, забыл. Хоть это в мире хайлевел скриптухи не котируется, но всё же. Почему здесь так важное RA. Дело в том, что вот это: (vec | reverse | transform(_ + 123))[2] - выполняется только для элемента с индексом 2(результирующим). Т.е. оно не будет брать массив и его реверсить, оно не будет применять map ко всем элементам. Оно возьмёт третий элемент с конца массива и прибавит к нему 123. Остальные элементы он даже не прочитает.
Это одно из требований реального мира, в том числе и для жаваскрипта. Нужно не просто иметь возможность описывать поведение "хоть как-то", но и сохранять необходимые требования по части производительности и не только.
Точно так же важно, что-бы типизация не заставляла людей жрать дерьмо(как в расте). Потому как никто не хочет(кроме фанатиков) писать на чём-то неудобном и не выразительном. Это в огород "у меня нужно явно приводить к bool".
Пример #1 на ts V 4.9 пофикшен уже выводится number | undefined, пример с id очень легко типизировать через шаблон ```const id = (x: T): T => x;```, проблемы связанные со структурной типизацией решаются брендированием
38:40 - никакого подхода раста не существует. Ну ведь автор ничего не знает про раст и типизацию - зачем он пользуется тем, что его ЦА не знает ещё больше? Раст на 90% состоит из динамического диспатча как по интерфейсам так и по юнионам. Для того, что-бы такое делать - нужно знать типы в рантайме. Тоже самое пусть автор погуглит про std::any, typeid и прочее. Либо почитает про С++ откуда всё это было взято.
В любом случае раст никакого отношения к языком "полностью типизированным" не относится. Типизация там хуже, чем в TS.
38:50 - можно. Но это не про раст и не про js.
39:35 - как хорошо быть жертвой пропаганды. Ничего не знает, но экспертно заявляет. В расте всё это есть. И null pointer и какой угодно поинтер. И к системе типов это не имеет никакого отношения.
39:40 - невежество в массы. Никаких null pointer exception в С++ нет и быть не может. Автор перепутал с жавой. И к типизации это не имеет никакого отношения. Это как деление на ноль. Или ещё любая другая рантайм-ошибка. Которая никак не обрабатывается убогой системой типов автора. И аналогичной оной системой типов раста.
39:45 - хорошая система и проверка типов? В расте? Ну про жертву пропаганды я уже говорил.
39:46 - всё что нужно знать об данном эксперте. Раст уже не нормальный язык, потому как там есть any. Как же так?
(38:40).
"Раст на 90% состоит из динамического диспатча как по интерфейсам так и по юнионам." Тут не прав, не являюсь экспертом в Rust.
"В любом случае раст никакого отношения к языком "полностью типизированным" не относится. Типизация там хуже, чем в TS. ". Ваше оценочное суждение, которое не является аргументом.
(38:50).
"можно. Но это не про раст и не про js.". Не про Rust - согласен. Хотя, что мое, что Ваше суждение - оценочное. Я своим проектом пытаюсь доказать, что можно. Вы пишите в комментариях, что нельзя.
(39:35).
" И null pointer и какой угодно поинтер. И к системе типов это не имеет никакого отношения."
Да, замечательно. Null pointer не имеет отнощение к системе типов. (сарказм).
Вот Вам как пример Idris. github.com/idris-lang/Idris-dev/blob/master/libs/base/Data/Vect.idr.
В Idris с типов `Vect` нельзя взять элемент, индекс которого привышает размерность `Vect`. Или тут тоже не система типов?
(39:45).
Хорошая/плохая - субьективное категорическое суждение. То, что Вы считаете ее плохой, не означает, что все остальные должны считать также.
(39:46)
Нормальное/неноральное - субьективное категорическое суждение. То, что я считаю что-то нормальным, не означает, что все остальные должны считать также.
@@MrDendi97
>Ваше оценочное суждение.
Нет. Просто нужно меньше ретранслировать пропаганды. Типизация раста крайне примитивна - это факт. Я могу рассказать и показать почему - мне не сложно. Начнём хотя-бы с вывода типов.
>Я своим проектом пытаюсь доказать, что можно. Вы пишите в комментариях, что нельзя.
Вы молодец, но вы поступаете неверно. Если проще, то ситуация в следующем. Вы утверждаете можно, но при этом просто проигнорировали все сложности и все проблемы, закрылись в своём локальном мире и говорите "в моём болоте всё работает". К тому же открою тайну - наиболее это показал С++.
>Да, замечательно. Null pointer не имеет отнощение к системе типов. (сарказм).
Не имеет. То, что вы увидели в жаваскрипте тип null - это не значит, что он существует в системе типов С++(на минутку самой мощной в мире) и вообще имеет смысл.
>Где я не могу взять элемент, индекс которого привышает размерность `Vect`. Или тут тоже не система типов?
Опять же - нет. Пример не корректен - оно никаким образом не относится к теме. Проблема вся та же. Данный недоязычок живёт в рамках своей примитивной реальности и пригоден только для лаб студентов. Причём его система типов слабее слабее С++, правда она немного другая. И слабее чем в других подобных языках. И проблема в том, что ошибки с указателями берутся в С++ оттуда же, откуда и ошибки в вашем жаваскрипте - из внешнего контекста. Вы, конечно же, можете фанатично игнорировать его. Но это не более чем поверство.
> Хорошая/плохая - субьективное категорическое суждение. То, что Вы считаете ее плохой, не означает, что все остальные должны считать также.
Нет, это не субъективный критерий. Я рассуждаю в контексте того, какое поведение может описать система типов. Чем больше - тем лучше. Больше - объективный, верифицируемый критерий.
> Нормальное/неноральное - субьективное категорическое суждение. То, что я считаю что-то нормальным, не означает, что все остальные должны считать также.
Аналогично указанному выше.
"Нет. Просто нужно меньше ретранслировать пропаганды. Типизация раста крайне примитивна - это факт.". Да, замечательно. Вы правы, утверждение что, что-то можно или нельзя без пруфов, не является оценкой. (для ШУЕ, это тоже сарказм).
"в моём болоте всё работает". Опять присваиваете мне слова, которых не говорил. Жду ссылки, где я говорю, что у меня Все работает. Я наоборот, везде говорю, что это эксперимент.
"То, что вы увидели в жаваскрипте тип null - это не значит, что он существует в системе типов С++". Null Pointer Exception существует не только в C++. К тому же, если в C++, нет null как значения, это не значит, что в других языках также (это логическая ошибка).
"системе типов С++(на минутку самой мощной в мире)" - опять Ваша личная оценка.
"Опять же - нет. Пример не корректен - оно никаким образом не относится к теме. Проблема вся та же. Данный недоязычок живёт в рамках своей примитивной реальности и пригоден только для лаб студентов. " Слушайте, я после этого комментария не хочу продолжать с Вами полемику. Вы кидаетесь высказываниями без малейших пруфов (да, да, макулатура не для Вас, Вы в своем познании преисполнились). Я надеялся на интересную позицию и дискуссию, но, я разочарован. Не вижу выгоды и интереса. Так что, доброй Вам ночи.
29:45 - пошло враньё. Автор здесь пытается вам обмануть, а именно выдать убогость своего вывода типов за фичу. Если проще - то, что здесь показано - это не слабость TS - это специальные фичи, которые расширяют типизацию. А автор показывая вам своё изваяние называет дефолтное поведение фичёй.
Строгость типизации никак не относится к явно. Когда вам говорят обратное - вас пытаются обмануть. Задача типизации полностью покрыть рантайм-логику. И если в рантайм-логике этот неявный каст существует - он должен быть описан на уровне типов. Автор же просто не осилил и решил выдать слабость за фичу.
Это очень просто проверяется - почему же он не показал ОШИБКИ, которые допустим ts неявными кастами? Правильно, потому что их нет.
29:56 - А далее автор опять пытается всех обмануть. То, что твоя примитивная система описания типов не позволяет учитывать неявные трансформации типов - это проблема твоей типизации(убогой). И автор убогость выдаёт за фишку.
30:30 - это позор. Автор просто начал манипулировать. Следим за руками. Контекст у нас "различия между моим и ТС" и тут бам - он показывает что-то. И мы должны думать, что в TS всё не так. Но нет - там всё так же. И зачем этот пример привёл автор?
30:46 - здесь автор совсем поломался. js скриптуха и никак не может быть полностью типизирован, потому как типы в нём вторичны. По этой причине все рантайм-проверки не должны учитывать типизацию - это базовое правило. Авторы TS его осилил, а данный эксперт нет. Да, оно бесполезно.
(29:45).
1. "Строгость типизации никак не относится к явно". Зависит от определения "строгой типизации"
Я пользуюсь высказыванием Aahz Maruch: "Coercion occurs when you have a statically typed language and you use the syntactic features of the language to force the usage of one type as if it were a different type (consider the common use of void* in C). Coercion is usually a symptom of weak typing. Conversion, on the other hand, creates a brand-new object of the appropriate type.", исходя из которого, я могу говорить, что языки с приведением типов являются языками со слабой типизацией.
2. "Задача типизации полностью покрыть рантайм-логику". Где Вы взяли эту "задачу типизации"? Можно пруф или ссылку на статью или книгу?
(29:56).
"То, что твоя примитивная система описания типов не позволяет учитывать неявные трансформации типов - это проблема твоей типизации(убогой)".
Оценочное суждение + спор об определениях. Я выше дал определение, которым пользуюсь и, исзодя из него, не могу с Вами согласиться.
(30:30).
"Контекст у нас "различия между моим и ТС" и тут бам - он показывает что-то.".
Боретесь с соломенным чучелом. Я не говорил, что проверок с "in" нет в TS. Давайте пруфы обратного.
(30:46).
1. " js скриптуха и никак не может быть полностью типизирован". А можно доказательство данного тезиса где-то посмотреть?
2. "По этой причине все рантайм-проверки не должны учитывать типизацию - это базовое правило.". Кто определили это долженствование? Можно опять какие-то пруфы увидеть на данную тему, вместо рефлексии?
@@MrDendi97
1) Неверно и ссылка не адекватна. Там говорится про "неявно" в контексте потери типовой информации, но в данном случае ситуация иная. Никакая информация не теряется.
2) Макулатура никого не интересует, в том числе и меня. Взял я это исходя из базовых прагматических соображений. Есть язык, который должен делать то, что может. И типизация должна давать ему это делать. В любом случае на эти заходы я могу ответить "прфы и ссылки на обратное".
> Опять таки, остылаю Вас к Маруху.
Опять детские заходы. Автор спастил цитату, значения которой ему не понятно, и теперь выдаёт её за опровержение моих тезисов. Причём никаким образом логически это не выведя из цитаты. И самое важное, с чего меня вообще кто-то должен волновать? Мне абсолютно неважно кто там и что сказал. Вера леммингов в идолов меня не интересует.
> Боретесь с соломенным чучелом. Я не говорил, что проверок с "in" нет в TS. Давайте пруфы обратного.
Опять детские заходы. Я чётко описал откуда взялось это сравнение с ТС. Почему данный адепт не процитировал и не ответил на него, а придумал какую-то херню, которой я не говорил.
>А можете доказательство данного тезиса где-то показать? Или это опять Ваши догадки?
Доказывать это должны вы, а не я. К тому же я уже ответил на этот вопрос. Типизация по отношению к js вторична. В статических языках нету ошибок типизации не потому, что там какие-то системы типов, а потому как там типизация первична.
Ещё раз, в ситуации с js типизация должна полностью ОПИСАТЬ поведение рантайма. Описать всегда дыряво и должно быть доказано. И в полной мере доказано не может быть никогда, по определению. В ситуации же со статическим языком типизация всегда описывает поведение рантайма исходя из своей природы, потому как рантайм поведение напрямую обусловлено ею.
>Кто определили это долженствование? Можно опять какие-то ссылки увидеть на данную тему?
Опять же, меня не волнуют эти заходы детсадовские про ссылки. Я не настолько недееспособный, что-бы прятаться за ссылками. В целом, когда адепт отсылает к ссылкам - это значит лишь одно. Ему нечего возразить.
Но я отвечу. Существует внешний мир, который никаким образом не учитывает типизацию в нахлабучках на жаваскрипт. Т.е. в рамках языка нет никаких гарантий, что любая функция не поменяет реальный тип данных. Точно так же нет никаких гарантий на то, что типизированная внешняя функция передаст тип соответствующий аннотации.
1. "Неверно и ссылка не адекватна." Оценочное суждение. Не адекватна, потому что Вас не устраивает?
"Никакая информация не теряется.". Да, замечательно. То есть при касте условного класса Cat к его родителю Animal я не теряю никакой информации?
2. "Макулатура никого не интересует, в том числе и меня. ". Да, замечательно. Куда лучше аргументы из головы в стиле "это говно" и "это вранье".
"Взял я это исходя из базовых прагматических соображений. Есть язык, который должен делать то, что может. И типизация должна давать ему это делать.". Метафизика пошла. Кто долженствование определили?
3. " В любом случае на эти заходы я могу ответить "прфы и ссылки на обратное". Вы сказали о какой-то задаче. Бремя доказательства лежит на Вас.
Для людей, которым "Макулатура не интересна" объясню. Если Вы говорите "Бог есть", то Вы и должны это утверждение доказать. Никто не в силах доказать отсутсвие Бога, пока нет доказательств его наличия.
4. "Автор спастил цитату, значения которой ему не понятно" Вы уже и уровень понимание цитате определили по ней же. 😄
5. " Я чётко описал откуда взялось это сравнение с ТС.". Мммм, четко. "Контекст" - это довольно такое четкое описание. Вы правы.
6. "Доказывать это должны вы, а не я." Да, замечательно. Почитайте "Учебник Логики" Г. И. Челпанова, может найдете там про тезисы и бремя доказательств что-то.
7. "Ещё раз, в ситуации с js типизация должна полностью ОПИСАТЬ поведение рантайма." Вы не отвечаете на вопрос. Кто определил данное долженствование?
8. "пять же, меня не волнуют эти заходы детсадовские про ссылки. Я не настолько недееспособный, что-бы прятаться за ссылками." Да, Вы определенно разумный муж, который аргументирует позицию неверефицируемыми тезисами и эпитетами в стиле "говеный", "дырявый" и тд.
9. " в рамках языка нет никаких гарантий, что любая функция не поменяет реальный тип данных." Мммм, в рамках языка, говорите. А конструкции `typeof`, `instanceof` по Вашему где и что проверяют? (В рантайме и типы), То есть `typeof a === "number"` гарантия, что в функцию "метафизический внешний мир" передал число -__-
Меня не перестаёт удивлять то как веб-гении с ничтожными познаниями берутся рассуждать о расте, С++. Понимаю, что там с тебя никто не спросит, но всё же.
9:58 - C++ не имеет вывода типов в твоём понимании. Типизация в С++ - это совершенно другая реальность, которая настолько сильно превосходит всё, что ты знаешь.
10:00 - никакого вывода типов в расте нет. Как же эпично обманул вас этот эксперт. В расте есть вывод типов(ну как вывод - огрызок для примитивных кейсов) только для лябд.
10:02 - типы не проаннотированы и в С++. Пациент либо не знает, либо в очередной раз пытается вас обмануть. Дело в том, что в C++ auto - это не только типовая аннотация. Это ещё и признак декларации. И везде он используется именно как признак декларации - как аннотация он не имеет смысла. И о чудо, если мы уберём эту аннотацию - мы потеряем признак декларации. И это решается костылём let, которого нет в С++. А let - это говно, по определению. Причина тому проста. Признаком декларации в С++ является любая аннотация, а не только auto.
И если мы желаем написать string x; - мы там и пишем. В костыльном let-говне мы так не можем. Мы обязаны оставить let и получить let x: string.
(9:58).
1. "C++ не имеет вывода типов в твоём понимании". Зависит от определения "вывода типов". Свое определение я не озвучивал в докладе, странно, что Вы его как-то узнали.
Я считаю механизмом реконструкции (вывода) типов - такой алгоритм, который без типовой декларации восстанавливает тип переменной/функции. Исходя из данного определения, и того, что `auto` - не является явным указанием типа, значит в C++, есть вывод типов.
2. "Типизация в С++ - это совершенно другая реальность, которая настолько сильно превосходит всё, что ты знаешь.". О, аргументы пошли (сарказм). Оценочное суждение не является аргументом.
(10:00).
1. "никакого вывода типов в расте нет.". Зависит от определения "вывода типов". Исходя из высше данного определения, есть.
2. "В расте есть вывод типов(ну как вывод - огрызок для примитивных кейсов) только для лябд.". Так есть или нет? (Ну и, "вывод типов для лямбд" исходя из названия, является "выводом типов").
(10:02).
1. "типы не проаннотированы и в С++.". Именно это я и говорил пару слайдов назад.
2. "Дело в том, что в C++ auto - это не только типовая аннотация. Это ещё и признак декларации.". Опять боретесь с соломенным чучелом. Я не говорил, что `auto` - это типовая декларация. Или жду пруфов, что говорил.
3. " А let - это говно, по определению.". With facts and logic.
4. "И если мы желаем написать string x; - мы там и пишем. В костыльном let-говне мы так не можем. Мы обязаны оставить let и получить let x: string.". Оценочное суждение. Вы считаете, что отсуствие возможности явно указать тип - плохо. Я так не считаю. И, о боже. боже. Мы с Вами оба не правы и оба правы. Потому что, категории "хорошо/плохо" оценочные. А из фактов нелзья прийти к моральному (оценочному) суждению, потому что это неверефицируемое утверждение.
@@MrDendi97
>Зависит от определения "вывода типов". Свое определение я не озвучивал в докладе, странно, что Вы его как-то узнали.
Это и не нужно. Я зная примерный уровень тех методичек, что вы потребляете. Зная я это исходя из транслируемых вами тезисов. И т.к. я знаю эти методички - я знаю откуда какой тезис и я знаю, что в этой методичке написано на тему вывода типов.
> Я считаю механизмом реконструкции (вывода) типов - такой алгоритм, который без типовой декларации восстанавливает тип переменной/функции. Исходя из данного определения, и того, что `auto` - не является явным указанием типа, значит в C++, есть вывод типов.
Не, это очень слабо для С++.
>О, аргументы пошли (сарказм). Оценочное суждение не является аргументом.
Эта не оценочные суждения. Если человек говорит "много" на то, что реально мало - значит он ничего не знает о много. Если человек говорит о том, что его вывод типов - это что-то состоятельное. Если он говорит о том, что в расте существует какая-то мощная система типов - это про то же.
>Так есть или нет? (Ну и, "вывод типов для лямбд" исходя из названия, является "выводом типов").
Не, не прокатит. Для лямбд в TS тоже есть вывод типов, но почему-то адепт показывал отдельные функции. Но дело даже не в этом. Под выводом типов подразумевается его наличие везде, а не где-то в одном месте. Сообщаю новость.
>Именно это я и говорил пару слайдов назад.
Далее сказано "вот в расте вообще нету аннотаций". Тут проблемы с показаниями. Если они есть и там и там, то зачем было выделять раст?
>Опять боретесь с соломенным чучелом. Я не говорил, что `auto` - это типовая декларация. Или жду пруфов, что говорил.
Выше.
>Оценочное суждение. Вы считаете, что отсуствие возможности явно указать тип - плохо. Я так не считаю. И, о боже. боже. Мы с Вами оба не правы и оба правы.
Опять либо враньё, либо не понимание вопроса. Я нигде не говорил отсутствие какой-то возможности. Я говорил про то, что в let-дерьме присутствует избыточность всегда. А эта избыточность ненужна. Любая избыточность ненужна. По определению.
Переходить из фактов к оценочному можно, потому как ничего оценочного нету. То, что вы называете оценочным - это не оценочное. Я могу написать "избыточное", но я пишу "говно". Потому как в данном случае моё мнение совпадает с фактом. И я их объединяю.
@@MrDendi97 Давайте забудем обо всём этом и поговорим предметно. Возможно это поможет вам в ваших изысканиях и я пойму вас, а вы будите более актуальную информацию людям доносить про что-то за пределами js. И не путать их, да и себя.
Слушай мужик ты где столько говна по жизни набрался. Меньше говномета больше смыслов. Ты как баба пукан открыл и аж на четыре коммента только вонь. Расслабся мир не живет только твоим супергалактическим С++.