LINUX.ORG.RU

Синтаксис и LISP'ы

 , ,


0

1

Часто можно наткнуться на мнение, что у лиспа(ов) нет синтаксиса. Хотелось бы понять, что конкретно тут имеется в виду.

Во-первых, синтаксическая запись s-expr'ов так же является некоторым языком, со своими синтаксическими правилами и возможностью описания посредством грамматики.

Во-вторых, различные диалекты лиспа вводят специальные дополнительные синтаксические конструкции, вроде [ и ] в clojure или typed racket.

Имеется в виду, что этот синтаксис прост и фактически без особых изменений определяет AST?


Имеется в виду, что этот синтаксис прост и фактически без особых изменений определяет AST

Именно так.

Когда синтаксис (+ (* 2 2) (* 3 4)), то AST очевидно, а когда 2*2+3*4, то надо учитывать порядок операций.

Соответственно проще декомпозиция и, при необходимости, контекстная замена операций.

monk ★★★★★ ()

Формат программы определяется reader'ом, который сама программа может переопределить. Я так делал для быстрого перегона данных внешних в s-форму.

Да и штатный легко управляется.

ziemin ★★ ()

Нет операторов, ключевых слов, которых нельзя переопределить.

qaqa ()

Нет предопределённого синтаксиса, так как есть макроопределения, которые позволяют управлять парсером и влиять на выдаваемое AST. В некоторых Лиспах нет и предопределённой лексики, так как есть доступ к readtable, который позволяет управлять лексером и влиять на читаемые sexprs.

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

s-expr'ы - это тоже синтаксис. Тем более, что во многих лиспах они не чистые.

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

которые позволяют
который позволяет
позволяет
позволяет
позволяет

За красивыми словечками где то спряталась суть дела.


Macro={
 self: function(){/**/},
 value: function(){},
 cerate: function(){return Object.create(this)},
 re: /\/\*([\s\S]*)\*\//,
 expr: function(){with(this) {return (self+"").match(re)[1]}},
}

with(macro=Macro.create()){
 self=function(){
  /* 
     foo
     foo
     foo
  */
 },
 value=Function(
      expr()
        .replace(/foo/g, "baz();")
    )
}

baz=function(){alert("hello!")}
macro.value()


// ::: hello!
// ::: hello!
// ::: hello!
[/js]
В JS нет синтаксиса? Какая нахрен разница, список или строка? Может пора прекратить демагогию?

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

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

anonymous ()

Буквально это выражается в отсутствии жесткой привязки собствено объектов к их символьному представленю в тексте. Так круглые скобки это лишь общепринятая условность которой конкретный пркладник может и пренебречь и заменить на какие-нибудь диграфы. Пример утрированый :) В переносном смысле подразумевают отказ от нескобочного «сахара» в угоду простоты кодогенерации. Пишем программы которые пишут программы!

синтаксис прост и фактически без особых изменений определяет AST?

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

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

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

То есть, лисп настолько суров, что может сделать вот так:


curlyBrackets := method(call evalArgs)
squareBrackets := method(call evalArgs)

write(
 {1,2,3}, "\n",  [1,2,3]
)

# ::: list(1, 2, 3)
# ::: list(1, 2, 3)
?

anonymous ()

Io is a ... programming language inspired by ...

LISP (code is a runtime inspectable/modifiable tree) ...

lisp is a ... programming language inspired by ...

JAVA (code is not a runtime inspectable/modifiable tree) ...

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

В переносном смысле подразумевают отказ от нескобочного «сахара» в угоду простоты кодогенерации. Пишем программы которые пишут программы!

То есть вот это:

(()''#(caaaadr((',(cdaar'',,',(caaadddddddr'(expr)))))))
проще да?

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

С момента определения синтаксиса []{} мы можем использовать его вместо list(). И это остается выражением языка, first-class, как и ф-ция. В Io все есть выражение. Это, по-сути, и означает отсутствие синтаксиса, если по хорошему то рассуждать. А в сраном лиспе ты спецформы никуда не денешь. Да и макросы — это не выражения. Так что это все пиар на пустом месте.

anonymous ()
Ответ на: комментарий от anonymous
> (module m racket
    (provide (rename-out [app #%app]))
    (define-syntax (app stx)
    (define parens (syntax-property stx 'paren-shape))
    (syntax-case stx ()
      [(_ args ...) (if (or (eq? parens #\[) (eq? parens #\{))
                        #'(list args ...)
                        #'(#%app args ...))])))
> (module m2 racket
    (require 'm)
    (displayln [1 2 3]))
> (require 'm2)
(1 2 3)
> 
anonymous ()
Ответ на: комментарий от anonymous

Это, по-сути, и означает отсутствие синтаксиса

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

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

А что, разве у меня обернуто что-то куда-то? Я так понимаю, у тебя это работает только внутри module m2? Если это так, то это детсад.

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

мало синтаксиса — не означает отсутствие его. Отсутствием синтаксиса можно считать отсутствие спецформ.

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

Я так понимаю, у тебя это работает только внутри module m2?

Работает где сделано (require 'm) очевидно. Можно специфицировать поведение хоть для каждого модуля по-своему.

Если это так, то это детсад.

В чем детсад? Везде, где а захочу, оно будет работать, как я захочу. А что тебе еще надо?

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

Отсутствием синтаксиса можно считать отсутствие спецформ.

Спецформы - это семантика, а не синтаксис.

мало синтаксиса — не означает отсутствие его.

«Отсутствия синтаксиса» (формального) быть не может. Если у тебя есть текст, то есть синтаксис. По-этому под «нету синтаксиса» подразумевается «синтаксиса очень мало, самый минимум».

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

Получается, макросы в лиспе мало чем отличаются от «макросов» в JS


Macro={
 self: function(){/**/},
 value: function(){},
 cerate: function(){return Object.create(this)},
 re: /\/\*([\s\S]*)\*\//,
 expr: function(){with(this) {return (self+"").match(re)[1]}},
}

with(macro=Macro.create()){
 self=function(){
  /* console.log({1,2,3})
  */
 },
 value=Function(
      expr()
        .replace(/\{/, "[")
        .replace(/\}/, "]")
    )
}

macro.value()

// ::: [ 1, 2, 3 ]

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

Спецформы - это семантика, а не синтаксис.

разупорись

Если у тебя есть текст, то есть синтаксис

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

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

Везде, где а захочу, оно будет работать, как я захочу. А что тебе еще надо?

Подозреваю, что вот так не будет работать.


write(
 {{1,2,3}, [1,2,3]}, "\n",  [{1,2,3}, [1,2,3]]
)

# ::: list(list(1, 2, 3), list(1, 2, 3))
# ::: list(list(1, 2, 3), list(1, 2, 3))
Да и много где еще...

anonymous ()

Часто можно наткнуться на мнение, что у лиспа(ов) нет синтаксиса. Хотелось бы понять, что конкретно тут имеется в виду.

Какая разница? Всё равно там нифига не понимают, что говорят.

В лиспе ДО ФИГА синтаксиса. Кажый макрос вводит новый кусок синтаксиса. Сколькими макросами пользуешься — столько синтаксиса тебе учить.

А скобочки — это уже так, дело десятое.

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

В лиспе ДО ФИГА синтаксиса. Кажый макрос вводит новый кусок синтаксиса.

Так это семантика, а не синтаксис, если не ошибаюсь.

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

А покажи как сделать то же самое, но чтобы элементы в {} и [] разделялись пробелом, а не запятой.

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

Получается, макросы в лиспе мало чем отличаются от «макросов» в JS

коненчо, отилчаются. В js нет компайлтайма и, следовательно, макросов.

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

Подозреваю, что вот так не будет работать.

Конечно же будет:

> (module m racket
    (provide (rename-out [app #%app]))
    (define-syntax (app stx)
    (define parens (syntax-property stx 'paren-shape))
    (syntax-case stx ()
      [(_ args ...) (if (or (eq? parens #\[) (eq? parens #\{))
                        #'(list args ...)
                        #'(#%app args ...))])))
> (require 'm)
> (display (~a {{1 2 3} [1 2 3]} #\newline [{1 2 3} [1 2 3]]))
((1 2 3) (1 2 3))
((1 2 3) (1 2 3))
> 
Я же сказал, что везде, это же робуст-интерпрайз солюшион, в отличии от игрушечного ио.

Алсо, если у тебя в 10 разных библиотеках скобочки поразному определены, и я хочу импортировать все 10 этих библиотек, то будет работать? Или один импорт насрет в другой и досвидос?

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

Так это семантика, а не синтаксис, если не ошибаюсь.

Именно. Но хачкелисты обычно не знают даже таких вот базовых вещей.

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

И еще переопределить запятую. можно же?

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

Ну и еще хотелось бы посмотреть на переопределение _круглых_ скобок.

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

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

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

Так это семантика, а не синтаксис, если не ошибаюсь.

Ошибаешься. Многие макроопределения так и называются, типа define-syntax syntax-rules и тд.

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

можно


curlyBrackets := method(
 call message arguments at(0) asString split()
)
squareBrackets := getSlot("curlyBrackets")

write({1 2 3}, [1 2 3])

# ::: list(1, 2, 3)list(1, 2, 3)

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

посмотри, посмотри, сынок


setSlot("", method(call evalArgs))

write((1,2,3))

# ::: list(1, 2, 3)
Жалко, что нам лисперы пока ничего внятного, кроме клоунады не показали. Лисп могуч своей клоунадой, оказывается, Вон оно как, михалыч, а мужики то и не знали.

anonymous ()

это значит, что у лиспов нет синтаксиса программ.

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

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

Не понял, о чем ты. Один раз пишем один макрос, там, где хотим его использовать - импортируем (один раз).

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

Тему уже все забыли. Ну и х с ней, это ж ЛОР.

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

Жалко, что нам лисперы пока ничего внятного, кроме клоунады не показали.

Так ты ничего ещё не просил показать. Проси, чо.

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

Ошибаешься.

Нет, не ошибается. На синтаксис макросы никак не влияют.

Многие макроопределения так и называются

ну да, define-syntax - определить семантику синтаксической единицы.

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

Жалко, что нам лисперы пока ничего внятного, кроме клоунады не показали.

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

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

И где ты тут что переопределил? ((1,2,3)) должно быть list(list(1,2,3))

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

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

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

И где ты тут что переопределил?

Я переопределил ровно то, что просили

переопределение _круглых_ скобок.

должно быть list(list(1,2,3))

что должно быть? Это список включающий один список, все равно что лисповский (list (list 1 2 3)) так оно и есть по-дефолту

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

тогда почему ты переписал первоначальный вариант

В каком месте я его переписал? Один и тот же макрос, слово в слово.

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

Так написал же.

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

Я переопределил ровно то, что просили

Нет. у тебя в write() скобочки не переопределены.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.