Fork me on GitHub

Clojure CLI tools user level aliases - for tools, libraries and environments across all your Clojure deps.edn projects Monthly library updates and readme clean-up All details in the changelog

🎉 18

I am discovering this gem! awesome 🙂

Karol Wójcik10:09:32

holy-lambda Released a new version of holy-lambda v0.5.0. This release has been done with the financial help of clojurists-together ❤️ Holy Lambda is extraordinary simple, performant, and extensible custom AWS Lambda runtime for Clojure. Changes • HL is now fully decoupled from AWS SAM • Clojure on official AWS Java runtime is obsolete. As a replacement the new Clojure on Clojure backend has been developed, which is more performant than the official one. (benchmarks in progress) • Removed interceptors. • • Smaller & more performant core! • Update babashka backend to 0.6.1

🎉 30
👍 6
Jakub Holý (HolyJak)19:09:03

Nice! Perhaps a typo here : >For Clojure on official AWS Lambda Java runtime the cold start is between 8-12on a 2GB memory-sized environment.  -> 8-12s on What is the Clojure on Clojure backend and why is it faster than AWS' Java? I couldn't find it quickly in the docs (though I suppose it's there somewhere..) Also, do you have some benchmarks for all the backend? I've once tried babashka lambda (without HL) and it still had considerable cold start - which I blame on the fact that unpacked it had 140MB (70 bb, 70 jdbc pod) that needed to be transferred and decompressed...


Where will you publish the benchmarks when they're ready? I'm very curious!

Karol Wójcik06:09:46

@U0522TWDA thanks! Fixed the typo. Will push the change soon 🙂 Clojure on Clojure is basically uberjar + custom Clojure runtime ran on some sort of JVM. This is different than the official AWS Java runtime that: 1. Invokes the handler using reflection based on name, 2. Uses Java Correto (regular JDK users will be in some time pushed to use Java Correto, which works kinda slow for Clojure) (don't know why, yet) Regarding babashka backend HL includes the pods in the zip, so no download of pods happen on runtime. Size of the artifact does not matter much in your case I think. @U09LZR36F Here are benchmarks although not yet edited, and without tiered compilation for Clojure on Clojure, so there will be some significant differences in cold starts i suppose. Disclaimer: Benchmarks for Java are still using OpenJDK.

Jakub Holý (HolyJak)08:09:40

Ok, so the Clojure runtime is essentially a Docker image, currently based on OpenJDK, like this one, correct? And it is faster b/c Correto is slower than OpenJDK for Clojure and because reflection on name is faster than whatever AWS does by default? > Regarding babashka backend HL includes the pods in the zip, so no download of pods happen on runtime What I meant was that for cold start, Lambda needs to transfer the whole lambda zip from S3 where it is kept, and the bigger it is the more time that takes. So 1kB Python script will have faster startup than 80MB (22MB compressed) bb (on my PC, unzipping that takes 500ms!)

Karol Wójcik09:09:16

Clojure runtime is essentially custom runtime, that does not include all the Java'ish bloat, and this is why it's faster. JVM implementation is a user choice, but yeah correto is slow, so by default I'm including openjdk

Karol Wójcik09:09:19

Regarding babashka I think you're assumptions are wrong. Do you cache jdbc pod? Or do you download the pod on cold start?

Karol Wójcik09:09:02

I mean 2-3 years ago I have packed 200mb of node_modules and cold start was around 300ms.

Jakub Holý (HolyJak)09:09:58

My zip included both bb and the pod

Karol Wójcik09:09:02

Are you sure the pod was not re-downloaded? 😄 I had to do some additional work on HL side to ensure it

Karol Wójcik09:09:36

And if you're using add-deps you can be sure that cold start is high.

Karol Wójcik12:09:58

Anyway @U0522TWDA. If you really care about minimal cold starts use native backend. We have some successful stories. Look NextDoc @U0510KXTU 🙂

👍 2
Jakub Holý (HolyJak)12:09:10

Thank you. I will experiment with that at the next opportunity. I am quite sure (99.9%) the pod was not re-downloaded as I included it using a local path. I still think that transferring 40-50MB (in my case) and unzipping it is bound to take some time, even if there is a super network between S3 and lambda.

Karol Wójcik12:09:04

Encourage you to try HL 🙂 Maybe you will see some difference in time 🙂

👍 2

I am pleased to announce the first release of fijit ( Fijit is a Clojure library for interop with Scala. The goal of this project is to make it easier and more idiomatic to use Scala projects from within your Clojure projects. Some key features include: • Conversions between Scala and Clojure collection types. • Macros for writing Clojure code that targets multiple Scala versions. • A Clojure implementation of the Scala function types. • Idiomatic Clojure interfaces for common Scala types like Option, Try, Tuple, and more. • An experimental Clojure API for Scala reflection and runtime compilation. If you (like me) have to call out to Scala projects, hopefully some of the functions and macros in fijit can help reduce some of the friction.

🎉 32
wizard 8
Noah Bogart14:09:47

I don’t use scala, but this is cool as shit. Congrats on the release!


Impressive! (doc links in the readme don't work btw)


Woops! Thanks for pointing that out. The link in the sidebar should work.


that indeed does

🙏 2

Readme links should be fixed now.


First star.

🙏 2

A long time ago I tried to use the Clojure REPL from Scala: This was during a short adventure in a Scala company.


That is a very interesting idea! I never thought about inspecting the Scala/Java context using an in-process Clojure repl. Very clever.


That's perfect! I added it to the FAQ and credited you. Perhaps one day I will retcon the origins to make myself seem far more clever and cultured than I am. 😄 Thanks!

💜 2

Nice, i tried to interop with scala code from clojure but gave up


it was too painful, i'll keep this lib in mind


clj-kondo 2021.09.14 A new linter :loop-without-recur and several other enhancements and bug fixes. #clj-kondo

🎉 34
clj-kondo 18
🙌 8
👍 10
Alex Miller (Clojure team)20:09:49

Clojure is now available with the following changes since alpha1: • Add :as-alias option to require like :as but not load • Added implementation of update-keys • Added implementation of update-vals • Add clojure.test api run-test and run-test-var to run single test with fixtures and report • IKVReduce - make old slow path (IPersistentMap) faster and extend to Object, detaching it from any fully enumerable set of types • Don’t block realized? of delay on pending result • Fix order of checks in some-fn and every-pred for 3 predicate case to match other unrollings • Get rid of reflection on java.util.Properties when defining clojure-version Improve keyword arity exception message • Fix typo in test-vars docstring • AOT compile more Clojure namespaces • Fix off-by-one in socket server port validation • Update dep to core.specs.alpha (0.2.62)

bananadance 12
clj 76
🚀 16
sheepy 56
👍 36
🎉 54
catjam 12

Where would be the best place to ask questions about some implementation details of some of these? I'm wondering why is not (transient (empty m)) but I don't seem to be able to comment on the Jira


Nevermind, I'll just comment on github

Alex Miller (Clojure team)13:09:34

@U08BJGV6E probably @U050WRF8X is the best person to answer this but I believe the difference here is that with update-keys, the keys are going to change and the structure of the map will change, so there is no reason to update the existing map. also, there are lots of potential issues with changing the key set for different map types (like sorted, ordered, etc). In update-vals, the keys stay the same, so the fastest thing to do is update a transient version of the existing map, if you can.


Thanks Alex. It caught my eye as we use which keeps insertion order and it became a habit of mine to use (empty m) everywhere I 'modify' a map without knowing the broader context

Alex Miller (Clojure team)13:09:40

Importantly, the docstrings for both update-keys and update-vals both say "returns a new map" which means you should not presume anything about the relationship of the returned map type and the input map.


I understand the reasoning but (I guess due to the problems I had when the type was lost) still tend to disagree - (empty m) also creates a new map (be it sorted or ordered etc.) so you aren't really 'modifying' the original one (as you would with (transient m)). Apologies for making noise if this has already been considered, I won't pursue this any further, just hoped handling this similarly to update-vals could broaden the applicability of this fn.

Alex Miller (Clojure team)13:09:13

tradeoffs exist, this is where we came down on it


Thank you for the explanation