LINUX.ORG.RU
ФорумTalks

“Программируйте с использованием языка, а не на языке” vs быдлокодерские и небыдлокодерские языки


4

2

//Видит бог, тему хотел создать в Talks...

Здравствуйте. Я новичок в программировании, опыта работы у меня нет. Следовательно какие-то особенности работы программиста, явления в программировании и “подводные камни” для меня могут быть скрыты. Сейчас я подыскиваю работу или место для стажировки и мне стали доступны вакансии C#-программиста и Python-программиста.

И вот в чём мой вопрос.

Я заметил, что существует два образа мышления среди программистов:

1. “Программируйте с использованием языка, а не на языке”. Программист – это образ мышления, способность к абстракции, логике, знание алгоритмов. Язык – это лишь инструмент для выполнения определённой задачи. Если ты хороший программист, то ты (с некоторыми оговорками) можешь решать разные задачи, на разных языках.

2. В мейнстримовых языках снижают порог вхождения. Их делают простыми. Технологии развиваются таким образом, чтобы сделать создание программ максимально простым и быстрым. Это правильно, но приводит к тому, что программисты “тупеют”, можно быть программистом, не зная основопологающих и очень важных вещей. Таким образом появляется деление на “быдлокодерские” и “небыдлокодерские” языки. Соответственно, программирование на “быдлоколерских” языках какбы отупляет.

С одной стороны есть C#. Он считается, как мне показалось, именно “быдлокодерским”. С другой стороны Python. Конечно, не haskell какой-нибудь, но язык (опять же – как мне показалось), считается серьёзным, пользуется популярностью в академиечских кругах, сам видел MIT'шные курсы на нём.

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

И в итоге, главный вопрос: в начале карьеры, стоит ли выбрать программирование на серьёзных языках (то есть, принять ли правильным пункт 2), или не парить себе мозг (принять пункт 1)? Или возможно, даже если первый пункт верен, всё равно стоит предпочесть Python?

Перемещено post-factum из general


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

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

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

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

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

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

я не слишком понимаю, какой смысл в импративном лиспе? Создатели этого вашего емакса возможно SICP не осилили?

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

я не слишком понимаю, какой смысл в импративном лиспе? Создатели этого вашего емакса возможно SICP не осилили?

лисп — он как пластилин — лепи что хочешь, и как хочешь, никто с калашом сзади стоять не будет.

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

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

это просто, и я могу тебе это рассказать: профит в том, что ты можешь ИЗМЕНЯТЬ свой код. А я - не могу (потому-что я пишу на сишечке, а в сишечке функция - это константные данные по определению. Т.е. их можно только выполнять). А твоя проблема в том, что ты _можешь_ менять код, но в силу своего скудоумия - не знаешь как. Для тебя эта возможность - как граната для обезьяны, единственное, что она может - принять Истинную Веру. У меня тоже есть такие гранаты, но я могу их использовать максимум как метательные снаряды, типа булыжников. Во всяком случае - хоть какой-то профит.

Обидно? Да?..

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

лисп — он как пластилин — лепи что хочешь, и как хочешь, никто с калашом сзади стоять не будет.

любой тьюринг-полный ЯП подойдёт под это определение.

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

Создатель емакса Столлман. sicp в 85 году появился, emacs - в 76.
Вообще то адепты лиспа не к фпшности лиспа апеллируют, а к другим фишками.

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

это просто, и я могу тебе это рассказать: профит в том, что ты можешь ИЗМЕНЯТЬ свой код. А я - не могу (потому-что я пишу на сишечке, а в сишечке функция - это константные данные по определению.

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

Обидно? Да?..

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

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

Создатель емакса Столлман. sicp в 85 году появился, emacs - в 76.

я знал, что ты знаешь. Но не думал, что ты не знаешь, что я это знаю. Это такая ирония, проще говоря...

Вообще то адепты лиспа не к фпшности лиспа апеллируют, а к другим фишками.

другие фишки не интересны, ибо за 40 лет напридумывали других ЯП, в которых эти фишки имеют лицо, а не свиное рыло.

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

это просто, и я могу тебе это рассказать: профит в том, что ты можешь ИЗМЕНЯТЬ свой код. А я - не могу (потому-что я пишу на сишечке, а в сишечке функция - это константные данные по определению.

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

согласен, я не знаю. Хорошо, ты знаешь, вот и продемонстрируй. Лично я-то знаю как это делается, вот только у меня ничего путного не получается...

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

ты рано обижаешься - этого ещё никто не придумал.

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

Лично я-то знаю как это делается, вот только у меня ничего путного не получается...

Для примера

int (*some_function)(int) = [](int x) -> int
{
    // initial implementation ...
};

// ...

    // JIT from file ...
    hot_function<llvm_ee, int(*)(int)> f("f1.llvm.bc", "f1");
    some_function = *f;

С llvm там строк сто нужно написать для реализации hot_function. Так же можно поступить и для libjit или любого кода который может генерировать машинный код в выделенный буфер, но тогда придёться писать что-то вроде

    hot_function<some_code_gen_ee, int(*)(int)> f;
    // и ручками строить функцию на неком абстрактном ассемблере
    f.ee.ssa_inst(...);
    ...
    some_function = *f;

при наличии llvm и clang уже нет смысла так делать.

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

Лично я-то знаю как это делается, вот только у меня ничего путного не получается...

Для примера

написать изменяемую функцию я могу на _любом_ ЯП. Расскажи, как её менять, что-бы получилось что-то путное?

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

написать изменяемую функцию я могу на _любом_ ЯП

Да ладно, как ты в C/C++ изменишь функцию

ResultType some_function(ArgTypes...)
{
    ...
}

? Вообще никак, потому что в машинном коде будут звонки на фиксированный адрес some_function (ты же не станешь менять права на запись для CS и переписывать машинный код some_function - может банально не хватить места).

Или как ты укажешь такой some_function:

ResultType (*some_function)(ArgTypes...) = ...

на новый код, если этот новый код не известен во время компиляции? Нужен JIT для C/C++, то есть LLVM + Clang.

Расскажи, как её менять, что-бы получилось что-то путное?

Если есть указатель вида

ResultType (*some_function)(ArgTypes...);

и нужно во время выполнения обновить код такой функции - пишем файл some_function.c (можно в tmpfs) с новой some_function, превращаем его в some_function.llvm с помощью clang, получаем биткод с помощью llvm-as (не забываем про symbol table, либо передаём явно контекст, либо делаем динамическую таблицу символов как в лиспе), подгружаем этот биткод в llvm::ExecutionEngine, находим функцию, берём её машинный код, кастуем к ResultType(*)(ArgTypes...) и присваиваем some_function. Можно отвязаться от CLI в виде clang и llvm и обойтись одним API, но так сложнее, если обновление функции не является узким местом (а оно не должно), то смысла в этом нет.

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

Да ладно, как ты в C/C++ изменишь функцию

напишу интерпретатор любого другого ЯП. Например LISP или ту-же сишечку. Очевидно же!

Или как ты укажешь

какая разница как, если ты не рассказал, ЗАЧЕМ? Интерпретировать (и компилировать) можно любой код. В т.ч. и машинные коды, это не проблема. В конце концов, я могу создать файл, записать туда код, и запустить этот файл. Разве нет?

Если есть указатель вида

твои жабокостыли мне не интересны. В C++ такое делается нативно, без потерь производительности. У тебя это всё равно костыль, ибо нет прямого доступа к коду. Если конечно твой CPU не умеет выполнять байткод нативно. Мой - не умеет.

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

напишу интерпретатор любого другого ЯП

Это никак не поможет в изменении (точнее, генерации и изменении указателя на) нативных сишных функций.

какая разница как, если ты не рассказал, ЗАЧЕМ?

Ты уже сказал:

профит в том, что ты можешь ИЗМЕНЯТЬ свой код. А я - не могу (потому-что я пишу на сишечке, а в сишечке функция - это константные данные по определению.

так что если тебе это нужно (предусмотреть замену некой сишной функции в рантайме на произвольную сишную же функцию пользователя с той же сигнатурой) и ты понимаешь в чём профит - получи нативный JIT (никакого байтокда, оно генерирует непосредственно машинный код) для сишечки в виде LLVM + Clang и распишись.

твои жабокостыли мне не интересны

Где ты тут увидел Java и байткод? В C/C++ можно определить указатель на функцию и вызвать функцию по указателю, Clang и LLVM могут генерировать нативные функции (в виде машкода) из кода на C/C++ в рантайме. Вот в лиспе все глобальные функции вызываются по указателю (предполагается SBCL-like реализация), указатель добывается из динамической таблицы символов лукапом и помещается в неё компилятором образа - поэтому там всё обновляемое, нет никаких проблем сделать то же самое для C/C++ при наличии JIT библиотеки.

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

напишу интерпретатор любого другого ЯП

Это никак не поможет в изменении (точнее, генерации и изменении указателя на) нативных сишных функций.

а зачем мне на настолько высоком уровне абстракций именно нативный изменяемый код? Для простых задач я могу и так написать, да в принципе glibc никто не отменил.

Ты уже сказал:

я сказал, что _могу_, но не сказал _зачем_. По всему выходит, что необходимости такой нет. Лично я вижу только один юзкейс: написание полиморфных вирусов для того, что-бы антивирус их по сигнатурам кода не спалил - каждый штамп с разным кодом, который впрочем гадит аналогично... В прочем, полиморфные вирусы тоже можно писать на сишечке, ибо нам нужен новый код только в новых штампах.

Где ты тут увидел Java и байткод? В C/C++ можно определить указатель на функцию и вызвать функцию по указателю, Clang и LLVM могут генерировать нативные функции (в виде машкода) из кода на C/C++ в рантайме

что мешает мне использовать свой байткод? Который я и буду невозбранно изменять в рантайме. Проблема в том, что байткод НЕ нативный. «Нативным» он является только для жабокодера(или лиспокодера), но CPU выполнять его НЕ может. В отличие от того кода, который выдаёт компилятор C/C++. И это не баг, а фича.

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

а зачем мне на настолько высоком уровне абстракций именно нативный изменяемый код?

Он всегда должен быть нативно изменяемый, чистый интерпретатор без JIT это просто недоделанная VM с JIT, такой интерпретатор может быть нужен для простоты реализации, переносимости, лёгкой встраиваемости или меньшего memory footprint, только без JIT он останется «тормозом». Но изначально у тебя речь шла про си, то есть «в лиспе мы можем обновлять функции, в си - не можем». Это не так.

я сказал, что _могу_, но не сказал _зачем_

Ты как раз сказал «не могу», то есть как будто это вообще невозможно. Даже без всякого LLVM можно подключать/отключать soшки с обновляемым кодом по dlopen/dlclose. Так можно делать плагины которые можно подключать и отключать без остановки (и тем более перекомпиляции) приложения.

Лично я вижу только один юзкейс

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

что мешает мне использовать свой байткод?

Будешь писать VM с байткодом которая, к тому же, будет тормозить? И это при наличии готовых решений.

«Нативным» он является только для жабокодера(или лиспокодера)

У JVM байткод это средство переносимости, для HotSpot это всё равно промежуточная стадия до получения нативного кода. Для лиспокодера использующего SBCL в режиме компиляции вообще никакого байткода нет - всюду происходит обновление нативного кода для CPU.

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

Он всегда должен быть нативно изменяемый, чистый интерпретатор без JIT это просто недоделанная VM с JIT, такой интерпретатор может быть нужен для простоты реализации, переносимости, лёгкой встраиваемости или меньшего memory footprint, только без JIT он останется «тормозом». Но изначально у тебя речь шла про си, то есть «в лиспе мы можем обновлять функции, в си - не можем». Это не так.

насколько я знаю, *любое* использование указателя на функцию(кроме прямого вызова) в сишечке == UB. А кроме этого к коду никак не добраться, ибо данные могут быть только в памяти данных, и выход за границы данных это тоже UB. Ну а в интерпретаторах - eval есть везде. Какая разница, выполнять код из текста программы, или откуда-то ещё? Код для интерпретатора это данные. (код для компилятора тоже данные, но запуская программу мы выполняем не компилятор, а саму программу). А JIT тут не причём. В принципе, можно сделать компилятор с изменяемыми данными, но это будет уже не C/C++.

Ты как раз сказал «не могу», то есть как будто это вообще невозможно.

В сишечке невозможно, но есть Over9000 других ЯП, в которых это возможно, и благодаря JIT'у достаточно быстро.

Даже без всякого LLVM можно подключать/отключать soшки с обновляемым кодом по dlopen/dlclose. Так можно делать плагины которые можно подключать и отключать без остановки (и тем более перекомпиляции) приложения.

можно. Ну и что это даёт? Очередной switch/case по уже готовому коду?

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

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

1. запускаем параллельно второй сервер

2. отправляем запросы на второй

3. ждём, пока первый обработает все запросы

4. отключаем первый.

вот и вся недолга. Первому серверу вовсе не обязательно менять свой код.

Будешь писать VM с байткодом которая, к тому же, будет тормозить? И это при наличии готовых решений.

буду. и тормозить она не будет, потому-что мой байткод будет на решение задачи «ЗАЧЕМ?», а твой готовый - для парсинга яваскрипта на быдлоконтакте.

У JVM байткод это средство переносимости, для HotSpot это всё равно промежуточная стадия до получения нативного кода. Для лиспокодера использующего SBCL в режиме компиляции вообще никакого байткода нет - всюду происходит обновление нативного кода для CPU.

байткод это конечно хорошо... В случае, если нам нужно написать игрушку для Over9000 разных мобил, и нам не потянуть Over9000 компиляций... Но это лишь одна из существующих задач. Часто процессоры однотипные, компилировать нужно 1..2 раза, и разработчик вполне себе может с этим справится, а не валить компиляцию на клиентов. Да ещё и в рантайме.

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

*любое* использование указателя на функцию(кроме прямого вызова) в сишечке == UB

UB это сильные касты указателей и присваивание указателю на функцию значения 0 - прямое проявление the billion dollar mistake, так как fat_pointer<A -> B> ::= 0 + valid_pointer<A -> B> тут явно не к месту, тип должен быть просто valid_pointer<A -> B> который под нормальным набором операций никак испортиться не сможет. Либо вызов функции по толстому указателю должен работать как map для функтора fat_pointer, то есть просто сохранять 0 в случае 0 и выполнять нормальный вызов в случае valid_pointer. С++11 это никак не исправил, хотя устранил UB для std::function - теперь можно ловить std::bad_function_call. Так что никаких UB. Ну и в C++ можно сделать свою шаблонную function которая будет вести себя совсем правильно.

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

Изначально код лежит в сегменте кода, а не в «памяти данных». Но это условности - всегда можно сделать mmap с MAP_ANONYMOUS / PROT_EXEC очередной страницы или изменить права существующей страницы с помощью mprotect (llvm::ExecutionEngine так и должен делать).

Ну а в интерпретаторах - eval есть везде

Не факт, интерпретатору достаточно интерпретировать свои выражения, производить побочные эффекты и возвращать значения, то есть делать (String ->) Expr -> Value * Effect (-> String), это уже будет интерпретатор даже без доступа к функции интерпретации из термов Expr (без eval).

А JIT тут не причём.

JIT это всё что позволит превратить текст на языке Lang (в данном случае C/C++) в машинный код данной Arch во время выполнения и тут же связать этот машинный код с символом (в C/C++ - указателем на функцию) известным ещё во время компиляции или появившимся во время выполнения (при динамической таблице символов), так, что обращение и вызов такого символа будет иметь уже новый, в соответствии с обновлением, смысл.

В сишечке невозможно

Возможно.

Ну и что это даёт? Очередной switch/case по уже готовому коду?

Нет, просто позволит сменить код функции в рантайме на любой произвольный, если таковое обновление было предусмотрено.

без таких извращений.

Читая следующий список задумываешься что ещё из является извращением. А вообще, Erlang так и делает как ты расписал (для своих лёгких процессов), но это не Ъ, единственное Ъ в этом смысле я видел только в CL.

и тормозить она не будет

Байткод зарулит JIT и вообще обгонит процессор?

а не валить компиляцию на клиентов

Gentoo? Не, не слышал :) По крайней мере, они же тонкие, либо получают обстрипаные бинарники с плугинами (что не мешает делать замену функций). Обновление нужно не клиентам, а разработчикам. Вот JIT ЛОРа никак тебе не мешает его смотреть (может «мешать» только JIT SpiderMonkey/V8).

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

просто valid_pointer<A -> B> который под нормальным набором операций никак испортиться не сможет.

я не нашёл в стандарте этому подтверждения.

Ну и в C++ можно сделать свою шаблонную function которая будет вести себя совсем правильно.

шаблоны бывают только во время компиляции, в рантайме нет никаких шаблонов.

Изначально код лежит в сегменте кода, а не в «памяти данных». Но это условности - всегда можно сделать mmap с MAP_ANONYMOUS / PROT_EXEC очередной страницы или изменить права существующей страницы с помощью mprotect

о том и речь, что получить доступ к сегменту кода можно только через непереносимые костыли.

Не факт, интерпретатору достаточно интерпретировать свои выражения, производить побочные эффекты и возвращать значения

не факт, согласен, но допилить функционал eval'а не составит труда.

В сишечке невозможно

Возможно.

может и возможно. Только такого никто не делал - JIT'а прямо в код arch. И это будет уже не сишечка, её надо расширить как-то так:

char str[] = "int f(){return printf(\"Hello world!\n\");}";
func_ptr buf[9001];// выделяем место под функцию в 9001 символов
buf = eval(str);// заполняем массив
buf();// выполняем созданную функцию
вторая строчка попросту не имеет смысла в си, третья интересная, но в си нет eval (в принципе в компиляторе есть). Четвёртая вроде возможна, если сегмент данных можно выполнять.

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

Байткод зарулит JIT и вообще обгонит процессор?

легко! Вот пруф:

байткод 0xAF, который рисует окно с двумя кнопками в чистом X11 вполне себе заруливает (в разы!) браузер с JIT компиляцией того же окошка на JavaScript.

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

я не нашёл в стандарте этому подтверждения.

Подтверждение нужно искать не этому, а существованию UB которое ты подозревал, то есть тому, что можно испортить указатель на функцию без кастов и 0-указателей, то есть как-то сделать так, чтобы он стал указывать на память по которой никакого полезного и правильного кода нет. Если ты найдёшь в стандарте описание такой возможности и соответствующее определение семантики как UB, тогда да. Иначе говоря, доказывать, что всё (∀) хорошо не нужно, нужно доказывать что не может быть плохо (¬∃, это одно и то же, но чтобы доказать первое нужно доказывать второе, то есть доказать отсутствие прецедента). Я вот не верю в существование такого прецедента (с определёнными допущениями про касты и т.п.), поэтому не вижу смысла искать в стандарте то чего там нет.

С другой стороны, во всяком JIT для C/C++ обязательно будут сильные касты, но это уже вопрос отсутствия багов (которые могут дать UB) в таком JIT и в коде его использующем.

шаблоны бывают только во время компиляции, в рантайме нет никаких шаблонов.

В статически типизированном языке то что существует во время компиляции как раз направлено на предотвращение нехороших вещей в рантайме. Например:

template <typename R, typename... A>
class function {
    typedef R(*FP)(A...);
    typedef R(&FR)(A...);
    FP fn;
  public:
    explicit function(FR fn_) : fn(fn_) {}
    R operator()(A... x) { return fn(x...); }
    void operator=(FR fn_) { fn = fn_; }
};

доступ к сегменту кода можно только через непереносимые костыли

Решаем задачу на Linux с mmap и всё у нас хорошо. Понадобилось переносимость на Windows? Пишем зависимую часть для неё и тоже решаем задачу, оставляя общим интерфейс. Например, JIT LLVM работает везде и имеет общий интерфейс.

допилить функционал eval'а не составит труда.

Ну а при наличии родного ассемблера и компилятора «не составит труда» допилить JIT. Титиретически :)

Только такого никто не делал - JIT'а прямо в код arch.

Ты про си и плюсы, да? Тогда ещё раз повторю про libJIT (это в arch из DSL на си), LLVM (это в arch из любого llvm кода), Clang (это из си и плюсов в llvm код) и загружаемые разделяемые библиотеки.

Вот пруф

Я вижу proposition, но не вижу proof. Но это не важно - речь же про реализацию _одного_ языка как байткода для VM и как JIT в машкод для CPU, а не «что угодно» vs «что угодно».

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

сишечка не из первородного вакуума , a C+ UNIX|OtherOS

в стандартной библиотеке есть функции создания/записи_в файла , запуска/обращения к ОС для выполнения процесса (выполнение компилятора) - так что UNIX is IDE

зы. tcc более прямой(похожий на твой) позволяет

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

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

можно-ли прибавлять к указателю на функцию какое-то число? Нет. Это UB. Причина в том, что не существует понятия «размер функции». По этой причине, ты можешь прибавить к указателю на int целое число, и получить следующий int. Но к указателю на функцию ничего прибавить нельзя. Можно только присвоить указатель на другую функцию(или NULL). У тебя есть ещё какие-то способы изменения указателей?

Я вижу proposition, но не вижу proof. Но это не важно - речь же про реализацию _одного_ языка как байткода для VM и как JIT в машкод для CPU, а не «что угодно» vs «что угодно».

твой JIT это тоже далеко не «всё что угодно», а реализация для вполне конкретного CPU.

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

У тебя есть ещё какие-то способы изменения указателей?

Я об этом и говорил - указатели на функции не портятся без кастов. Ссылки на функции - тем более, то есть не портятся nullptr-ами.

твой JIT это тоже далеко не «всё что угодно», а реализация для вполне конкретного CPU.

То есть JIT для конкретного языка под конкретные CPU будет производительней интерпретации байткода для этого же языка (допустим, рантайм уже разогрелся и JIT прошёл - выполнение машкода явно производительней интерпретации байткода).

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

У тебя есть ещё какие-то способы изменения указателей?

Я об этом и говорил - указатели на функции не портятся без кастов. Ссылки на функции - тем более, то есть не портятся nullptr-ами.

именно потому, можно считать указатели на функции - константами, известными во время компиляции. Т.е. в рамках C++ невозможно написать изменяемую функцию, возможно только написать набор функций. Что в принципе эквивалентно switch/case.

твой JIT это тоже далеко не «всё что угодно», а реализация для вполне конкретного CPU.

То есть JIT для конкретного языка под конкретные CPU будет производительней интерпретации байткода для этого же языка (допустим, рантайм уже разогрелся и JIT прошёл - выполнение машкода явно производительней интерпретации байткода).

конечно. Однако я не о том, а о том, что _существующий_ JIT (например JS) намного менее производительный, чем специализированный байт-код. Например:

байткод 0xAF, который рисует окно с двумя кнопками в чистом X11 вполне себе заруливает (в разы!) браузер с JIT компиляцией того же окошка на JavaScript.

Напомню, что речь шла об этом:

Будешь писать VM с байткодом которая, к тому же, будет тормозить? И это при наличии готовых решений.

буду. и тормозить она не будет, потому-что мой байткод будет на решение задачи «ЗАЧЕМ?», а твой готовый - для парсинга яваскрипта на быдлоконтакте.

повторюсь: готовый JIT под сферически-вакуумную VM в данном случае - худшее решение.

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