Трейсинг - одна из техник GC. Рассуждение про него идёт в контексте GC, если вы не обратили внимание.
Никто не мешает нахерачить поддержку исключений хоть в голый цэ. Не задумывались почему этого никто до сих пор не сделал за 50 лет? Вот подумайте. Подсказка: посмотрите исходник ядра линукса, найдите там распространенный паттерн с goto exit_bla_bla_bla, где по метке free() и return. Подумайте.
А, ну да, язык с трейсингом/rc всех значений в куче - это язык без GC. Ага. Передайте привет фрагментированной памяти в своем языке мечты! Потом не забудьте дописать в него полновесные gc cycle, иначе сильно быстрее php работать не получится, увы.
Про байткод вы конечно прекрасно написали. А мужики-то не знали.
МАШИННЫЙ код - это mov ax bx, add 0x34, jmp и все прочие инструкции, знакомые ПРОЦЕССОРУ. Машинный код как есть отдается процессору, без промежуточной обработки.
БАЙТКОД - это incr(i), goto(1000) и что угодно ещё, что придумается инженеру птичьего "ассемблера" для своей виртуальной машины. Эти инструкции выполняются ИНТЕРПРЕТАТОРОМ байткода, либо в некоторых случаях компилируются в МАШИННЫЙ код JIT-компилятором.
Машинным кодом байткод становится с физическим изобретением процессора, способного исполнять инструкции этого байткода. Как например в 1970-80-х появлялись лисп-машины для исполнения байткода, скомпилированного из лиспа.
Вас не смущает, что shared_ptr в плюсах – это примитивный сборщик мусора? Только в большинстве языков, где GC официально заявлен, free() вызывается не сразу при исчезновении последней ссылки на объект, а для оптимизации периодически и массово, что позволяет бороться в т.ч. и с фрагментацией памяти.
Если хотите "что-то вроде низкоуровневого Go без GC", то давайте заодно хотите и без shared_ptr.
Транслятор - общее название для любых программ, которые что-то делают с исходным кодом.
Компилятор - вариант транслятора, который компилирует исходник в машинный код или байткод.
Транспилятор - вариант транслятора, который преобразует исходный код одного языка в исходный код на другом равнозначном языке.
И например интерпретатор - это тоже вариант транслятора, который исполняет исходный код as is. В свою очередь, он может сначала распарсить в AST и ходить уже по асту (большинство современных интерпретируемых языков, которые не компилят в байткод), либо парсить и исполнять построчно (большинство шелл-интерпретаторов).
Например, как вы себе представляете низкоуровневый язык без gc, очевидно без плюсовых умных указателей (и без растового доказательства безопасности памяти), но с исключениями? Вы осознаёте какой неуправляемый адище с malloc/free ждет программиста, когда исключение в любой вызванной функции создаёт в нашей пусть даже синхронной функции весь букет UB? Никакие defer не спасут.
В общем, расскажите своё видение, может я правда чего-то не понимаю.
Вы сейчас про какую систему типов? В моем мире противоположный опыт. Ocaml за деньги с 2007, хаскель для души с 2011(?), раст за деньги с 2019. Во всех этих языках ADT, и везде активная эксплуатация типов упрощала жизнь, особенно на больших проектах.
Типа того. Только люди, рассуждающие в рамках классических интов, строчек и классов с интерфейсами и темплейтами, не осознают глубину этой кроличьей норы.
GC никак не связан с увеличенным потреблением памяти (с точностью до оверхеда на счетчики ссылок). Скорее наоборот: когда автоматика за программиста думает о высвобождении памяти вовремя, в среднем потребление ниже.
Не очень понимаю как вы себе представляете язык с ручным управлением памяти и одновременно с исключениями. А память кто будет освобождать, когда исключение выкинуло нас в стеке вниз на 10 функций?
Интересно, что вы называете го низкоуровневым, хотя он проектировался наоборот как максимально простой высокоуровневый язык для студентов, который позволит им гонять джсоны без понимания как работает память, треды, кооперативная многозадачность, системные вызовы и т.д.
Также интересно, что вы плюетесь от трейтов раста, но при этом почему-то ничего не сказали про интерфейсы в го или плюсах. Мне кажется, рядом же называя код на расте перетипизированным, вы путатете унаследованную из ocaml/haskell алгебру типов в трейтами. Но даже здесь спешу вас разочаровать: чем дальше будет двигаться мейнстрим-индустрия, тем активнее будут использоваться языки с развитой системой типов, и в первую очередь - с алгеброй типов. И чем точнее типами описана программа, тем доказано меньше в ней потенциальных багов. Вплоть до формально верифицированных программ в каких-нибудь coq/idris, где верификация работает как раз на тотальном знании компилятора о теореме, описанной через систему типов. Короче говоря, с типами придется смириться :)
В статье не только языки со сборщиком мусора, есть и сравнимые с плюсами по методу работы с памятью.
Комментарии
Слив засчитан.
Трейсинг - одна из техник GC. Рассуждение про него идёт в контексте GC, если вы не обратили внимание.
Никто не мешает нахерачить поддержку исключений хоть в голый цэ. Не задумывались почему этого никто до сих пор не сделал за 50 лет? Вот подумайте. Подсказка: посмотрите исходник ядра линукса, найдите там распространенный паттерн с goto exit_bla_bla_bla, где по метке free() и return. Подумайте.
Почитайте хоть статью на которую сами ссылаетесь. Хоть до 4-й строчки.
А, ну да, язык с трейсингом/rc всех значений в куче - это язык без GC. Ага. Передайте привет фрагментированной памяти в своем языке мечты! Потом не забудьте дописать в него полновесные gc cycle, иначе сильно быстрее php работать не получится, увы.
Про байткод вы конечно прекрасно написали. А мужики-то не знали.
Байткод НЕ МАШИННЫЙ код.
МАШИННЫЙ код - это mov ax bx, add 0x34, jmp и все прочие инструкции, знакомые ПРОЦЕССОРУ. Машинный код как есть отдается процессору, без промежуточной обработки.
БАЙТКОД - это incr(i), goto(1000) и что угодно ещё, что придумается инженеру птичьего "ассемблера" для своей виртуальной машины. Эти инструкции выполняются ИНТЕРПРЕТАТОРОМ байткода, либо в некоторых случаях компилируются в МАШИННЫЙ код JIT-компилятором.
Машинным кодом байткод становится с физическим изобретением процессора, способного исполнять инструкции этого байткода. Как например в 1970-80-х появлялись лисп-машины для исполнения байткода, скомпилированного из лиспа.
Грамотей, блин.
Байткод интерпретируется (исполняется) виртуальной машиной. Последовательно, от инструкции к инструкции. Он всё правильно написал.
Вас не смущает, что shared_ptr в плюсах – это примитивный сборщик мусора? Только в большинстве языков, где GC официально заявлен, free() вызывается не сразу при исчезновении последней ссылки на объект, а для оптимизации периодически и массово, что позволяет бороться в т.ч. и с фрагментацией памяти.
Если хотите "что-то вроде низкоуровневого Go без GC", то давайте заодно хотите и без shared_ptr.
Всё ещё круче :)
Транслятор - общее название для любых программ, которые что-то делают с исходным кодом.
Компилятор - вариант транслятора, который компилирует исходник в машинный код или байткод.
Транспилятор - вариант транслятора, который преобразует исходный код одного языка в исходный код на другом равнозначном языке.
И например интерпретатор - это тоже вариант транслятора, который исполняет исходный код as is. В свою очередь, он может сначала распарсить в AST и ходить уже по асту (большинство современных интерпретируемых языков, которые не компилят в байткод), либо парсить и исполнять построчно (большинство шелл-интерпретаторов).
Никто не компилирует в c++, это не имеет практического смысла.
java компилируется в байткод jvm и затем в jre выполняется. Как есть, инструкция в инструкцию.
ruby последние ндцать лет компилируется в байткод их виртуальной машины, и ей исполняется.
swift компилируется в llvm байткод, который затем llvm-компилятором компилируется в машинный код.
go имеет свой компилятор, но дополнительно имеет экспериментальные фронтенды gcc и llvm.
rust аналогично swift, но также экспериментально поддерживает фронтенд gcc.
Жду конструктива.
Например, как вы себе представляете низкоуровневый язык без gc, очевидно без плюсовых умных указателей (и без растового доказательства безопасности памяти), но с исключениями? Вы осознаёте какой неуправляемый адище с malloc/free ждет программиста, когда исключение в любой вызванной функции создаёт в нашей пусть даже синхронной функции весь букет UB? Никакие defer не спасут.
В общем, расскажите своё видение, может я правда чего-то не понимаю.
Вы сейчас про какую систему типов? В моем мире противоположный опыт. Ocaml за деньги с 2007, хаскель для души с 2011(?), раст за деньги с 2019. Во всех этих языках ADT, и везде активная эксплуатация типов упрощала жизнь, особенно на больших проектах.
Типа того. Только люди, рассуждающие в рамках классических интов, строчек и классов с интерфейсами и темплейтами, не осознают глубину этой кроличьей норы.
слив засчитан.
GC никак не связан с увеличенным потреблением памяти (с точностью до оверхеда на счетчики ссылок). Скорее наоборот: когда автоматика за программиста думает о высвобождении памяти вовремя, в среднем потребление ниже.
Не очень понимаю как вы себе представляете язык с ручным управлением памяти и одновременно с исключениями. А память кто будет освобождать, когда исключение выкинуло нас в стеке вниз на 10 функций?
Интересно, что вы называете го низкоуровневым, хотя он проектировался наоборот как максимально простой высокоуровневый язык для студентов, который позволит им гонять джсоны без понимания как работает память, треды, кооперативная многозадачность, системные вызовы и т.д.
Также интересно, что вы плюетесь от трейтов раста, но при этом почему-то ничего не сказали про интерфейсы в го или плюсах. Мне кажется, рядом же называя код на расте перетипизированным, вы путатете унаследованную из ocaml/haskell алгебру типов в трейтами. Но даже здесь спешу вас разочаровать: чем дальше будет двигаться мейнстрим-индустрия, тем активнее будут использоваться языки с развитой системой типов, и в первую очередь - с алгеброй типов. И чем точнее типами описана программа, тем доказано меньше в ней потенциальных багов. Вплоть до формально верифицированных программ в каких-нибудь coq/idris, где верификация работает как раз на тотальном знании компилятора о теореме, описанной через систему типов. Короче говоря, с типами придется смириться :)
В статье не только языки со сборщиком мусора, есть и сравнимые с плюсами по методу работы с памятью.