Fork me on GitHub
#babashka
<
2023-02-18
>
Richie01:02:11

Is sun.nio.fs.WindowsPath not included in babashka? I get Could not resolve symbol: sun.nio.fs.WindowsPath.

Bob B03:02:51

it doesn't look like it's exposed for reflection/direct instantiation, but the class is "included":

user=> (class (fs/path "."))
sun.nio.fs.WindowsPath

borkdude07:02:05

Need more context, why do you need this? If you need to deal with paths, you can use babashka.fs or cast to a public super class. sun. classes are implementation details that you should usually not refer to directly

Richie21:02:23

I was trying to serialize paths to edn as a tagged thing so that I could read it back into a path. I expect to be told that it's a bad idea and I should put it in a defrecord instead or not do it at all.

(defmethod print-method sun.nio.fs.WindowsPath [c ^java.io.Writer w]
  (spit w (str "#path " (pr-str (str c)))))
Currently, I'm trying to just not need to do it at all.

Richie21:02:32

print-method dispatches by the class and I don't know how to make that work with a superclass.

borkdude21:02:10

@UPD88PGNT

user=> (defmethod print-method java.nio.file.Path [c ^java.io.Writer w] (spit w (str "#path " (pr-str (str c)))))
#object[clojure.lang.MultiFn 0x1d24865a "clojure.lang.MultiFn@1d24865a"]
user=>  (pr-str (fs/path "."))
"#path \".\""

borkdude21:02:53

you could also walk the structure and do the conversion yourself

Richie21:02:23

Oh. It's working now. Thanks! I don't know why it wasn't working before.

Benjamin14:02:06

Hi, is there a full example for a babashka.nrepl middleware? I am currently unclear about the concepts. Can I define a middleware in a bb program or do I need to compile a bb with my middleware?

borkdude15:02:56

There is currently no way to evaluate middleware in user space

borkdude15:02:49

Of course we could figure out a way to accomplish this!

borkdude15:02:33

E.g. by adding the middleware as a bb.edn dependency and then evaluating it. There is a programmatic way of starting the nrepl server already in: babashka.nrepl.server/start-server! where users could maybe pass the middleware or so

Benjamin15:02:08

I'm still in the process of understanding. babashka.nrepl.server/start-server! can be passed an :xform , where I pass middleware, correct? And my middleware I can hypothetically load in user space? I checked and I can load almost all of cider.nrepl (middleware) with bb

borkdude15:02:20

yes, you can pass an xform, but I'm not sure if this works in user space. you can view the babashka nrepl tests how this works, it's transducer-based

Benjamin15:02:10

I see. Yea I need to bend my mind into juggleling the 2 phases of graalvm program and user space. So those examples I make work by either running a clojure program (already did) or compiling them with graalvm (basically a bb version with middleware?)

borkdude15:02:28

You need to make a change in babashka to enable user-space middleware

borkdude15:02:44

you can run bb using the jvm for development

borkdude15:02:11

I do this using clj -M:babashka/dev :

:babashka/dev {:paths []
                          :deps {babashka/babashka {:local/root "/Users/borkdude/dev/babashka"}}
                          :main-opts ["-m" "babashka.main"]
                          }
That alias is in my ~/.clojure/deps.edn

✍️ 2
borkdude15:02:24

The middleware xform implementation isn't something that I came up with myself but was designed by @U7RJTCH6J - perhaps he has ideas how to enable middleware from the JVM nrepl ecosystem

👏 2
borkdude15:02:38

it would be sweet if we could just re-use the cider inspector middleware for example

Benjamin15:02:09

yea with as little wrapper as possible I suppose.

borkdude15:02:40

I suspect there will be a way to transform a JVM nREPL middleware function to a bb-middleware compatible thing, at least, I hope

borkdude15:02:55

else we could maybe implement another stack of JVM middleware on top of the xform stuff

borkdude15:02:26

maybe it would be good to start with the simplest / dumbest middleware example and try to make that work

Benjamin15:02:12

yea first a user defined middleware that logs all requests to file for example. The cider inspect

borkdude15:02:37

yeah or even a middleware which logs all requests using timbre, the debugging middleware :)

👍 2
borkdude16:02:46

I think the exposed nrepl server function should just take the (fn [handler msg]) kind of middleware and not expose this :xform stuff to users since it's more or less for people who want to implement a babashka-like thing, but bb users are likely not familiar with that

borkdude16:02:08

maybe the babashka.nrepl library should also support passing those, as an alternative to :xform

phronmophobic18:02:51

As long as babashka.nrepl.server/start-server! is available from within the sci context, I think passing the xform based middleware should work.

phronmophobic18:02:30

> it would be sweet if we could just re-use the cider inspector middleware for example When I looked into this previously. It didn't seem like it was possible to reuse existing cider middleware without pulling a bunch of dependencies. If you're pulling in a bunch of dependencies, then why not just use cider's nrepl implementation?

phronmophobic18:02:29

> I think the exposed nrepl server function should just take the (fn [handler msg]) kind of middleware and not expose this :xform stuff The xform and the handler forms are mostly just rearrangements of the same stuff:

(def my-handler-middleware
  (fn [handler msg]
    (handler response)))

(defn my-xform-middleware
  (fn [rf]
    (fn [result msg]
      (rf result response))))
The main difference is that instead of calling handler, you call (rf result ...) . Some of the nice things about the transducer approach is that there's a place to init state and it's much easier to test since you can just transduce requests into a vector of responses.

✍️ 2
borkdude18:02:24

> If you're pulling in a bunch of dependencies, then why not just use cider's nrepl implementation? Because those would not be babashka's own dependencies, but dependencies in bb.edn in user space

👍 2
borkdude19:02:21

So to convert a handler to an xform-middleware you can do:

(defn handler->xform-middleware [handler]
  (fn [rf]
    (fn [result msg]
      (rf result (handler identity msg))))
?

phronmophobic19:02:25

I was looking back at the old issue, https://github.com/babashka/babashka.nrepl/issues/11#issuecomment-879300306. I think you can convert it with:

(defn middleware->transducer
  ([middleware]
   (fn [rf]
     (fn
       ([] (rf))
       ([result] (rf result))
       ([result input]
        ((middleware #(rf result %)) input))))))

borkdude19:02:06

@U02CV2P4J6S Is that enough for you to work with? I think any custom middleware should go through that function and then be "appended" to the default xform middlewares

Benjamin19:02:37

I try tomorrow. I suspect its enough to work with 😛

Benjamin10:02:32

@U04V15CAJ for loading the middleware. Maybe we pass a list of symbols with --middleware , then in babashka.main.clj we resolve those with the sci context right? Maybe then we produce a middleware handler that in turn uses sci/eval ?

borkdude10:02:03

Something like this yes

👍 2