В данном случае оно не сработает, т.к. стека не будет.
«If you try to call the nested function through its address after the containing function exits, all hell breaks loose. If you try to call it after a containing scope level exits, and if it refers to some of the variables that are no longer in scope, you may be lucky, but it’s not wise to take the risk. If, however, the nested function does not refer to anything that has gone out of scope, you should be safe.»
Да. Если в сишке рассматривать пары из указателя на функцию и контекста, то такое подмножество сишки, внезапно, становится полноценным функциональным языком. Вот и вся магия.
Есть только одна проблема: компилятор не сможет инлайнить ничего, везде будут переходы по указателю. В общем в данном случае лучше использовать не C, а C++. Там можно многое сделать чище и производительней.
В крестах нормального ФП все равно нет, и всякие там каррирование и проч. будет выглядеть довольно-таки уродливо даже с новыми стандартами, см. https://habr.com/ru/post/466985/ например.
Да и с частичной специализацией функции, например если мы хотим из функции int func (int a, int b, int c) сгенерить ф-цию int func(int a, int c) в которой аргумент c фиксирован и принимает известное значение (допустим 0) и при этом это должно быть не на этапе компиляции, а динамически сделано на этапе исполнения и честно скомпилировано в функцию(JIT) на которую можно получить нормальный указатель - такого в крестах нет. Впрочем, что-то похожее я уже описывал inline callback-функций как способ метапрограммирования
// Некоторая карта (ассоциативный массив)
val mm = Map("A" -> 100, "B" -> 101, "C" -> 201)
// В типаже (трейте) определим
val === = (a: Int, b: Int) => a == b
val > = (a: Int, b: Int) => a > b
val < = (a: Int, b: Int) => a < b
val <= = (a: Int, b: Int) => a <= b
val >= = (a: Int, b: Int) => a >= b
val !== = (a: Int, b: Int) => a != b
// Пример использования
print (mc(mm, 101, !==))
// Выведет: Map(A -> 100, C -> 201)
Это один из простеньких примерчиков, который обычно на собеседовании задают.
Простая проверка на «вшивость».
(Попробуйте то же самое не только с Int, но и в обобщённом виде.)
Соискатели со знанием Spark, Lagom, Akka и т.п. востребованы.
Весьма востребованы в enterpriZe.
Это профи своего дела, а не доморощенные форумные болтуны типа Jopich1-куна
А нахрена она здесь, если первоначально вопрос был именно к названию и содержимому лекции? Для того, чтобы от темы увести? Или доколупаться до оппонента? Так себе троллинг…
Для этого подойдет любой язык, умеющий генерить машинный код.
Так я всего-то и попросил другой «язык, умеющий генерить машинный код» без потери скорости выполнения этого самого машкода. В ответ - тупой троллинг…
Давай, показывай свою скорость…
Ты совсем берега попутал? Это я прошу мне показать нечто иное. Вместо этого гнилые наезды? Тебя царь покусал? Нечего ответить - хера ты вообще в тему впёрся со своим тупым троллингом?
Язык тут вообще не причем. Особенно после оптимизаций, когда из изначального представления строятся такие модели, что от фон-неймана мало чего остается
Я тебя просил пересказывать мне азбуку? Нахера ты опять отвечаешь на те вопросы, что я не задавал в ответе на мои сообщения? Я к твоим голосам вы голове не имею ни малейшего отношения.
Как банальный пример, оптимизация хвостовой рекурсии.
Опять 25… Меня не отдельные трюки интересуют (я знаю и про оптимизацию хвостовых вызовов, в том числе и в gcc, и про их ограничения), а про новые готовые продукты. Ну скажи ты просто, что нет ещё таких - и я успокоюсь. :)
Ну и в крестах нормальной компилтайм рефлексии и метапрограммирования как не было, так и нет. И скорее всего не будет
Единого подхода к понятию метаданные пока ни у кого нет.
Каждый разработчик изобретает свой «велосипед» /СУБД, GUI, …/.
Отчасти от этого и имеем 1000000 разных форматов данных.
А «единое» понимание, что такое метаданные возможно.
Далее немного иронии.
Для этого нужно в некоих RFC стандартизировать представление метаданных 500 наиболее часто используемых объектов.
И затем остается реализовать API для создания метаданных и возможности на их основе динамически создания и использования таковых объектов.
Фирма 1С развивает этот подход уже лет двадцать.
Да и другие фирмы «не дремлют» /Microsoft, … и еще 100000 фирм/.
Но «единой» архитектуры представления метаданных нет.
А то, что эти трюки не влезают в модель фон Неймана, тебя никак не интерсует?
Хотя как тебя может интересовать, если ты не знаешь о существовании «архитектуры фон Неймана», и понимаешь под ним хрен знает что, и объяснить не можешь.
готовые продукты
Математический сопроцессор x87 - стековая машина. Ускоряет операции с плавающей точкой.
И современный ширпотреб - многопроцессорные, многоядерные системы. Пораспрашивай «царя», он лучше знает насколько там все запущено и далеко от фон-неймановсти.
А то, что эти трюки не влезают в модель фон Неймана, тебя никак не интерсует?
Совершенно не интересует. Вернее, это, конечно, здорово, что в тот-же gcc добавили TCO, но там такие ограничения, что действительно по факту осталась только «хвостовая рекурсия». Все определения - в первородной статье. И меня не интересует классификация порождаемого кода - только его эффективность.
Но меня больше интересует, есть ли рабочий вариант языка, заточенного под «аппликативную модель» или иную какую «прогрессивную и современную не фон-Неймановскую модель» с эффективностью порождаемого кода и универсальностью не хуже си.
Хотя как тебя может интересовать, если ты не знаешь о существовании «архитектуры фон Неймана»
Меня интересует только вышеуказанная статья, в которой определено только понятие «фон-Неймановской вычислительной модели» как «основы» некоторых ЯП. Зачем здесь обсуждать «архитектуру фон Неймана» как модель вычислительной машины мне не совсем понятно, даже если вышеуказанная «вычислительная модель» является логическим продолжением или следствием «архитектуры фон Неймана».
Разве речь шла о связи GUI и СУБД?
Почитайте о том, чем отличаются метаданные от данных и для чего они нужны
/это тривиальный совет, но ваш вопрос «принудил» мне его вам привести/.
PS: На форуме «все равны» и нет дядей, тетей, дедушек, …
С чего это не будет? Оно четко значится в планах после C++23.
В планах что угодно написать можно. Как это будет выглядеть? Нормальной гомоиконности (код как данные, чтоб на этапе компиляции можно было нормально всё разбирать и генерить на основе одного кода или данных другой код или данные) на сушествующем упоротом крестосинтаксисе сделать невозможно. Учитывая тяжелое наследие Си и кучи уже существующего нагроможденного в стандарте крестов хлама со всяким там темплейтным метапрограммированием, вряд ли что что-то толковое может получиться.
Начали «улучшать» C и получили C++. Ныне начали «улучшать» C++ … /что будет в результате затрудняюсь сказать/.
Вряд ли что-то хорошее. Что-то мне подсказывает, что всякое такое «улучшение» имеет свой предел, обусловленный начальной точкой отсчета, от которой мы пытаемся «улучшаться», сохраняя с ней некую синтаксически-семантическую совместимость.
Си предоставляет возможность разработки алгоритмов.
То бишь в целом с использованием Cи возможна разработка различного API, которое
затем можно использовать опять таки как для разработки API, которое еще более упрощает разработку иного API.
Собственно скажем ядро ОС, что из себя представляет?
Это некоторая система взаимосвязанного API, предоставляющего прикладным программам возможность абстрагироваться от железа, …
ИМХНО Си превосходно подходит для системной разработки /не обязательно ядра/.
Но «некоторым» захотелось «улучшить» Си для возможности разработки прикладных программ, …
Вот мы теперь и имеем «улучшенный» Си.
PS: Катастрофы ни какой в этом нет, но мне «ближе» использовать Си лишь для разработки API.
Для прикладных же задач использую иные языки программирования, которые используют API, разработанное с использованием Си.
Меня интересует только вышеуказанная статья, в которой определено только понятие «фон-Неймановской вычислительной модели» как «основы» некоторых ЯП.
Там не дано определение «фон-Неймановской вычислительной модели». Там даны некоторые собирательные характеристики этой модели, которые ты привел как определение. При этом в конце данных характеристик моделей написано, что возможно многие несогласятся с такими характеристиками моделей вычисления.
Статья предполагает, что читатель имет опредленную базу знаний. Ты не имеешь необходимую базу знаний для чтения этой статьи, ты не читал даже его оглавления,…
Но «единой» архитектуры представления метаданных нет.
Эта задача не из серии «нерешаемых».
Разрабатываю один из вариантов обеспечения «единой» архитектуры метаданных.
Метаданные объектов 1С в метадата базе «чувствуют себя хорошо».
Что такое «единая» архитектура метаданных?
В моей трактовке это такое представление метаданных объектов при котором алгоритмы доступа к ним являются «едиными».
В объектно ориентированных программах польза от метаданных состоит в том, что
они позволяют в run-time создавать объекты и конечно использовать.
В чем профит?
Не нужно каждый раз изобретать «велосипед», позволяющий создавать некую архитектуру
представления метаданных и некую run-time подсистему, позволяющую их использовать.
Что касаемо к примеру вопроса типизации, то она решаема не на стадии компиляции, а в
run time режиме работы программы /и то если алгоритм того требует/.
PS: Не претендую на то, что у меня «лучший» подход к обеспечению возможности работы с метаданными.
Ныне профит в том, что он имеется не в «маниловских фантазиях».
PS2: Работа весьма трудоемка.
Ведь метаданные должны предоставлять возможность представления и работы с: таблицами, списками, деревьями, индексами, …, …
Дядя Вова какая связь между ГУИ и СУБД, я не поняла? Поведай в аспекте метаданных.
Думаю, речь про то, что для любых данных есть представление для человека (в частности в ГУИ) и представление в СУБД (в виде последовательности байт и сортировки).
Вообще, такой подход к метаданным был ещё во времена Фортрана и Кобола, когда для переменной указывался не только формат хранения (сколько байт и как трактовать арифметику), но и формат ввода-вывода.
Для этого нужно в некоих RFC стандартизировать представление метаданных 500 наиболее часто используемых объектов.
Даже в разных конфигурациях 1С разный формат одинаковых объектов (сравни справочники Номенклатура и Контрагент в Управлении Торговлей и в Бухгалтерии, например).
И даже понятия «справочник» и «документ» стандартизовать нет особого толку, так как в 1С есть понятие проведения/перепроведения, а в SAP есть понятие истории реквизита. Что в стандарт воткнём? Если всё сразу, то родится ещё один X.500 (помните такой протокол?) и его можно будет сразу хоронить.
Нормальной гомоиконности (код как данные, чтоб на этапе компиляции можно было нормально всё разбирать и генерить на основе одного кода или данных другой код или данные) на сушествующем упоротом крестосинтаксисе сделать невозможно.
Почему? В Scala синтаксис почти так же упорот, но конструкции типа
но как-то это все сложно выглядит в сравнении с обычными однородными S-expression-ами. Куча каких-то экстракторов для разных языковых конструкций... S-выражения это уже по сути AST, с каким-то иным синтаксисом все будет сложнее. Да и еще как эту фичу увязать с другими крестовыми фичами? Например, можно ли будет породить этим манипулированием с AST новый шаблон, который после этого раскрывается в нечто, а потом еще взять результат раскрытия этого шаблона, и с его AST что-то делать?
Я думаю что можно просто дать возможность программе тупо читать собственный исходник как массив из байт, и потом его переписывать. Вот например генератор куайна, тут используется raw string literal которого в стандартном Си нет, но есть как гну-расширение. C++ поддерживает raw string literal по стандарту.
Такая программа выдает в stdout исходник, который при компиляции выдает сам себя. Тут содержимое массива char s[] фактически дублирует весь исходник, исключая сам массив.
Вот если натянуть на язык Си S-expression, и если в коде можно помимо просто main сделать некий специальный main_compiletime который бы видел весь собственный исходник со всеми функциями, массивами и проч. не только как код, но и как дерево и на основе него мог синтезировать новое дерево, которым как бы переписывался исходник, который потом прогоняется повторно компилятором - вот это было бы супер я считаю.
Да и еще как эту фичу увязать с другими крестовыми фичами? Например, можно ли будет породить этим манипулированием с AST новый шаблон, который после этого раскрывается в нечто,
Конечно. Как в лиспе: кусок исходника на входе, кусок исходника на выходе.
а потом еще взять результат раскрытия этого шаблона, и с его AST что-то делать?
Результат раскрытия шаблона не присутствует в исходнике. В лиспе разве можно сделать что-то с результатом компиляции функции?
По мне, так пусть лучше будут структуры, соответствующие конструкциям языка, а не списки, где надо запоминать, что в первом элементе возвращаемый тип, во втором имя, в третьем ….
если в коде можно помимо просто main сделать некий специальный main_compiletime который бы видел весь собственный исходник
Это хоть сейчас любым C++ генератором можно делать.
Результат раскрытия шаблона не присутствует в исходнике. В лиспе разве можно сделать что-то с результатом компиляции функции?
В лиспе можно сделать что-то с результатом раскрытия макросов.
Вполне можно реализовать всю эту машинерию с раскрытием рекурсивных шаблонов через механизмы переписывания AST в компилтайме(если такие механизмы будут), и тогда с результатом раскрытия шаблонов можно было бы что-то делать.
Т.е. по-моему лучше взять какой-нибудь самый универсальный механизм для всего-что-можно на этапе компиляции, и на этом фундаменте уже реализовывать более узкие вещи, такие как шаблоны, констэкспры, наследования и проч. и сделать их как некие библиотеки времени компиляции, а не вшивать эти фичи в сам компилятор.
В лиспе можно сделать что-то с результатом раскрытия макросов.
Только вручную сделав macroexpand. А в случае реализации шаблона, он раскрывается не по месту вызова, а на верхнем уровне. То есть, если в Common Lisp пытаться делать шаблоны через макросы, то придётся просто выполнять код при раскрытии. В Racket есть syntax-local-lift-module, но результат этого раскрытия тоже в макрос уже не запихнуть, разве что результатом раскрытия делать макрос.
Вполне можно реализовать всю эту машинерию с раскрытием рекурсивных шаблонов через механизмы переписывания AST в компилтайме
Не очень. Потому что где-то добавиться реализация для конкретных типов, где-то оптимизатор сразу же выбросит реализацию и заинлайнит результат. Через AST делать сложнее. И опять же, даже в лиспе макрос не может переписать кусок AST, который не находится внутри макроса (а, например, просто в этом же файле).
по-моему лучше взять какой-нибудь самый универсальный механизм для всего-что-можно на этапе компиляции, и на этом фундаменте уже реализовывать более узкие вещи
В соседней ветке уже предлагали использовать универсальный парсер для разбора Си++. Универсальный механизм всегда проигрывает специализированному. В частности, можешь попробовать на макросах Common Lisp реализовать шаблоны C++ с выбором реализации по типам и SFINAE.
наследования и проч
Слабо на макросах Common Lisp сделать классы Си++? С выбором реализации в момент компиляции, а не выполнения, чтобы скорость выполнения метода равнялась скорости выполнения обычной функции (и при возможности вообще метод инлайнился)?
Добавить макросы в Си++ можно. Заменить ядро компилятора на лиспоподобное не выкинув половину оптимизаций – крайне сложно.
Только по поводу натягивания S-выражений я говорил про Си, а не про кресты.
Вообще, если брать S-выражения и компилятор Си/С++, то можно просто использовать L++. Лисповые макросы есть, скорость выполнения определяется компилятором C++.
М-да. В Scheme/Racket неожиданностей гораздо меньше. В Си/Си++ они хотя бы размечены в стандарте. А здесь попытался в документации найти, что так должно быть, ничего не нашёл. Object в документации называется Any, про то, что его методы должны быть глобальными функциями ничего не сказано.
Зато нашёл неожиданный генератор случайных чисел:
scala> (## _)()
res21: Int = 1476913734
scala> (## _)()
res22: Int = 35126588
scala> (## _)()
res23: Int = 1668613848