clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
euccastro 2021-02-01T00:14:39.055300Z

Racket's cons cells are immutable. I don't think you want to pick a fight with Racket on syntax 😛

euccastro 2021-02-01T00:17:36.055600Z

there's an (unmaintained) port of Clojure to Gambit Scheme which does have TCO: https://github.com/takeoutweight/clojure-scheme

euccastro 2021-02-01T00:23:10.055900Z

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

euccastro 2021-02-01T00:24:56.056100Z

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

euccastro 2021-02-01T00:32:18.056800Z

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

2021-02-01T01:25:22.057500Z

What would it take for http://teavm.org/ to support Clojure?

alexmiller 2021-02-01T01:33:39.058300Z

If it starts from bytecode then it should work with aot-compiled Clojure (which is bytecode)

alexmiller 2021-02-01T01:33:51.058700Z

but why not ClojureScript?

2021-02-01T01:39:04.060500Z

It would be interesting to see how bundle size & runtime performance compare between that & clojurescript.

2021-02-01T01:41:31.061Z

I love ClojureScript but why not explore other options as well?

1👍
2021-02-01T02:19:29.063100Z

Bundle size must be larger. Cljs compilation model includes tree shaking via Google closure

vemv 2021-02-01T02:55:01.063900Z

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

2021-02-01T16:20:32.067Z

you can use Clojure.*var*("clojure.core", "*out*"); to get the root binding of out

2021-02-01T16:21:32.067200Z

you still need to deref that though if used from java

2021-02-01T16:24:16.067400Z

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

2021-02-01T16:24:50.067600Z

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)

borkdude 2021-02-01T16:33:56.067800Z

The root binding is probably not so interesting since it's just a stream to stdout

2021-02-01T16:36:56.068Z

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

borkdude 2021-02-01T16:37:40.068200Z

@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

2021-02-01T16:37:57.068400Z

oh - I must have misunderstood the question

mbarillier 2021-02-01T16:52:08.074500Z

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"?

2021-02-01T16:52:18.074600Z

actually, if the java code is being called from clojure, resolving *out* doesn't get the root binding, it gets the dynamic binding

2021-02-01T16:52:54.074800Z

as long as you didn't do something like call the Thread constructor and lose your binding

2021-02-01T16:54:04.075200Z

that's what the lein uberjar task does (along with packaging all those deps into one jar file)

2021-02-01T16:55:07.076Z

I wouldn't expect a jdbc specific jar to include all the adapters for the various dbs for example

borkdude 2021-02-01T16:56:09.076600Z

nice

mbarillier 2021-02-01T16:57:39.077700Z

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.

dpsutton 2021-02-01T17:00:19.078700Z

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

mbarillier 2021-02-01T17:01:59.080100Z

depending -- just trying to run some queries interactively in a clj scratch buffer

dpsutton 2021-02-01T17:02:42.080800Z

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

mbarillier 2021-02-01T17:04:25.081400Z

what's the proper way to add a java .jar to the runtime classpath?

dpsutton 2021-02-01T17:05:00.081700Z

a local jar or a jar that has coordinates on maven?

mbarillier 2021-02-01T17:06:27.083200Z

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

mbarillier 2021-02-01T17:09:05.084300Z

yeah, version's listed in maven central -- will give that a shot.

dpsutton 2021-02-01T17:09:45.085100Z

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

dpsutton 2021-02-01T17:11:56.086400Z

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

2021-02-01T17:18:05.087300Z

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

2021-02-01T17:18:41.087900Z

it reduces the complexity of every dev / CI setup, at the cost of being one more service to install and configure for global usage

2021-02-01T17:19:26.088500Z

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

dpsutton 2021-02-01T17:20:12.089100Z

that makes sense. my mind went to treating a local directory as the repo so it completely avoided all the benefits you were touting

2021-02-01T17:20:51.089800Z

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

2021-02-01T17:21:11.090100Z

(it still does dep resolution thankfully...)

p-himik 2021-02-01T17:29:13.090300Z

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

2021-02-01T17:43:12.090600Z

@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👍
2021-02-01T17:45:03.090900Z

yeah, clojail is a hack, a modern redo of 4clojure would likely be better off using a self hosted cljs in browser

2021-02-01T17:45:52.091100Z

though that leaves an opening for exploits where a "solution" does something unexpected when run in your browser

2021-02-01T18:21:58.091300Z

I mean, if someone wanted to make http://5clojure.com , I doubt anyone at http://4clojure.com is going to complain 🙂

2021-02-01T18:29:52.091500Z

since 4clojure uses clojure 1.4, maybe we are due for 11clojure

Ronny Li 2021-02-01T20:52:32.095100Z

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?

2021-02-01T20:53:52.096300Z

@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😮
2021-02-01T20:55:38.097200Z

but I've had decent luck with going down the list of hotspots until I find functions I wrote

Ronny Li 2021-02-01T20:56:33.097300Z

ah okay! I was going to ask if you use different tools for profiling in Clojure

Ronny Li 2021-02-01T20:56:56.097500Z

it sounds like you use something similar to visualvm but then you scroll down the hotspot list?

2021-02-01T20:57:44.097700Z

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

2021-02-01T20:57:58.097900Z

there are clojure specific profilers but I haven't used any of them in anger

2021-02-01T20:58:30.098200Z

https://github.com/hugoduncan/criterium

Ronny Li 2021-02-01T20:59:55.098500Z

Thank you!

2021-02-01T21:01:05.098700Z

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

2021-02-01T21:01:33.098900Z

also definitely turn on reflection and boxed math warnings

alexmiller 2021-02-01T21:13:00.099100Z

the https://github.com/clojure-goes-fast/clj-async-profiler flame graphs are pretty useful

1🙏
alexmiller 2021-02-01T21:13:22.099400Z

you are still fighting the same thing you're seeing in visualvm though

2021-02-01T21:58:43.099700Z

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🙏
2021-02-01T21:59:05.100Z

It might be useful for part of your case.