@snoe I'm struggling with writing a good macro def for Midje's fact
midje.sweet/fact [:element {:element [:element '=> :element] :repeat true}]
works for the simple case.
but it's common to nest a let
, and I can't figure that out.
I'm feeling like the best solution is to add a way to write
{:element :bound-elements :bindings ['=>]}
to supply some extra bindings in the scope.
alternatively, does it make sense for a :bound-elements
to support a let
, with the same contents in its body as are expected in the parent? that feels like it might have some unexpected fallout.
I think the answer might lie in trying to use :sub-forms
how about {'midje.sweet/fact [{:element :bound-elements :sub-forms {'=> [] 'provided [:elements]}}]}
I didn't realize I could use subforms like that.
let me experiment with it.
I didn't either. but if that doesn't work I think it might need a patch
so the subform => []
doesn't work for top-level assertions, nor for those nested in a let.
I can sidestep the problem by defining my own fact-let
that doesn't have the nesting, but that really sucks. and let
is magic, so I can't seem to define :sub-forms {'let [:bindings :bound-elements]}
@snoe ^
oh wow, I found a pretty serious parser bug. if I do a Datalog sort of query, it tries to identify the symbols even though it's quoted:
'[:find [?a ?b] :where [...]]
and it complains that it can't find ?a
and ?b
(deftest ^:test-refresh/focus custom-sub-forms
(let [code "(defmacro fact [& _]) (fact (let [x 1] 1) => 2 (provided (inc) => [1 2]))"
usages (parser/find-usages code :clj {'user/fact [{:element :bound-elements :sub-forms {'=> [] 'provided [:elements]}}]})]
(is (= nil (some :unknown (mapcat :tags usages))))))
here's my fact test i did at lunch, can you show me where it's insufficient?yeah quoting is tricky
I write them like this:
(fact "foo"
(let [a (blah c)]
(bar a) => 1
(baz a false) => nil))
so the =>
is inside the let
(and there's multiple)well, a vanilla '
should be just a black box?
@snoe so is a datalog query supposed to work?
I don't use them so I'm guessing they don't, but datalog is common enough in clojureland that I would love to support them fully.
Last I thought about it I was probably thinking '
is similar to comment
or #_
Looking around, though, I think you're right. There are situations when writing macros you want to resolve quoted symbols and keywords but that's probably much more rare than using it for datalog, or using a placeholder symbol.
symbols are a specific data structure and quote is just used to construct them (literal s-exps in general). doesn't make sense to resolve it
it'd only make sense in special forms imo
out of curiosity: wouldn't it be easier to first macroexpand everything before parsing the code? macro expansion happens during read anyway, so it'd still be a static analyzer?
Ahh yeah. That makes sense. I guess I got confused since macros are expanded during compilation, but you need a runtime to compile too