top | item 42872117

(no title)

anothername12 | 1 year ago

Why is it that Lisp family macros are easy to implement and use, but not so in other languages?

discuss

order

munificent|1 year ago

Lisp is dynamically typed and macros are syntactic. The macro gets in an AST and spits out an AST with little in the way of semantic information involved beyond maybe some identifier resolution.

Dart is a statically typed language and we wanted macros to be able to introspect over the semantics of the code the macro is applied to, not just the semantics. For example, if a macro is generating code for serialization, we wanted the macro to be able to ask "Does the type of this field implement JsonSerializable?". Answering that means being able to look up the type of the field, possibly walk its inheritance hierarchy, etc.

It's a very different problem from just "give me a way to add pretty loop syntax".

_moof|1 year ago

This is just my opinion but I believe it's because the syntax tree is the syntax. In a Lisp macro you are working with lists, just like you are for any other Lisp code. Almost every other language I've used (I've been programming since the late 1980s) has, at best, a special data structure to manipulate ASTs. So it ends up being quite unnatural. Lisp macros are just Lisp.

soegaard|1 year ago

> This is just my opinion but I believe it's because the syntax tree is the syntax.

This holds for "old" lisps. There are other options. Racket and Scheme uses "syntax objects". Syntax objects contain besides the old syntax tree also source location information and lexical information.

See for example the last part of:

https://parentheticallyspeaking.org/articles/bicameral-not-h...

lolinder|1 year ago

Are Lisp macros easy to use? My understanding was that Lisp code is notoriously difficult to understand if you didn't write it, largely because of the obscenely powerful macro system that makes it too easy to be too clever. Which is essentially the same complaint that everyone has about every macro system.

fiddlerwoaroof|1 year ago

I’ve been working with Common Lisp for about ten years now and I’ve never found that this criticism matches the reality of working on lisp codebases.

db48x|1 year ago

It’s possible to do that, but in practice it’s quite uncommon. Especially since Lisps offer great tools for programmers to learn what the macros that the are using actually do.

dokyun|1 year ago

Why is it that square pegs are easy to fit in a square hole, but not so in a round hole?

behnamoh|1 year ago

in Scheme you can redefine `define` to be number 5. Easy to implement, but a nightmare in real world scenarios [0]. That's why languages like Go became popular, they're trashy, boring, and dumb, but that's exactly what's needed in big projects.

[0]: imagine your colleague wrote a macro that redefines for loops because at the time, it made life easier for him.

codemac|1 year ago

> in Scheme you can redefine `define` to be number 5.

This is like asking "what if your coworker named all errs as `ok`" so everything was `if ok { return errors.New("Not ok!!"); }`. It's possible but no one does it.

This is why `defmacro` and `gensym` in common lisp are awesome, and similarly why Go's warts don't matter. Much of programming language ugliness is an "impact x frequency" calculation, rather than one or the other.

It's also why javascript is so terrible, you run into it's warts constantly all day long.

neilv|1 year ago

You might have been misled by a CS professor's enthusiasm about what they thought was neat, or was a good way to communicate something.

But I don't recall seeing someone re-define `define` in real life.

Nor do I recall seeing any problematic redefinitions in Scheme in real life.

That said, if you wanted to make a language variant in which `define` did something different than normal (say, for instrumentation, or for different semantics for variable syntax), then you'd probably use Racket, and you'd probably define your own `#lang`, so that the first line of files using your language would be something like `#lang myfunkylang`.

You can randomly sample code in <https://pkgs.racket-lang.org/>, and look for people doing anything other than `#lang racket/base` or `#lang typed/racket/base`.