Live data from Hacker News

How Lisp macros differ from static code-generation and metaprogramming

brandonbyars.com

31–40 of 84 posts

Re: How Lisp macros differ from static code-generation and metaprogramming

#31
post #22
post #9

Earlier quoted context omitted.

Yesterday I was writing code that kept messing my Lisp's signal handling, so I wrote a FOR-DURATION macro that arms a timeout and makes sure whatever that runs in its body gets killed after N seconds. Here it is: (defmacro for-duration ((seconds) &body body) `(handler-case (bt:with-timeout (,seconds) ,@body) (bt:timeout () nil))) Five lines to alter the evaluation model of your language. Not bad. Use as: (for-duratio…

C99 + GCC extensions + POSIX: #define for_duration(seconds, body) \ { \ pthread_t tid_task, tid_watcher; \ \ void* task(void* arg) { \ body ; \ pthread_cancel(tid_watcher); \ return NULL; \ } \ \ void* watcher(void* arg) { \ sleep((seconds)); \ pthread_cancel(tid_task); \ return NULL; \ } \ \ pthread_create(&tid_task, NULL, &task, NULL); \ pthread_create(&tid_watcher, NULL, &watcher, NULL); \ pthread_join(tid_task, N…

Is there a C macro that can do this?

    (defmacro execute-in-reverse (&body body)
      `(progn ,@(reverse body)))

    (execute-in-reverse (print "Hi") (print "Middle") (print "Bye"))
Prints...

    "Bye"
    "Middle"
    "Hi"
Point: You can do whatever you want with the symbols sent to the macro, whatever their contents. Mahmud's wrapper macro is trivial (it could be done with lambdas). Lisp's macro system allows you to create new syntax, including changes in flow control.

But my example is trivial, too. I could go on to swap individual parts of my forms around, remap them to other forms depending on various conditions, etc.

In addition, people often talk about Lisp macros, but they neglect to mention the power of reader macros, which allow you to go beyond Lisp's basic AST look-and-feel.

Re: How Lisp macros differ from static code-generation and metaprogramming

#32
post #17

> Except, of course, that doesn’t work. The preprocessor only makes one pass > through the file, meaning a macro can’t call another macro. Huh? That's just blatantly wrong, and I (and many others) have used the C preprocessor to create multi-level macros in quite powerful ways. See for example http://blog.nelhage.com/2010/07/implementing-an-edsl-in-cpp/ or the insanity Linux's tracing macros have implemented: http://…

The reason Linux trace macros are insane is because C preprocessor is so primitive. Think about it. > they are quite powerful For small values of "quite". C macros are strictly less (and by large margin powerful than Lisp macros. One can't even use #ifdef inside #define!

Note, the power of the macro system is not equal to its general good.

The C macro system was already too powerful, and one of the things that hurts languages is a preprocessor of virtually any kind. The badness of the C preprocessor starts much earlier with things like include files, and the fact that you can't statically analyze the code in any reasonable way.

The benefit from the preprocessor is absurdly small. With that said, I think the benefit of the Lisp preprocessor is pretty small too. C would be harmed more by its omission due its compilation model, but as we've seen with languanges in its family, like C#, its unnecessary.

In a decade or less, the Lispers will see this light too.

Re: How Lisp macros differ from static code-generation and metaprogramming

#33
post #31
post #22

Earlier quoted context omitted.

C99 + GCC extensions + POSIX: #define for_duration(seconds, body) \ { \ pthread_t tid_task, tid_watcher; \ \ void* task(void* arg) { \ body ; \ pthread_cancel(tid_watcher); \ return NULL; \ } \ \ void* watcher(void* arg) { \ sleep((seconds)); \ pthread_cancel(tid_task); \ return NULL; \ } \ \ pthread_create(&tid_task, NULL, &task, NULL); \ pthread_create(&tid_watcher, NULL, &watcher, NULL); \ pthread_join(tid_task, N…

Is there a C macro that can do this? (defmacro execute-in-reverse (&body body) `(progn ,@(reverse body))) (execute-in-reverse (print "Hi") (print "Middle") (print "Bye")) Prints... "Bye" "Middle" "Hi" Point: You can do whatever you want with the symbols sent to the macro, whatever their contents. Mahmud's wrapper macro is trivial (it could be done with lambdas). Lisp's macro system allows you to create new syntax, in…

>Is there a C macro that can do this?

No, of course. C macros only see strings; you need to parse a syntax tree to do your reverse example (like lisp macros).

No argument from me.

>Lisp's macro system allows you to create new syntax, including changes in flow control.

Well, C macros seem to be able to manipulate control flow. You can't break up an expression to do that (not smart enough to parse), but you can rearrange expressions that are given whole.

Re: How Lisp macros differ from static code-generation and metaprogramming

#34
post #3

By the way, don't confuse macros with backquote; the backquote facility is probably closer to C's preprocessors. I haven't heard this claim before, and I might not be entirely right, but it's what provides for the "fill in the blanks" type symbolic computing. For example: (defun sum (x y) `(,x + ,y = ,(+ x y))) This is a SUM function which looks like this when run: (sum 4 5) ==> (4 + 5 = 9) The backquote (`) says the…

Don't forget that `, (backquote-comma) can also be adapted for pattern matching/destructuring (http://www.cliki.net/fare-matcher does this).

I think combining backquote-comma's s-exp-making and s-exp-destructuring powers is a viable way to abstract s-exps from their representations as linked lists/arrays/whatever sequence you want to use.

Re: How Lisp macros differ from static code-generation and metaprogramming

#35

Earlier quoted context omitted.

The reason Linux trace macros are insane is because C preprocessor is so primitive. Think about it. > they are quite powerful For small values of "quite". C macros are strictly less (and by large margin powerful than Lisp macros. One can't even use #ifdef inside #define!

Note, the power of the macro system is not equal to its general good. The C macro system was already too powerful, and one of the things that hurts languages is a preprocessor of virtually any kind. The badness of the C preprocessor starts much earlier with things like include files, and the fact that you can't statically analyze the code in any reasonable way. The benefit from the preprocessor is absurdly small. Wit…

"I think the benefit of the Lisp preprocessor is pretty small too"

Lisp doesn't have a preprocessor, Lisp is a preprocessor. You can program with it, but thinking about it as a programming language (ASCII or Unicode Strings to be Interpreted) is at least partially wrong.

"In a decade or less, the Lispers will see this light too."

It hasn't happened in the last half century, so how much do you want to bet on it?

Re: How Lisp macros differ from static code-generation and metaprogramming

#36

Earlier quoted context omitted.

The reason Linux trace macros are insane is because C preprocessor is so primitive. Think about it. > they are quite powerful For small values of "quite". C macros are strictly less (and by large margin powerful than Lisp macros. One can't even use #ifdef inside #define!

Note, the power of the macro system is not equal to its general good. The C macro system was already too powerful, and one of the things that hurts languages is a preprocessor of virtually any kind. The badness of the C preprocessor starts much earlier with things like include files, and the fact that you can't statically analyze the code in any reasonable way. The benefit from the preprocessor is absurdly small. Wit…

Does everyone just troll now?

Re: How Lisp macros differ from static code-generation and metaprogramming

#37

Are natural languages homoiconic? (If you get my drift.) Does that question even make sense?

Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo

But seriously, take a look at Quines and Hofstadter's Godel, Escher, Bach

Re: How Lisp macros differ from static code-generation and metaprogramming

#38
post #26

Are natural languages homoiconic? (If you get my drift.) Does that question even make sense?

Even early stabs at x-bar theory indicate that natural languages are highly homoiconic. http://en.wikipedia.org/wiki/X-bar_theory

Can you please explain more?

Re: How Lisp macros differ from static code-generation and metaprogramming

#39
post #22
post #9

Earlier quoted context omitted.

Yesterday I was writing code that kept messing my Lisp's signal handling, so I wrote a FOR-DURATION macro that arms a timeout and makes sure whatever that runs in its body gets killed after N seconds. Here it is: (defmacro for-duration ((seconds) &body body) `(handler-case (bt:with-timeout (,seconds) ,@body) (bt:timeout () nil))) Five lines to alter the evaluation model of your language. Not bad. Use as: (for-duratio…

C99 + GCC extensions + POSIX: #define for_duration(seconds, body) \ { \ pthread_t tid_task, tid_watcher; \ \ void* task(void* arg) { \ body ; \ pthread_cancel(tid_watcher); \ return NULL; \ } \ \ void* watcher(void* arg) { \ sleep((seconds)); \ pthread_cancel(tid_task); \ return NULL; \ } \ \ pthread_create(&tid_task, NULL, &task, NULL); \ pthread_create(&tid_watcher, NULL, &watcher, NULL); \ pthread_join(tid_task, N…

GCC extensions make me want to hurt people.

Re: How Lisp macros differ from static code-generation and metaprogramming

#40
post #35

Earlier quoted context omitted.

Note, the power of the macro system is not equal to its general good. The C macro system was already too powerful, and one of the things that hurts languages is a preprocessor of virtually any kind. The badness of the C preprocessor starts much earlier with things like include files, and the fact that you can't statically analyze the code in any reasonable way. The benefit from the preprocessor is absurdly small. Wit…

"I think the benefit of the Lisp preprocessor is pretty small too" Lisp doesn't have a preprocessor, Lisp is a preprocessor. You can program with it, but thinking about it as a programming language (ASCII or Unicode Strings to be Interpreted) is at least partially wrong. "In a decade or less, the Lispers will see this light too." It hasn't happened in the last half century, so how much do you want to bet on it?

Lisp doesn't have a preprocessor, Lisp is a preprocessor. You can program with it, but thinking about it as a programming language (ASCII or Unicode Strings to be Interpreted) is at least partially wrong.

This would be news to McCarthy. McCarthy on several occassions, including the History of Lisp, refers to Lisp as a programming language. I've never heard him say Lisp is a preprocesser. I certainly am no expert compared to McCarthy. Maybe you are?

It hasn't happened in the last half century, so how much do you want to bet on it?

It's importance has ebbed and flowed over time. This is natural of language features. It was a decade ago where all the rage was template metapgrogramming in C++. Now, outside of a few library writers, most people don't touch it. This isn't to say it won't be popular again some time in the future.

I should probably ammend my statement in that light and say that we'll likely see a major ebb in the coming years.

Post reply on HN