How far can LISP macros go?

I read a lot that LISP can override syntax on the fly, presumably using macros. I'm curious how far this goes Can you redefine the structure of the language so much that it borders on the compiler for another language? For example, can you change the functional nature of LISP to a more object-oriented syntax and semantics, perhaps say that the syntax is closer to something like Ruby?

In particular, is it possible to get rid of the adhesive in parentheses using macros? I have learned enough (Emacs -) LISP to configure Emacs with my own microfunctions, but I am very curious how far you can configure macros in the language settings.

+41
macros lisp
Aug 05 '08 at 7:32
source share
14 answers

This is a really good question.

I think it is nuanced but definitely accountable:

Macros do not get stuck in s-expressions. See LOOP Macro for a very complex language written using keywords (characters). So, although you can start and end the loop with parentheses, inside it has its own syntax.

Example:

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

However, most simple macros simply use s-expressions. And you will be stuck using them.

But s-expressions, as Sergio replied, are starting to feel right. The syntax gets out of the way and you start coding in the syntax tree.

As for reader macros, yes, you could write something like this:

 #R{ ruby.code.goes.here } 

But you need to write your own Ruby syntax parser.

You can also mimic some of the Ruby constructs, such as blocks, with macros that compile with existing Lisp constructs.

 #B(some lisp (code goes here)) 

translates to

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

For more information on how to do this, see this page .

+32
Sep 15 '08 at 15:07
source share

Yes, you can override the syntax so that Lisp becomes a compiler. You do this with the help of "Reading Macros", which are different from the usual "Compiler Macros" that you are probably thinking of.

Common Lisp has a built-in tool for defining new syntax for reading and reading macros to process this syntax. This processing is performed at the time of reading (which occurs before compilation or computation time). To learn more about defining reader macros in Common Lisp, see Common Lisp Hyperspec — you'll want to read Ch. 2, Syntax and Ch. 23, The Reader . (I believe that a circuit has the same object, but I'm not so familiar with it - see Scheme Sources for Arc Programming Language ).

As a simple example, suppose you want Lisp to use curly braces rather than parentheses. This requires the following reader definitions:

 ;; { 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 #\( #\[ ) 

You tell Lisp that {looks like (and that) like a). Then you create a function ( lcurly-brace-reader ) that the reader will call whenever it sees {, and you use set-macro-character to assign this function {. Then you tell Lisp that (s) are like [and] (that is, no meaningful syntax).

Other things you could do include, for example, creating a new string syntax or using [and] to enclose the notation and the process of fixing it in an S-expression.

You can also go far beyond that by overriding the entire syntax with your own macros that trigger actions in the reader, so the sky is indeed the limit. This is one of the reasons why Paul Graham and others that Lisp is a good language for writing a compiler.

+19
Sep 16 '08 at 19:28
source share

I’m not a Lisp expert, damn it, I’m not even a Lisp programmer, but after a little experiment with the language, I came to the conclusion that after a while the brackets begin to become “invisible” and you begin to see the code the way you want. You pay more attention to the syntactic constructions that you create using s-exprs and macros, and less to the lexical form of the text of lists and brackets.

This is especially true if you use a good editor that helps with indentation and syntax coloring (try setting the brackets to a color very similar to the background).

You may not be able to completely replace the language and get the Ruby syntax, but you don't need it. Thanks to language flexibility, you could complete a dialect that feels like you're following the “ruby style of programming” if you want, whatever that means to you.

I know this is just an empirical observation, but I think I had one of those Lisp moments of enlightenment when I realized this.

+15
Aug 26 '08 at 9:49
source share

Again and again, newcomers to Lisp want to "get rid of all the brackets." It lasts a few weeks. No project to create a serious general-purpose programming syntax on top of a regular S-expression parser ever gets anywhere, because programmers invariably prefer what you currently perceive as “brackets at the end”. It's a little getting used to, but not so much! Once you get used to it, and you can really appreciate the plasticity of the syntax by default, returning to languages ​​in which there really is only one way to express any particular programming construct.

At the same time, Lisp is an excellent substrate for creating domain languages. As good as if not better than XML.

Good luck

+13
Sep 16 '08 at 19:29
source share

The best explanation of Lisp macros I've ever seen is on

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

starting in about 55 minutes. This is a video chat written by Peter Seibel, author of Practical General Lisp, which is Lisp's best tutorial.

The motivation for Lisp macros is usually difficult to explain, because they really come into their own in situations that are too large to be presented in a simple tutorial. Peter came up with a great example; you can fully understand it, and it makes good, proper use of Lisp macros.

You asked: “Could you change the functional nature of Lisp to more object-oriented syntax and semantics.” The answer is yes. In fact, Lisp initially had no object-oriented programming at all, not surprisingly, since Lisp has been around since before object-oriented programming! But when we first learned about OOP in 1978, we were able to easily add it to Lisp using, among other things, macros. As a result, the Common Lisp Object System (CLOS) was developed - a very powerful object-oriented programming system that fits elegantly into Lisp. All of this can be downloaded as an extension - nothing is built in! All this is done using macros.

Lisp has a completely different function called “reader macros,” which can be used to extend the language’s surface syntax. Using read macros, you can create sub-languages ​​with syntax like C or Ruby. They convert text to Lisp internally. They are not widely used by most real Lisp programmers, mainly because it is difficult to extend the interactive development environment to understand the new syntax. For example, Emacs indent commands will be confused by the new syntax. If you're energetic, Emacs is also expanding, and you can teach it new lexical syntax.

+11
Oct 05 '08 at 15:03
source share

Regular macros work with lists of objects. Most often, these objects are other lists (thus forming trees) and symbols, but they can be other objects, such as strings, hash tables, user objects, etc. These structures are called S-EXPS .

So, when you download the source file, your Lisp compiler will parse the text and produce s-exp. Macros work on them. This works great, and it's a wonderful way to expand the language in the spirit of s-exps.

In addition, the aforementioned parsing process can be expanded through “reader macros” that allow you to customize the way text is converted to s-exps. However, I suggest you instead of Lisp syntax instead of bending it into something else.

It sounds a bit vague when Lisp is referred to as "functional" and "object-oriented Ruby syntax." I'm not sure what the "object-oriented syntax" should be, but Lisp is a language with several paradigms and it perfectly supports object-oriented programming.

By the way, when I say Lisp, I mean Common Lisp .

I suggest you put aside your prejudices and give Lisp an honest move .

+10
Aug 26 '08 at 9:36
source share

Sorrowful hell? I no longer see parentheses:

 (function toto) 

than in:

 function(toto); 

And in

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

no more:

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

I see fewer brackets and ';' though.

+8
Sep 16 '08 at 16:23
source share

What you ask for is somewhat reminiscent of the question of how to become an expert chocolate so that you can remove all these hellish brown things from your favorite chocolate cake.

+8
Sep 17 '08 at 12:14
source share

Yes, you can fundamentally change the syntax and even avoid the “parentheses in brackets”. To do this, you will need to define a new reader syntax. Look at reader macros.

I suspect, however, that in order to achieve the Lisp level of experience for programming such macros, you will need to immerse yourself in the language so much that you will no longer consider parenthese hell. That is, by the time you know how to avoid them, you will come to accept them as good.

+5
15 Sep '08 at 12:07
source share

If you want lisp to look like Ruby, use Ruby.

Perhaps the use of Ruby (and Python) is very similar to lisp, which is one of the main reasons that they gained recognition so quickly.

+2
Aug 05 '08 at 7:40
source share

@sparkes

Sometimes LISP is a pure choice of language, namely the Emacs extension. I'm sure I could use Ruby to extend Emacs if I wanted to, but Emacs was designed to expand with LISP, so it seems to make sense to use it in this situation.

+1
Aug 05 '08 at 7:45
source share

see this example of how reader macros can extend the lisp reader with complex tasks such as XML templates:

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

this user library compiles the static parts of XML into UTF-8 encoded literal byte arrays at compile time, which are ready for writing to the network stream. and they are applicable to regular lisp macros, they are orthogonal ... placing a comma character affects which parts are constant and which should be evaluated at runtime.

more information is available at: http://common-lisp.net/project/cl-quasi-quote/

another project that for Common lisp syntax extensions: http://common-lisp.net/project/cl-syntax-sugar/

+1
Sep 17 '08 at 0:30
source share

It's a difficult question. Since lisp is already structurally so close to the parsing tree, the difference between a large number of macros and the implementation of your own mini-language in the parser generator is not very clear. But, with the exception of the open and closing paren, you could easily get something that doesn't look like lisp.

0
Aug 6 '08 at 12:14
source share

One of the uses of the macros that blew my brain is to check the execution time of SQL queries from DB.

Once you understand that you have the full language at hand during compilation, it opens up interesting new perspectives. It also means that you can shoot yourself in the foot in a new way (for example, rendering compilation that is not reproducible, which is very easy to turn into a debugging nightmare).

0
Sep 19 '08 at 10:43
source share



All Articles