Racket's cons cells are immutable. I don't think you want to pick a fight with Racket on syntax 😛
there's an (unmaintained) port of Clojure to Gambit Scheme which does have TCO: https://github.com/takeoutweight/clojure-scheme
most Schemes allow you to extend the reader to introduce data literals, and there are implementations of immutable/persistent data structures. Clojure doesn't stand out for what it can do (except if you count the reach of the JVM, but there are other lisps there). it stands out by the good things it nudges you to do and the bad things it discourages you from doing, which has helped create a more widely shared culture around those values
i.e., Racket probably has persistent data structures (I haven't checked), but if you grab any Racket library at random you can't assume its interface is based around them in the same way you've come to expect in Clojure
I think recur
is enough for most application code in practice. TCO and continuation support would allow to implement things like core.async without macros: https://pastebin.com/ff732013 (this is just an old POC and it's of course much more limited in scope than core.async, but it has the fundamental mechanics). I don't miss them much, though
What would it take for http://teavm.org/ to support Clojure?
If it starts from bytecode then it should work with aot-compiled Clojure (which is bytecode)
but why not ClojureScript?
It would be interesting to see how bundle size & runtime performance compare between that & clojurescript.
I love ClojureScript but why not explore other options as well?
Bundle size must be larger. Cljs compilation model includes tree shaking via Google closure
This thread is worth a read https://groups.google.com/g/clojure/c/Ng_GXYSrKmI/m/q0cxahB3BAAJ indeed a thin replacement can be ok, but it's better to assess first the structure of your code
I think I'm Doing It the Wrong Way (TM): I'm using hive-jdbc-uber.jar and clojure.java.jdbc
but "uber" doesn't quite mean uber: calling jdbc/execute!
is resulting in a series of class not found exceptions, so I'm killing the inferior clojure process (under emacs), editing project.clj to add a missing jar to :resource-paths
and restarting clj. this seems stupid ... is there a way to tell leiningen "just go out to a repo and get whatever dependencies are needed to load this jar"?
that's what the lein uberjar
task does (along with packaging all those deps into one jar file)
I wouldn't expect a jdbc specific jar to include all the adapters for the various dbs for example
agreed ... but I'm getting errors for classes from jetty, antlr, etc. I suspect it's related to logging: this nonsense started a bit after I tried to set up slf4j/logback/etc.
are you making an uberjar or are you depending on an uberjar? I'm a bit confused where uber fits into this. As you're talking about how to get lein to get dependencies. So it sounds like regular repl development to me
depending -- just trying to run some queries interactively in a clj scratch buffer
and you added all of your deps to the :dependencies
vector in your project.clj? I'm confused why you think :resource-paths
is the way to go
what's the proper way to add a java .jar to the runtime classpath?
a local jar or a jar that has coordinates on maven?
local ... though it may be on maven as well, didn't look. I've got local copies of hive and hadoop in $HOME/opt/
(older versions to match the versions we're running in prod).\
yeah, version's listed in maven central -- will give that a shot.
simplest option is to just add the deps you require to your dependencies vector specifying the versions that you need. this will get all transitive deps required by those. if you have jars locally it gets a bit more complicated with lein it seems. reading a stack overflow example that mentions the runtime trick of using :resource-paths
but if you make your own uberjar it will put the jars in the jar and not the classfiles
the suggested fixes seem to be to set up your own private repo to serve the deps which seems strange. but that gets into more java world than i'm familiar with. I do remember from my time in .NET that nuget makes it far easier to treat a directory with packages in it as a repo. seems kinda heavy
the advantage of having a private repo for the deps is that it makes a "build" a transparent and repeatable thing, if every dev / CI task uses the same repo every build will produce the same result
it reduces the complexity of every dev / CI setup, at the cost of being one more service to install and configure for global usage
using the s3 wagon for example is trivial if you already use amazon s3 - no maven server needed, it just uses a plugin to treat s3 as a repo
that makes sense. my mind went to treating a local directory as the repo so it completely avoided all the benefits you were touting
right, that's just a re-shuffle of the "put all the jars you use in a folder" option, which is what you have to do without maven
(it still does dep resolution thankfully...)
Hi everyone, I just got started using VisualVM which is awesome and it helped me identify that plumatic schema was slowing down my code a lot. After switching off schema validation my profiling results say that clojure.lang.RT.seq
is the new bottleneck. Based on what you see here do you identify any "easy" optimization wins or should I quit while I'm ahead?
@ronny463 this is where normal profiling gets weird in clojure - if you do work inside a lazy seq, then consume it later, the method that forces the data shows up as the one performing the work
but I've had decent luck with going down the list of hotspots until I find functions I wrote
ah okay! I was going to ask if you use different tools for profiling in Clojure
it sounds like you use something similar to visualvm but then you scroll down the hotspot list?
there are good tools for micro-benchmarking (eg criterium) - I use the dump of a real profiler, find which of my code is up in that list, then microbenchmark, then attempt to speed it up and microbenchmark it again
there are clojure specific profilers but I haven't used any of them in anger
Thank you!
there are also disassembly tools, if reasoning about what your code does from first principles is failing and you'd rather read pseudocode derived from jvm assembly...
also definitely turn on reflection and boxed math warnings
the https://github.com/clojure-goes-fast/clj-async-profiler flame graphs are pretty useful
you are still fighting the same thing you're seeing in visualvm though
I sometimes use this for looking at how quickly latency drops with number of calls. It's isolated though and not part of a larger ecosystem. https://github.com/dmillett/clash/blob/master/src/clash/tools.clj#L114
It might be useful for part of your case.