Pull to refresh

Comments 88

UFO landed and left these words here
так и не нашел, как канонически звучит фраза «внутри каждой большой программы на С обязательно найдется маленький интерпретатор Lisp», или что-то типа «каждый прогарммист на С рано или поздно напишет свой Lisp» — не помню.

Но вот пассаж автора про площадь и путь по прямой однозначно с лиспом ассоциируется (для любителей можно заменить на
форт :)
«Любая достаточно сложная программа на Си или Фортране содержит заново написанную, неспецифицированную, глючную и медленную реализацию половины языка Common Lisp.»
UFO landed and left these words here
UFO landed and left these words here
с фортом, даже не знаю, а вывод лиспа в массы идет постоянно. То схему придумали, теперь вот кложа.

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

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

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

отсюда: How Object-Oriented Programming Started
The Simula languages were developed at the Norwegian Computing Center, Oslo, Norway by Ole-Johan Dahl and Kristen Nygaard. Nygaard's work in Operational Research in the 1950s and early 1960s created the need for precise tools for the description and simulation of complex man-machine systems.


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

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

Да что женщины, возьмем совсем простую штуку — нож. Что может быть проще — полоска стали, заточенная с одной стороны с ручкой, нужная для разрезания. Сколько разных ножей бывает? Почему никто не сделал «идеальный нож»?
Ответ очевиден — разные задачи, разный инструмент.
Когда нужда в высоко-уровневых абстракциях обнаруживается по ходу дела, к третьей версии системы, тогда и начинают по-быстрому колхозить недо-ЛИСП…
Важное уточнение, что «на С или Фортране». Про ООП такое по крайней мере уже не говорят.
люди, которые хотя бы пролистали курс sicp, понимают, что реализовать ООП, в принципе ничего сложного.

А те, кто хотя бы читал исходники gtk, так смогут даже с примерами на перевес показать, что нет никаких сложностей писать код в ООП-стиле на plain C.

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

И если авторы Rust поставили для себя цель — решить проблемы работы с памятью, то в ходе решения и получаются все вот эти навороты, которые кажутся «переусложнены».
«Недостатки С++ — это в первую очередь тяжелое наследие Си: ужасная система инклудов и полное отсутствие модульности.» — это и есть самые серьезные недостатки? Автор явно придирается к мелочам :-)
К мелочам? Да временами это в такой ад превращается, что аж мозг выдрать хочется. До тех пор пока вы делаете софт уровня хеллоу ворлд, вы не встретите таких проблем. А когда библиотеки уровня буста, вот тогда придется поплакать и поколоться кактусом.
Полностью согласен, было бы замечательно, если бы люди сделали не «инновационную замену C++», а C++ но без всякой С-фигни типа той, которая написана в посте (у меня точно такое же впечатление, спасибо автор за этот пост).

Я бы ещё выкинул отношения declaring != defining. Чтобы можно было сразу писать и прототип и реализацию в одном месте. Компилятор вполне может с этим справится (см Java). (Ну и без C-хедеров само собой).

Ещё есть проблема со строками: стандартный повсеместный std::string не поддерживает unicode, есть конечно std::wstring, но кто ж его использует?

Помните всяческие UINT, uint, u32, DWORD, uint32_t…

Над системой типизации надо тоже поработать. Кстати те самые сотни строк ошибок из-за небольших ошибок тоже плод этого.
Я ещё не успел ознакомился с ним в той степени, в какой хотелось бы.
Первое впечатление такое: «чересчур питон».
Да всё там нормально у автора. Просто надо читать дальше. Упоминается и препроцессор и метапрограммирование на шаблонах и т.п. Кстати, замечу, что с другой стороны наличие этих возможностей является как раз сильной стороной языка в данный момент, т.к. позволяет делать недоступное другим языка (не считая такие далёкие от мейнстрима как D, Nemerle, Rust). ))) Т.е. проблема в кривой реализации, приводящей к сложному коду, а не в самой сущности.

Кстати, забавно что автор отдельно отметил кривую систему модульности и сомнительный препроцессор, в то время как #include формально говоря тоже является директивой препроцессора. ))) Но в общем то это тоже правильно, т.к. в других языках модульность и является отдельной вещью.
Именно, модульность (как например ещё и условная компиляция) должны реализоваться на более высоком уровне, чем препроцессор C.
сборка мусора (см. Rust — Gc)

Для «идеального» языка — только в полностью отключаемом варианте…
По статье у меня есть только два вопроса:

1. И? Перечислены в общем то правильные и очевидные вещи, но не видно никаких практические выводов из всего этого.
2. А почему на geektimes, а не на Хабре? ) Вроде как нормальная техническая статья…
А какие выводы могут следовать из посылки, что самой проблемной частью с++ является — наследие С?!
Я бы добавил — из-за слабости системы типов С! И архитектурную дыру вызванную тем бардаком, который устроила MS в комитете по стандартизации, и требование обеспечения совместимости с ее поделиями, хотя еще Фортраны были разделены на поколения и режим работы (для быстрой компиляции за счет скорости исполнения, или наоборот). Почему библиотеки 8х-9х должны компилироваться с++14/17? Все должно компилироваться своей средой 200х -с++03, старье 2010 — с++11… требование обеспечения совместимости — требование написания потенциально глючных, медленных уродцев, которые никто не проверяет на совместимость и наслоения самописных переходников.
Ну так заголовок статьи вроде как намекает, что она не про критику C++, а должна предлагать что-то интересное взамен. Так вот чего-то практического на эту тему я так и не увидел. Максимум общие лозунги в конце статьи, в стиле «мы за всё хорошее и против всего плохого». )))
Objective-C со своей динамикой известен только лишь потому, что после того, как улеглась пена (а улегающаяся пена была представлена, например, Sun OBI, SGI Delta C++, эти темы обсуждались на конференциях USENIX), среди подобных подходов на плаву остался он один, и не в силу своих технических достоинств, а в силу кодовой базы, уже написанной на языке прошлого поколения. Отчасти IBM OS/2 и Apple Copland дружно сдохли, отчасти головокружение от Java, отчасти подход IBM к SOM «не доставайся же ты никому», отчасти очень малый период, когда программисты могли пощупать DTS C++, чтобы это отпечаталось в голове, и в open source проектах типа GObject был бы воплощён именно такой подход к ООП, а не тот, который в Delphi и C++.

Мне недавно удалось запустить компилятор DTS C++ от IBM, на Win8 x64 до сих пор работает, можно было бы сделать сравнение DTS C++ и Objective-C, чтобы понять, что мы потеряли. Мне вообще кажется, всем было бы лучше, если взять Foundation, AppKit и т. п. и заменить Objective-C на SOM и DTS C++ или его аналог, ускоренно повторивший эволюцию Objective-C. В WebObjects была относительно успешная замена всего на Java, в Cocoa-Java был относительно успешно работающий мост, позволяющий писать приложения на Java, из этого я делаю вывод, что возможности, не имеющие соответствия 1:1 между Objective-C и DTS C++, вроде poseAs, не помешают сделать такой переезд.

Касательно метапрограммирования, я думаю, чтобы как–то совладать с ним, можно было бы сделать возможность компилировать расширения языка в dll, и они бы манипулировали AST. Не везде будет достаточно, но тем не менее.

Языки типа ParaSail, Limbo, Erlang, Go, Rust, Cilk поднимают более общую тему — создание единого зелёнопоточного планировщика, потому что когда у каждого из этих языков планировщик свой, совмещать их все не очень очевидно, как. Пока получается только так, что у каждого из них планировщики на разных потоках OS. Подобно тому, как поверх ядер CPU работает планировщик OS, поддерживающих вытесняющую многозадачность, поверх потоков OS должен работать планировщик зелёных потоков, и у этих зелёных потоков должны быть свои зелёные мьютексы, зелёные условные переменные и т. п. Как я понимаю, такой планировщик есть у ParaSail, а у планировщиков остальных языков из списка другая модель многозадачного взаимодействия, что усложняет портирование программ, написанных в расчёте на потоки, мьютексы и условные переменные. Чтобы зелёные потоки не тратили время больше положеного, их, наверное, как–то размечать придётся, и компиляторы разных языков програмирования могут оценивать затраты CPU по–разному, не очень понятно, что с этим делать. Наверное, перекладывать задачу разметки на библиотеки времени выполнения.
Зеленые потоки без смены парадигмы программирования?! Как серьезно можно ожидать повышения быстродействия приложения, если сохраняется концепция изменяемости?! просто программы обрастут гроздями мьютексов и контроля за рейсингом( потому и ParaSail, и замена комуникациями через каналы в Лимбо и Го, обмена через общую память ), а С++ без хаков по управлению памятью ничем не будет лучше ParaSail по быстродействию. Да, и назовите библиотеки С++, которые учитывают, что будут запускаться на системах с разделенной памятью?
Зелёные потоки без проблем реализуются на C++ с помощью сопрограмм (например Boost.Coroutine). Примеры можно глянуть скажем в Boost.Asio, где показаны образцы написания сервера на сопрограммах.

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

Ну и наконец, если уж говорить о межпотоковом (или даже межпроцессном или вообще межмашинном) взаимодействие, то для этих целей есть известные удобные инструменты, не зависящие от языков. Например модель акторов. И опять же на C++ мы давным давно имеем нормальные реализации этого инструмента.
Зеленые потоки и сопрограммы — это совершенно не пересекающиеся парадигмы (первая — одна из парадигм создания многозадачности, вторая — однопоточного безблокировочного приложения).
То что в некоторых языках есть необходимые инструменты никоим образом не делает С++ их содержащим(рантайм слабоват, даже в сравнении с явой, модулой и адой, хотя и в них многозадачность куцая, но в сравнении с С++ она там, таки есть.):

" Далее, мьютексы (системные), разделяемая память и т.п. совершенно не обязательны для зелёных потоков, т.к. они могут даже не вылезать за рамки своего системного потока. " — что?! учите многозадачность, Сэр! Я не про сопрограммы, а про зелень!

" Например модель акторов. И опять же на C++ мы давным давно имеем нормальные реализации этого инструмента. " — давным-давно, да, но не этого, а того, что получилось. Зачатки появились в Occam-2/Ada, но с-программисты всегда идут своим путем, и назовите хоть одну современную программу на С++, которая работает используя все ресурсы, что многоядерного, что много машинного окружения?
Сопрограммы — это действительно другая сущность (которая кстати используется совсем не для «безблокировочных приложений»). Но достаточно добавить к ней планировщик (в простейшем случае банальный цикл for по списку сопрограмм) и мы получим работающую реализацию зелёных потоков.

Насчёт многозадачности надо как раз кому-то другому тут поучиться. Я же точно описал где смотреть (разве что прямую ссылку не дал) примеры. В примерах Boost.Asio с помощью сопрограмм реализуется удобная организация кода для многозадачности внутри одного системного потока. Далее, мы просто запускаем нужное количество (например по числу ядер процессора) таких системных потоков и получаем идеально работающую систему.

В самом C++ имеется нормальная реализация системной многопоточности. Плюс имеются сторонние библиотеки реализующие всё что угодно. Например модель акторов можно увидеть здесь www.theron-library.com. Насчёт последнего вопроса не понял — что, у кого-то действительно есть сомнения, что на C++ тривиально пишется программа, загружающая процессор на 100%? Или что? )))

P.S. Самое забавное, что сама концепция зелёных потоков полезна для решения только очень узкого спектра проблема. Когда мы имеет тысячи одновременных маленьких задач. Т.е. что-то вроде написания высоконагруженного демона. Во всех остальных случаях системные потоки очевидно удобнее и эффективнее.
Про костыли буста( и множества переносимых МТ библиотек ) в курсе, но ТС писал об идеальных языках, Вы считаете, что язык должен быть костильным?

Или что! ))) полное распределение нагрузки прямо из языка. JS-ая, на ровном месте, тотальная загрузка не то!

###
P.S. Самое забавное, что сама концепция зелёных потоков полезна для решения только очень узкого спектра проблема. Когда мы имеет тысячи одновременных маленьких задач. Т.е. что-то вроде написания высоконагруженного демона. Во всех остальных случаях системные потоки очевидно удобнее и эффективнее.
###
Самое забавное, что к зеленым потокам можно свести вообще все алгоритмы выразимые на с++ ))) а эффективность системных потоков и удобство… это, м-м, на любителя ))) если не зыбывать, что зеленые строятся поверх них, не имея никакой помощи от ОС.

Единственное, с чем можно согласиться, так это с тем, что с++ никак не поддерживает создание удобных и эффективных приложений))) как и другие языки.
Ну собственно получается всё снова сводится к тому же вопросу, поднимаемому и автором статьи. При реализации любой возможности в любом языке, где нам её разместить:
1. в конструкциях языка
2. в расширениях языка
3. в стандартной библиотеке языке
4. в сторонних библиотеках языка.

В C++ системная многопоточность реализована на уровне 2 (openmp, openacc и т.п.) и 3 (std::thread и т.п.). А всяческие лёгкие потоки, пулы задач, акторы и т.п. на уровне 4 (тут есть бесчисленное количество разных библиотек).

Так где оно должно быть реализовано, чтобы с вашей точки зрения не считалось костылями? ) Обязательно на уровне 1 (как в Эрланге) что ли?

Ну и главное… Если говорить исключительно о быстродействие (и однопоточном и многопоточном), то с правильно написанным приложением на C++ вряд ли способно что-то поспорить. )))
### www.gamedev.ru/flame/forum/?id=168247
Наконец, хотя этот предмет не из приятных, я должен упомянуть PL/1, язык программирования, документация которого обладает устрашающими размерами и сложностью. Использование PL/1 больше всего напоминает полет на самолете с 7000 кнопок, переключателей и рычагов в кабине. Я совершенно не представляю себе, как мы можем удерживать растущие программы в голове, когда из-за своей полнейшей вычурности язык программирования — наш основной инструмент, не так ли! — ускользает из-под контроля нашего интеллекта. И если мне понадобится описать влияние, которое PL/1 может оказывать на своих пользователей, ближайшее сравнение, которое приходит мне в голову, — это наркотик. Я помню лекцию в защиту PL/1, прочитанную на симпозиуме по языкам программирования высокого уровня человеком, который представился одним из его преданных пользователей. Но после похвал в адрес PL/1 в течение часа он умудрился попросить добавить к нему около пятидесяти новых «возможностей», не предполагая, что главный источник его проблем кроется в том, что в нем уже и так слишком уж много «возможностей». Выступающий продемонстрировал все неутешительные признаки пагубной привычки, сводящейся к тому, что он впал в состояние умственного застоя и может теперь только просить еще, еще, еще… Если FORTRAN называют детским расстройством, то PL/1, с его тенденциями роста подобно опасной опухоли, может оказаться смертельной болезнью.
###

habrahabr.ru/company/hexlet/blog/248921

### Э. Дейкстра. ”Дисциплина программирования” Роль языков программирования
Я рассматриваю язык программирования преимущественно как средство для описания (потенциально весьма сложных) абстрактных конструкций. Как показано в главе «Абстракция исполнения», первейшим достоинством алгоритма является потенциальная компактность рассуждений, на которых может основываться наше проникновение в его сущность. Как только эта компактность потеряна, алгоритм в значительноймере теряет «право на существование», и поэтомумы будем стремиться к сохранению такой компактности. Соответственно и наш выбор языка программирования будет подчинен той же цели.
###

Каюсь, пока прямого ответа на Ваш вопрос не нашел, но где-то у дедов он был, суть — язык программирования — это операционная система (компьютер), и абстракты утоплены в ней, чтоб не писать все кишки в программах (тут следует пояснить — гибкость важна, но не ее выпячивание, чем меньше писать, тем лучше, как трейты за место прагм, на этапе компиляции, а не в программе, тут конечно спорный момент, но проходить джунглии из списков инстансев — это бред, по моемому, даже не костыль, а неосиляторство.).
Мы же пишем кишки сишных-тредов и считаем это простым и удобным! Сишных-тредов, юниксовских сред! И огорчаемся, что МС поменяло их описание в заголовочных файлах. И вершинной инкапсуляции считаем Эрланг! Не, серьезно?! Эток костыль к юникс-тредам? ( Единственное «да» — стеклесс-треды! все остальное — академические бредни, приводящие к тормозам. )

"… Если говорить исключительно о быстродействие (и однопоточном и многопоточном), то с правильно написанным приложением на C++ вряд ли способно что-то поспорить… " — а это просто рекламный булшит. Я застал времена, когда декус-с генерил код в разы медленнее паскаля или блиса, а фортран делал бессмысленным писанину на аде. То, что развитие опенсорсных компиляторов застряло на gcc, ником образом не значит, что с++/с приложения вообще приближаются к вершинам. Там, где даже assembler — неэффективен (распределенные вычисления/приложения, многозадачность) С++ выполняет роль баша. Да, многозадачность уровня Occam-2 должна быть в языке, SIMD-типы и управление одновременностью в распределенной сети исполнения.
Ну т.е. или мы делаем красивый язык, в котором есть сразу всё (т.е. по сути засовываем в него ОС, но тогда и получится PL/1) или делаем маленькое ядро и добиваем остальное сторонними библиотеками (но это по сути C++ и есть, если забыть о излишней сложности, вызванной в основном историческими причинами, а не излишней функциональностью).

Что касается быстродействия, то речь естественно была не о какой-то гениальности самого устройства C++ (хотя принцип «не платишь за то, что не используешь» безусловно сильно помогает), а как раз о текущей ситуации с компиляторами. К примеру тот же D теоретически мог бы быть как минимум не медленнее, а возможно и даже быстрее (за счёт наличие в языке дополнительной информации для компилятора, типа pure, immutable и т.п.) чем C++. Но на практике он уступает, как раз из-за неразвитого оптимизатора.

Да, и насчёт simd… Пока что действительно автовекторизация компилятора заметно уступает ручному кодированию. Но я думаю что тут ситуация аналогичная обычной оптимизации 20 летней давности (тогда ручной ассемблерный код гарантированно был быстрее любого компилятора). Соответственно я подозреваю, что через несколько лет автовекторизация компиляторами аналогично догонит ручной использование SIMD (собственно в специализированных SIMD языках это уже реализовано, осталось перенести это на уровень оптимизатора GCC), так что смысла во введение специальных типов не видно — компиляторы будущего должны обрабатывать подобное сами. Ну а пока хватит intrinsic'ов и обёрток типа Boost.SIMD.

Что же касается распределённых вычислений, то напомню, что там до сих пор стандартом де факто является MPI, который как раз родной для C++. ))) Хотя лично мне больше нравится модель акторов. ))) Как на уровне межпоточного взаимодействия, так и на уровне межмашинного. )
))) как раз с++ это «современный» PL/1, но с «с» синтаксисом (правда неглючного компилятора PL/1 небыло… но все еще есть куда рости, для с++)
Если засунуть все в ОС, то получится «с». А сторонние библиотеки ничем не лучше «толстого» языка (сказывается отсутствие стандартизации).
Какой же C++ современный PL/1? ) Там вообще почти ничего нет от возможностей ОС. Ни файловой системы, ни сети, ни графики, потоки вот только в последней версии добавили (в стандартную библиотеку). Да тут можно тысячи отсутствующих вещей перечислять. Какой-нибудь Python или Java на порядки богаче в этом смысле. C++ обретает силу как раз только с учётом сторонних библиотек. А вот с учётом них, C/C++ становится уже мощнее всех остальных. Собственно очень многие дополнительных возможности реализуются в других языках с помощью биндингов к этим самым C/C++ библиотекам. )))
Так PL/1 их не имел, это был набор фич из разных языков того времени, и все. Какая сеть, графика, файловая система в PL/1, акститесь! Это древняя древность от IBM.

$$$ Собственно очень многие дополнительных возможности реализуются в других языках с помощью биндингов к этим самым C/C++ библиотекам.
А почему, знаете? )))
UFO landed and left these words here
:) Вы наивно считаете, что это что-то другое?!
UFO landed and left these words here
Это такой же механизм разделения доступа к данным (как мьютексы, семафоры, мониторы, LockFree структуры и ...), причем мало масштабируемый, как и LockFree структуры, без рейсинга — очень оптимистично, он скрывается на уровне аппаратуры/кеша, но откат транзакции делает его ограниченным. Вы можете описать сценирий в котором STM, будет быстрее мьютексов/мониторов?

Как раз «прочее счастье» сообщений — это то, что оно единственно масштабируемый из этого списка.
UFO landed and left these words here
А в таком «переделанном» варианте насколько потери при использованиии RO-структур будут заметны? И так прийдем к вменяемым алгоритмам/библиотекам, и хаскелисты опять будут повторять ну-у-мы-же-говорили.
UFO landed and left these words here
Расскажите подробнее, чувствуется что вы знаете что-то интересное. Насчет Sun OBI, SGI Delta C++, DTS C++…
Манипуляция с AST из dll уже давно реализовано, в Nemerle. Это сейчас язык с одним из самых сильных инструментов метапрограммирования. Однако это к сожалению не помогло ему вырваться из ниши маргинальных языков. Видимо сказалась ошибка (на мой взгляд) авторов в привязке к платформе .net.

Ну и насчёт зелёных потоков… Откуда такая мания на них? ) Вообще то это инструмент подходящий только для очень специфической цели. Когда имеем тысячи одновременных маленьких задач. Т.е. что-то вроде высоконагруженного сервиса. Во всех остальных случаях системные потоки будут эффективнее.
Я думаю язык будущего не будет иметь никаких спецификаций — каждый будет писать в том стиле в котором хочет, нужно будет только настроить компилятор на распознание всего этого синтаксиса. Библиотеки будут распространяться в байт-коде, чтобы не было исходников которые начнут конфликтовать или не будут компилироваться.
Предположим что ваш идеальный язык реализуют. Думаю, что через некоторое время он сам разделится на два языка:
1. Язык минимум — все расширения отключены.
2. Язык максимум — все включено.

Просто потому что у нас есть библиотеки, и наверняка многим из них придется зависеть от каких-то расширений языка. Мы же не сможем отключить GC у нашего приложения если нам нужна библиотека написанная с его помощью.
Да, такой вопрос есть. Однозначного ответа я пока не придумал, хотя разные мысли есть…
Наверное, если библиотека реально пользуется какой-то функциональностью, и это обусловлено логикой, смыслом библиотеки — то она должна быть включена. С другой стороны, если библиотека пользуется динамическим выделением памяти и предполагается, что она должна работать как в конфигурации со сборкой мусора так и без нее, то язык должен предоставлять более абстрактные примитивы «выделить память» и «освободить память», которые будут уже подключаться — или к обычному аллокатору, или к сборке мусора (тогда «освобождение» просто сведется к обнулению ссылки)
Можно RAII применить, как в С++. (т.е. всё выделение и освобождение «под капотом»)
Не кажется ли автору что «красивый и сбалансированный» C# уже сейчас стал излишне усложненным, слишком уж оброс сомнительной необходимости фичами и синтетическими сахарами? (А судя по направлению его развития в будущем ситуация будет только усугубляться)
Он оброс дополнительными фичами и синтасическим сахаром потому что так удобней разработчикам. Вот например мне часто не хватает Null coalescing operator. Умелое использование фич только подчернет лаконичность кода.
Видимо, у каждого человека свой уровень комфортной сложности.
Кому-то бейсик в самый раз, кому-то Haskell.
Текущие обновления C# меня нисколько не смущают, пока всё делают правильно.
Фичи и синтетический сахар составляет крайне малую долю в сложности языка. Зато удобства они предоставляют не мало. C# вообще уникальный язык — он один из самых молодых, но при этом имеет огромную поддержку за спиной в виде microsoft. Если бы microsoft так же поддерживала какую-нибудь альтернативу С++, то мы бы давно уже имели более удобный язык.
Чем плох D? Что не так с метапрограммированием?
Бессистемно как-то (по крайней мере впечатление такое, особенно после просмотра исходников компилятора). Метапрограмминг на строках вместо специальных квазицитат:
string s = "int y;";
mixin(s);  // ok
y = 4;     // ok, mixin declared y

По сути работа со строками лишает программиста возможности использовать систему типов и концепций. Если я хочу макрос, который должен принимать первым аргументом тип, вторым — имя и третьим — операторный блок, то на строках это никак не указать явно. Пока не передам в такой макрос что-то левое и не получу загадочные ошибки компиляции…
Хотя конечно по сравнению с С++ это реальный прогресс. Надо будет собраться с мыслями и уже для Хабра сделать статейку про связь шаблонов и макросов.
В общем D вовсе не плох, но допиливать там надо многое — таково мое ИМХО :)
Да, это уже лучше (хотя синтаксис все равно производит странное впечатление, но по смыслу лучше).
В общем, философия метапрограмминга сводится к тому, что должно быть два контекста:
1. компилируемый код (и конструкции для подстановки такого кода в произвольные места — шаблоны), ключевое слово template
2. интерпретируемый во время исполнения код — macro; макросы кстати могут писаться на приизвольных языках, не обязательно на том же языке что и код. Главное, чтобы из них был доступ к AST DOM и API компилятора.

При этом в контексте компилируемого кода можно вставлять интерпретируемые на этапе компиляции конструкции (в D — static if, в C++ с некоторой натяжкой — препроцессор). Это ограниченное подмножество операторов «условной компиляции» — для более сложных вещей прелполагаются макросы.
А в интерпретируемый на этапе компиляции код можно вставлять компилируемые вставки — «квазицитаты».
Получается что два контекста симметричны друг относительно друга, и это должно быть отражено на уровне синтаксиса.
Рантайм интерпретация — это, мягко выражаясь, не быстро да и областей применения у неё, как мне видится, не много. Зачем вам рантайм интерпретация?
Интерпретируемый во время компиляции, конечно же:)
Ну так в D так и есть. Один и тот же код, удовлетворяющий некоторым очевидным ограничениям, может быть выполнен как на этапе компиляции, так и в рантайме.
Мне не очень понятно, почему в golang надо реализовать три метода, чтобы сделать сортировку.
Обычные языки заставляют реализовать по факту, один (в виде лямбды или метода класса компаратора).
Здесь есть обсуждение: тема на StackOverflow
В конце парень показал пример, когда это хорошо работает. Очень частный, на мой взгляд. Почему так?
Спасибо, очень интересная статья получилась.
Зашел, чтобы увидеть комментарий, что язык — всего лишь инструмент… и не увидел =(
Для любого X всегда найдется Y, такой, что X — всего лишь инструмент для Y :)
Когда программа на Си или Фортране достаточно сложна, чтоб содержать «заново написанную, неспецифицированную, глючную и медленную реализацию половины языка Common Lisp», то становится видно, что Си или Фортран — это всего лишь инструмент. А написанную на нём недореализацию половины языка Common Lisp можно, в общем, не считать языком…
UFO landed and left these words here
Никогда не будет идеального языка, т.к. идеал всегда устареет прежде, чем на него перейдет достаточное кол-во народа. Все существующие языки создавались ведь не с мыслью «а давайте сделаем фиговый язык». Создавалось под задачи и с учетом своего представления об идеальном.

Создадут в 2020 идеальный язык, на нем начнут писать, и потом бах, квантовые компы и все языки на помойку надо, ибо костыли для квантовых компов не айс.
Это никак не отрицает необходимости создания «идиальных» языков. Без эволюции и революций язык — мертв.
Я думаю, что в будущем станут рулить не языки программирования, а IDE и среды сборки.
Уже сейчас без IDE крайне неудобно работать над чем-то сложнее Hello World, а в будущем именно связка «IDE плюс среда» начнёт определять разработку, а собственно языки пойдут небольшими front-end плагинами к ней.
К этому всё идёт. Создатели нового языка, хотят они того или нет, должны подстраиваться под существующие крупные IDE, т.к. написать собственную внезапно оказывается значительно сложнее, чем придумать язык и потом состряпать к нему компилятор. А если не будет IDE, то язык не получит популярности, т.к. немного найдётся желающих набирать код в Блокноте или создавать самописные IDE на основе vim…
И вместо «я программирую на C++» или «пишу на Javascript» будут говорить, к примеру, «я программирую в Visual Studio» или «программирую в Eclipse».
Согласен полностью. У меня среди evernote-заметок, где я храню различые идеи по языкам программирования, немаленький раздел посвящен IDE; при проектировании языка учитываю связку с IDE (в частности, синтаксис языка должен строиться таким образом, чтобы было удобно работать автокомпилиту, построителю деревьев классов и прочим инструментам IDE, которые должны работать «на лету»); я даже указываю специальные рекомендации к IDE, к организации проектов и т.п., что обычно в язык не входит. А одна из первых вещей с чего я начал эксперименты со своим компилятором (форком D) — это написал простейшую IDE на Qt и делаю визуализатор AST (а затем будут визуализаторы всех преобразований внутри компилятора, вплоть до кодогенератора). То есть не только пользоваться компилятором, но даже разрарабывать его без графического интерфейса неудобно.
Скорее будут говорить «пишу под .NET» или «пишу под JVM» или «пишу сам .NET или JVM» ))
Т.е. будет пара тройка универсальных платформ для 99% софта. Ну системное что-то, вроде C++ или Rust, на которых эти платформы и будут делать. А IDE под них уже в общем-то сформированы.
Системное — это C (интересно, влезет ли в эту область rust). C++ уже для прикладного софта.
Пишу на C++ (с шаблонами и лямбдами) в том числе и для микроконтроллеров (причём результат местами получается эффективнее C, за счёт агрессивного инлайна у шаблонов, не говоря уже о красоте кода) — никаких проблем не видно. )))
Под какие контроллеры? Какой компилятор? Используете ли -fno-exceptions?

Шаблоны определяются либо рядом, либо в заголовочниках. И в том, и в другом случае на C можно использовать static inline функции. Для иных случаев ещё неплохо работает -flto, который делает инлайн на этапе линковки.
Преимущественно Cortex-M0 и соответственно gcc. Да, no-exceptions и ещё десяток других флагов обычно не применяющихся на взрослых системах. Из общего разве что -std=c++14 (полиморфные лямбды очень хороши) и уровень оптимизации. )))

Ну и в любом случае, даже если добиться аналогичной производительности на C, то всё равно это будет выглядеть на порядки ужаснее и главное намного менее безопасно.
UFO landed and left these words here
Это совсем не так, были: лисп, фортран, алгол, ада и смолтолк CPU(для которых ассмом были эти языки), я застал такого «зверька» www.cs.tufts.edu/~nr/cs257/archive/ronald-brender/bliss.pdf его можно считать высокоуровневым ассемблером, или чем-то средним между асмом и с--. А еще есть оссам(-2, -пи), тоже ассемблер-подобный язык. HP LJ управляются postscript. В инферно системным языком — лимбо. И Ява… тоже системный язык… jvm, dalvik или их замена — асм, а системные языки — java инфраструктура. Диезы формально — тоже(и ОС на с-диез есть), но как-то не принято их так называть.
лисп, фортран, алгол, ада и смолтолк
В текущий момент это устаревшая экзотика. Широкого использования bliss сейчас тоже не заметно (при этом, по сути он не сильно далеко ушел от макроассемблера).

HP LJ управляются postscript
Да, а интерпретатор пайтона интерпретирует пайтон. Но давно ли они пишут firmware на ps?

И Ява… тоже системный язык… jvm, dalvik или их замена — асм, а системные языки — java инфраструктура. Диезы формально — тоже(и ОС на с-диез есть), но как-то не принято их так называть.
С каких пор? Даже процы с jazelle и реализации java card содержат ядро написанное на C с фрагментами ассемблера. JVM не может работать без некого системного слоя, реализующего работу с cpu, памятью и периферией. С CLR то же самое. Какой-нибудь .NET Micro Framework также работает поверх glue-кода на C и не лезет в область системного программирования. Пока CLR не реализован в железе — C# не может быть системным языком. То такими темпами у вас опкоды виртуальной машины rar'а станут системным языком.
ада — есть и работает там где с не допускается. Про «Экзотичность» и «устаревание» я ничего и не говорил, но они системные — да, безусловно, как и с.
ps — можно и на форте сделать, а форт чисто системный низкоуровневый.
Ява — по дизайну, количество кода на асм/с ни как не влияет на системность(osv)! (рантайм библиотеки «с» тоже имеют «асм» вставки, он не системный язык?) Диезы — аналогично (в «космос» не заглядывал, но он есть, как и дотНЕТ), по этому МС имеет право поставить себе звездочку в разделе языков системного совту.

# То такими темпами у вас опкоды виртуальной машины rar'а станут системным языком.
Системное на «D», «OCaML» писали и даже пытались ОС на Haskell, можно ли баиткод считать «асм» — да, вероятнее всего.
По этому и сказал: «Это совсем не так», более чем совсем, роль 'с' в другом, он был использован в написании юникс, а системы эмулирующие юникс логично писать на нем же. Баидинги же RSX-11 были на асм, фортран и стековых под паскаль, сишных не было. Как и другие RTOS — писали на разных языках, тут меньше зависимости от ОС и си.
Вы путаете системный и низкоруовневый.
Jazelle — это расширение набора команд для ARM, типа MMX на i586, ни в коем случае не самостоятельная система команд. Видел когда-то давно упоминания контроллеров, программируемых на Java. Подозреваю, там урезанная Java, не совсем совместимая со стандартной.
Jazelle DBX (Direct Bytecode eXecution) allows some ARM processors to execute Java bytecode in hardware as a third execution state alongside the existing ARM and Thumb modes
Про диезы слышал, правда лет 10 назад, что там «библиотечный» слой якобы очень тонкий, практически сразу — обёртка над нативными функциями из DLL. Если это было так, то движок был слишком сильно привязан к винде. Вообще, насколько совместимы диезовые виртуальные машины и программы под винды и под линукс?
Космос — тоже в стагнируещем состоянии, за месяц 27 коммитов, в основном бошевская конфигурация. К винде? Скорее симуляция среды, чем полное исполнение. Хм, как понимать совместимость с ними? Космос — конструктор, на базе него на кодоплекс строят ОС, это не совсем ВМ, сама ос — скомпилированный бинарник, наличия в сборке ВМ никто не гарантирует.
Sign up to leave a comment.

Articles