sci

https://github.com/babashka/SCI - also see #babashka and #nbb
mkvlr 2021-03-02T15:18:00.008700Z

@borkdude there’s no way to also read and get information about comments ; in edamame, is there?

borkdude 2021-03-02T15:18:29.009Z

@mkvlr can you explain why you would want this?

mkvlr 2021-03-02T15:19:36.009900Z

@borkdude literate programming in which the comments get parsed as markdown as explanatory between the code

mkvlr 2021-03-02T15:20:55.011Z

rewrite-clj does return comment nodes but I like edamame’s api better

borkdude 2021-03-02T15:22:26.011700Z

@mkvlr I guess we could do something here: https://github.com/borkdude/edamame/blob/9823a7af0edab2cf8596e345b6ea50979f1e9149/src/edamame/impl/parser.cljc#L538 but the question is: what would you return when parsing (defn foo [] ;; nice comment \n 1)

1
borkdude 2021-03-02T15:23:05.012200Z

Right now this returns (defn foo [] 1)

borkdude 2021-03-02T15:27:18.012800Z

if you stick to a strict format, e.g. ;; only at the start of a line, you can probably parse this manually

mkvlr 2021-03-02T15:34:56.014500Z

this would have to be an opt-in thing anyway, right? Maybe the caller could decide what to turn this into? but not sure

borkdude 2021-03-02T15:35:29.015300Z

but what would you want to return? this can mess up the sexpr pretty badly probably

mkvlr 2021-03-02T15:35:34.015500Z

did you use rewrite-clj for deps.edn rewriting?

borkdude 2021-03-02T15:35:42.015700Z

yes

mkvlr 2021-03-02T15:36:12.016300Z

ah ok, I had assumed this must be possible within the borkdude ecosystem 😼

borkdude 2021-03-02T15:36:29.016500Z

the borkdude ecosystem is not a closed world ;)

mkvlr 2021-03-02T15:36:39.016700Z

but it’s pretty complete

borkdude 2021-03-02T15:36:48.017Z

clj-kondo also uses rewrite-clj

borkdude 2021-03-02T15:37:03.017600Z

@lee knows what to use nowadays (I lost track of all his rewrite-clj repos)

mkvlr 2021-03-02T15:37:59.019600Z

thinking of wanting to get (comment ";nice comment") or (line-comment ";nice comment") back maybe

borkdude 2021-03-02T15:38:35.021Z

@mkvlr I can see it being useful to return comments when you are on the top-level but within balanced { .. } for example, I can see this going wrong, like {:a 1 ;; foo \n :b 2} => incorrect map

lread 2021-03-02T15:40:24.022800Z

I started in lread/rewrite-cljc-playground and am migrating that work into clj-commons/rewrite-clj v1 branch which will be merged to clj-commons/rewrite-clj main.

mkvlr 2021-03-02T15:42:49.023600Z

@borkdude ah right, guess top level only would be fine for my use case but unsure if it’s worth it then…

borkdude 2021-03-02T15:45:43.024300Z

@mkvlr if top-level, I think this is pretty easy to parse manually, with (str/starts-with? (str/trim ...) ";")

mkvlr 2021-03-02T15:59:20.024900Z

@borkdude true, I guess rewrite-clj is also fine

Huahai 2021-03-02T22:15:41.027100Z

@borkdude I am using sci in datalevin command line tool, it works for most part, however, there are some datalog queries that work in JVM do not work in sci

Huahai 2021-03-02T22:16:05.027400Z

No implementation of method: :-find-vars of protocol: #’datalevin.parser/IFindVars found for class: datalevin.parser.Constant

Huahai 2021-03-02T22:17:06.028200Z

Is there anything special needed for loading the namespaces?

borkdude 2021-03-02T22:17:36.028900Z

Hey! I'm not sure what this means without having some kind of repro

borkdude 2021-03-02T22:18:28.029300Z

You can point me to your repo and I can have a look if you can make some kind of failing test

borkdude 2021-03-02T22:18:37.029600Z

and instruct me how to run that

Huahai 2021-03-02T22:19:53.031200Z

this is what i currently doing, i expect it won’t work as I am not using sci namespaces, but I also tried using SciNamespace and SciVar, still doesn’t work

Huahai 2021-03-02T22:20:51.032Z

i saw that your datascript feature is using SciNamspace and copy-var, so I tried to do that, but still no luck

borkdude 2021-03-02T22:21:14.032300Z

> I can have a look if you can make some kind of failing test

Huahai 2021-03-02T22:21:51.032500Z

sure

borkdude 2021-03-02T22:22:14.032800Z

Are you trying to expose a protocol to the sci scripts?

Huahai 2021-03-02T22:22:33.033300Z

no, i am just trying to run functions in sci

borkdude 2021-03-02T22:22:36.033400Z

What is the example script that manifests this error?

borkdude 2021-03-02T22:22:51.033700Z

(or REPL input for that matter)

Huahai 2021-03-02T22:23:07.034100Z

the kind of datalog query that involve (pull …)

Huahai 2021-03-02T22:23:31.034900Z

normal queries work fine

borkdude 2021-03-02T22:23:36.035100Z

I need a complete example / test so I can have a look. If you can provide me with details instructions how to clone and run that, I'll take a look tomorrow

borkdude 2021-03-02T22:23:57.035600Z

I have already tried your native binary locally, that worked for me

borkdude 2021-03-02T22:24:03.035900Z

Very cool stuff btw

Huahai 2021-03-02T22:24:09.036100Z

sure thanks, i will create a test case

borkdude 2021-03-02T22:24:23.036600Z

is pull a macro perhaps

Huahai 2021-03-02T22:24:47.037Z

yeah, it works for most part, only some queries that don’t work

Huahai 2021-03-02T22:24:58.037300Z

yes, a macro is involved i think

borkdude 2021-03-02T22:25:04.037500Z

ah, macros need special attention

Huahai 2021-03-02T22:25:13.037700Z

that’s what i suspected

borkdude 2021-03-02T22:25:30.038Z

can you show me the macro expansion of the failing pull query?

Huahai 2021-03-02T22:26:49.038500Z

#?(:clj (defmacro deftrecord “Augment all datalevin.parser/ records with default implementation of ITraversable” [tagname fields & rest] (let [f (gensym “f”) pred (gensym “pred”) acc (gensym “acc”)] `(defrecord ~tagname ~fields ITraversable (~’-postwalk [this# ~f] (let [new# (new ~tagname ~@(map #(list ‘datalevin.parser/postwalk % f) fields))] (if-let [meta# (meta this#)] (with-meta new# meta#) new#))) (~’-collect [_# ~pred ~acc] ;; [x y z] -> (collect pred z (collect pred y (collect pred x acc))) ~(reduce #(list ‘datalevin.parser/collect pred %2 %1) acc fields)) (~’-collect-vars [_# ~acc] ;; [x y z] -> (collect-vars-acc (collect-vars-acc (collect-vars-acc acc x) y) z) ~(reduce #(list ‘datalevin.parser/collect-vars-acc %1 %2) acc fields)) Traversable (~’-traversable? [_#] true) ~@rest))))

Huahai 2021-03-02T22:27:14.038700Z

`#?(:clj (defmacro deftrecord "Augment all datalevin.parser/ records with default implementation of ITraversable" [tagname fields & rest] (let [f (gensym "f") pred (gensym "pred") acc (gensym "acc")] `(defrecord ~tagname ~fields ITraversable (~'-postwalk [this# ~f] (let [new# (new ~tagname ~@(map #(list 'datalevin.parser/postwalk % f) fields))] (if-let [meta# (meta this#)] (with-meta new# meta#) new#))) (~'-collect [_# ~pred ~acc] ;; [x y z] -> (collect pred z (collect pred y (collect pred x acc))) ~(reduce #(list 'datalevin.parser/collect pred %2 %1) acc fields)) (~'-collect-vars [_# ~acc] ;; [x y z] -> (collect-vars-acc (collect-vars-acc (collect-vars-acc acc x) y) z) ~(reduce #(list 'datalevin.parser/collect-vars-acc %1 %2) acc fields))` Traversable (~’-traversable? [_#] true) ~@rest))))

Huahai 2021-03-02T22:27:20.038900Z

sorry, this is messed up

Huahai 2021-03-02T22:28:47.040600Z

that’s the macro responsible to flesh out all the defrecord in parser.clj,

borkdude 2021-03-02T22:35:24.043Z

I see yes. So:

(deftrecord Aggregate [fn args]
  IFindVars (-find-vars [_] (-find-vars (last args))))
expands in some defrecord call which needs the IFindVars protocol to be around. This is where it gets a little hacky, but you can make this work. In sci, due to GraalVM limitations, protocols are implemented as multimethods. E.g. this is how Datafiable is added to the sci config of babashka: https://github.com/babashka/babashka/blob/bbf144fbce66c6986253119eb81392a440cb17c6/src/babashka/impl/protocols.clj#L33

Huahai 2021-03-02T22:36:29.043900Z

ok i see

Huahai 2021-03-02T22:38:42.044300Z

so i need to do the same for IFindVars?

borkdude 2021-03-02T22:39:32.044600Z

if you want that macro to work, yes

borkdude 2021-03-02T22:39:35.044800Z

$ bb -e "(require '[clojure.core.protocols :as p] '[clojure.datafy :as d]) (defrecord Foo [] p/Datafiable (datafy [_] :foo)) (d/datafy (->Foo))"
:foo
 

borkdude 2021-03-02T22:40:28.045600Z

It magically works, but it works around the byte code restriction by using multimethods. This is a little bit undocumented right now and the implementation might change in the future

borkdude 2021-03-02T22:41:10.046200Z

So why do users need to use (deftrecord ...) in their scripts/REPL?

Huahai 2021-03-02T22:41:48.046900Z

not users, but the parser does that

borkdude 2021-03-02T22:41:59.047100Z

at REPL-time?

Huahai 2021-03-02T22:42:14.047400Z

right, the query has to be parsed

borkdude 2021-03-02T22:42:27.047700Z

and then it defines these record types during parsing?

Huahai 2021-03-02T22:42:52.048200Z

that’s an interesting question, maybe they should not

Huahai 2021-03-02T22:43:11.048800Z

because those record type should be compiled

Huahai 2021-03-02T22:43:21.049200Z

but somehow they didn’t

borkdude 2021-03-02T22:44:31.050100Z

yeah, it seems a little odd. a parser should just take some data in and produce some other data probably

borkdude 2021-03-02T22:44:34.050300Z

are you aware of https://github.com/lambdaforge/datalog-parser?

Huahai 2021-03-02T22:45:00.050900Z

it’s the same as the datascript one, they just extract that out i believe

borkdude 2021-03-02T22:45:08.051200Z

ok

Huahai 2021-03-02T22:47:09.052500Z

ok, let me figure it out, it looks like a compilation problem

borkdude 2021-03-02T22:47:24.052900Z

ok, that would simplify stuff a lot

Huahai 2021-03-02T22:48:22.053300Z

i will try the macro fix, thanks for point me at that

👍 1
borkdude 2021-03-02T22:52:01.054100Z

I'm off to bed now, will read again tomorrow. Exciting stuff, looking forward to using datalevin from babashka scripts :)

Huahai 2021-03-02T22:52:13.054300Z

thanks, have a good sleep!