LINUX.ORG.RU
ФорумTalks

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


4

2

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

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

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

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

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

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

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

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

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

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


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

некорректно сравнивать давно мёртвые паскакал и бэйсик

Корректно! Они *тогда* уже были мертвыми. А на данный момент нас всех еще и переживут.

это ты про высер мысы под названием VBS

Скорее про QuickBasic, потом про VisualBasic, потом про VBA, а затем уже и про VBS.

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

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

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

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

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

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

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

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

Корректно! Они *тогда* уже были мертвыми. А на данный момент нас всех еще и переживут.

эта твоя реальность как-то может найти отображение в моих интернетах?

Скорее про QuickBasic, потом про VisualBasic, потом про VBA, а затем уже и про VBS.

на сегодня, ИМХО, олдфаги юзавшие VBS уже вымерли. Я уж не говорю про всё остальное...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Скорее про QuickBasic, потом про VisualBasic, потом про VBA, а затем уже и про VBS.

Ну вообще-то Бейсики были во всех микрокомпьютерах 80-х. По количеству инсталляций, так сказать, был куда более распространён, чем Си.

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

на сегодня, ИМХО, олдфаги юзавшие VBS уже вымерли

Да нет, я вот пользовался совсем недавно :)

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

Если тебе интересно, то этим летом я тоже срал в сартире типа МЖ с двумя дырками.

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

Как лето прошло, на ЛОР по нужде теперь ходишь?

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

Ну вообще-то Бейсики были во всех микрокомпьютерах 80-х.

КвикБейсик кардинально отличается от бейсиков в микрокомпьютерах. И появился он уже много позже.

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

КвикБейсик кардинально отличается от бейсиков в микрокомпьютерах.

Чем?

И появился он уже много позже.

В 85-м, если верить википедии. Я бы даже не сказал, что позже.

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

КвикБейсик кардинально отличается от бейсиков в микрокомпьютерах.

Чем?

Наличием примитивов структурного программирования, насколько я понимаю. Все-таки микрокомпьютерные бейсики были типа «10 IF 20 GOTO 30».

Кроме того, для срерьезного «индустриального» программирования они не использовались. В отличие от КБ.

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

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

Изучение ассемблера - это как раз способ изучения «низкоуровневой архитектуры».

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

Изучение ассемблера - это как раз способ изучения «низкоуровневой архитектуры».

Ассемблер - это ISA. Толку с неё для эффективного программинга не так много, если микроархитектуру не знать, под которую пишешь.

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

Кроме того, для срерьезного «индустриального» программирования они не использовались. В отличие от КБ.

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

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

Ассемблер - это ISA. Толку с неё для эффективного программинга не так много

«Здравствуйте. Я новичок в программировании.»

если микроархитектуру не знать, под которую пишешь.

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

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

это как раз способ изучения «низкоуровневой архитектуры».

Да - способ. Но это не значит что нужно кропеть над изучением C ради изучения C.

Изучение C должно идти параллельно какой-то низкоуровневой задаче системного, прикладного или еще какого-либо программирования.

И уж точно, что С не должен быть первым и/или основным языком начинающего программиста. Да и низкоуровневое программирование вообще, не должно быть. В противном случае, развивается хроническое неуважение к чужим, ИЧСХ, к своим абстракицям, из-за чего «прилетает» всем.

C же, ввиду своей специфики, не представляет средств «принудительного уважения» в отличие от того же C++, а значит, от программиста требуется определенная (само)дисциплина которой на начальном этапе нет по-определению.

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

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

Ок. Убедил. Спорить не буду.

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

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

Нууу... В ассемблере x86, например, есть замечательная, удобная инструкция LEA, а потом оказывается, что где-то в районе Нехалема появился перфкаунтер «pipeline stalls caused by LEA».

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

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

В ассемблере x86, например, есть замечательная, удобная инструкция LEA, а потом оказывается, что где-то в районе Нехалема появился перфкаунтер «pipeline stalls caused by LEA».

Замечательно. И как понять этот счетчик, если не знаешь, что такое LEA?

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

Замечательно. И как понять этот счетчик, если не знаешь, что такое LEA?

Ну так для того, чтобы вникать в микроархитектуру, нужно знать ISA для начала. Но изучение ISA тебе мало что про MA скажет.

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

Ну так для того, чтобы вникать в микроархитектуру, нужно знать ISA для начала.

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

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

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

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

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

Я считаю, что его (ассемблер больших машин) сейчас изучать вообще нет смысла

Я не уверен, что понимаю термин «ассемблер больших машин», но насчет необходимости изучения ассемблера уже ответил.

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

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

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

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

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

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

Сейчас даже gcc приличный код генерирует. Ловить вручную уже почти нечего

Как ты его оценишь, если не знаешь асма?

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

На ЛОРе умные люди пишут, что нужно знать ассемблер :)

Ну знайте, знайте :) Просто его полезность переоценена. Это если знать, а не примерно понимать листинг дизассемблера.

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

его полезность переоценена. Это если знать, а не примерно понимать листинг дизассемблера.

«Понимать листинг дизассемблера» - это тоже знание. Знать асм на уровне основного или даже вспомогательного языка программирования, наверное, уже не нужно.

tailgunner ★★★★★
()
Ответ на: комментарий от 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 ★★★★
()
Ответ на: комментарий от Macil

КвикБейсик кардинально отличается от бейсиков в микрокомпьютерах.

тоже самое дерьмо, только от мысы и на более быстрых CPU.

И появился он уже много позже.

лучше-бы он не появлялся, а мысы запили-ла бы что-то более человеческое. Впрочем, к винтукею(или ХП) мысы это и сама поняла, и выкинула этот бэйсик нафиг. Без альтернативы.

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

Потому что в современных реальностях с ассемблерной шашкой ничего не выдоишь

выдоить-то ты выдоишь, вот только _только_ для своего компьютера. На других это либо вообще не взлетит, либо будет работать уныло. Ну и смысл? И да, для других придётся переписывать ВСЁ с нуля.

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

На ЛОРе умные люди пишут, что нужно знать ассемблер

одно дело знать, и совсем другое - писать на нём.

drBatty ★★
()
Ответ на: комментарий от 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

В таком случае, C++ прямой предок BrainFuCk'а.

Это очевидно ещё при взгляде на спеки. Только у брейнфака это несколько строчек, а у С++ — несколько сотен страниц.

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

Это очевидно ещё при взгляде на спеки.

а ты их видел? Тогда я тебя понимаю - C++ действительно очень простой и логичный ЯП.

Только у брейнфака это несколько строчек, а у С++ — несколько сотен страниц.

боюсь, что ты ниасилил даже несколько строчек...

drBatty ★★
()
Ответ на: комментарий от 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 ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.