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?
1👍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
you can use Clojure.*var*("clojure.core", "*out*");
to get the root binding of out
you still need to deref that though if used from java
the old clojure version is intentional (the site maintainer thinks it would be unfair to past participants to introduce a clojure version that wasn't available to them) - but very little that you learn about clojure 1.4 doesn't apply to today's version
I learned a lot about clojure from 4clojure (though many of the answers that others submit, if you compare your answers, are written for code golf and not quality)
The root binding is probably not so interesting since it's just a stream to stdout
that's fair, but in order to know a specific binding, you would need to have your handle on a specific thread / context. which is implicit in clojure but it's a weird hoop to jump through if interacting with clojure via java
@noisesmith He is calling Java from Clojure. So you can just pass *out*
as an argument which will pass the dynamically bound value to the Java side
oh - I must have misunderstood the question
fyi, https://ask.clojure.org/index.php/10136/persistentprioritymap-reduce-reducing-function-priority
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"?
actually, if the java code is being called from clojure, resolving *out*
doesn't get the root binding, it gets the dynamic binding
as long as you didn't do something like call the Thread
constructor and lose your binding
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
nice
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...)
Transducers are a significant chunk of Clojure that's missing from 4Clojure. I remember encountering some other issues where the documentation clearly states that something is possible but 4Clojure doesn't work with it - alas, I don't remember the details.
@noisesmith Do you have a reference to that statement about an update being unfair (which, IMO, is not a good argument all by itself)? I know only of this comment that explains that the update hasn't been done only because of clojail
: https://github.com/4clojure/4clojure/issues/303#issuecomment-509882098
@p-himik this is the explanation that amalloy gave when I asked about updating the version, he still hangs out on #clojure freenode IRC, though he isn't active in clojure dev any longer
1👍yeah, clojail is a hack, a modern redo of 4clojure would likely be better off using a self hosted cljs in browser
though that leaves an opening for exploits where a "solution" does something unexpected when run in your browser
I mean, if someone wanted to make http://5clojure.com , I doubt anyone at http://4clojure.com is going to complain 🙂
since 4clojure uses clojure 1.4, maybe we are due for 11clojure
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
1😮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
1🙏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
1🙏It might be useful for part of your case.