Skip to content

Macros should be a property of a value, not a property of a binding #1612

@afranchuk

Description

@afranchuk

I've found the behavior of macro definitions confusing (as someone who's had a good amount of experience with Janet) and very different from other languages (as a PL nerd). The problem arises from the fact that defmacro only works as intended at the top-level, because the compiler only evaluates bindings with a :macro attribute as a macro. I think that (do (defmacro foo ...) (foo ...)) should work just like it does when not in a do scope. This also impacts things like macex.

I concede that, yes, a macro is just a function, however in practice a user rarely (if ever) wants to use it as a normal function (i.e., calling it to return syntax); it should operate like a macro! There should be a separate JanetType to distinguish them.

I imagine it would be cleanest to add a keyword to fn to create a macro (e.g., (fn :macro [x] ...)). On the surface this might be a breaking change, however to retain backwards-compatibility, there could be a special case on def to still accept :macro and change a function type to be a macro type instead. Since users overwhelmingly use defmacro to create macros, in practice it might not actually be a breaking change (since defmacro could be changed accordingly), but it's best to be cautious all the same.

This would also clean up hacks like as-macro.

I would be happy to contribute a patch for this (though it might be a little delayed as my free time is limited right now).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions