LINUX.ORG.RU

Vim или Emacs? А LISP в 2021?

 , ,


1

3

https://www.youtube.com/watch?v=8Q9YjXgK38I&t=42s

Парень в определённых кругах, личность известная.
посмотрел я его ролик, стал ковыряться по истории:

А ведь Crashbandicoot была годной игрой…

Что выбрать? Vim или Emacs?
Изучать в 2021 году Lisp? Если изучать, какой? Практика?
А не засмеют сотрудики?

Времени в сутках маловато, на всё не хватает.


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

Как глубока кроличья нора?

Смотря как копать :) Я то сам не глубоко копаю, потому что основную работу пишу не на схеме (а часто и не пишу вовсе, а рисую).

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

Последний раз функции знали имена фактических аргументов где-то в 70-х годах.

Потому это и не функция.

А ты, кстати, так и не сказал, что будет, если сделать (foo (+ a 1) b something)

А не надо так делать, не для этого это. А если хочется, то можно сделать дополнительную проверку.

а в этом и вся причина, почему уже 50 лет так не делают

«Если мне не надо, значит никому не надо»

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

А если хочется, то можно сделать дополнительную проверку.

И делают. В видео выше был пример. (Правда там паниша интерпритатор писал на CL).

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

Ого!

Hardware description languages such as Verilog are similar to software programming languages because they include ways of describing the propagation time and signal strengths (sensitivity)

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

Вот только сколько человековыходных будет потрачено на аналог, например, grep…

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

Последний раз функции знали имена фактических аргументов где-то в 70-х годах

Потому это и не функция

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

[(key, array[key]) for key in ('a', 'b', 'something')]

И всё. Какой макрос? Какая функция? Лиспа обожрался натощак?

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

Пока люди упрощают себе жизнь макросами, ты будешь упорно писать костыли и копипастить

Я выберу простую жизнь изначально. Как и сделала индустрия.

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

При всём троллинге @MOPKOBKA правильно написал: JS. Но оно такое странное, что если, допустим, знать только Java - будешь возиться с классами, плеваться, возиться дальше. Если плотно на Haskell наяривал, будешь плотно возиться с неизменяемыми структурами, плеваться, возиться дальше.
А тут выходит на сцену Lisp. Говорят, дикий зверь. Я вот всё время мимо кропроходил. Может он даст Сатори и я смогу дружить с JS как нормальный человек?

Ответ прост: на JS нужно писать как на JS — вот и весь секрет успеха. Неизменяемые структуры плохо поддерживаются в JS, потому их можно считать глубокой оптимизацией. Но это не запрещает пересоздавать структуры данных на каждый чих, как это делает тот же React. Причем. в случае контейнеров малого размера операция копирования почти бесплатна, потому что под капотом V8 делает то же самое.

Вот пример сразу под рукой — чел везде видит лисп, «как у вас тут макросы пишутся»:
Vim или Emacs? А LISP в 2021? (комментарий)
Хотя реально ему макросы не нужны. В том же C/C++ условную компиляцию можно было бы реализовать вообще без макросов, но для этого нужен был контексто-независимый синтаксис, а где ж его возьмешь в сях. Если я не ошибаюсь, этот подвиг все-таки сделал Zig.

Классы в JS — это самый вредный аспект языка, который упорно натягивают на JS с жавы. Почему-то люди никак не могут понять, что JavaScript и Java — это совершенно разные языки.

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

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

Дружить с JS ты сможешь если у тебя будет больше практики, и использования, чтения нормальных либ

О! А где же список «нормальных либ»? Где их найти в 2021, когда весь NPM завален тайпскриптом и жавой? Твой ответ по сути значит «чтобы хорошо писать на JS — нужно хорошо писать на JS».

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

Остаётся, что там 20 лет косяки дизайна под ковёр заметали и теперь куча мух пользуется. Звучит так заманчиво (нет)

С 2015 стандартом многие подковерные вещи больше не используются и порицаются в линтерах. Модули переписаны с нуля и имеют универсальный вид для ноды и браузера. Оператор сравнения «==» считается абсолютным злом и полностью вытеснен из практики. Сложение строк заменено оператором форматирования ` `. Отсутствие точки с запятой или наличие переноса строки между if/for и фигурной скобкой считается моветоном. Вместо кривых костылей для итерации по объектам введены унифицированные итераторы с «for (let ... of...)», и Object.keys/values для превращения объектов в эти итераторы. Также эти итераторы при необходимости всегда можно превратить в простой массив и сделать map/forEach. Старые же методы создания объектов заменены новыми в виде spread notation, которая поощряет неизменяемые объекты и даже позволяет раскрывать массивы как аргументы функции. И самая главная фича асинхронного программирования — промисы. Теперь никаких колбэков и ёлочек на двадцать уровней вложенности.

Короче говоря, если этот язык показать жаваскриптеру, залезшему в криокамеру примерно в 2010 году (когда начали вылазить библиотеки с промисами), то он даже не узнает, что перед ним JS.

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

одна только фича с потерей this меня радует просто безмерно

Уже давно пофикшено с лямбдами. Естественно, работает только для нового кода, написанного на лямбдах.

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

Ок, я тебе назову одно преимущество лиспа в 2к21 чтобы опровергнуть всю твою позицию о «преимуществ нет». :) Дальше - в поиск по ЛОРу, или Гугл.
Ридер макросы

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

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

Что же на самом деле остается от киллер фичи? Глубокая интегрированность ридер макросов в REPL, для лиспа есть больше всего готовых инструментов для них. С другой стороны, в питоне даже отладчик может правильно ходить по транслированному кастомным загрузчиком сорцу, так что в этом плане дистанция между питоном и лиспом абсолютно минимальна.

А теперь минус reader macro, который компенсирует плюс: легкость писания DSL приводит к тому, что каждый школьник пишет на лиспе свой DSL, который не сможет прочитать другой такой же школьник, написавший совершенно иной DSL для своей задачи. То есть, получается низкая переиспользуемость знания языка. Лиспер говорит «зачем уметь, если можно творить, созидать?» — индустрия отвечает «ваше место у параши».

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

Будешь смеяться, но игорь чаще всего на C# пишут, который не быстрее Java

Еще раз: C# значительно быстрее Java. Не из-за волшебных свойств языка, а из-за платформоспецифичной реализации. Разрабы жавы поставили себе целью идеальную кроссплатформенность, все либы должны быть написаны на самой жаве, а в нативном коде только самые базовые функции. C# построен на огромной куче нативного кода, которые работает намного быстрее аналогичных жавовых либ.

С другой стороны, в «моей любимой» They are Billion таки большая часть логика реализована на шарпе, без натива, из-за чего игорь периодически дичайше тормозит при сборке мусора.

Опять же, в случае Lua и прочих скриптов этот подход еще более ярко проявляется, потому что там большая часть низкоуровневых функций реализовано на C/C++, как в упомянутом Warcraft 3 или неупомянутом Starcraft 2. По этой причине тот же питон в продакшене может тормозить удивительно быстро.

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

Ответ прост: на JS нужно писать как на JS — вот и весь секрет успеха.

Да никто не знает, как на нём правильно писать. Ты вообще мимо кассы. Мозги включи, прочти мой пост, подумай.

Ещё раз. Человек не может взят из ниоткуда знания. Он учится на ОПЫТЕ. Посмотрел, скопировал, сравнил с предыдущим.

Вон пацаны при написании SICP с первой страницы нормально троллили Д. Локком.

А ты - писать на JS. Ты его знаешь? Да хрена с два. Я же по постам видел. Так, по верхам, как и большинство. И пишут, как умеют. Короче, скучно. Мало кто абстрагируется, вы всё байтики перебираете и кто как пук парадигму назвал.

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

Восклицательный знак? Наверное, имелось в виду «!!»?

У тебя же не список, а массив^ https://hackage.haskell.org/package/array-0.5.4.0/docs/Data-Array.html#v:-33-

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

Вот поэтому хаскел читабельней, чем Си.

Ты должен получить контейнер на элемент массива pabc[idx]

Мы таки переписываем Си в эквивалентный хаскел или работаем с чуждыми внешними указателями?

К тому же, что такое to_sometype?

Функция, преобразующая аргумент к типу sometype. Хаскелевский вариант (*sometype).

Ну и вариант «тупо превратить сишный структуры в родные хаскевы» не прокатывает, потому тчо условие было «переписать строчка в строчку».

Если в сишном коде была та строчка, то в хаскелевском эквивалентном будет эта, делающая то же самое.

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

    to_someType >>= readIORef >>= (readIORef . abc) >>= (flip unsafeRead idx) >>= (readIORef . fld) >>= readIORef >>= (readIORef . val)
monk ★★★★★ ()
Ответ на: комментарий от byko3y

Это и есть тот самый «новый синтаксис», который эти макросы приносят? Просто чтобы сделать ленивое вычисление аргументов?

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

И я уже приводил примеры макросов, которые не сводятся к ленивому вычислению.

Ты развернул причинно-следственную связь: это в лиспе макросы заменяют функции за счет отсутствия ленивости.

Ленивость в лиспе делается достаточно тривиально. Но макросами проще. Ещё для изменения значения параметров макросы используются (что в Си++ решается передачей по ссылке).

В F# ленивость есть и макросов нету — как так?

Так же как и в Java. Страдают и сложные случаи решают внешними кодогенераторами.

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

Так линковка последняя стадия компиляции программы. И ошибка будет до запуска программы, а не при обращении к несуществующему символу.

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

Вот и я о том же — на хаскеле нельзя написать GUI.

Написать можно (все базовые операции для доступа к WinAPI или серверу X Window есть). Но пока никто не написал.

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

«Read macro» у меня сейчас в моей питоньей либе.

Можно ссылку на описание? Или как оно работает?

Как же так, говорили ведь, что только лисп умеет в DSL?

Кто такое говорил? Он был первым, кто умеет в DSL. Но в целом языков с макросами много. От Nemerle до попсового Rust.

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

Тебе не нужна функция, тебе не нужен макрос

Хоть ссы в глаза - всё божья роса. Ты вроде не дурак, зачем тупишь?

Вот без макроса:

(foo `((var1 ,var1) (var2 ,var2) (var3 ,var3))

Вот с макросом:

(foo var1 var2 var3)

Видишь разницу?

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

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

Если брать Common Lisp, то там один набор киллер фич: макросы, ридер макросы, динамические переменные, CLOS, работа в образе (сохранение/загрузка, возможность добавлять/удалять любые объекты программы в процессе работы), отладчик (в котором можно изменить программу произвольным образом и продолжить выполнение).

Если брать Racket, то немного другой: гигиенические макросы, модули, большая стандартная библиотека, поддержка написания языков (DSL) с произвольным синтаксисом и поддержкой IDE на уровне модулей.

А теперь минус reader macro, который компенсирует плюс: легкость писания DSL приводит к тому, что каждый школьник пишет на лиспе свой DSL

На ООП пишут свои DSL через паттерн Builder. На C++ вообще каждый школьник свою реализацию строк и массивов пишет. NIH работает вне зависимости от языка.

И переиспользовать DSL никто не мешает (cl-sql, например, или cl-match).

monk ★★★★★ ()

Самые лучшие макросы в FASM Самый лучший лисп это newLISP Но если охота лиспа без скобочек, то это Lua ну или JS (хотя и тут скобочек хватает)

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

макросы выполняют ту же роль, что и функции, а потому макросы не нужны

Как бы в языке всё выполняет одну роль - вычисления. Если говорить что то или это ненужно, то получится брейнфак.

Макросы выполняют вычисления во время компиляции и в гомоиконном языке это очень важно, т.к. можно вычислять конструкции самого языка.

Я уже говорил в одной теме, что макросы в ЛИСП позволяют выражать взаимосвязи бизнес-логики явно в коде программы. А в «обычных» языках взаимосвязи выражаются динамически (паттерны как раз про это). Насколько это нужно или ненужно вопрос отдельный.

no-such-file ★★★★★ ()

Что выбрать? Vim или Emacs? Изучать в 2021 году Lisp?

Маленький старенький встроенный LISP в 2021 есть ещё в XEdit. В Scratch буфере по С-j

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

Емакс луче. Любители виэскода идут в сраку.

Спасибо, а почему?

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

Оператор сравнения «==» считается абсолютным злом

Это 5.

Отсутствие точки с запятой или наличие переноса строки между if/for и фигурной скобкой считается моветоном.

Ну всё, господа, расходимся. JS больше не игрушечный язык для снежинок.

Но это ладно, это я придираюсь. А вот объясните мне, господин хороший, отчего в репозитории typescript, который всё что делает — дергает несколько API вызовов:

du -sch node_modules 
576M    node_modules

Это вообще нормальным считается среди жабоскриптеров?

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

в репозитории typescript

мне нравится преобразование ts —> js —> babel —> js

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

превратить в простой массив и сделать map

дада.

[«10», «10», «10»].map(parseInt)

ты так говоришь, как будто в js не хватает дичи. причем совершенно упоротой дичи.

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

А IDE это PyCharm, PhpStorm, итд.

Хочу набросить: Goland по комплишену проигрывает youcompleteme, потому что полностью не способен в cgo. Редакторы из 70-х победили одну из самых продвинутых IDE 21-го века.

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

Да никто не знает, как на нём правильно писать. Ты вообще мимо кассы. Мозги включи, прочти мой пост, подумай.
Ещё раз. Человек не может взят из ниоткуда знания. Он учится на ОПЫТЕ. Посмотрел, скопировал, сравнил с предыдущим

Я знаю. Проблема в том, что по этой методике сложно написать книжку, потому что книжку обычно пишут про «делай вот это», а не про «не делай вот это». Им нужно «копировать» и «сравнивать с предудущим» — особенно когда задание новое и сравнивать, на самом деле, не с чем. Конечно, есть факторы плана «вот эти структуры данных в JS работают очень медленно», который можно проверить только экспериментально — но экспериментальных сведений нынче есть достаточно, чтобы с хорошей точностью оценивать новую архитектуру.

Опять же. говоря про

А ты - писать на JS. Ты его знаешь? Да хрена с два

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

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

Или вот еще: я не знал, что прототипы изменяемы и изменение прототипа приводит к изменению использующих этот прототип классов. Дает ли это знание мне какие-то способности по сравнению с незнающими эту деталь анатомии? Конечно нет, потому что среди культурных людей принято не совать побриаемые с земли вещи в рот и не изменять прототипы у активно используемых объектов — что еще более актуально в свете оптимизаций, поскольку движки JS точно так же не ожидают, что кто-то будет менять прототип после создания объекта.

А ты начинаешь тут «не совал бейсбольную биту в жопу — не программист».

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

Восклицательный знак? Наверное, имелось в виду «!!»?

У тебя же не список, а массив^ https://hackage.haskell.org/package/array-0.5.4.0/docs/Data-Array.html#v:-33-

Проблема в том, что я так и не нашел каких-то способов выразить эту структуру данных в более-менее стандартных либах:

https://hackage.haskell.org/package/array-0.5.4.0/docs/Data-Array-Unboxed.html

Как ты видишь, в Unboxed массив нельзя засунуть сложную структуру данных иначе, нежели через указатель. Есть вот такая штука:
https://downloads.haskell.org/~ghc/7.10.1/docs/html/libraries/Foreign-Marshal...
но там весь доступ через функции и тип «Ptr a».

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

Вот поэтому хаскел читабельней, чем Си

Да, типы в Си — та еще блевотина, но я могу и на паскале тебе то же самое написать:

PSomeType(@(p^.abc[idx].fld))^.val

Мы таки переписываем Си в эквивалентный хаскел или работаем с чуждыми внешними указателями?

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

to_someType >>= readIORef >>= (readIORef . abc) >>= (flip unsafeRead idx) >>= (readIORef . fld) >>= readIORef >>= (readIORef . val)

Уже лучше — это тот хаскель, к которому мы привыкли.

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

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

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

И я уже приводил примеры макросов, которые не сводятся к ленивому вычислению

Константы и условные компиляции? А я уже отвечал, что для них не нужны макросы на самом деле, даже в алгол-подобных языках не нужны, если по-хорошему, как то сделано в Zig.

Ленивость в лиспе делается достаточно тривиально. Но макросами проще. Ещё для изменения значения параметров макросы используются (что в Си++ решается передачей по ссылке)

Вот именно — еще одно применение макросов, которое на самом деле решается банальными функциями. Практически все назначения макросов в лиспе реализованы другими инструментами в других языках. Есть отдельная узкая ниша продвинутых генераторов кода, но там, как правило, они вполне четко отделены от обычного кода, и с таким же успехом код можно генерировать на голом Си.

Потому гнуть 99% кода на языке ради удоства 1% применений — это такая себе история. Которая, тем не менее, подается как киллер фича лиспа.

Страдают и сложные случаи решают внешними кодогенераторами.

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

Так линковка последняя стадия компиляции программы. И ошибка будет до запуска программы, а не при обращении к несуществующему символу

Ошибка будет при запуске, при загрузке библиотеки, или даже при активации фичи в случае поиска функций в рантайме.

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

Написать можно (все базовые операции для доступа к WinAPI или серверу X Window есть). Но пока никто не написал

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

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

«Read macro» у меня сейчас в моей питоньей либе.

Можно ссылку на описание? Или как оно работает?

Например:
https://stackoverflow.com/questions/43571737/how-to-implement-an-import-hook-...

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

Кто такое говорил? Он был первым, кто умеет в DSL. Но в целом языков с макросами много. От Nemerle до попсового Rust

Он не просто был «первым, кто умеет» — он вообще был самым первым в своем классе. Пора бы закопать уже.

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

Вот без макроса:
(foo `((var1 ,var1) (var2 ,var2) (var3 ,var3))
Вот с макросом:
(foo var1 var2 var3)
Видишь разницу?

Вижу:

>>> import sys
>>> var1 = 1
>>> var2 = 2
>>> def foo(*args):
	for name in args:
		print(name, '=', sys._getframe(1).f_locals[name])

		
>>> foo('var1', 'var2')
var1 = 1
var2 = 2

Я только не вижу, зачем тебе эта шморгалка.

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

CLOS

Точно?

динамические переменные

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

работа в образе (сохранение/загрузка, возможность добавлять/удалять любые объекты программы в процессе работы)

Умеет питон. Не умеет сохраняться да, но это спорная фича в век повсеметных операций с файлами, GUI, и сетью.

отладчик (в котором можно изменить программу произвольным образом и продолжить выполнение)

Умеет питон. Даже дотнетовый отладчик умеет в рантайме подменять код на новый.

Если брать Racket, то немного другой: гигиенические макросы, модули, большая стандартная библиотека, поддержка написания языков (DSL) с произвольным синтаксисом и поддержкой IDE на уровне модулей

Ну гигиенические макросы ты будешь только с остальными лиспами и с препроцессором Си мерять. DSL, как я уже неоднократно подчеркивал, почти никому не нужен на самом деле — большинству, наоборот, нужен инструмент для того, чтобы быть по руками мамкиных архитекторов, пишущих криптокод на криптоязыке.

На ООП пишут свои DSL через паттерн Builder. На C++ вообще каждый школьник свою реализацию строк и массивов пишет

Не знаю про Builder, но в проектах, которые использовали кастомные строки и массивы, вроде UE и Qt, внутри фреймворка эти строки и массивы одинаковы.

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

Макросы выполняют вычисления во время компиляции и в гомоиконном языке это очень важно, т.к. можно вычислять конструкции самого языка

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

Макросы выполняют вычисления во время компиляции и в гомоиконном языке это очень важно, т.к. можно вычислять конструкции самого языка

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

Я уже говорил в одной теме, что макросы в ЛИСП позволяют выражать взаимосвязи бизнес-логики явно в коде программы. А в «обычных» языках взаимосвязи выражаются динамически (паттерны как раз про это). Насколько это нужно или ненужно вопрос отдельный

Спасибо, не понял.

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

А вот объясните мне, господин хороший, отчего в репозитории typescript, который всё что делает — дергает несколько API вызовов

У меня 65 МБ, из которых сам тайпскрипт — порядка 15 МБ. Что там у тебя внутри-то?

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

[«10», «10», «10»].map(parseInt)
ты так говоришь, как будто в js не хватает дичи. причем совершенно упоротой дичи

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

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

Goland по комплишену проигрывает youcompleteme, потому что полностью не способен в cgo. Редакторы из 70-х победили одну из самых продвинутых IDE 21-го века

Ты слишком преувеличиваешь значимость продуктов ЖирБрейнс.

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

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

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

Но в ЛИСПе ты по крайней мере увидишь структуру взаимосвязей. Тебе не придётся её в голове выстраивать.

Спасибо, не понял

Объясняю на примере. Путь у тебя есть функция для работы с api, которая принимает 2 функции get_response для получения ответа и save_data для парсинга и сохранения данных из ответа. Т.е.

api(get_response, save_data)

Теперь тебе нужно получать ответ через прокси, ты заворачиваешь get_response в декоратор, который будет заворачивать взаимодействие через прокси

const proxied_get_response = new ProxyDecorator(get_response)
api(proxied_get_response, save_data)

Т.о. ты динамически, в виде алгоритма определил взаимосвязь между ProxyDecorator, get_response и api. Чтобы понять эту взаимосвязь тебе нужно «прокрутить» код в голове и понять какое состояние будет в динамике в момент вызова api.

В ЛИСПе ты вместо этого пишешь макрос, с помощью которого взаимосвязи задаются явно в декларативной форме:

(with-proxy (api get-response save-data))

В питоне для декораторов есть сахарок на эту тему, но как всегда это там сугубо костыльное и специфичное решение. Но даже оно сильно помогает в тех же web-фреймворках декларативно задавать роуты, мидлварь и т.п., а не писать лапшу в стиле app.use и route.get.

no-such-file ★★★★★ ()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от byko3y

Ты же понимаешь, что это грязь?

Сишные макросы работают также. И GObject/GTK только благодаря ним в Си более-менее нормально выглядит.

это должно быть описано явным протоколом

А это так и есть: всё описано в документации. Также как в ООП языках есть неявные переменные типа this, так и в макросах могут быть неявные переменные (например внутри loop есть it, в котором результат условия).

Константы и условные компиляции?

Нет. loop и for/list.

Ошибка будет при запуске, при загрузке библиотеки, или даже при активации фичи в случае поиска функций в рантайме.

Так динамический линковщик до запуска программы отрабатывает.

monk ★★★★★ ()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)