Fork me on GitHub
#babashka
<
2019-12-02
>
dominicm09:12:49

It would be cool if nrepl had a customizable Eval like clojure main does

borkdude10:12:40

@dominicm is this related to babashka somehow or just a general remark?

dominicm11:12:33

The babashka eval could be hooked up to nrepl then for most tooling to just work

plexus19:12:49

@dominicm make a middleware that intercepts eval messages, that's basically what piggieback does

dominicm20:12:09

That's a good idea. I think there's good reason to treat it as differently for babashka though, I'm assuming babashka would be a standalone server rather than coexisting with clojure

plexus19:12:42

slightly less trivial than it sounds because nrepl middleware is confusing as heck, but at least in theory fairly straightforward

borkdude19:12:39

is there a tutorial on cider / nrepl middleware? this topic also has come up in clj-kondo: maybe it's possible to have a middleware which lints your project and then emits feedback like unused vars.

borkdude19:12:25

so it seems useful to know at least some basics about it

dominicm19:12:59

@borkdude I think that my blog post has a lot of internal detail. But the examples in the source of nrepl are pretty good.

borkdude19:12:22

which blog post?

borkdude20:12:15

nice, thanks

borkdude22:12:11

What do you think about the following? in babashka / sci everything that is def'ed is effectively treated as a constant. it's even a little bit more strict than direct linking in clojure. so (def ^:const x 1) (defn foo [] x) (def x 2) (foo) will return 1 in Clojure but: (def x 1) (defn foo [] x) (def x 2) (foo) will return 2 in Clojure, but 1 in babashka. I'm now implementing real vars, so you can opt out of this:

$ bb '(def ^:redef x 10)
(defn foo [] x)
(def x 11)
(foo)'
11 I would consider making this the default behavior (without the ^:redef annotation), but so far nobody has complained / asked about this.

borkdude22:12:13

also, there will be "real" dynamic vars:

$ bb '(def ^:dynamic *foo* 1) (binding [*foo* 2] (prn *foo*)) *foo*'
2
1

sogaiu22:12:53

my vote is to make redef default without the annotation -- i think it will be less confusing

1
sogaiu22:12:23

iiuc, the number of current users is not enormous

sogaiu22:12:52

i presume porting code would be facilitated if behavior is closer to clojure's

sogaiu22:12:12

cool about the dynamic vars

sogaiu22:12:15

definitely want them 🙂

borkdude22:12:33

yeah, it wasn't a very conscious decision to make it behave like ^:const, I think it was more driven by the absence of real vars so far

borkdude22:12:49

we can still have direct linking + ^:const

borkdude22:12:53

there is a var branch in babashka and sci where I'm developing this, in case you want to try it out. I agree with sogaiu that we should probably be as close to clojure as possible

borkdude22:12:23

the CLJS version of sci is even closer to JVM clojure than CLJS is in this respect:

(require '[sci.core :as sci])
(println (sci/eval-string "(def ^:dynamic x) (set! x 10)")) ;; Can't change/establish root binding of #'x with set

sogaiu22:12:36

i guess you are working on binding

sogaiu22:12:52

hmm, i asked because when i tried in sci, i got:

(print (sci/eval-string "(def ^:dynamic x) (binding [x 2] (set! x 10) (print x))"))
nilnil

sogaiu22:12:24

so i presume it is "in-progress"

sogaiu22:12:38

or may be i screwed up or misunderstand 🙂

borkdude22:12:08

try `(sci/with-out-str (sci/eval-string ..))'

borkdude22:12:43

by default the out stream is bound to a Writer to not mess with the outside world

sogaiu22:12:09

oh, great it seems to work 🙂

borkdude22:12:02

but you can bring in the normal in and out by using the {:out *out*} option, then you will bind the internal *out* dynamic var to the external *out* value

borkdude22:12:47

so (sci/eval-string "..." {:out **out*})*

borkdude22:12:31

or you can just bring in the external print using {:namespaces {'clojure.core {'print print}}} , these are your options now

sogaiu22:12:17

thanks -- just tried the options map with :out -- worked fine

borkdude22:12:52

this decision is based on not mutating the world when evaluating sci expressions, unless the sci library user gives permission for this

borkdude23:12:36

in the babashka var branch you can see that :in and :out are used

sogaiu23:12:44

also the :namespaces approach worked too sounds like there is some kind of jail functionality

borkdude23:12:32

there is also (sci/with-bindings {sci/*in* *in* sci/*out* *out*} (sci/eval-string ...))

borkdude23:12:26

maybe I should deprecate the :in and :out options in favor of the latter

sogaiu23:12:41

that worked here too 🙂

borkdude23:12:26

I will copy paste this conversation and distill some docs out of this

sogaiu23:12:35

docs via socratic dialogue...or would that be slackratic dialogue?

borkdude23:12:50

like the little schemer, etc

borkdude23:12:37

I'm pretty excited that sci now gets "real" vars with thread-local bindings

sogaiu23:12:09

i am too -- i have something i'm hoping will work in bb before too long

borkdude23:12:40

you can tell me what it is later, but it's sleepy time here

borkdude23:12:47

bye bye

👋 1
borkdude23:12:04

and thanks for testing!

👍 1