LINUX.ORG.RU
Ответ на: комментарий от monk

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

В программе пишется примерно так:

(a ((href ,(embed/url any-closure))) ...)

где any-closure — любое замыкание с одним параметром, возвращающее страницу. Можно даже так

(a ((href ,(embed/url 
             (lambda (request)
                ...)))) ...)

А веб-сервер сам сформирует из этого ссылку и при переходе по ней выполнит функцию.

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

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

Тем не менее, вот SBCL:

CL-USER> (defmacro foo (var-name &environment env)
           `',(multiple-value-list (sb-cltl2:variable-information var-name env)))
FOO
CL-USER> (let ((x 123)) (declare (type fixnum x)) (foo x))
; in: LET ((X 123))
;     (X 123)
; 
; caught STYLE-WARNING:
;   The variable X is defined but never used.
; 
; compilation unit finished
;   caught 1 STYLE-WARNING condition
(:LEXICAL T ((TYPE . FIXNUM)))
CL-USER> 

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

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

В Scheme и ее потомках вообще статическая глобальная область видимости. О каком лиспе тут может вообще речь идти?

Являются ли Java и C# диалектами C++? C? Алгола? Симулы? Нет, не являются.

Повлияли ли на них C, C++, Алгол и Симула? Да, естественно.

Но почему-то никто не говорит что Java это Си.

Затой каждый дурачок почему-то называет Clojure лиспом. Или вон, ромбус теперь выкатили какой-то вшивый, тоже у них лисп. Охереть не встать.

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

В Scheme и ее потомках вообще статическая глобальная область видимости. О каком лиспе тут может вообще речь идти?

Не понял, чем глобальный define отличается от глобального defvar или defun. Или приведи пример, что имеешь в виду.

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

А реальность следующая:

  • Clojure - наиболее захайпованный, вот и все. Никто там особо Java не использует, все пишут свои велосипеды, причем кривые. Язык является смесью кривых костылей вследствие JVM, той части стандартной библиотеки CL которую Рич Хики осилил реализовать(многие полезные вещи, да и главные основные даже - не осилил), и каких-то упориновых взглядов на Ъ фп, абсолютно непрактичных, даже менее практичных чем в настоящих Ъ ФП(ML, Haskell), всеобъемлющей тормознутости, и адском сракотане в плане отладки.

  • Racket и прочее - ресерч проекты, использующиеся максимум для обучения студентов. В быту бесполезны.

  • CL - наиболее практичный, доступный и развитый из всех трех, с самыми навороченными компиляторами, с кучей библиотек, включая доступ к дотнету (а в коммерческих реализациях или в ABCL - и к Java тоже), и вообще чему угодно.

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

Потому что это CLTL2. Он понятия не имеет как устроен вывод типов в SBCL.

А кто имеет понятие? Естественно SBCL.

CL-USER> (defmacro foo (&environment env) env)
FOO
CL-USER> (let* ((x 123) (y x)) (foo))
; in: LET* ((X 123) (Y X))
;     (Y X)
; 
; caught STYLE-WARNING:
;   The variable Y is defined but never used.
; 
; compilation unit finished
;   caught 1 STYLE-WARNING condition
#S(SB-KERNEL:LEXENV
   :FUNS NIL
   :VARS ((Y . #<SB-C::LAMBDA-VAR :%SOURCE-NAME Y {1003E80723}>)
          (X
           . #<SB-C::LAMBDA-VAR
               :%SOURCE-NAME X
               :TYPE #<SB-KERNEL:NUMERIC-TYPE (INTEGER 123 123)>
               :FLAGS (SB-C::DELETED) {1003E80633}>))
   :BLOCKS NIL
   :TAGS NIL
   :TYPE-RESTRICTIONS NIL
   :LAMBDA #<SB-C::CLAMBDA
             :%SOURCE-NAME SB-C::.ANONYMOUS.
             :%DEBUG-NAME (SB-C::&AUX-BINDINGS (SB-C::LAMBDA-VAR))
             :KIND :ZOMBIE
             :TYPE #<SB-KERNEL:BUILT-IN-CLASSOID FUNCTION (read-only)>
             :WHERE-FROM :DEFINED
             :VARS (Y) {1003E80E93}>
...

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

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

https://github.com/Lovesan/bike - тестировать и портировать под яблоговно предлагаю тебе самому.

плюс

https://avaloniaui.net/

inb4, «Переносимый UI» в жопу никому нахер не сдался, кроме тех комплюхтерщиков, которые предпочитают сидеть на линуксе, а программы для клиентов писать виндовые. Но таким надо визин от красноглазия закапывать почаще, и помнить что они для клиентов программы пишут а не для развлечения. Все вещи реализующие «переносимый UI» это либо ад и сракотан типа Electron, который из себя тупо представляет веб-браузер на стероидах, либо говно которое выглядит как говно и работает как говно, потому что является говном и нигде нормально не работает кроме м.б. линуксов, и кроме них же выглядит чужеродно и всрато (GTK, Tk и Qt всякие)

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

https://github.com/Lovesan/bike - тестировать и портировать под яблоговно предлагаю тебе самому.

Не понял. Где там линуксовый GUI?

https://avaloniaui.net/

Если это, то в каком Линуксе оно есть? Я её даже в Debian не вижу.

«Переносимый UI» в жопу никому нахер не сдался

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

помнить что они для клиентов программы пишут а не для развлечения

Именно так. Сейчас даже 1С клиента для Линукса запилил.

Все вещи реализующие «переносимый UI» это либо

Вот Racket GUI и является исключением не попадающим ни в одну из этих двух категорий.

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

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

Вынесу из одного чата, где я недавно это обсуждал, в частности

в Java и C# метапрограммирование пытаются пропихнуть средствами GraalVM и PostSharp, и где-то это даже используется, но получается это адски черезжопно по той простой причине, что нормальное метапрограммирование возможно только в лиспе. В C# и Java - слишком много самого_языка, и во-первых оперировать им ты задолбаешься(сложные языки усложняют правило оперирования ими - дохерища всяких ключевых слов, специальных corner-case правил, и я это еще не говорю про типизацию - тут кстати можешь посмотреть как делается составление AST в лиспе у меня в либе и там же в C#), а во-вторых когда ты пишешь свое расширение языка под задачу, или доменно-специфичный язык под задачу - то тебе часто термины нижележащего языка нахер не всрались.

Не всрались в каком плане. Вот допустим у нас в некоем абстрактном мета-C# есть возможность написать язык для оперирования бизнес-правилами ипотечного кредитования(от которых в США можно повеситься). У этого гипотетического доменно-специфичного языка LQL будут ключевые слова loan, fico, reject и прочее. Прямо аки у SQL ключевые слова table, select, и так далее.

Но так как мы его пишем на гипотетическом мета-C#, то нам придется каким-то образом обрабатывать термины C# в этом языке, и пропихивать их в этот язык, хотя они там в жопу не сдались. Например в C# есть ключевое слово class. И че с ним делать? На кой хер нам этот class и вообще это ООП если мы хотим в нашем условном LQL сделать так чтобы class значил класс заема в терминах ипотечной торговли? То есть мы не можем нормально встроить этот наш DSL в наш мета-C# получается. Поэтому никакого мета-C# и нету(PostSharp не считается, потому что это говно и костыли), а есть говноинтерпретаторы конфигов на XML, потому что вот у XML, никаких таких ограничений нет, это тупо древовидная структура, семантику которой ты определяешь сам. Что собственно и делается постоянно в энтерпрайзе.

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

Сейчас импортозамещение и санкции.

Проблемы негров.

Соответственно, программы должны работать, как минимум на Windows

Пусть и переносят. А пишут сразу под красноглазикс.

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

Но так как мы его пишем на гипотетическом мета-C#, то нам придется каким-то образом обрабатывать термины C# в этом языке, и пропихивать их в этот язык, хотя они там в жопу не сдались. Например в C# есть ключевое слово class. И че с ним делать?

Не понял. В реальном CL никто не мешает внутри DSL дать другое значение ключевым словам go и if. Что мешает в гипотетическом мета-C# внутри DSL переопределить class?

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

Проблемы негров.

А там, где нет проблем, у пользователей нет Линукса. Чему радуешься? Тому, что отсутствие переносимого GUI у CL не так мешает? Кстати, а на Линуксе какой нынче актуальный GUI? cl-cffi-gtk два года как заброшен… cl-gtk4?

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

Не понял. В реальном CL никто не мешает внутри DSL дать другое значение ключевым словам go и if.

Потому что в CL они никуда не встроены, вот именно. Это не ключевые слова вообще. Ты не понимаешь как работает лисп, похоже.

Что мешает в гипотетическом мета-C# внутри DSL переопределить class?

Каким образом ты это переопределишь? У тебя class встроен в язык C# как ключевое слово

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

Каким образом ты это переопределишь? У тебя class встроен в язык C# как ключевое слово

Также, как в лиспе:

change_syntax(lql);

здесь class трактуется по правилам парсера lql

change_syntax(c#);

Или

lql {
   здесь class трактуется по правилам парсера lql
}

Тем более, что есть прецедент. Ключевое слово in в C# в LINQ переопределено.

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

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

Типизация позволяет раскрывать в разные формы в зависимости от типа переменной. И это как раз приспосабливать инструмент.

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

Также, как в лиспе:

ЛОЛ, я же говорю ты не понимаешь как работает лисп.

Это как раз не как в лиспе. Это как в ASP.NET - в Razor, Blazor и прочее - это называется внешний DSL, для которого построен отдельный лексер, отдельный парсер, и отдельный компилятор и/или интерпретатор.

А по-другому никак! Потому что class в C# ты не переопределишь без переопределения работы компилятора. А компилятор C#, как и большинства современных ЯП работает следующим образом - там ФИКСИРОВАННАЯ грамматика, причем ОЧЕНЬ сложная и контекстно-зависимая, поэтому там РУКАМИ написан хитровыебанный парсер, РУКАМИ написан не менее сложный лексер с обратной связью от парсера, и все такое. И ключевое слово типа class ты там просто так не переопределишь, потому что тебе придется менять грамматику и перехерачивать парсер с лексером(и это, для КЗ-грамматик, да и вообще для любых грамматик, это не вопрос «одну функцию написать»(inb4 макросы в лиспе), а вопрос переопределения всей схемы построения дерева анализатором).

Ключевое слово in в C# в LINQ переопределено.

LINQ это часть C#, але. Это никакой не пример метапрограммирования.

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

Потому что class в C# ты не переопределишь без переопределения работы компилятора.

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

LINQ это часть C#, але. Это никакой не пример метапрограммирования.

Этот подход возможен в любом метапрограммировании. LING распознаётся по слову from. Можно добавить конструкцию macro, позволяющую создавать новые слова и будет аналогично

macro lql(Stream code) { ... }

lql здесь макрос читает произвольный синтаксис с class имеющим другое значение;
monk ★★★★★
()
Ответ на: комментарий от monk

Да тебе не нужна типизация блеать, нижележащего языка, в твоем DSL приспособленном под задачу, алё. Она тебе там только МЕШАЕТСЯ.

Это одна из причин почему Template Haskell или макросы Scala или Rust такое говно, и ими пользоваться вообще нахер невозможно кроме совсем простеньких кейсов(аля циклы поудобнее писать, или прости г-ди printf в compile-time раскрыть в последовательность print)

Вот еще пример.

(define-dotnet-object-printer DateTime (this stream)
  (pprint-dotnet-object (this stream :type t)
    (write-string [this ToString [:CultureInfo GetCultureInfo "en-US"]]
                  stream)))

Вот где здесь и на какой хер нужна типизация нижележащего языка? Ты понимаешь, что тут работается с объектной системой дотнета, которая вообще совершенно отличается от ООП в лиспе(хотя я там делаю связку потом, конечно, но это про другое). И вот эта функция - она вызывается в зависимости от типа объекта дотнета в рантайме. Тут твоя типизация твоего всратого Racket, будь это написано на Racket - не сдалась нахер вообще от слова совсем.

И вот подавляющее большинство настоящего(inb4 Production Quality) метапрограммирования - оно такое. Оно про то, чтобы делать что-то не относящееся к самому базовому языку.

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

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

Ты не понимаешь вообще чтоли? В CL ты пишешь одну сраную функцию времени компиляции, ВСЁ. И она автоматически подставляется при транскрипции правил компилятора. В C# тебе для каждого ключевого слова придется перепидорашивать ВСЁ НУТРО КОМПИЛЯТОРА.

Этот подход возможен в любом метапрограммировании. LING распознаётся по слову from.

Это не метапрограммирование, это часть C#

Можно добавить конструкцию macro, позволяющую создавать новые слова и будет аналогично

Блеать какой ты упоротый а. НЕТ, НЕЛЬЗЯ. Иди почитай сорцы компилятора C#, и вообще про грамматики, парсеры и компиляторы, начиная там хотя бы со сраного Dragon Book.

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

Template Haskell или макросы Scala или Rust

Там нельзя менять синтаксис. Только сопоставлять уже разобранный. Впрочем, как и в defmacro. Сделать через него макрос типа (my-macro f[x] = g(x), 4) не получится. Потому что скобки и запятая уже определены.

Никто не мешает в любой из них добавить аналог set-dispatch-macro-character. Думаю, не хотят, так как тогда слишком легко будет «творить дичь» (по твоему определению).

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

Иди почитай сорцы компилятора C#, и вообще про грамматики, парсеры и компиляторы

Что мешает на стадии чтения понимать macro …; и тут же наткнувшись далее на id { … }; передавать выполнение макросу?

Идеология, что лексер не имеет права быть переопределяемым?

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

А по-другому никак! Потому что class в C# ты не переопределишь без переопределения работы компилятора. А компилятор C#, как и большинства современных ЯП работает следующим образом - там ФИКСИРОВАННАЯ грамматика, причем ОЧЕНЬ сложная и контекстно-зависимая, поэтому там РУКАМИ написан хитровыебанный парсер, РУКАМИ написан не менее сложный лексер с обратной связью от парсера, и все такое.

и что такого в грамматике шарпа, что там парсер меняет этап лексического анализа всерьез? то есть парсер должен менять правило для лексем, а это странно

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

в классическом компиляторе предопределенные слова меняются легко. если они есть идентификаторы.

когда лексер выделяет из потока идентификатор, например foo или class, он должен быстро определить, не является ли идентфикатор предопределенным. например class. тут либо лезут в мапу предопределенных идентфикаторов навроде c++ std::map<string, symbol>, либо делают через хеш таблицу.

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

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

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

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

Clojure у них лисп

А почему нет-то. Вот макросы, например, писать можно, прям как в коммон лиспе. В питоне и руби так нельзя, а в коммон лиспе и кложе можно. И в схеме можно, хотя внутре это и устроено по-другому.

Наверное, всё-таки что-то есть между ними общее, а?

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

освой вопрос для начала. в грамматику добавляются не правила «интерпретации слов», а грамматическое правило. выбор граматического правила в граматиках LL1 осуществляется по первому лексическом символу. если этот символ - «class_sy» какой-нить, то выбирается процедура разбора правила «class».

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

Когда ты в грамматику добавляешь правило интерпретации слова class в новом контексте - это по-твоему, как делается?

ручками это делается и головой, а не «волшебством лиспа», как у тебя вечно.

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

выбор граматического правила в граматиках LL1 осуществляется по первому лексическом символу.

У C# не LL1, и вообще даже не КС-грамматика.

Всё, иди гуляй.

ручками это делается и головой, а не «волшебством лиспа», как у тебя вечно.

У лиспа вообще нет грамматика, и поэтому там для тебя, наверное, магия, да

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

у лиспа тваво грамматика есть. это грамматика S-выражений.

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

не всякая строка текста является S выражением. поскольку чтобы быть таким выражением, строка должна удовлетворять грамматике s выражений… которой у тебя нет. гы.

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

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

у лиспа «сложные грамматические правила», навроде классического

if <boolean_expression> <statement>
else <statement>

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

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

у лиспа тваво грамматика есть. это грамматика S-выражений.

Нет, конечно. Выше пример кода на лиспе.

Ответы для темы «Почему Go это плохо....» (комментарий)

У лиспа нет грамматики, для него нельзя написать BNF.

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

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

Конечно же ее нет, и евангелисты тут вообще не при чем.

У лиспа есть только reader-алгоритм, причем модифицируемый. А грамматики нет.

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

без понятия?.. ты ж главный спец… я нарисовал неправильную точечную пару. лисп твой ругается. это я первый попавшийся взял

Unhandled SB-C::INPUT-ERROR-IN-LOAD in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                                 {10015B0003}>:
  READ error during LOAD:

    Nothing appears after . in list.
alysnix ★★★
()
Ответ на: комментарий от alysnix

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

CL-USER> (set-macro-character
          #\{ (lambda (s c)
                (declare (ignore c))
                `(print ,(read s t nil t))))
T
CL-USER> (let ((x 1) (y 2)) {x {y t)

1 
2 
T
lovesan ★★
()