babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
grazfather 2021-03-03T00:01:44.241100Z

off topic but have you seen bat? It syntax highlights things to terminal

nate 2021-03-03T00:28:51.241400Z

definitely, bat is the coolest

flowthing 2021-03-03T09:06:03.243200Z

I see Babashka implements the clojure.main/with-bindings macro, but Babashka can't seem to resolve it:

user=> (require '[clojure.main :as main])
nil
user=> main/demunge
#object[babashka.impl.clojure.main$demunge 0x78db0375 "babashka.impl.clojure.main$demunge@78db0375"]
user=> main/repl
#object[babashka.main$fn__28956$fn__28957 0x4f9ed1e2 "babashka.main$fn__28956$fn__28957@4f9ed1e2"]
user=> main/with-bindings
Could not resolve symbol: main/with-bindings [at <repl>:4:1]
Do I need to do something special to require a macro? Or is it that they can't be required at all?

borkdude 2021-03-03T09:13:54.243500Z

Babashka doesn't expose this macro to scripts right now I think

borkdude 2021-03-03T09:20:33.243800Z

We can improve this if you need this

borkdude 2021-03-03T09:20:40.244Z

Post an issue in that case

flowthing 2021-03-03T09:23:00.244400Z

All right, thanks! Will do.

flowthing 2021-03-03T09:51:24.244800Z

Same with dynamic vars like *flush-on-newline* and *source-path*, I guess?

borkdude 2021-03-03T10:01:44.245Z

I guess

borkdude 2021-03-03T10:03:30.245600Z

What's the difference between *source-path* and *file* ?

borkdude 2021-03-03T10:03:47.245900Z

*source-path* has no docstring

flowthing 2021-03-03T10:05:07.246500Z

Weirdly enough, *source-path* is just the file name of the source file. *file* is the full path.

borkdude 2021-03-03T10:05:33.246900Z

maybe *source-path* is the relative path?

borkdude 2021-03-03T10:05:50.247200Z

I've never really used or needed this

flowthing 2021-03-03T10:06:56.247800Z

Well, it affects something in exception stack traces, I think, but I forget what exactly.

flowthing 2021-03-03T10:07:09.248100Z

Either way, it's not very important, I think.

flowthing 2021-03-03T10:10:00.249100Z

Ah, yeah, got it now. If you evaluate something without *source-path* bound, :trace in the exception map has e.g. [user$eval75800 invokeStatic "NO_SOURCE_FILE" 32]. However, if you bind it to the file name of the source file you're evaluating from, it has e.g. [user$eval76227 invokeStatic "user.clj" 32].

flowthing 2021-03-03T10:10:27.249700Z

(`NO_SOURCE_FILE` instead of NO_SOURCE_PATH because of https://clojure.atlassian.net/browse/CLJ-1167)

borkdude 2021-03-03T10:10:28.249800Z

The babashka traces only use *file*

Jakub Holý 2021-03-03T11:12:02.251200Z

Show time: Babashka-based better alternative to python -m http.server for serving files from a local directory: https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8

👍 8
😎 1
Tomas Brejla 2021-03-04T08:57:41.001Z

btw it also has fairly nice performance, compared to python's http.server. Here're some numbers, serving 7.5K index.html on my dell xps 13 with Intel(R) Core(TM) i7-8550U CPU @ 1.80GH

Running 10s test @ <http://localhost:8000/index.html>
  8 threads and 8 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   206.34us  301.38us   9.88ms   98.08%
    Req/Sec     5.71k   428.99     6.81k    73.76%
  458684 requests in 10.10s, 3.29GB read
Requests/sec:  45414.91
Transfer/sec:    333.24MB
Here's the same with python3 -m http.server:
Running 10s test @ <http://localhost:8000/index.html>
  8 threads and 8 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.88ms  428.80us   9.55ms   81.75%
    Req/Sec   507.72     99.10   808.00     90.30%
  33680 requests in 10.07s, 250.02MB read
Requests/sec:   3345.18
Transfer/sec:     24.83MB
Seems that this default python's http.server doesn't use threads (or at least not efficiently). Of course, bb version in way more memory hungry than the python one, but for simple native dev-server using generic compiled version of bb, it's still quite good. I also learned yesterday that you can actually pass -Xmxand similar flags to graalvm-natively compiled apps (therefore including bb). Didn't know that this was possible and yes, it works :thumbsup: (more info here https://www.graalvm.org/reference-manual/native-image/MemoryManagement/#memory-management-options)

borkdude 2021-03-04T09:40:32.001500Z

nice!

borkdude 2021-03-03T11:15:27.251900Z

Awesome :) I think if you will add #_" -*- mode: clojure; -*-" towards the top of the file, Github will understand the syntax (emacs as well)

✅ 1
borkdude 2021-03-03T11:19:07.252200Z

Can you explain what is the "better than Python" part? :)

borkdude 2021-03-03T11:54:48.253400Z

It seems navigating into directories doesn't work well yet.

borkdude 2021-03-03T11:55:08.253600Z

This is in babashka/logo

borkdude 2021-03-03T11:55:45.254Z

Oh it does work, but there is no .. to navigate back :)

Jakub Holý 2021-03-03T14:02:33.254600Z

> Can you explain what is the "better than Python" part? 🙂 I can provide -d &lt;dir&gt; , am not limited to pwd

borkdude 2021-03-03T14:03:01.254800Z

Awesome :)

Jakub Holý 2021-03-03T14:03:19.255Z

.. could be added, fo course 🙂 I am old fashioned and use ⬅️ in the browser 😉

Jakub Holý 2021-03-03T14:04:14.255200Z

(The ././ in your example could be fixed too but I feel it is good enough for the time being :))

borkdude 2021-03-03T14:04:26.255400Z

:)

Jakub Holý 2021-03-03T14:04:58.255600Z

BTW awesome work with bb, httpkit integration and babashka/fs!

borkdude 2021-03-03T14:05:10.255800Z

Yes, it's coming together isn't it :)

💯 1
borkdude 2021-03-03T14:06:04.256Z

🙏

grazfather 2021-03-03T14:14:41.256200Z

Hm, doesn’t work for me on osx

grazfather 2021-03-03T14:15:06.256400Z

CallHistoryTransactions failed on newest bb

borkdude 2021-03-03T14:15:07.256600Z

It does for me on macOS

borkdude 2021-03-03T14:15:16.256800Z

wut?

borkdude 2021-03-03T14:16:46.257Z

@grazfather This is probably a security issue: https://www.retrospect.com/au/support/kb/macos_full_disk_access

grazfather 2021-03-03T14:18:32.257300Z

Naw, i use python3 -m http.server all the time, iTerm is already in there. Unless you’re saying i’d have to grant it to bb specifically

borkdude 2021-03-03T14:20:28.257500Z

That wouldn't surprise me

Jakub Holý 2021-03-03T14:34:07.257900Z

I am on OSX and have just upgraded to the latest bb, no issue. Big Sur 11.2.1.

grazfather 2021-03-03T14:51:15.258200Z

I’ll try later on my non-work laptop 😉

zane 2021-03-03T19:00:41.261600Z

Anyone in here editing Babashka scripts with clojure-lsp enabled? I’m curious what people are doing to inform clojure-lsp of e.g. Babashka’s built-ins.

ericdallo 2021-03-03T19:09:13.261700Z

right now clojure-lsp does nothing as there is no deps.edn/project.clj file, but that's something we could have

ericdallo 2021-03-03T19:09:28.261900Z

but we'd need to know somehow that's a bb script

ericdallo 2021-03-03T19:09:56.262100Z

ATM, clojure-lsp check for deps.edn, project.clj, etc to get the classpath

ericdallo 2021-03-03T19:10:14.262300Z

if we have some bb --classpath just like the other comands, that could work

ericdallo 2021-03-03T19:10:58.262500Z

I think I discussed that with @borkdude in some thread in #lsp

zane 2021-03-03T19:27:51.262700Z

> right now clojure-lsp does nothing as there is no deps.edn/project.clj file Got it. I have several deps.edn projets that also include Babashka scripts.

ericdallo 2021-03-03T19:31:47.262900Z

Yeah, we need some reliable way to get the classpath, just like if user has a deps.edn file, we call clj -Spath to get the classpath

ericdallo 2021-03-03T19:32:03.263100Z

but that's not always true for bb

Jakub Holý 2021-03-03T19:34:55.263300Z

@borkdude fs/glob seems to have problems with performance in same cases according to https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8#gistcomment-3652518 Is that a known issue?

zane 2021-03-03T19:35:36.263500Z

Makes sense. I don’t see a clear way for clojure-lsp to get access to Babashka’s classpath (such as it is) given that Babashka is a native image. Perhaps a feature for writing out the classpath could be added to Babashka? Hmm.

ericdallo 2021-03-03T19:37:42.263700Z

Yes, that was my idea, something like bb --classpath but we'd need from clojure-lsp when to run that

borkdude 2021-03-03T19:39:01.263900Z

Or maybe clojure-lsp can have a pre-configured classpath that you can choose from a menu?

borkdude 2021-03-03T19:39:15.264100Z

So people can add a deps.edn there with libs that occur in babashka

borkdude 2021-03-03T19:42:44.264300Z

Repro welcome.

borkdude 2021-03-03T19:42:50.264500Z

Not sure what goes on there

borkdude 2021-03-03T19:44:01.264800Z

There are some ideas here. Needs hammock time. https://github.com/babashka/babashka/issues/733

ericdallo 2021-03-03T19:44:19.265200Z

Interations with menus would need change on LSP clients, so I think it'd be better to only the server know somehow to get the classpath

ericdallo 2021-03-03T19:44:34.265400Z

oh that's the issue, thanks

borkdude 2021-03-03T19:46:12.265600Z

Oh yes, I sometimes forget there are other editors besides emacs

😆 1
borkdude 2021-03-03T19:46:45.265900Z

So how would lsp know from only a script.clj that it should retrieve a classpath from babashka?

ericdallo 2021-03-03T19:47:35.266100Z

yeah, that's the problem

ericdallo 2021-03-03T19:47:47.266300Z

there is an idea

ericdallo 2021-03-03T19:48:32.266500Z

user has a .lsp/config.edn file on the project root with some config maybe specifying the bb script files

ericdallo 2021-03-03T19:48:33.266700Z

not sure

ericdallo 2021-03-03T19:48:57.266900Z

it'd still need a lot of changes on clojure-lsp specific to that

ericdallo 2021-03-03T19:49:14.267100Z

a way to get the classpath following all the other build tools it'd be perfect

borkdude 2021-03-03T19:50:01.267300Z

What if a user would have something like ;; *clojure-lsp-preset: babashka* in the script, e.g. at the end?

ericdallo 2021-03-03T19:50:53.267500Z

still need a lot of changes 😕 as we scan the classpath on the LSP initialize request, that has only the project-root

ericdallo 2021-03-03T19:51:10.267700Z

then clojure-lsp do its magic to check what kind of project it is

borkdude 2021-03-03T19:51:12.267900Z

or #_{:clojure-lsp/classpath-cmd ["bb" ...]

zane 2021-03-03T19:51:14.268100Z

> So how would lsp know from only a script.clj that it should retrieve a classpath from babashka? Many of my scripts have #!/usr/bin/env bb at the top, but I know that won’t always be the case. I imagine some people also use a .bb file extension.

ericdallo 2021-03-03T19:51:32.268400Z

only after the initialize, that client send the didOpen for a specific file

ericdallo 2021-03-03T19:51:41.268600Z

any ideas for this @snoe?

ericdallo 2021-03-03T19:54:09.269Z

Also, the initialize method is sent only when the server start, one time, the didOpen is sent for every file opened, we would need to track that somehow

ericdallo 2021-03-03T19:55:40.269200Z

@borkdude maybe user could have a .bb-deps , then we could have a project spec on clojure-lsp of:

{:project-path ".bb-deps"
 :classpath-cmd ["bb" "--classpath"]}

ericdallo 2021-03-03T19:56:16.269400Z

I know is not the ideal as scripts are kind of independent of other files

borkdude 2021-03-03T20:00:12.269900Z

there is an issue about a bb.edn file, but most people just want a script without a bb.edn

borkdude 2021-03-03T20:00:31.270100Z

anyway, if you add a deps.edn right now in your script dir, it should already work

borkdude 2021-03-03T20:00:37.270300Z

maybe that's just the best solution

snoe 2021-03-03T20:01:24.270500Z

is babashka clojure? maybe it is as simple as encouraging a different extension like cljs cljr and joker

borkdude 2021-03-03T20:01:57.270700Z

yes, babashka scripts are compatible with clojure

borkdude 2021-03-03T20:02:32.270900Z

and encouraging another extension: I don't personally like this, as syntax highlighting etc. don't work as nicely. just .clj

snoe 2021-03-03T20:05:02.271100Z

ok, then it probably needs to be a client responsibility, our initializationOptions could take a classpath string and we just use that instead of running a project command if present.

ericdallo 2021-03-03T20:06:03.271300Z

yes, good suggestion, we would still need to change emacs lsp-mode or vim client etc, but I can help with that from emacs side

ericdallo 2021-03-03T20:06:38.271500Z

but the client would still need to know if the file is a bb script and need a way to get the classpath string, right @snoe?

snoe 2021-03-03T20:14:02.272Z

yeah, or they hardcode it to the babashka classpath they use most often and we use that when there's no project found

snoe 2021-03-03T20:14:10.272200Z

something like that tho

ericdallo 2021-03-03T20:15:31.272400Z

The built-in deps of bb can change I think, that's why a bb --classpath makes sense to me, WDYT @borkdude?

zane 2021-03-03T20:16:12.272600Z

Getting clojure-lsp the right classpath is only half the battle, right? There’s also Babashka’s pre-defined built-in aliases.

ericdallo 2021-03-03T20:18:01.272800Z

I don't know what is bb pre-defined aliases

borkdude 2021-03-03T20:19:35.273300Z

Query params middleware :)

zane 2021-03-03T20:20:23.273400Z

https://book.babashka.org/#built-in-namespaces

borkdude 2021-03-03T20:21:12.273800Z

@zane I don't encourage to use those in scripts, that's mostly for one-liners

zane 2021-03-03T20:21:19.274Z

For instance, you can use the alias shell to refer to clojure.java.shell without explicitly requiring the alias.

borkdude 2021-03-03T20:21:25.274200Z

Just add a require in scripts, even if you don't need one

snoe 2021-03-03T20:22:18.274400Z

@ericdallo I don't think there's anyway to tell the difference between a babashka script and a clojure file so clojure-lsp calling the bb --classpath I don't think we can use

zane 2021-03-03T20:22:19.274600Z

That’s what I’ve been doing, but clojure-lsp flagging usage of those aliases is probably not the expected behavior.

zane 2021-03-03T20:22:28.274800Z

Maybe that’s fine. Just pointing it out.

borkdude 2021-03-03T20:22:39.275100Z

It's actually clj-kondo flagging those aliases

zane 2021-03-03T20:22:51.275300Z

Ah, right.

borkdude 2021-03-03T20:22:51.275500Z

unless I misunderstand

zane 2021-03-03T20:23:14.275700Z

No, you’re probably right.

zane 2021-03-03T20:24:10.275900Z

But it’s still related to clojure-lsp in that go-to-definition, etc, won’t work on usages of such aliases.

ericdallo 2021-03-03T20:24:20.276100Z

@snoe with the ;; *clojure-lsp-preset: babashka* suggestion from @borkdude we could know

ericdallo 2021-03-03T20:24:51.276300Z

otherwise, how the client would know that need to send the bb --classpath ?

borkdude 2021-03-03T20:25:20.276500Z

Are there other types of clojure files that this problem also holds for?

borkdude 2021-03-03T20:25:34.276700Z

Maybe it can be solved in a more general way

ericdallo 2021-03-03T20:27:18.276900Z

I don't know any other issue related to that, all build tools usually have a file for the deps and a command to get the classpath

borkdude 2021-03-03T20:35:33.277500Z

@holyjak You can try: https://babashka.org/fs/babashka.fs.html#var-list-dir instead. But if there is a bug in glob, I'd like to know to get it fixed.

grazfather 2021-03-03T20:42:54.277700Z

Hm, tried on my other laptop and it also doesn’t work.

snoe 2021-03-03T20:45:16.277900Z

1) clojure-lsp is built around a single classpath for a project-root. since bb and the project would have separate cps I think it needs to be done carefully. So far we've gotten away with cljs and clj classpaths not colliding, but this is probably pointing us to a place where the classpaths get determined by source-paths. 2) The order of operations here gets messed up. We init and read classpaths and then we read the file, we don't want to read the file then read a classpath based on that. 3) for projects, I imagine a scripts/ dir could be created with some bb project file within it to indicate scripts are in a different project-root and they have a different classpath. 4) for standalone scripts, there's probably an lsp-command that could be made to re-crawl a given classpath. and like it'll be up to bb users to either write scripts to detect that it's babashka or run manually. even then, users are probably not mixing clj and bb files and the bb project file could be put in your ~/scripts/ dir or wherever you're writing.

borkdude 2021-03-03T20:47:09.278100Z

sometimes people just put a script in the root, but I often put it in script if it's in a JVM clojure project

borkdude 2021-03-03T20:47:41.278300Z

I don't think we can prescribe where people should put scripts

grazfather 2021-03-03T20:48:47.278700Z

Looks like it has trouble walking some directories

borkdude 2021-03-03T20:49:01.278900Z

Might be related to the same issue reported under that gist

borkdude 2021-03-03T20:49:40.279100Z

@grazfather Can you just try the same (babashka.fs/glob "." "*") expression from that dir?

borkdude 2021-03-03T20:50:00.279300Z

bb -e '(babashka.fs/glob "." "*")'

borkdude 2021-03-03T20:52:10.279500Z

Just adding a deps.edn in the root of the script dir would solve it for now

borkdude 2021-03-03T20:52:29.279700Z

This is a manual operation, but a sane workaround for now

👍 1
ericdallo 2021-03-03T20:56:16.280Z

Make sense, thanks for testing it @borkdude I think user still need to add the script as another project? to get a different project-root

grazfather 2021-03-03T21:08:38.280300Z

Yeah, that hangs

grazfather 2021-03-03T21:09:04.280500Z

or takes very long. I have a lot in my home dir

grazfather 2021-03-03T21:10:25.280700Z

1: (babashka.fs/glob "." "*")
   ^--- Visiting /Users/graziano/./Library/Saved Application State/com.bitrock.appinstaller.savedState failed

borkdude 2021-03-03T21:18:36.280900Z

I haven't actually tested it, but I think it should work ;)

👍 1
borkdude 2021-03-03T22:11:47.282Z

An overview of the babashka news of February 2021: https://github.com/babashka/babashka/blob/master/doc/news.md#2021-02

Tomas Brejla 2021-03-03T22:16:11.282300Z

I can confirm, it doesn't really freeze, it just seems to traverse all the nested directories/files, as strace confirms (see https://gist.github.com/holyjak/36c6284c047ffb7573e8a34399de27d8)

Tomas Brejla 2021-03-03T22:16:58.282500Z

fs/list-dir works fine and is very quick

borkdude 2021-03-03T22:25:01.282700Z

Weird, I did have an optimization for this when the pattern didn't contain any slashes. https://github.com/babashka/fs/blob/5b8cf66c4cc06bfc24615043c8f8c31f14321f2a/src/babashka/fs.cljc#L248

borkdude 2021-03-03T22:25:06.283Z

But there may be a bug

borkdude 2021-03-03T22:25:33.283300Z

I recommend using list-dir for now then, if all you want is to list a dir :)

borkdude 2021-03-03T22:36:45.283500Z

Found the issue with glob

borkdude 2021-03-03T22:37:41.283700Z

Tracked and fixed: https://github.com/babashka/fs/issues/18

borkdude 2021-03-03T22:40:40.284100Z

^ @grazfather I think changing fs/glob in fs/list-dir should also fix it for you

borkdude 2021-03-03T22:41:48.284300Z

^ @holyjak Please adapt the gist before more people use it as is :)

borkdude 2021-03-03T22:42:04.284500Z

Oh you already did, thanks!

Jakub Holý 2021-03-03T22:49:41.284700Z

Thank you for the quick fix to glob! 🙂

👏 1
1
borkdude 2021-03-03T22:57:19.286Z

I have a native compiled version of tools.deps.alpha here: https://github.com/borkdude/tools-deps-native-experiment I think I can make a babashka pod out of it. What would a tools.deps.alpha pod bring to babashka scripting? Think of it as being able to use the tools.deps.alpha library as you're used to on the JVM. You can do all kinds of crazy dependency-related stuff now in milliseconds.

3
borkdude 2021-03-03T23:00:04.286600Z

But maybe the more exciting thing would be native deps downloading for babashka itself. Bye bye JVM startup time.

👍 2
nate 2021-03-03T23:38:03.287600Z

that would be amazing! I've started using babashka.deps to include libraries and removing the jvm penalty for first runs would be great

nate 2021-03-03T23:38:27.288Z

feels like it could be a useful thing to have built-in to babashka

nate 2021-03-03T23:38:46.288500Z

otherwise, we are replacing the jvm startup time with a pod download time

nate 2021-03-03T23:38:56.288800Z

it would be less often, but still

borkdude 2021-03-03T23:39:17.289400Z

I don't see this as going to be part of babashka, it would double the binary size

nate 2021-03-03T23:39:23.289700Z

oh wow

borkdude 2021-03-03T23:39:25.289800Z

tools-deps-native is around 80mb

nate 2021-03-03T23:40:06.290600Z

as a pod it would be downloaded once, so it's a much smaller wait than every time the deps change

borkdude 2021-03-03T23:40:14.290800Z

right

nate 2021-03-03T23:40:26.291Z

awesome, great work!