LINUX.ORG.RU
ФорумTalks

Чем плох Python?

 ,


4

4

Просьба к Python-хейтерам - вы можете адекватно и по пунктам сформулировать, чем он плох? Чем он хуже по сравнению с Perl, Ruby, Javascript, другими подобными языками?

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

Есть два вида людей. Одни считают что третий питон сломал слишком многое, вторые что третий питон сломал недостаточно.

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

Я, пожалуй, думаю, что если уж ломать, так ломать основательно. А иначе нечего и браться. Так что значит я из вторых.

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

У нас видимо разные понятия об «асинхронности». Асинхронный, это когда есть евентлуп, в который мы передаём управление, и при наступлении какого-либо события он передаёт управление куда-то обратно в наш код.

А уж определяются точки продолжения колбаками, промисами, деферредсами, хаками на уровне байткода как у гринлетов, или ключевым словом await, это уже детали реализации.

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

а что там выкинули кроме строк которые были массивами/списками байт

не силен в питоне. пытался вкатиться как раз в момент перехода со второго на третий. не осилил

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

А если мы делаем что-то более креативное модное клиент-микросерверное, ну или пишем банальную скрейпилку, то тут уже профит есть. С тысячей-другой открытых сокетов управляться проще чем с таким же количеством потоков, особенно если им надо как-то обмениваться данными

Чешу репу, и как-то интуитивно понимаю, что ты прав, но не могу сформулировать. Например... многопоток в питоне все равно был похож на зеленые потоки, а потому был бессмысленным карго-культом изначально. И тогда зеленые потоки реализовали явно! Правда, не совсем ясно, почему бы вместо этого не сделать неотдаваемый GIL вместо нынешнего поведения (GIL отдается после скольки-то-там выполненных строк). Таким образом, в любом потоке питонового кода я могу обращаться к разделяемым данным, имея гарантию, что никакой другой поток с питоньим интерпретатором не получает доступ к этим объектам.

Правда, в этом месте может оказаться, что сами разработчики питона тоже не совсем понимают, зачем нужен async/await. А может быть понимают, что нужен он для хайпа: у всех есть — и у нас будет.

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

а что там выкинули кроме строк которые были массивами/списками байт

Я не говорил «выкинули», я говорил «сломали». А так, несколько переименований и перетасовок в стандартной библиотеке (которых можно было сделать всяко больше, убрав хохмы вида datetime.datetime). Оператор print убрали. / между двумя интами всегда возвращает флоат. Ну и поменяли местами u-строки и b-строки.

В общем-то изменений не много, но те что есть привели к тому, что имеющийся код сломался. А это боль. И каких-то тулз для упрощения процесса перехода не было. Даже для добавления пары элементов синтаксиса, которые упрощали написание кода, который одновременно работал и в 2, и в 3, пришлось ждать 3.3.

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

Есть такие две темы в IT шумные: ФП и асинхронность

Прям-таки ФП шумное? По-моему, на каком-нибудь хабре по ФП гробовая тишина. Зато машинное обучение, веб-фреймворки, микросервисы — хоть отбавляй.

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

Я хз, что в этот термин вкладывается. Есть евент луп, есть точки входа в код на js из него. Ну и что?

Вся магия основана только на том, что стек js (по которому идет привязка переменных) — отдельная сущность от стека самого эвент лупа.

Все это десятилетиями работало без особого шума, а теперь стало модным вдруг.

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

Я могу ошибаться, а проверять влом, но кажется в питоне async/await появился после C#, но до JS. Так что это JS который пошёл на поводу у толпы.

Когда создатели питона приняли решение иметь один лок вместо кучи мелких, компьютеры с более чем одним процессором стоили очень много денег.

GIL защищает сугубо состояние интерпретатора, он не защищает исполняемую программу. Иметь GIL контролируемый из питоновского кода было бы совсем тупо, его поведение файнтюнили под то, чтобы он не давал дополнительных просадок на типичной ОС с типичным количеством тредов.

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

ради выкидывания однобайтных строк емнип

Я участвовал в портировании проекта на миллион строк на Delphi с однобайтовых строк на юникод. Через месяц проект уже работал как часы. А питон, вроде как, должен быть по уровню абстракций повыше, так что коду должна быть безразлична байтовость строк, только если это не специализированные преобразования текста с учетом кодировок.

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

свалить и пердолиться напополам между шарпами/плюсами и кромсать змею

Я не карьерист, и моей гипоманиакальности недостаточно, чтобы сидеть в одном айти веки-вечные. Так что айтишный проект в моей жизни может быть только один. А шарп с питоном весьма плохо сращиваются в одном проекте так-то. В отличие от плюсов.

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

Специфика такова, что любой проект, который работал с текстовыми данными, волей-неволей превращался в «специализированный преобразователь текста с учетом кодировок».

Я до сих пор вспоминаю эти питоноподелия, который падали, если получали в неожиданном месте utf8 хотя бы в качестве имени файла. Бррр.

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

Во втором питоне было два типа данных — массив байт и юникодная строка.

В третьем питоне есть два типа данных — массив байт и юникодная строка.

Основная разница в том, что во втором питоне если массив байт и юникодную строку использовать в одном контексте, то они друг в друга автоматом конвертировались (используя кодировку по дефолту, обычно ASCII). В третьем питоне те же выражения приводят к TypeError. Т.е. считай всё равно что 5 + 5.0 в одной версии языка позволяли делать, а в следующей версии сказали 5 + 5.0 теперь ошибка типов. А у кучи народа программы написаны без оглядки на то, что это были разные типы.

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

Я могу ошибаться, а проверять влом, но кажется в питоне async/await появился после C#, но до JS. Так что это JS который пошёл на поводу у толпы

https://www.python.org/dev/peps/pep-0492/ - 2015
ECMASCript 2015 — внезапно, тоже 2015

Одновременно. А появился он сначала в F#, где async/await давал огромный прирост читаемости кода, а обычное разбиение кода на блоки функций обратного вызова создавало кучу проблем с передачей значений.

Когда создатели питона приняли решение иметь один лок вместо кучи мелких, компьютеры с более чем одним процессором стоили очень много денег

Ты переоцениваешь создателей питона. Гвидо вообще не подразумевал, что у компьютера может быть больше одного процессора:

https://github.com/python/cpython/blob/f70e43a073b36c6f6e9894c01025243a77a452...

1991 год, никаких потоков, никакого GIL. Блокировки и thread local storage — это, на самом деле, костыли под убогим однопоточным кодом, чтобы у параллельно запускаемых программ создавать иллюзию эксклюзивного доступа к данным — как они привыкли работать. Истинные параллельные вычислители используют совершенно другие механизмы организации выполнения.

GIL защищает сугубо состояние интерпретатора, он не защищает исполняемую программу

«Состояние интерпретатора» — это абсолютно все учтенные в GC объекты из кучи. В число которых также входят классы type, dict, list, константы None, True, False, и прочие фундаментальные штуки. То есть, почти все действия, которые делает питоний код, подразумевают взятие GIL. Пока ты выполняешь что-то в питоновом коде — у тебя всегда есть GIL, у тебя есть гарантия, что никакой другой поток не изменит в это время объекты. Однако, в какой-то момент разрабы питона решили, что неплохо было бы иногда отпускать GIL и позволять внезапно начать исполнение другого потока интерпретатора, что с позиции пользователя-программиста выглядит похоже на параллельное недетерминированное выполнение нескольких потоков. «Ух ты, в моем питоне появились потоки» — радуется секретарша, и идет просить гугл принять питон в качестве основного языка прототипирования.

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

Основная разница в том, что во втором питоне если массив байт и юникодную строку использовать в одном контексте, то они друг в друга автоматом конвертировались (используя кодировку по дефолту, обычно ASCII). В третьем питоне те же выражения приводят к TypeError. Т.е. считай всё равно что 5 + 5.0 в одной версии языка позволяли делать, а в следующей версии сказали 5 + 5.0 теперь ошибка типов. А у кучи народа программы написаны без оглядки на то, что это были разные типы

Ага, ну я понял — говнокод, который написан без чтения документации. Соответственно, это и были те самые люди, которые жаловались при переходе — их срань просто не спортировалась сама по себе, а осилить ручное портирование они не в состоянии, как не в состоянии были грамотно написать код изначально.

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

«Состояние интерпретатора» — это абсолютно все учтенные в GC объекты из кучи. В число которых также входят классы type, dict, list, константы None, True, False, и прочие фундаментальные штуки

GIL защищает от того что код d['foo'] += 1 не словит сегфолт при одновременном выполнении в двух потоках, он не защищает от того, что два потока которые делают d['foo'] += 1 не прочтут из дикта одно и то же значения, и не запишут в него по два одинаковых результата.

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

Я до сих пор вспоминаю эти питоноподелия, который падали, если получали в неожиданном месте utf8 хотя бы в качестве имени файла. Бррр

Да, было такое: качаешь очередную говнолибу, а она отказывается работать с русскими буквами.

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

Ага, ну я понял — говнокод, который написан без чтения документации.

А если кто-то прочитал документацию, и решил, что ascii им хватит, и автоконвертация это удобно?

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

GIL защищает от того что код d['foo'] += 1 не словит сегфолт при одновременном выполнении в двух потоках, он не защищает от того, что два потока которые делают d['foo'] += 1 не прочтут из дикта одно и то же значения, и не запишут в него по два одинаковых результата

Еще раз: ни одна питонья команда не может быть выполнена без взятия GIL; если какой-то поток при выполнении «d['foo'] += 1» взял GIL и не отдает его, то есть 100% гарантия, что не только содержимое d['foo'], но даже весь «d», и еще «c», и «e» в это время будут неизменными.

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

А если кто-то прочитал документацию, и решил, что ascii им хватит, и автоконвертация это удобно?

В документации второго питона указано, что для для превращения массива байт в строку нужно использовать encode/decode. Потому «решил» он на свой страх и риск. Это примерно как обоссать штаны на морозе.

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

«Асинхронный» он потому, что дальше писать на вложенных коллбеках уже было просто никак.

Лет 20 было нормально. Пока применяли язык по назначению для проверки форм и рисования снежинок. А как стали бизнес-логику писать на этом, так сразу стало тяжко. Потому что асинхронная бизнес-логика это безумие. Что касается gui, то сто лет его писали и пишут на колбеках без проблем.

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

Строчка d['foo'] += 1 это уже больше одной «питоньей команды» aka единиц байткода, между которыми может произойти переключение на другой тред.

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

Строчка d['foo'] += 1 это уже больше одной «питоньей команды» aka единиц байткода, между которыми может произойти переключение на другой тред

Чем плох Python? (комментарий)

Правда, не совсем ясно, почему бы вместо этого не сделать неотдаваемый GIL вместо нынешнего поведения (GIL отдается после скольки-то-там выполненных строк). Таким образом, в любом потоке питонового кода я могу обращаться к разделяемым данным, имея гарантию, что никакой другой поток с питоньим интерпретатором не получает доступ к этим объектам.

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

Это уже давно не тот JS

Я js учил где-то в 1999 году, так что наверно предвзят. Такое эпичное говно, прям аж восхищение было. Но для скриптования странички этого хватало.

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

Краткий экскурс в историю:

  1. В операционных системах появляются треды
  2. Питонисты: о, давайте добавим трединг в стдлибу, но тут у нас в каждом объекте сидит reference counter и прочий shared state. Ну давайте лочить интерпретатор на всякий чтобы промеж PY_INCREF объекты не располосило.
  3. Появляется пентиум 4 с гипертредингом. Большинство людей впервые видят больше одного графика загруженности процессора в таскманагере.
PolarFox ★★★★★
()
Последнее исправление: PolarFox (всего исправлений: 1)
Ответ на: комментарий от byko3y

Ну блин, а зачем создавать нативные треды чтобы потом полностью (пытаться) рулить ими из интерпретируемого кода? Тогда уж лучше целиком рулить control flow из интерпретируемого кода (async/await). У текущего состояния дел с GIL есть хоть один плюс, что нативщина GIL может отпускать когда не работает с питон-объектами.

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

А сейчас когда делают крутые языки и технологии, то нужно еще убеждать чем это лучше десятков других разработок тоже на высоком уровне. Ой чота лень учить, не

Лет 10 назад энтузиасты носились с Nemerle. Тоже задавали вопросы, почему никто не хочет его учить. Ещё был язык Boo - смесь питона и бейсика, преподносимый как новое слово в разработке. Но что-то давно о них не слышно.

Rust, безусловно, прошёл дальше, чем Nemerle. Его уже корпорации заметили. Но Crystal, Zig, V не доросли до той известности, какая была у Nemerle в 2010. Я предполагаю, что и по фичам им далеко.

Приходите с вашими крутыми технологиями когда взлетит Nemerle.

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

Ну блин, а зачем создавать нативные треды чтобы потом полностью (пытаться) рулить ими из интерпретируемого кода? Тогда уж лучше целиком рулить control flow из интерпретируемого кода (async/await). У текущего состояния дел с GIL есть хоть один плюс, что нативщина GIL может отпускать когда не работает с питон-объектами

Последний твой тезис никак не меняется с моим предложением: потоки всё так же отпускают GIL на длинных операциях, не трогающих питоньи объекты. Хотя бы потому, что GIL никак не защищает непитоньи объекты. Однако, отпустить GIL больше одного раза нельзя в однопоточной асинхронщине — и в этом ее огромный минус. А зачем тогда нужна асинхронщина? Чтобы делать неблокирующий параллельный ввод-вывод? Дык это я могу делать и без асинхронного сахара, на одних колбэках и неблокирующих ситемных вызовах.

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

Прям-таки ФП шумное?

Может я немного в криокамере застрял, но в какой-то момент оно стало очень модным. Причем, эта же старая академическая тема из 80-х. И вдруг оно через 20 лет вылезло и начало всех кусать за голову. Даже фронтенд-инженегров покусали, они стали такое вытворять! Хотя из задача просто отрисовать табличку и три кнопочки обработать. И кто-то даже стал делать функциональную генту aka nixos. Дурка плотно накрыла планету. И даже в C++ и жаву внесли лямбды. Причем никак нельзя сказать, что качество софта от этого поветрия как-то улучшилось.

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

Лет 10 назад энтузиасты носились с Nemerle

Можно для слоупоков пояснить, чем оно отличается от F#? Наличием макросов? Тут недавно в треде про CLojure мне один пытался пояснить, что без макросов никак нельзя жить. Так что ж получается, F# без макросов взлетел, а Nemerle с макросами — нет?

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

миллион строк

На питоне это займёт от пары лет до бесконечности.

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

Чтобы делать неблокирующий параллельный ввод-вывод? Дык это я могу делать и без асинхронного сахара, на одних колбэках и неблокирующих ситемных вызовах.

Как показала практика, синтаксический сахар делает неблокирующие системные вызовы гораздо удобоваримее.

Упрощение ментальной модели по сравнению с тредами — код между двумя await исполняетеся сугубо синхронно. В твоём предложении с условным gil.release() нельзя быть уверенным, что вызываемый тобой код втихаря его не выполнит. Даже этот пресловутый d['foo'] += 1 вызывает как минимум 3 метода на двух объектах, каждый из которых может втихаря выполнить gil.release().

Ну и все асинк-фреймворки имеют функционал вида «выполнить в другом треде, вернуть future с результатом исполнения». Как раз для того, чтобы посылать в другой тред долгоиграющие непитоньи операции вроде распаковки архива.

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

Упрощение ментальной модели по сравнению с тредами — код между двумя await исполняетеся сугубо синхронно. В твоём предложении с условным gil.release() нельзя быть уверенным, что вызываемый тобой код втихаря его не выполнит

Со одной стороны — да. С другой стороны — проброс всех этих await-ов становится конкретным геморром. То есть, всё то, что раньше «вызывалось втихаря» теперь нужно вызывать самому явно.

Ну и все асинк-фреймворки имеют функционал вида «выполнить в другом треде, вернуть future с результатом исполнения»

Да. Что еще больше делает меня непонимать, зачем нужна асинхронщина. Если добавить в язык явное разрешение отпускания GIL (аналог await), запрещая при этом все неявные (опционально), то потоки покрывают все применения, отправляя асинхронщину на мусорку. Где ей и место, на мой взгляд.

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

Я тут ничего особенного не могу сказать, ибо не учил. Но энтузиасты хвалились макросами. Паттерн-матчингом и прочими ФП-шными штуками хвалились, но они и в F# есть. Ещё каким-то Nemerle.Peg хвалились, как крутым инструментом для создания языков.

У F# всё-таки поддержка корпорации была. И все равно взлетел он не очень высоко.

У Nemerle с корпорациями история интересная вышла. В 2012 или даже раньше русские разработчики этого языка начали хвалиться, что их заметила JetBrains, берёт на работу, чтобы развивать язык. И после этого Nemerle исчез. Зато в это же время появился Kotlin от той же JetBrains.

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

Вся фича await как раз в том, что его надо протаскивать на самый верх call-стека, чтобы всем было видно, что тут происходит.

Для тех, кто так делать не хочет, никуда не исчезали нативные треды, и гринлеты с gevent наперевес.

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

У F# всё-таки поддержка корпорации была. И все равно взлетел он не очень высоко

F# постоянно висит если не на первых местах, то в первых десятках. При том, что это язык, который не похож ни на питон, ни на JS, ни на C, ни на C++, ни на C# — вообще ни на что не похож, короче говоря.

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

F# это для тех, кто на самом деле хотел бы писать на хаскелле, но «мы в данной организации используем стек от MS, а не ваши академические эксперименты».

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

Вся фича await как раз в том, что его надо протаскивать на самый верх call-стека, чтобы всем было видно, что тут происходит

Да, вот я и говорю, что можно было бы то же самое сделать для обычного кода: если функция сверху унаследовала разрешение на отпускание GIL, то имеет право отпускать GIL. Для реализации подобной штуки нужно вносить еще меньше изменений в язык и стандартную либу, чем было внесено для реализации асинхронного сахара, при этом многопотоки покрывают одновременно и нишу неблокирующего ввода-вывода, и нишу многопоточных вычислений, не покрывая. разве что, каких-то стремных случаев разветвления и слияния путей выполнения, которые не так-то просто реализуются даже в самой асинхронщине, потому что в таком случае нужно делать всякие create_task. Future, и прочие прыжки через кольца.

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

F# это для тех, кто на самом деле хотел бы писать на хаскелле, но «мы в данной организации используем стек от MS, а не ваши академические эксперименты»

Так и я о том же. Хаскель никому не нужен, а по F# работа стабильно есть. Мало, но есть. Причем, одна из самых высокооплачиваемых в отрасли (в среднем по палате).

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

У меня есть подозрение, что хаскелистам F# не зайдёт. Разве что от безысходности могут на нём писать. Это больше для особо одаренных скриптушечников, которые очень жаждут функциональщины без особого понимания зачем оно нужно. Ну и каких-то реальных академиков можно припахать. В общем, штука полезная.

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

Запаковывать интерпретатор с программой это в общем практика более древняя чем многие здесь присутствующие, но в случае с питоном это как-то… сложнее чем нужно.

ну и как нужно, где эталон?

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

Строки и кодировки.
Я на ровном месте могу получить b строку с содержимым u строки, и привести тип с сохранением смысла значения строки я могу только серией encode/decode с неочевидными значениями параметров.

Во втором питоне нужно было просто один раз decode сделать.

В остальном третий питон и правда лучше.

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

Подожди.

Но для всего этого вовсе не требуется имитировать вытесняющую многозадачность, принудительно перебрасывая gil между потоками. По сути мы и так всё исполняем как простые корутины, но еще обмазались потоками зачем-то.

За пределами gil есть многопоточность, да. Но она и при использовании gil как простого мьютекса «вошел — вышел» будет.

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

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

Я на ровном месте могу получить b строку с содержимым u строки, и привести тип с сохранением смысла значения строки я могу только серией encode/decode с неочевидными значениями параметров.

+1

Или может я чего-то про работу со строками не понял…

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

Вся фича await как раз в том, что его надо протаскивать на самый верх call-стека, чтобы всем было видно, что тут происходит.

Эмм… нет.

Вот пусть будет функция:

let foo = async function(x)
{
    ...
}

Теперь я её вызываю:

let bar = function(x)
{
    let y = baz1(x);
    let z = baz2(x);
    foo(y + z);
}

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

В общем, не серебряная пуля даже близко.

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

Я тоже поиблизительно в то же время, может на пару лет позже. И это был реально язык для рисования снежинок. Где-то у меня книга по js тех лет была, щас было бы забавно её полистать, если она сохранилась.

Но херовые свойства языка определялись тем, что:

  • Писать на нём особо нечего, он есть только в браузере и в мелкомягком JScript.
  • Даже если было бы что, совершенно не понятно, зачем. В то время на си-то не всегда удавалось хоть как-то вписаться в производительность машины.
  • Стандартная библиотека де факто отсутствует. Любое мало-мальски приличное скриптование начинается с копипаста велосипедов.
  • Дыры в дизайне языка. Глобальные переменные по дефолту и т.п.
  • Как писать на ЯП с прототипной моделью, вообще мало кто представлял. В результате имели только говнокод, в том числе в учебниках.

Сейчас всё это либо давно неактуально, либо исправлено.

Остался только дебильный косяк, что «разделители statement-ов» точка с запятой и новая строка работают по-разному.

Реализаций полно, от жирных до сверхтонких, которые можно засунуть даже в МК.

Реально я не вижу сейчас причин не использовать js как ЯП общего назначения, в том числе для логики внутри приложений, для скриптов локалхоста, или для написания самостоятельных консольных приложений, например.

Учитывая, сколько всего сейчас вокруг этого языка вращается, я вангую, что возможно появление спецификации, накладывающей ограничение на произвольность изменения прототипов и полей после фазы парсинга и частичного исполнения кода в топ-левел контексте. А это выводит язык на совершенно новый уровень с выводом типов и компиляцией в натив.

Будем посмотреть.

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

ну и как нужно, где эталон?

Electron. Всякие ранние паскали с их p-code. Löve который фреймворк на lua для создания игр.

Не пробовал, но говорят нынче с java идёт тулза чтобы эту самую jvm бандлить с приложением.

PolarFox ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.