Hello!
On Clojure/JVM, I can evaluate clojure.lang.PersistentVector
, and get a java class. On Babashka, I cannot. See attached error message.
@beoliver and I could "just use symbols" instead. But I would like to ask why this behavior is different from clj to bb first.
Any advice?
@teodorlu This is because not all classes are "mapped" into bb because this takes extra space. Most interfaces are available though, like clojure.lang.IPersistentVector
What are you trying to accomplish?
Hoping @beoliver will jump in to explain here.
Both clojure.lang.IPersistentVector
and clojure.lang.IPersistentMap
are available for instance checks, protocols, etc
Hi - jumping in as @teodorlu mentioned⦠Good to know about the interfaces. the concrete example of the issue we are trying to solve is in porting the following pattern (The following is a simplified example)
we could re-write and use map?
string?
etc or use interfaces - but the ability to use sets of types makes the algorithm fairly clean :thinking_face:
Maybe you could implement this like (every? #(instance? clojure.lang.IPersistentMap %) ...)
instead. This will avoid relying on concrete classes
Or you can make a function that translates your thing to a keyword based on a predicate
Or you can use hierarchies maybe as well (`isa?`, derive
, etc)
π I think just using some predicates will work.
> Or you can use hierarchies maybe as well (`isa?`,Β `derive`Β , etc)
I think we should be able to get the same performance guarantees as we have right now with a custom hierarcy, and derive
calls. Good idea. As ben says, we might just go for a simple solution, though.
@borkdude thanks for the help!
I think I could support instance checks for the concrete classes as well in bb. You could post an issue for next time you need it
the only reason for sets was to reduce the search space but chances are that every?
will return quickly on error. for the other usecase we can rewrite it as
(defn partition-by-type [items]
(let [key-fn (juxt number? string? boolean? vector? map?)]
(vals (group-by key-fn items))))
> (partition-by-type [1 "2" 2 "3" true ])
([1 2] ["2" "3"] [true])
I really donβt think performance will be an issue π
In honor of @borkdude half-life, here is a single multifaceted form to celebrate:
#!/usr/bin/env bb
(require '[babashka.deps :as deps])
(deps/add-deps '{:deps {cljc.java-time/cljc.java-time {:mvn/version "0.1.12"}}})
(require '[cljc.java-time.local-date :as ld])
(require '[cljc.java-time.temporal.chrono-unit :as cu])
(let [min-bork "1981-02-08"
max-bork (int (* 365.25 80.6)) ; NL male, round down
all-bork 100]
(defn borkdays [] (cu/between cu/days (ld/parse min-bork) (ld/now)))
(defn borkcal []
(format "Borkdude is %d days old, expiration in %d days. (%.2f%% remaining)"
(borkdays)
(- max-bork (borkdays))
(double (- all-bork (* all-bork (/ (borkdays) max-bork)))) ))
(println (borkcal)) )
Thank you! :)
It's early days, but this is all of the boilerplate you need to deploy bb to lambda, as a docker image; https://gist.github.com/lukaszkorecki/a1fe27bf08f9b98e9def9da4bcb3264e - works in the emulator at least π Once I got it all working down to deploying to AWS, I'll open source a sample repo along with Terraform manifests required to deploy this
Whats the best way to determine if a script is being executed vs say imported or REPLed? Use the file variable?
@heow we have one system property (System/getProperty "babashka.file")
which contains the name of the file that is being executed
if you call it with bb foo.clj
(or using a shebang)