LINUX.ORG.RU

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

В данном случае оно не сработает, т.к. стека не будет.

«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.»

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

Да. Если в сишке рассматривать пары из указателя на функцию и контекста, то такое подмножество сишки, внезапно, становится полноценным функциональным языком. Вот и вся магия.

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

Есть только одна проблема: компилятор не сможет инлайнить ничего, везде будут переходы по указателю. В общем в данном случае лучше использовать не C, а C++. Там можно многое сделать чище и производительней.

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

В крестах нормального ФП все равно нет, и всякие там каррирование и проч. будет выглядеть довольно-таки уродливо даже с новыми стандартами, см. 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-функций как способ метапрограммирования

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

В данном случае оно не сработает, т.к. стека не будет.

Можно на Си изобрести свой особый диалект языка FORTH с шитым кодом и EVALUATE, и дальше на нем все пилить

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

Ну и в крестах нормальной компилтайм рефлексии и метапрограммирования как не было, так и нет. И скорее всего не будет

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

Процедурного?

Может «императивного»?

Императивное программирование - вычисления есть изменение состояния.

В функциональном программировании нет т.н. «побочных эффектов».

Выходные данные зависят только от входных данных.

Однако, изучение Ъ-функциональных языков требует высокой математической подготовки и высокого «порога вхождения».

Понять без подготовки, что означает

def mc(m:Map[_,Int],a:Int,f:(Int,Int)=>Boolean):Map[_,Int]=m.filter({case(k,e)=>f(e,a)})

кодерочку сложно.

Зато легко использовать:

// Некоторая карта (ассоциативный массив)
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-куна

Про собеседования ...

Про собеседования ... (комментарий)

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

Что такое «редьюсер» можно на русском объяснить?

Наверное, функция, которую можно передать как аргумент reduce/fold/шотамувасвнедоязычкевместоэтого.

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

Что такое архитектура фон Неймана не знаешь.

А нахрена она здесь, если первоначально вопрос был именно к названию и содержимому лекции? Для того, чтобы от темы увести? Или доколупаться до оппонента? Так себе троллинг…

Для этого подойдет любой язык, умеющий генерить машинный код.

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

Давай, показывай свою скорость…

Ты совсем берега попутал? Это я прошу мне показать нечто иное. Вместо этого гнилые наезды? Тебя царь покусал? Нечего ответить - хера ты вообще в тему впёрся со своим тупым троллингом?

Язык тут вообще не причем. Особенно после оптимизаций, когда из изначального представления строятся такие модели, что от фон-неймана мало чего остается

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

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

в каком месте стандарта С сказано про оптимизацию хвостовой рекурсии

А в каком месте стандарта сказано, что стек вызовов вообще должен быть, а уж тем более переполняться?

no-such-file ★★★★★
()
Ответ на: комментарий от yyk

Что такое архитектура фон Неймана не знаешь.

А нахрена она здесь, если первоначально вопрос был именно к названию и содержимому лекции? Так себе троллинг…

Троллить начал ты.

Не знаешь про архитектуру фон Неймана. Не знаешь про что книжка. Но осудил. Своим переиначенным вопросом, который хрен знает о чем.

Лучше бы написал сразу: можно ли писать «не на си» с неменьшей скоростью выполнения?

Поспорили бы про скорость «фон-немановских» васиков, питонов и «не фон-неймановских» лиспов, хаскелей по сравнению с эталоном - си.

anonymous
()
Ответ на: комментарий от Siborgium

Они не функциональные а мультипарадигменные.

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

Но осудил. Своим переиначенным вопросом, который хрен знает о чем.

Задел за больное? Извини. Ну да, вопрос был, мягко говоря, провокационным - признаю. Но не такой реакции я ожидал )

Поспорили бы про скорость «фон-немановских» васиков, питонов и «не фон-неймановских» лиспов, хаскелей по сравнению с эталоном - си.

А есть о чём спорить? Я надеялся - может что новое изобрели…

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

Задел …?

Обвинил в троллинге, потом признаешь, что сам троллил.

Я надеялся - может что новое изобрели

Давно уже изобрели. Как банальный пример, оптимизация хвостовой рекурсии.

Но сишник-фон-нейманист, который ничего кроме си не знает (как царь), везде видит, что всё своровали из си.

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

Как банальный пример, оптимизация хвостовой рекурсии.

Опять 25… Меня не отдельные трюки интересуют (я знаю и про оптимизацию хвостовых вызовов, в том числе и в gcc, и про их ограничения), а про новые готовые продукты. Ну скажи ты просто, что нет ещё таких - и я успокоюсь. :)

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

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

С чего это не будет? Оно четко значится в планах после C++23.

anonymous
()
Ответ на: комментарий от SZT

Ну и в крестах нормальной компилтайм рефлексии и метапрограммирования как не было, так и нет. И скорее всего не будет

Единого подхода к понятию метаданные пока ни у кого нет.
Каждый разработчик изобретает свой «велосипед» /СУБД, GUI, …/.
Отчасти от этого и имеем 1000000 разных форматов данных.
А «единое» понимание, что такое метаданные возможно.

Далее немного иронии.

Для этого нужно в некоих RFC стандартизировать представление метаданных 500 наиболее часто используемых объектов.
И затем остается реализовать API для создания метаданных и возможности на их основе динамически создания и использования таковых объектов.

Фирма 1С развивает этот подход уже лет двадцать.
Да и другие фирмы «не дремлют» /Microsoft, … и еще 100000 фирм/.
Но «единой» архитектуры представления метаданных нет.

Владимир

anonymous
()
Ответ на: комментарий от yyk

Меня не отдельные трюки интересуют

А то, что эти трюки не влезают в модель фон Неймана, тебя никак не интерсует?

Хотя как тебя может интересовать, если ты не знаешь о существовании «архитектуры фон Неймана», и понимаешь под ним хрен знает что, и объяснить не можешь.

готовые продукты

Математический сопроцессор x87 - стековая машина. Ускоряет операции с плавающей точкой.

И современный ширпотреб - многопроцессорные, многоядерные системы. Пораспрашивай «царя», он лучше знает насколько там все запущено и далеко от фон-неймановсти.

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

А то, что эти трюки не влезают в модель фон Неймана, тебя никак не интерсует?

Совершенно не интересует. Вернее, это, конечно, здорово, что в тот-же gcc добавили TCO, но там такие ограничения, что действительно по факту осталась только «хвостовая рекурсия». Все определения - в первородной статье. И меня не интересует классификация порождаемого кода - только его эффективность.

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

Хотя как тебя может интересовать, если ты не знаешь о существовании «архитектуры фон Неймана»

Меня интересует только вышеуказанная статья, в которой определено только понятие «фон-Неймановской вычислительной модели» как «основы» некоторых ЯП. Зачем здесь обсуждать «архитектуру фон Неймана» как модель вычислительной машины мне не совсем понятно, даже если вышеуказанная «вычислительная модель» является логическим продолжением или следствием «архитектуры фон Неймана».

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

Дядя Вова какая связь между ГУИ и СУБД?

Разве речь шла о связи GUI и СУБД?
Почитайте о том, чем отличаются метаданные от данных и для чего они нужны
/это тривиальный совет, но ваш вопрос «принудил» мне его вам привести/.

PS: На форуме «все равны» и нет дядей, тетей, дедушек, …

Владимир

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

С чего это не будет? Оно четко значится в планах после C++23.

В планах что угодно написать можно. Как это будет выглядеть? Нормальной гомоиконности (код как данные, чтоб на этапе компиляции можно было нормально всё разбирать и генерить на основе одного кода или данных другой код или данные) на сушествующем упоротом крестосинтаксисе сделать невозможно. Учитывая тяжелое наследие Си и кучи уже существующего нагроможденного в стандарте крестов хлама со всяким там темплейтным метапрограммированием, вряд ли что что-то толковое может получиться.

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

Учитывая тяжелое наследие Си …

Начали «улучшать» C и получили C++.
Ныне начали «улучшать» C++ … /что будет в результате затрудняюсь сказать/.

Использую C++ «как C» /так как 100% использую C++ лишь для разработки API/.

Владимир

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

Начали «улучшать» C и получили C++.
Ныне начали «улучшать» C++ … /что будет в результате затрудняюсь сказать/.

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

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

Си предоставляет возможность разработки алгоритмов.
То бишь в целом с использованием Cи возможна разработка различного API, которое
затем можно использовать опять таки как для разработки API, которое еще более упрощает разработку иного API.

Собственно скажем ядро ОС, что из себя представляет?
Это некоторая система взаимосвязанного API, предоставляющего прикладным программам возможность абстрагироваться от железа, …

ИМХНО Си превосходно подходит для системной разработки /не обязательно ядра/.
Но «некоторым» захотелось «улучшить» Си для возможности разработки прикладных программ, …
Вот мы теперь и имеем «улучшенный» Си.

PS: Катастрофы ни какой в этом нет, но мне «ближе» использовать Си лишь для разработки API.
Для прикладных же задач использую иные языки программирования, которые используют API, разработанное с использованием Си.

Владимир

anonymous
()
Ответ на: комментарий от yyk

Меня интересует только вышеуказанная статья, в которой определено только понятие «фон-Неймановской вычислительной модели» как «основы» некоторых ЯП.

Там не дано определение «фон-Неймановской вычислительной модели». Там даны некоторые собирательные характеристики этой модели, которые ты привел как определение. При этом в конце данных характеристик моделей написано, что возможно многие несогласятся с такими характеристиками моделей вычисления.

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

Но осуждаешь.

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

Но «единой» архитектуры представления метаданных нет.

Эта задача не из серии «нерешаемых».
Разрабатываю один из вариантов обеспечения «единой» архитектуры метаданных.
Метаданные объектов 1С в метадата базе «чувствуют себя хорошо».

Что такое «единая» архитектура метаданных?

В моей трактовке это такое представление метаданных объектов при котором алгоритмы доступа к ним являются «едиными».
В объектно ориентированных программах польза от метаданных состоит в том, что
они позволяют в run-time создавать объекты и конечно использовать.

В чем профит?
Не нужно каждый раз изобретать «велосипед», позволяющий создавать некую архитектуру
представления метаданных и некую run-time подсистему, позволяющую их использовать.

Что касаемо к примеру вопроса типизации, то она решаема не на стадии компиляции, а в
run time режиме работы программы /и то если алгоритм того требует/.

PS: Не претендую на то, что у меня «лучший» подход к обеспечению возможности работы с метаданными.
Ныне профит в том, что он имеется не в «маниловских фантазиях».

PS2: Работа весьма трудоемка.
Ведь метаданные должны предоставлять возможность представления и работы с: таблицами, списками, деревьями, индексами, …, …

anonymous
()

Шутка.

Мне бы хоть процедурный подход научиться использовать …
А «функциональный» для меня - «неведомая вселенная».

Владимир

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

«Старый Мазай, разболтался на ЛОР-е».

Переменная, выражение, … это тоже метаданные.

Владимир

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

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

anonymous
()
Ответ на: комментарий от Liz812

Дядя Вова какая связь между ГУИ и СУБД, я не поняла? Поведай в аспекте метаданных.

Думаю, речь про то, что для любых данных есть представление для человека (в частности в ГУИ) и представление в СУБД (в виде последовательности байт и сортировки).

Вообще, такой подход к метаданным был ещё во времена Фортрана и Кобола, когда для переменной указывался не только формат хранения (сколько байт и как трактовать арифметику), но и формат ввода-вывода.

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

Для этого нужно в некоих RFC стандартизировать представление метаданных 500 наиболее часто используемых объектов.

Даже в разных конфигурациях 1С разный формат одинаковых объектов (сравни справочники Номенклатура и Контрагент в Управлении Торговлей и в Бухгалтерии, например).

И даже понятия «справочник» и «документ» стандартизовать нет особого толку, так как в 1С есть понятие проведения/перепроведения, а в SAP есть понятие истории реквизита. Что в стандарт воткнём? Если всё сразу, то родится ещё один X.500 (помните такой протокол?) и его можно будет сразу хоронить.

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

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

Почему? В Scala синтаксис почти так же упорот, но конструкции типа

def assert(cond: Boolean, msg: Any) = macro Asserts.assertImpl
object Asserts {
  def raise(msg: Any) = throw new AssertionError(msg)
  def assertImpl(c: Context)
    (cond: c.Expr[Boolean], msg: c.Expr[Any]) : c.Expr[Unit] =
   if (assertionsEnabled)
      <[ if (!cond) raise(msg) ]>
      else
      <[ () ]>
}

работают. Что мешает добавить <[ … ]> в С++? Понятно, что с полным аналогом scala.reflect.api.Trees.

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

Добавить конечно можно

https://www.scala-lang.org/api/2.13.1/scala-reflect/scala/reflect/api/Trees.html

но как-то это все сложно выглядит в сравнении с обычными однородными S-expression-ами. Куча каких-то экстракторов для разных языковых конструкций... S-выражения это уже по сути AST, с каким-то иным синтаксисом все будет сложнее. Да и еще как эту фичу увязать с другими крестовыми фичами? Например, можно ли будет породить этим манипулированием с AST новый шаблон, который после этого раскрывается в нечто, а потом еще взять результат раскрытия этого шаблона, и с его AST что-то делать?

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

Я думаю что можно просто дать возможность программе тупо читать собственный исходник как массив из байт, и потом его переписывать. Вот например генератор куайна, тут используется raw string literal которого в стандартном Си нет, но есть как гну-расширение. C++ поддерживает raw string literal по стандарту.

char s[]= R"(#include <stdio.h>
int main ()
{
    printf ("char s[]= {");
    for (char *s_p = s; *s_p; s_p++ )
    {
        printf ("%i,", *s_p);
    }
    printf ("0};\n%s", s);
    return 0;
}
)";
#include <stdio.h>
int main ()
{
    printf ("char s[]= {");
    for (char *s_p = s; *s_p; s_p++ )
    {
        printf ("%i,", *s_p);
    }
    printf ("0};\n%s", s);
    return 0;
}
Такая программа выдает в stdout исходник, который при компиляции выдает сам себя. Тут содержимое массива char s[] фактически дублирует весь исходник, исключая сам массив.

Вот если натянуть на язык Си S-expression, и если в коде можно помимо просто main сделать некий специальный main_compiletime который бы видел весь собственный исходник со всеми функциями, массивами и проч. не только как код, но и как дерево и на основе него мог синтезировать новое дерево, которым как бы переписывался исходник, который потом прогоняется повторно компилятором - вот это было бы супер я считаю.

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

но как-то это все сложно выглядит в сравнении с обычными однородными S-expression-ами

Они тоже не очень однородные. Всё равно приходится разбирать (let …), (destructuring-bind …) и прочее каждую по отдельности. Посмотри на этот ужас: https://gitlab.common-lisp.net/iterate/iterate/blob/master/iterate.lisp#L275

Да и еще как эту фичу увязать с другими крестовыми фичами? Например, можно ли будет породить этим манипулированием с AST новый шаблон, который после этого раскрывается в нечто,

Конечно. Как в лиспе: кусок исходника на входе, кусок исходника на выходе.

а потом еще взять результат раскрытия этого шаблона, и с его AST что-то делать?

Результат раскрытия шаблона не присутствует в исходнике. В лиспе разве можно сделать что-то с результатом компиляции функции?

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

Вот если натянуть на язык Си S-expression

Нарисуешь, как будет выглядить в виде S-expression:

template<int I, typename Head, typename... Args>
    struct getter
    {
        typedef typename getter<I-1, Args...>::return_type return_type;
        static return_type get(tuple<Head, Args...> t)
        {
            return getter<I-1, Args...>::get(t);
        }
    };

?

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

если в коде можно помимо просто main сделать некий специальный main_compiletime который бы видел весь собственный исходник

Это хоть сейчас любым C++ генератором можно делать.

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от Bioreactor
val >=  = (a: Int, b: Int) => a >= b
val !== = (a: Int, b: Int) => a != b

А почему для «!=» сделано новое имя, а для «>=» – нет?

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

Результат раскрытия шаблона не присутствует в исходнике. В лиспе разве можно сделать что-то с результатом компиляции функции?

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

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

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

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

Нарисуешь, как будет выглядить в виде S-expression:

Ну конечно что-то такое можно изобразить:

(templatedef ((int I) (typename Head) (typename... Args))
  (defstruct getter
    (
      (typedef 
        ( typename
          (::
            (INST getter (- I 1) (Args ...) )
            return_type
          )
        )
        return_type
      )

      (defun get (return_type) ( (INST Head (Args ...)) t)
        (return
          (::
            (INST getter (- I 1) (Args ...) )
            (get t)
          )
        )
      )
    )
  )
)

Только по поводу натягивания S-выражений я говорил про Си, а не про кресты.

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

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

Только вручную сделав macroexpand. А в случае реализации шаблона, он раскрывается не по месту вызова, а на верхнем уровне. То есть, если в Common Lisp пытаться делать шаблоны через макросы, то придётся просто выполнять код при раскрытии. В Racket есть syntax-local-lift-module, но результат этого раскрытия тоже в макрос уже не запихнуть, разве что результатом раскрытия делать макрос.

Вполне можно реализовать всю эту машинерию с раскрытием рекурсивных шаблонов через механизмы переписывания AST в компилтайме

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

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

В соседней ветке уже предлагали использовать универсальный парсер для разбора Си++. Универсальный механизм всегда проигрывает специализированному. В частности, можешь попробовать на макросах Common Lisp реализовать шаблоны C++ с выбором реализации по типам и SFINAE.

наследования и проч

Слабо на макросах Common Lisp сделать классы Си++? С выбором реализации в момент компиляции, а не выполнения, чтобы скорость выполнения метода равнялась скорости выполнения обычной функции (и при возможности вообще метод инлайнился)?

Добавить макросы в Си++ можно. Заменить ядро компилятора на лиспоподобное не выкинув половину оптимизаций – крайне сложно.

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

Только по поводу натягивания S-выражений я говорил про Си, а не про кресты.

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

Ну конечно что-то такое можно изобразить:

Что ж ты скобки не по-лисповому ставишь…

И хочешь сказать, что работать с этим списком

(typedef (typename (::
                     (INST getter (- I 1) (Args ...))
                     return_type))
         return_type)

проще, чем со структурами (struct typedef (source dest)), (struct templ-instance (name params)), ….?

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

Только по поводу натягивания S-выражений я говорил про Си, а не про кресты.

Вообще, если брать S-выражения и компилятор Си/С++, то можно просто использовать L++. Лисповые макросы есть, скорость выполнения определяется компилятором C++.

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

А вот это интересный вопрос.

Можно задавать на собеседованиях.

Welcome to Scala 2.12.10 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_172).
Type in expressions for evaluation. Or try :help.

scala> val mm = Map("a" -> 100, "b" -> 101, "c" -> 201)
mm: scala.collection.immutable.Map[String,Int] = Map(a -> 100, b -> 101, c -> 201)

scala> def mc(m:Map[_,Int],a:Int,f:(Int,Int)=>Boolean):Map[_,Int]=m.filter({case(k,e)=>f(e,a)})
mc: (m: Map[_, Int], a: Int, f: (Int, Int) => Boolean)Map[_, Int]

scala> val != = (a: Int, b: Int) => a != b
!=: (Int, Int) => Boolean = $$Lambda$1269/1496396949@4a04ca74

scala> val !== = (a: Int, b: Int) => a != b
!==: (Int, Int) => Boolean = $$Lambda$1270/1974690755@6ea3a513

scala> print (mc(mm, 101, !==))
Map(a -> 100, c -> 201)

---> !!!!!!!! <----

scala> print (mc(mm, 101, !=))
<console>:11: warning: imported `$bang$eq' is permanently hidden by definition of method != in class Object
       import $bang$eq
                                   ^
<console>:15: error: type mismatch;
 found   : Any => Boolean
 required: (Int, Int) => Boolean
       print (mc(mm, 101, !=))

---> !!!!!!!! <----

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

:-)

Scala - сплошная загадка.

Просто живая иллюстрация эффекта - https://ru.wikipedia.org/wiki/Эффект_Даннинга_—_Крюгера

Сначала я думал, что в Scala всё просто.

Когда реально началась работа, то я возненавидел Скалу.

Потом стал привыкать.

До сих пор привыкаю...

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

М-да. В Scheme/Racket неожиданностей гораздо меньше. В Си/Си++ они хотя бы размечены в стандарте. А здесь попытался в документации найти, что так должно быть, ничего не нашёл. Object в документации называется Any, про то, что его методы должны быть глобальными функциями ничего не сказано.

Зато нашёл неожиданный генератор случайных чисел:

scala> (## _)()
res21: Int = 1476913734

scala> (## _)()
res22: Int = 35126588

scala> (## _)()
res23: Int = 1668613848
monk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.