Cât de departe poate merge macro-uri LISP?

voturi
43

Am citit o mulțime care LISP poate redefini sintaxă pe zbor, probabil cu macro-uri. Sunt curios cât de departe merge de fapt face acest lucru? Poți să recalifice structura de limbă atât de mult încât devine limita un compilator pentru o altă limbă? De exemplu, ar putea să schimbați natura funcțională a LISP într-o sintaxă mai orientat obiect si semantica, poate spune cu sintaxa mai aproape de ceva de genul Ruby?

Mai ales, este posibil pentru a scăpa de dracu 'paranteze folosind macro-uri? Am învățat destul de (Emacs-) LISP pentru a personaliza Emacs cu propriile mele micro-caracteristici, dar eu sunt foarte curios cum macro-uri de departe poate merge în personalizarea limbii.

Întrebat 05/08/2008 la 08:32
sursa de către utilizator
În alte limbi...                            


14 răspunsuri

voturi
33

E o întrebare foarte bună.

Cred că e nuanțată, dar cu siguranță răspunde:

Macro-urile nu sunt blocate în s-expresii. A se vedea macro LOOP pentru un limbaj foarte complex scrise folosind cuvinte cheie (simboluri). Deci, în timp ce s-ar putea începe și se termină bucla cu paranteze, în interiorul are propria sintaxă.

Exemplu:

(loop for x from 0 below 100
      when (even x)
      collect x)

Acestea fiind spuse, macro-uri cele mai simple folosesc doar s-expresii. Și te-ai fi „blocat“ folosindu-le.

Dar s-expresii, cum ar fi Sergio a răspuns, începe să se simtă bine. Sintaxa iese din drum și de a începe de codificare în arborele de sintaxă.

În ceea ce privește macro cititor, da, ai putea scrie conceivably ceva de genul:

#R{
      ruby.code.goes.here
  }

Dar ai nevoie pentru a scrie propria Ruby sintaxa parser.

Puteți imita, de asemenea, unele dintre Ruby construiește, cum ar fi blocuri, cu macro-uri care compilează la constructele Lisp existente.

#B(some lisp (code goes here))

s-ar traduce

(lambda () (some lisp (code goes here)))

Consultați această pagină pentru modul de a face acest lucru.

Publicat 15/09/2008 la 16:07
sursa de către utilizator

voturi
20

Da, puteți redefini sintaxa, astfel încât Lisp devine un compilator. Acest lucru se face folosind „Reader Macrocomenzi“, care sunt diferite de la normal „compilatoare Macrocomenzi“ pe care probabil te gândești.

Common Lisp are facilitatea de built-in pentru a defini sintaxa noi pentru cititor și cititor macro - uri pentru a procesa acea sintaxa. Această prelucrare se face la citire de timp (care vine înainte de compilare sau timpul eval). Pentru a afla mai multe despre definirea macro - uri cititor în Common Lisp, a se vedea Lisp Hyperspec comună - veți dori să citiți Ch. 2, "Sintaxa" și Ch. 23, "Reader" . (Cred că schema are aceeași facilitate, dar nu sunt la fel de familiar cu ea - a se vedea sursele Schema pentru limbajul de programare Arc ).

Ca un exemplu simplu, să presupunem că doriți să utilizați Lisp acolade, mai degrabă decât între paranteze. Acest lucru necesită ceva de genul următoarele definiții cititor:

;; { and } become list delimiters, along with ( and ).
(set-syntax-from-char #\{ #\( )
(defun lcurly-brace-reader (stream inchar) ; this was way too easy to do.
  (declare (ignore inchar))
  (read-delimited-list #\} stream t))
(set-macro-character #\{ #'lcurly-brace-reader)

(set-macro-character #\} (get-macro-character #\) ))
(set-syntax-from-char #\} #\) )

;; un-lisp -- make parens meaningless
(set-syntax-from-char #\) #\] ) ; ( and ) become normal braces
(set-syntax-from-char #\( #\[ )

Tu spui Lisp că {este ca un (și că} este ca o). Apoi , creați o funcție ( lcurly-brace-reader) , care cititorul va apela ori de câte ori vede un {, și utilizați set-macro-characterpentru a atribui această funcție împreună cu {. Apoi , vă spun Lisp că (și) sunt ca [i] (adică, nu sintaxă semnificativă).

Alte lucruri pe care le - ar putea face includ, de exemplu, crearea unei noi sintaxă șir sau folosind [și] pentru a închide în notația-fix si procesa - l în S-expresii.

Puteți merge , de asemenea , mult dincolo de aceasta, redefinirea întreaga sintaxa cu propriile personaje macro , care va declanșa acțiuni în cititor, astfel încât într - adevăr cerul este limita. Acesta este doar unul dintre motivele pentru care Paul Graham și alții tot spun că Lisp este o limbă bună pentru a scrie un compilator.

Publicat 16/09/2008 la 20:28
sursa de către utilizator

voturi
16

Nu sunt un expert în Lisp, naiba eu nu sunt chiar un programator Lisp, dar după un pic de experimente cu limba pe care am ajuns la concluzia că, după un timp paranteza începe să devină „invizibil“ și de a începe să vedeți codul ca doriți să fie. Începe să acorde mai multă atenție construcțiilor sintactice pe care le creați prin e-exprs și macro-uri, și mai puțin la forma lexicală a textului listelor și paranteze.

Acest lucru este în special adevărat dacă ați profita de un editor bun, care ajută cu indentare și colorat sintaxa (încercați să setați parantezelor la o culoare foarte asemănătoare cu fundalul).

Este posibil să nu fie în măsură să înlocuiască limba complet și pentru a obține sintaxa „Ruby“, dar nu ai nevoie de ea. Datorită flexibilității limbii ar putea încheia cu un dialect care se simte ca tine sunt în urma „stilul de programare Ruby“, dacă doriți, indiferent ce ar putea însemna pentru tine.

Știu că acest lucru este doar o observație empirică, dar cred că am avut una dintre acele momente de iluminare Lisp când am realizat acest lucru.

Publicat 26/08/2008 la 10:49
sursa de către utilizator

voturi
15

Peste și peste din nou, noii membri Lisp doresc să „scape de toate paranteza.“ Aceasta durează câteva săptămâni. Nici un proiect pentru a construi o sintaxă serioasă de programare de uz general pe partea de sus a parserul obișnuit S-expresie devine vreodată oriunde, pentru că programatorii vânt invariabil preferând ceea ce percep în prezent ca „iad paranteze.“ Este nevoie de un pic obisnuirea, dar nu de mult! Odată ce te obișnuiești să-l, și puteți aprecia cu adevărat plasticitatea sintaxa implicit, merge înapoi la limbi în cazul în care nu există decât un singur mod de a exprima orice construct de programare special, este într-adevăr grilaj.

Acestea fiind spuse, Lisp este un substrat excelent pentru construirea de domeniu anumite limbi. La fel de bun ca, daca nu mai bine decât, XML.

Mult noroc!

Publicat 16/09/2008 la 20:29
sursa de către utilizator

voturi
12

Cea mai bună explicație a macro-uri Lisp am văzut vreodată este la

https://www.youtube.com/watch?v=4NO83wZVT0A

începând de la aproximativ 55 de minute în. Acesta este un film cu un discurs dat de Peter Seibel, autorul „practic Lisp comun“, care este cel mai bun manual Lisp există.

Motivația pentru macro-uri Lisp este de obicei greu de explicat, pentru că ei vin într-adevăr în propria lor în situații care sunt prea lungi pentru a prezenta într-un tutorial simplu. Petru vine cu un exemplu; puteți înțelege complet, și-l face bine, utilizarea corectă a macro-uri Lisp.

Ai întrebat: „poți să schimbi natura funcțională a LISP într-o sintaxă mai orientat obiect și semantica“. Raspunsul este da. De fapt, Lisp inițial nu a avut nici o programare orientată pe obiecte, la toate, nu este surprinzător, deoarece Lisp a fost în jur de mult înainte de programarea orientată pe obiecte! Dar când am aflat prima dată despre OOP în 1978, am fost capabili să-l adăugați la LISP cu ușurință, folosind, printre altele, macro-uri. În cele din urmă a fost dezvoltat un sistem comun de obiect Lisp (CLOS), un sistem foarte puternic de programare orientat-obiect care se potrivește elegant în Lisp. Totul poate fi încărcat ca o extensie - nimic nu este built-in! Totul se face cu macro-uri.

Lisp are o caracteristică complet diferită, numit „macro cititor“, care pot fi utilizate pentru a extinde suprafața sintaxa limbii. Folosind macro-uri cititor, puteți face sublanguages ​​care au sintaxa C-like sau Ruby-like. Ele transformă textul în Lisp, pe plan intern. Acestea nu sunt utilizate pe scară largă de către cei mai mulți programatori Lisp reale, mai ales pentru că este greu să se extindă mediul de dezvoltare interactiv pentru a înțelege noua sintaxă. De exemplu, comenzile Emacs-ului de indentare ar fi confundat cu o nouă sintaxă. Dacă ești energic, deși, Emacs-ul este extensibila prea, și ai putea învăța despre noua ta sintaxa lexicală.

Publicat 05/10/2008 la 16:03
sursa de către utilizator

voturi
11

Macro - uri regulate funcționează pe liste de obiecte. Cel mai frecvent, aceste obiecte sunt alte liste (arbori formând astfel) și simboluri, dar ele pot fi și alte obiecte , cum ar fi siruri de caractere, hashtables, obiecte definite de utilizator, etc. Aceste structuri sunt numite s-EXPS .

Deci, atunci când încărcați un fișier sursă, compilatorul dvs. Lisp va analiza textul și să producă s-EXPS. Macrocomenzi operează pe aceste. Acest lucru funcționează mare și este un mod minunat de a extinde limba în spiritul s-EXPS.

În plus, procesul de parsare menționat mai sus poate fi extinsă prin „macro-uri cititor“ care vă permit să personalizați modul în care compilatorul transformă textul în e-EXPS. Sugerez, totuși, că îmbrățișează sintaxa Lisp lui în loc de a îndoi în altceva.

Pari un pic confuz atunci când vorbim de „natura funcțională“ Lisp și Ruby „sintaxa orientată-obiect“. Nu sunt sigur ce „sintaxa orientată spre obiect“ ar trebui să fie, dar Lisp este un limbaj multi-paradigmă și suportă programarea orientată pe obiecte extremelly bine.

BTW, când spun Lisp, mă refer la Common Lisp .

Vă sugerez să pun prejudecățile deoparte și da Lisp un du - te cinstit .

Publicat 26/08/2008 la 10:36
sursa de către utilizator

voturi
9

Ceea ce se cere este oarecum ca întreba cum să devină un ciocolatier expert, astfel încât să puteți elimina toate aceste lucruri maro infernal de la tortul de ciocolata preferata.

Publicat 17/09/2008 la 13:14
sursa de către utilizator

voturi
9

Parantezele iad? Nu văd nici mai în paranteză:

(function toto)

decât în:

function(toto);

Si in

(if tata (toto)
  (titi)
  (tutu))

nu mai mult decât în:

if (tata)
  toto();
else
{
  titi();
  tutu();
}

Eu văd mai puțin între paranteze și „;“ deşi.

Publicat 16/09/2008 la 17:23
sursa de către utilizator

voturi
6

Da, puteți schimba fundamental sintaxa, și chiar a scăpa „dracu paranteze“. Pentru că va trebui să definească o nouă sintaxă cititor. Uită-te în macro-uri cititor.

Eu fac suspect, totuși, că pentru a ajunge la nivelul de expertiză Lisp pentru a programa astfel de macro-uri, va trebui să vă cufunda în limba într-o asemenea măsură, încât nu va mai lua în considerare Parenthese „iad“. IE de timpul pe care îl știi cum să le evite, va trebui să vină să le accepte ca un lucru bun.

Publicat 15/09/2008 la 13:07
sursa de către utilizator

voturi
2

a se vedea acest exemplu de modul în care macro-uri cititor poate extinde cititorul Lisp cu sarcini complexe, cum ar fi templating XML:

http://common-lisp.net/project/cl-quasi-quote/present-class.html

această bibliotecă utilizator compilează componentele statice ale XML în matrice octet literal codificat UTF-8 la momentul compilarii , care sunt gata pentru a fi scrie-sequence'd în fluxul de rețea. și ele sunt utilizabile în macro - uri Lisp normale, ele sunt ortogonale ... plasarea virgulei influentelor de caractere ce părți sunt constante și care ar trebui să fie evaluate în timpul rulării.

mai multe detalii disponibile la: http://common-lisp.net/project/cl-quasi-quote/

un alt proiect care pentru extensiile comune de sintaxa Lisp: http://common-lisp.net/project/cl-syntax-sugar/

Publicat 17/09/2008 la 01:30
sursa de către utilizator

voturi
2

Dacă doriți să arate ca Lisp Ruby folosesc Ruby.

Este posibil să se utilizeze Ruby (și Python) într-un mod foarte asemănător peltic, care este unul dintre motivele principale care le-au câștigat de acceptare atât de repede.

Publicat 05/08/2008 la 08:40
sursa de către utilizator

voturi
1

Una dintre utilizările de macro-uri care suflau mintea mea a fost verificarea compilării timp a cererilor SQL împotriva DB.

Odată ce vă dați seama că aveți limba deplină la îndemână în timpul compilării, se deschide perspective interesante noi. Ceea ce înseamnă că, de asemenea, vă puteți trage în picior în moduri noi și interesante (cum ar fi redarea de compilare nu reproductibile, care se poate transforma foarte ușor într-un coșmar de depanare).

Publicat 19/09/2008 la 11:43
sursa de către utilizator

voturi
1

Este o întrebare delicată. Deoarece Lisp este deja structural atât de aproape de un copac parsare diferența între un număr mare de macro-uri și de punere în aplicare propriul mini-limbaj într-un generator de parser nu este foarte clar. Dar, cu excepția deschidere și închidere Paranteză, ai putea ajunge foarte ușor cu ceva care arata nimic ca Lisp.

Publicat 06/08/2008 la 13:14
sursa de către utilizator

voturi
1

@sparkes

Uneori LISP este alegerea limbaj clar, și anume extensii Emacs. Sunt sigur că aș putea folosi Ruby pentru a extinde Emacs dacă am vrut, dar Emacs-ul a fost proiectat pentru a fi extins cu LISP, astfel încât pare să aibă sens să-l folosească în această situație.

Publicat 05/08/2008 la 08:45
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more