sci

https://github.com/babashka/SCI - also see #babashka and #nbb
borkdude 2020-08-07T06:47:35.444300Z

@kevin.van.rooijen it doesn’t, but I think for this kind of simple transformation it’s really better to write your own function that walks the structure instead of using sci for this

kwrooijen 2020-08-07T07:02:53.445Z

👍

borkdude 2020-08-07T07:29:48.445500Z

@kevin.van.rooijen I think you can adapt this function from sci to create your own transpiler:

(defn analyze
  [ctx expr]
  ;; (prn "ana" expr)
  (let [ret (cond (constant? expr) expr ;; constants do not carry metadata
                  (symbol? expr) (let [v (resolve-symbol ctx expr false)]
                                   (cond (constant? v) v
                                         ;; (fn? v) (utils/vary-meta* v dissoc :sci.impl/op)
                                         (vars/var? v) (if (:const (meta v))
                                                         @v (types/->EvalVar v))
                                         :else (merge-meta v (meta expr))))
                  :else
                  (merge-meta
                   (cond
                     (map? expr)
                     (-> (zipmap (analyze-children ctx (keys expr))
                                 (analyze-children ctx (vals expr)))
                         mark-eval)
                     (or (vector? expr) (set? expr))
                     (-> (into (empty expr) (analyze-children ctx expr))
                         mark-eval)
                     (and (seq? expr) (seq expr))
                     (analyze-call ctx expr)
                     :else expr)
                   (select-keys (meta expr)
                                [:line :column :tag])))]
    ;; (prn "ana" expr '-> ret 'm-> (meta ret))
    ret))

borkdude 2020-08-07T07:30:15.445700Z

You can also keep track of the depth, etc

kwrooijen 2020-08-07T07:56:21.446500Z

Currently at work so I can't look at this in depth. But I think you're suggesting to extract sci code and use that instead of using sci itself?

borkdude 2020-08-07T07:57:04.447300Z

Yes. Just walk your structure like in the above snippet. If it's a map, use zipmap, if it's a seq, treat it like a function call, etc.

kwrooijen 2020-08-07T08:00:51.449500Z

I'll take a look at Sci and see how it does it, always good to read other people's code. I already have a working implementation, I was mostly just tripping over the macro part. Last night I was able to figure out a decent solution though.

kwrooijen 2020-08-07T08:03:22.450900Z

Currently my transpiler supports all the language features of the target language. I now need to implement more clojure specific features. Which is quite a challenge for such a limited target language (but very educational)

2020-08-07T08:18:31.454400Z

Is there a Sci variation of the backquote? When working with Sci macros the ` doesn’t work as desired. E.g. for unknown keywords it will use the current clojure namespace which is not the current Sci namespace

2020-08-07T08:18:36.454500Z

I’m thinking of writing another macro for this if this doesn’t exist

borkdude 2020-08-07T08:34:23.455100Z

Can you make an example? Could be a bug, backquote should work as in Clojure.

2020-08-07T08:51:54.455300Z

No it is not a bug as far as i know. It’s more of a usability issue

2020-08-07T08:52:58.455500Z

Like the following doesn’t work intuitively

(def my-macro ^:sci/macro true
  (fn [_ _ form]
    `(some-other-ns-function form)
    ))

borkdude 2020-08-07T08:53:15.455700Z

Yeah, that's not something sci can do anything about, it's evaluated outside of it

2020-08-07T08:53:46.455900Z

yeah I was hoping to find some way of dealing with this, but the current-ns is not available either

2020-08-07T08:54:35.456100Z

My current efforts to write a macro for this are not very succesful yet. I was thing of having a macro where you pass the desired ns as an argument

2020-08-07T08:55:06.456300Z

Something like this

(defn sci-backquote* [current-ns form]
  (clojure.walk/postwalk (fn [x]
                           (if (symbol? x)
                             (if (namespace x)
                               x
                               (let [n (name x)]
                                 (if (clojure.string/ends-with? x "#")
                                   x
                                   (if (resolve (symbol "clojure.core" n))
                                     x
                                     (symbol current-ns n)))))
                             x))
                         form))

(defmacro sci-backquote [ns & form]
  `(quote (do ~@(sci-backquote* (str ns) form))))

2020-08-07T08:55:15.456500Z

It’s not working 🙂

borkdude 2020-08-07T08:57:01.456700Z

Maybe just use fully qualified symbols in your macros? That's how I tend to do it

borkdude 2020-08-07T08:57:30.456900Z

^:sci/macro true
should just be ^:sci/macro btw

2020-08-07T08:58:14.457200Z

ah good catch 🙂 thanks

2020-08-07T08:58:43.457400Z

yeah I use fully qualified symbols now, but it becomes a bit tedious. It’s ok for now

2020-08-07T08:59:21.457600Z

Not much too complain otherwise. Sci is working really well 🙂

borkdude 2020-08-07T08:59:54.457800Z

Cool! I do want to look at that iterate-max thing soon, but first I'm working on getting a proper stacktrace, which is a bit harder than I thought :)

borkdude 2020-08-07T09:00:32.458Z

and now it's ff-ing hot...

2020-08-07T09:00:41.458200Z

haha yeah brain is frying

borkdude 2020-08-07T09:01:03.458400Z

btw I think spire also has some logic around this same problem

borkdude 2020-08-07T09:01:07.458600Z

for macros

2020-08-07T09:01:31.458800Z

ah i’ll have a look