babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
teodorlu 2021-02-17T09:50:21.010800Z

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?

borkdude 2021-02-17T09:55:53.011800Z

@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

1
borkdude 2021-02-17T09:56:58.012200Z

What are you trying to accomplish?

teodorlu 2021-02-17T09:57:09.012500Z

Hoping @beoliver will jump in to explain here.

borkdude 2021-02-17T10:00:26.013200Z

Both clojure.lang.IPersistentVector and clojure.lang.IPersistentMap are available for instance checks, protocols, etc

πŸ‘ 1
beoliver 2021-02-17T10:04:57.013300Z

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)

beoliver 2021-02-17T10:05:15.013500Z

beoliver 2021-02-17T10:06:25.013900Z

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:

borkdude 2021-02-17T10:10:53.014100Z

Maybe you could implement this like (every? #(instance? clojure.lang.IPersistentMap %) ...) instead. This will avoid relying on concrete classes

borkdude 2021-02-17T10:12:14.014300Z

Or you can make a function that translates your thing to a keyword based on a predicate

borkdude 2021-02-17T10:12:49.014500Z

Or you can use hierarchies maybe as well (`isa?`, derive , etc)

beoliver 2021-02-17T10:14:55.014700Z

πŸ‘ I think just using some predicates will work.

teodorlu 2021-02-17T10:29:22.015Z

> 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!

borkdude 2021-02-17T10:30:27.015200Z

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

πŸ‘ 2
beoliver 2021-02-17T10:31:14.015400Z

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])

beoliver 2021-02-17T10:32:12.015600Z

I really don’t think performance will be an issue πŸ˜‰

βœ”οΈ 1
borkdude 2021-02-17T10:55:25.015900Z

πŸ‘ 2
2021-02-17T13:49:00.018700Z

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)) )

πŸ˜„ 6
2021-02-17T13:49:16.018800Z

borkdude 2021-02-17T14:50:25.019500Z

Thank you! :)

lukasz 2021-02-17T17:15:42.020900Z

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

πŸ†’ 6
πŸš€ 7
2021-02-17T18:58:55.025200Z

Whats the best way to determine if a script is being executed vs say imported or REPLed? Use the file variable?

borkdude 2021-02-17T19:02:55.025900Z

@heow we have one system property (System/getProperty "babashka.file") which contains the name of the file that is being executed

borkdude 2021-02-17T19:03:12.026300Z

if you call it with bb foo.clj (or using a shebang)

πŸ‘ 1
borkdude 2021-02-17T19:03:24.026500Z

See https://book.babashka.org/#main_file