lsp

:clojure-lsp: Clojure implementation of the Language Server Protocol: https://clojure-lsp.io/
2020-03-25T17:52:16.000400Z

@snoe I'm struggling with writing a good macro def for Midje's fact

2020-03-25T17:53:01.001200Z

midje.sweet/fact [:element {:element [:element '=> :element] :repeat true}] works for the simple case.

2020-03-25T17:53:41.001700Z

but it's common to nest a let, and I can't figure that out.

2020-03-25T17:55:08.003100Z

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.

2020-03-25T17:59:07.004Z

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.

snoe 2020-03-25T19:13:27.005300Z

I think the answer might lie in trying to use :sub-forms how about {'midje.sweet/fact [{:element :bound-elements :sub-forms {'=> [] 'provided [:elements]}}]}

snoe 2020-03-25T19:13:35.005600Z

@braden.shepherdson ^

2020-03-25T19:14:06.006Z

I didn't realize I could use subforms like that.

2020-03-25T19:14:10.006200Z

let me experiment with it.

snoe 2020-03-25T19:14:24.006800Z

I didn't either. but if that doesn't work I think it might need a patch

2020-03-25T20:23:36.007600Z

so the subform => [] doesn't work for top-level assertions, nor for those nested in a let.

2020-03-25T20:24:44.008600Z

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]}

2020-03-25T20:27:41.008900Z

@snoe ^

2020-03-25T20:44:16.010300Z

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

snoe 2020-03-25T20:44:57.010900Z

(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?

snoe 2020-03-25T20:45:01.011100Z

yeah quoting is tricky

2020-03-25T20:46:22.012200Z

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)

2020-03-25T20:51:59.012700Z

well, a vanilla ' should be just a black box?

2020-03-25T21:10:59.013300Z

@snoe so is a datalog query supposed to work?

snoe 2020-03-25T22:02:27.014600Z

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.

snoe 2020-03-25T22:11:43.019600Z

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.

2020-03-25T22:34:01.021600Z

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

2020-03-25T22:34:18.022Z

it'd only make sense in special forms imo

2020-03-25T22:38:03.023400Z

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?

2020-03-26T11:07:21.024200Z

Ahh yeah. That makes sense. I guess I got confused since macros are expanded during compilation, but you need a runtime to compile too