Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macros should work in bindings inside let-nom #1

Open
egli opened this issue Jun 17, 2022 · 3 comments
Open

Macros should work in bindings inside let-nom #1

egli opened this issue Jun 17, 2022 · 3 comments

Comments

@egli
Copy link

egli commented Jun 17, 2022

The following code fails to compile (syntax error):

(nom/let-nom [foo (-> 1 (+ 1))] (= foo 2))

It complains that Can't take value of a macro: #'clojure.core/->

Funnily enough when using let-nom> it works

(nom/let-nom> [foo (-> 1 (+ 1))] (= foo 2))
@svantevonerichsen6906
Copy link

Yes, thanks for the heads up.

let-nom is based on nom, which checks everything before evaluating, and then it tries to check the var, e. g. ->, but that fails with this message on a macro.

It is difficult to do something about macros, because it is unclear, resp. different from macro to macro, which parts could be checked beforehand.

E. g. in a let, you can't check the bindings vector, and in an or, you don't want to evaluate things before it is their turn.

I thought about just skipping macro forms, just checking their return values, but then it might be surprising that checking doesn't work inside in certain cases. This would then lead to bugs where you do not immediately see that something is not checked before being passed on.

I now think the way forward would be to throw a better error message at macro expansion time, and provide macro replacements for e. g. or that do the right thing. However, the right thing can also be different from use case to use case, e. g. for or: short-circuit on an anomaly, or treat it like nil?

Still a bit to think about…

@egli
Copy link
Author

egli commented Jul 4, 2022

Not sure I quite follow. It just seems weird that for the nom/let-nom> macro this is possible. That macro simply expands into nested let and with-nom invocations. Wouldn't it be possible to use s similar strategy for let-nom?

@svantevonerichsen6906
Copy link

I don't see how. let-nom and let-nom> have quite different semantics: the latter just short-circuits and returns out, while the former propagates and goes into the body.

Maybe one could use metadata on forms to finetune the checks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants