Hacker News new | past | comments | ask | show | jobs | submit login

For the same reason that it wouldn't be a normal function in any Lisp. The difference is that the macro expander keeps a list of macros (separate from the set of normal functions in the program), so that when it sees a list with a symbol in the first position, it can look up that symbol in its macro list, and if it is a macro, it can call the macro and replace the macro call form with the return value of the macro. Then that gets fed into the evaluator, just like how macros work in any lisp.



I see, thank you so much for the explanation.

I think to clarify what I said - I didn't mean that static typing and macros are excluding each other. But I think you can either have a sound static type system and highly restricted macros, or less restricted macros but only an unsound type system. That's what I meant with "conflict".


No problem.

I'm interested to hear though why you think unrestricted macros make the type system unsound. Can you explain? The code generated by macros would be type-checked in the scheme I described, and type-unsafe code can't be executed by the macro itself, so it seems safe to me.


That is more of my impression that I have gathered from watching programming languages evolving. Rust is a good example, where they tried hard and the macros still become unsound. Scala is another good example where macros where unsound first and they had a really hard time to make them sound and work with the type-system - they lost a lot of power in the process.

Now, that doesn't have to mean that there is some inherential that stops the combination from super powerful macros and sound statical types from working together, but if anything, there is at least a compromise to be made in terms of resources, because it seems you would have to put a lot of effort into it.

> The code generated by macros would be type-checked in the scheme I described, and type-unsafe code can't be executed by the macro itself

Well, I would already consider this to be quite a big restriction though.


OCaml comes to mind as a static language with a macro system that sees a lot of use. I have no idea, though, how sound its type system is.

For my part, my sense is that it would be appropriate for a static lisp to choose completeness over soundness in its type system. Gödel's incompleteness theorem tells us that a static type checker can't be both sound and complete. So you've got to pick one, and there's something about sacrificing liberty for the sake of security that strikes me as being fundamentally un-lispy. All the talk further up about CL-style unhygienic macros seems like a good illustration of the relevant culture. You can't ignore Scheme and Racket, of course, but the longer tradition in Lisp is to say, "We'll give you all the power and all the footguns, and leave it up to you to use them responsibly."


> Well, I would already consider this to be quite a big restriction though.

Which part, the type-checking? Don't we want it to be type-checked?


I think it's a trade-off. By enforcing type-checking you now prevent people from altering the language in a way that could be both helpful and still safe even when not type-checking. (just because code doesn't type-check doesn't mean it will or could fail)




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: