Has anybody been working on a spec-guided completion?
what I mean: you can compute the firsts set of a regular expression and you can also compute its derivative towards a prefix
(defn firsts
([re] (firsts re (s/form re)))
([re form]
(case (::s/op re)
::s/pcat (if-let [[p & ps] (:ps re)]
(into (firsts p (first (:forms re)))
(when (s/valid? p nil)
(firsts (-> re (assoc :ps (vec ps))
(update :ks (comp vec next))
(update :forms (comp vec next)))
’???)))
#{})
::s/alt (into #{} (mapcat firsts (:ps re) (:forms re)))
::s/accept #{}
#{form})))
=> (firsts (s/cat :name symbol? :meta map?))
#{clojure.core/symbol?}
=> (firsts (s/cat :name (s/? symbol?) :meta map?))
#{clojure.core/symbol? clojure.core/map?}^^ rough poc
what is this sorcery
@pesterhazy given a regular expression you can know what are the valid inputs for the first transition (“firsts set”)
given a regular expression and a prefix you can compute the remaining regular expression after having consumed prefix
together they allow to offer completion on macros that are specced
you can have the following interactions (pipe being the caret)
(if-l|
(if-let [|] ; autompletion automatically creates the vector because it’s the only valid input, a hint may say that a binding is epxected
...
@pesterhazy anything against the use of spec in unravel?
Might slow lumo down significantly
why?
spec is precompiled in Lumo
AOTed to JS
so I can use it for cmdline args parsing?
do it
Beautiful
(I'm here in the peanut gallery)
@ghadi wouldn’t spec derivatives be your kind of thing?
i'm more of a PEG kinda guy
but yeah, 100% behind what you said
this is funny to me -- it's like the dual to your original 2010 conj talk on partial parsing
except it's not parsing, it's partial generation