Fork me on GitHub

what exactly does seasel/piggieback add? looking at github, they seem to do sxomething to nrepl, but I can't figure out what


isn't piggieback the thing that lets a cljs repl take over your clj nrepl session?


or was that weasel? maybe weasel uses piggieback?


OK yeah - just refreshed my memory, piggieback is the part that latches onto an nrepl with your cljs, weasel is the part that makes the cljs eval in the browser


so if I am just doingpure clj nrepl, I can ditch both piggieback & weasel from my dependencies ?


@noisesmith : alright, removing the two works; thanks for the clarification



openssl genrsa -aes128 -out auth_privkey.pem 2048
You should probably use something stronger than -aes128. You’ll need to fiddle with your JVM, but might be worth it unless it’s important for you that your government agencies have access to decrypting your token signatures.
In this case, what algorithm should be used besides aes128 ?


Hi, I have a macro question. I’m trying to have a macro generate some defrecords based on some values passed from an array I have something like the following

(defmacro testmac3
  `(do [email protected](map makerecsimple ss)))
Where makerecsimple returns (defrecord <RecordName> [a]) I can’t figure out how to get the syntax quoting working properly. In the code above ss is a list of strings. When I run it as is, I get a CompilerException java.lang.IllegalArgumentException: Don’t know how to create ISeq from: clojure.lang.Symbol, which appears to be due to the list not being evaluated. If I remove the @, and just unquote the list with ss, then the macro returns a list of (defrecord) statements but doesn’t evaluate them. any suggestions?


so I assume makerecsimple is another macro?


no, it can't be, or you'd get an error


needs to be a function


since it's passed to map


works here

+user=> (defn makerecsimple [s] `(defrecord ~s [~'a]))
+user=> (makerecsimple 'foo)
(clojure.core/defrecord foo [a])
+user=> (defmacro testmac3 [ss] `(do [email protected](map makerecsimple ss)))
+user=> (macroexpand-1 '(testmac3 [foo bar baz]))
(do (clojure.core/defrecord foo [a]) (clojure.core/defrecord bar [a]) (clojure.core/defrecord baz [a]))
+user=> (testmac3 [foo bar baz])
+user=> (foo. 1){:a 1}
+user=> (bar. 1){:a 1}
+user=> (baz. 1)
#user.baz{:a 1}


noisesmith: ah crap I forgot to mention that yes it works fine with a ‘literal’ list or vector. The problem arises when i have something like

(def mylist ["A" "B" "C"])
(testmac mylist)
HEre’s the full code almost exactly identical to yours
(defn makerecsimple
  (let [name (symbol tag)]
    `(defrecord ~name [~'a])))

(defmacro testmac3
  `(do [email protected](map makerecsimple ss)))
So yes (testmac3 ["A" "B" "C"]) works perfectly but (testmac3 mylist) creates the IllegalArgumentException Don’t know how to create ISeq from: clojure.lang.Symbol error presumably as mylist is what’s being passed to map as opposed to the actual list it represents


yes, this is an issue with macros, fundamentally


they don't work on runtime data, they work with literal input


@eoliphant I just did literally what you described, and the code works


I'm facing a strange issue, it could be with my setup, but I'm trying to call clojure from Java using the I get a var unbound exception, but the thing is, my code works if I run it from a unit test. But the way I have it setup it prod is that it runs from Spring, with MethodInvokingFactoryBean. Anyone knows if there would be something with having Spring call in to require a var that maybe its too early it the startup and something isn't working right?


@didibus are you calling require before accessing the var?


with unit testing I could easily imagine a scenario where some other code caused the ns to be required


Ya I am. ITs quite strange. I have a java static that requires the namespace, and than gets the var and calls it.


If I call it from a test, the method works. But from Spring, it does not


what var comes back as unbound - does it come directly from the namespace you require?


Its a method


wait, a method?


I mean function


getting confused with the back and forth with Java lol


so you resolve require, call it to require ns, resolve the function, call it


sometimes the function comes back as unbound?


is there possibly a code path that resolves the function before the require is done?


I have a Java static method which gets require var from clojure.core, and then uses it to require a Clojure namespace. I then get a var from that namespace and when I invoke it, I get the unbound exception


because require shouldn't return until all applicable vars are bound


Hum, well, its not sometime, its always. When my app start, it does with spring, and spring calls my method which does the clojure interop.


unless there's something bad like a defn inside a defn and the outer one didn't get called


But in a unit test, a java unit test, f I call that same java method, it works


what if you put a log at the top level of the file, at the bottom, to verify whether the message is logged before the unbound exception?


The namespace you mean?


the clojure namespace?


Ya, I'll try that


if the var just didn't exist, you'd get NPE - to get an unresolved var it would have to be declared but not have a value yet...


which is super weird


Ya, this normally happens if you forget to require the namespace, but I definitely am. I'm wondering if its something to do with Spring and the way its invoking that Java static method


Which could interfere


no no not requiring the namespace can't do that


an unbound exception is weird


you just get an NPE if the resolve fails


resolving and getting unbound is another thing entirely, there's very few ways to get that state


"java.lang.IllegalStateException: Attempting to call unbound fn"


right, you need declare to get that


or a defn that is inside another defn that didn't get called


or a defn just got called before it finished running...


or someone created a var using the clojure.lang.Var constructor but never gave it a value


but you should be using resolve, so that wouldn't happen


(if you aren't using resolve, fix that)


Wait, resolve?


oh never mind, with interop you call Clojure.var instead


I misremembered


Thats my clojure


So if I have Spring call initClojure when m app starts, it gives the unbound exception. If I call initClojure from a test, it works.


OK - reading the source for calling it's var method can give you an unbound var


if the var doesn't exist yet


wait, why are you using a one segment namespace?


that is wrong and bad


I don't know that this is causing your problem, but I also don't know that it isn't...


single segment namespaces cause weird bugs


I'm not, but its like work code, so I just replaced all identifiable things by test, sorry


If it wasn't work, I would be doing 100% Clojure 😛


another thing is you could try finding all-ns and seeing if your ns is in the result


and calling ns-publics on your ns symbol to see if the function is actually in there


these would be debugging tactics, since I really don't know what would be breaking that code


I'll try your suggestions and keep digging, thanks for the help


@didibus Given that you're calling this via Spring as a static function at startup, I wonder if this is because Clojure's runtime isn't being properly initialized at startup?


When you can it via a test, Clojure's runtime will have been initialized prior to that...


I call Class.forName("");


A stackoverflow post from Alex Miller mentioned that's the new way to make sure the runtime is initialized


I know that my build does AOT compilation, I wonder if this could be part of it. Is compatible with AOT compilation?


Yup, that rings a bell. I remember there being a special way to bootstrap Clojure.


@didibus are you sure you need to aot compile? in my experience avoiding it tends to reduce a lot of complexity


We certainly had some problems getting AOT-compiled Clojure loaded. We had to isolate the things that specifically needed AOT compilation and leave the rest as source.


AOT compilation = bad in general.


Hum, I'm not sure I need too. We've got custom build tools, and its just the way things integrate with it. I never looked into seeing if I could change that


If you're AOT-compiling, you need to package that as JAR files specifically and ensure those are on your classpath directly (and you'll probably need to something specific to "load" each compiled class). Way more complex than just having the source on your classpath and loading it via the Clojure API...


Prior to this, we'd always relied on gen-class for interop


I'd say treat AOT-compilation as regular compiled (Java) code and interact with it via native interop. The Clojure API feels like it's designed to interact with compile-on-demand source code...


Right, I could go back to that. I was trying out the Clojure API, as I felt it was simpler, but gen-class has worked for me perfectly in the past


How would I not do AOT compilation? So, we use clojure to compile. We have an ant script that does it using Clojure. What would I do instead, I'd just copy my src to the build folder? Wouldn't I still need to package them inside a jar, I'm confused.


Most Clojure code is packaged as source JARs.


Why would you AOT anything?


I guess gen-class needs AOT. But my question was more, if I dont compile clojure, I just need to package its src in a jar and put that on my classpath?


usually I use lein uberjar for this


I'll have to use ANT unfortunatly, to integrate with my company build infrastructure


But ok, I find its almost too simple lol


not even having to compile, the build step seems like it barely does anything


yeah, it's just a packaging step


One question, can you mix AOT compiled jars with non aot compiled? Say I depend on 2 libs, both are in jars on my classpath, one contains compiled clojure .class files, the other clojure source files. Is that ok?


We don't AOT compile anything.


We previously used Ant to call Leiningen to deal with Clojure. We've replaced all of that with Boot these days.


When running a war, it is obvious where the resourdces directory comes from. When running directly in a repl, how dc I figure out (or better yet, set) where the resources directory is?


I'm assuming at a minimum the main clojure namespace must be compiled, so that it can bootstrap the gen-class which has main on it?


Thanks, I'll read it.


BTW, problem solved. Nothing to do with Clojure, just deployment issues, somehow I kept getting an old clojure source that actually was missing the var inside of it


Is there a simple way to test if a float, Ratio or Integer is equal to 1?


(= 1 1.0) -> false


(= 1N 1.0) -> false


oh I see. We have ==


noisesmith: ah crap I forgot to mention that yes it works fine with a ‘literal’ list or vector. The problem arises when i have something like

(def mylist ["A" "B" "C"])
(testmac mylist)
HEre’s the full code almost exactly identical to yours
(defn makerecsimple
  (let [name (symbol tag)]
    `(defrecord ~name [~'a])))

(defmacro testmac3
  `(do [email protected](map makerecsimple ss)))
So yes (testmac3 ["A" "B" "C"]) works perfectly but (testmac3 mylist) creates the IllegalArgumentException Don’t know how to create ISeq from: clojure.lang.Symbol error presumably as mylist is what’s being passed to map as opposed to the actual list it represents


is there a simple way to make a spec that only accepts one particular value? E.g. '(spec/def ::42 (spec/of 42))' only accepts the value 42 and has a generator just repeating 42 over and over


Ok I got it to work in both cases by doing the following, but it just feels weird lol

(defmacro testmac3
  `(do [email protected](map makerecsimple (eval ss))))


Any advise regarding selecting web server with NIO. At present I have used ring and compojure deployed as uberwar to Jetty running on Azure web app. However my other colleague swears by nodejs for its NIO and future scalability. Is NIO is really that crucial or you can configure Jetty to be as performance.


node doesn't perform as well as java does... it absolutely needs to use nonblocking IO because it doesn't do threads


but if you find you need a non blocking IO based ring server, you can switch to aleph


I thought spec/unform was supposed to be the inverse of spec/conform. Then why does

(spec/def ::i (spec/coll-of (spec/or :i int?)))
(spec/unform ::i (spec/conform ::i [1]))
yield [[:i 1]]?


I was reading on aleph and yada which looks promising. I have not found a way yet how to deploy to Azure we app. At present only Jetty or Tomcat.


deployment with an uberjar consists of making the uberjar then making sure you have java installed on the server


you don't actually need one of those java container server things


(I actually use the apache commons daemon, the unix port is called jsvc but there's also a windows version - but it's not neccessary)


That's interesting. Usually I was worried about keeping it running. But as I rethink, Azure worker service is already there to manage the java process. I should give it a try.


right, this is what jsvc does


it hooks into whatever native features exist to keep a process running / restart on reboot etc.


Anyway, I am really curious is it really important? So far I have not faced much issue. But again I lack much experience about these.


with higher loads async io handlers can help, but they are neither neccessary nor sufficient


async is a really big deal when you only have on thread though


but we don't have that problem


Curious about @seancorfield's experience here. > AOT compilation = bad in general.


I've used it for one smallish standalone app and it worked exactly as expected.


it has very few benefits, and introduces sources of bugs that don't otherwise exist


even with jsvc, I used a shim approach to minimize AOT to a single namespace (since jsvc needs to be able to find a class on startup)


Speed of of startup was the reason I used it. I'm genuinely not sure what the speedup is though. Wasn't exactly rigorous about the decision to use it


What is the approach to background processing in Clojure? Is there something like Sidekiq from Ruby world?


typically you can just use a ScheduledThreadPoolExecutor


or one of the various wrappers like quartzite


I use a stpe - it's an easy thing to use via interop


I've looked at quartzite and if I understood correctly it doesn't provide persistent queue


you want persistent over restarts of the vm?


if so, use a db for the queue


yes, I need persistence between restarts


durable-queue is great for this kind of things


so I need to implement it on my own?


I have a table that represents the scheduled tasks, including last run time etc.


there might be something decent, I haven't really looked, sorry


Well depends on the use case


yeah - for me disk backed doesn't cut it because we have N servers and any one of the machines might disappear at any moment


so I need a db


@tokenvolt oh, my mistake - quartzite which I mentioned above does support a queue that persists across restarts of the vm


so I would just go with that


hm, good news, I'll check it


@mpenet What is this durable queue of which you speak?


You don't happen to know of somebody building an SQS-compatible dev service on that?^ We use elasticmq and it currently drops everything across restarts, which is a bit of a hassle for us.


kafka is a durable queue - it has a configurable backlog you can rewind and read through


Yeah, really just want something that re-implements SQS semantics.


Don't really care what's backing it I guess 🙂


Yes that lib from factual/ztellman. Super userful/reliable, highly recommended if that fits your use case


(deftask build-jar []
   (aot :all true) 
   (jar :main '
        :file "uberjar.jar")
   (target :dir #{"output"})))
when I do "java uberjar.jar" does it try to run ? if not, what does it try to run ?


You mean java -jar output/uberjar.jar? Yes, I believe it will run We generally omit :main and specify -m when we run the JAR file. That runs the main Clojure entry point and tells it to then run the -main in the namespace specified via -m — which lets us have multiple -main functions (in different namespaces) in a single uber-jar file (convenient for bundling a whole series of cron tasks into one JAR, for example).


you can also do that with java -cp uber.jar clojure.main -m ..., overriding the jar's main


The XY problem is that (1) I am deploying to elastic beanstalk and (2) it's not calling my main function, and (3) I haven't figured out how to get the logs in a useful manner.


java -jar output/uberjar.jar Error: Could not find or load main class


do I need an AOT flag ; no wait, I have (aot :all true) already


figured out the problem; apparently I need a (:gen-class) on the main 'entry point for clj' file


if you aot everything why would you need gen-class? asking 'cause i don't know.


I don't know eiehter.


but adding a (;gen-class) made it go from not working to working.


even with aot, you don't create a .main method on your class, so yeah, you need gen-class


or to point the server at clojure, and tell clojure which ns to run


(the above java -cp snippet)


I guess there are other ways to make something with a main method? reify or proxy or whatever


i thought (defn -main ... ) would take care of that. no?


I really wish this was slightly better documented, I still don't understand -main :gen-class or :aot fully


defn creates a class that implements IFn with an invoke method


it doesn't create a method of that name


aot just runs the clojure compiler and writes class files to disk, it doesn't create classes from namespaces or methods from functions


so, nothing special about defn -main? (i'm going by stuff like


not without gen-class no


gen-class is the thingy that makes classes out of namespaces and methods out of defns


oops, never mind. read further in the article and saw gen-class. what's the icon for embarrassment?


(i must say i'm with @qqq, this needs mo' betta docs.)


well, doc for defn leads to fn which links to this which is pretty clear about what it creates


sure, we can also read the source, haha. 😉


so what's your alternative?


noisesmith: someday, maybe, i hope, i'll find the time to put my money where my mouth is and write some good docs regarding gen-class, aot, etc. until then i can only kvetch and hope somebody else will beat me to it. :)


noisesmith: i'm fine with reading the source, but a good high level explanation would have saved me mountains of time and effort, that's all.


yeah. the prob (as i see it) is that is already takes a huge amount of knowledge to even begin to grok that page. i think we need sth better, esp. wrt gen-class, which routinely gets beaten up for no goid reason i can see.


look at it this way: neither @qqq nor i just fell off the tomato truck. yet we both have had to put in an inordinate amount of work to understand aot, gen-class, etc. that's a problem, imo.


it's beaten up for good reasons - relying on aot compilation (which gen-class requires) leads to all sorts of avoidable problems


oy vey. gen-class is no different than any other construct - use it correctly and it solves your problems; use it incorrectly, not so much. there is absolutely nothing wrong with gen-class per se, akaics.


that's a documentation problem.


maybe it would be more accurate to say: aot must be used corrctly.


i personally have never had a problem with aot/gen-class, maybe that's why i don't understsnd the complaints.


among other problems it leads to errors caused by cached byte code on disk, code that is broken and you won't know it's bad even after a namespace reload; you only see the breakage after a full clean of class files from disk and process restart; those cache based errors will cause nonsense stack traces in irrelevant places that aren't related to the root problem. Aot compiling code leads to bizarre Foo cannot be cast to Foo errors if you use protocols, records, deftype.


that's off the top of my head


There's a few ways to address this. Learn all the counter intuitive ways it breaks and what the misleading messages actually mean; treating clojure as a non-reloadable language and do a clean of disk cache and restart of the repl after each change; or simply not using aot. The last option is a lot simpler.


@noisesmith : I don't think the argument is "make gen-class easy to use so everyone will use it", but rather: if you want to deploy on GAE or ElasticBeanStalk or Tomcat, you WILL have to gen-class at some point -- and if it's better documented, alot of pain could be saved there. 🙂


are we talking :aot all? in my use cases i only needed to aot the file that contains my gen-class. i've not run into those kinds of problems.


gen-class needs aot, why would one need to aot anything else?


fwiw i never put implementation code in a gen-class ns. everything gets delegated to the :impl-ns. so e.g. "cached byte code on disk" problems never occur.


to me what gen-class is all about is delegation.


aot is recursive


aot in a specific class always aot compiles every class it requires


@qqq more generally: if your runtime involves a container which will be asked to load something, and it is designed to look for that something on disk, then u need gen-class. but you do not need to implement your stuff in gen-class.


@noisesmith no. that is easily overcome. i don't have the code at hand, alas, but it is easy to aot a single file without aoting its deps.


by using thedeps indirectly via runtime require and runtime resolve yes


Hi, I have a question about (deftype). I’m sending some stuff off to Kafka and using the franzy lib. For testing, I was initially using the simple string serializers which worked fine, but I’m having trouble using the ones that come with the library, there’s for instance a KeywordSerializer that’s clojure-aware The issue is that in a snippet like the following

(let [pc {:bootstrap.servers (-> env :kafka :bootstrap.servers)
            :retries           1
            :batch.size        16384
            :         1
            :buffer.memory     33554432}
        key-serializer (serializers/edn-serializer)
        value-serializer (serializers/string-serializer)
string-serializer works fine, edn-serializer does not, it fails with a class not found for the EdnSerializer class which is defined by franzy. In looking at the source and playing with this, the string-serializer and others that map directy to those provided by kafka work fine. The EdnSerializer is defined by the library
(deftype EdnSerializer [opts]
  (configure [_ _ _])
  (serialize [_ _ data]
    ;;TODO: process + inject more options? better defaults via configure or opts?
    ;;no reason to close bos, but we do so to keep clean
    (with-open [bos (ByteArrayOutputStream. 1024)]
      (with-open [w (if opts ( bos opts) ( bos))]
        (binding [*print-length* false
                  *out* w]
          (pr data)))
      ;;death to efficiency, but easiest way without writing something low-level to encode a stream directly into Kafka
      (.toByteArray bos)))
  (close [_]))

(defn edn-serializer
  (^EdnSerializer [] (edn-serializer nil))
  (^EdnSerializer [opts]
   (EdnSerializer. opts)))
What I think is happening is that the (deftype EdnSerializer …) isn’t being evaluated when I require the namespace that contains it, but I’m not sure what I’m supposed to do to address this. edn-serializer is accessible in my namespace but the EdnSerializer type blows up when it’s executed


What’s the error?


ah nvm. It worked fine in the repl, so kept digging. looks like I need to have it :aot in the project config


though based on other stuff I’ve seen here, wondering if that’s going to cause other issues


if you need aot you need aot, it makes things more complicated and introduces new kinds of errors but it can be managed...


So is this something that can be avoided via doing something differntly in the library, etc? Like I said, after I posted, tried it in the repl, worked fine. Adding :aot :all to my dev config to see if that works


ugh, yeah so according to HLS’ note here, I need to add :aot :all but I’m not sure where… would it go in my lein :profiles. Just tried it in my :dev config and now other stuff is blowing up NoClassDefFoundError etc, exceptions when I do a lein run


In clojure (or functional programming in general), how do you solve problems where in an imperative language you'd set a flag? If in the process of doing something to a collection, you discover that something will have to be done after? With an imperative language I'd set a flag and put an if statement after the loop.


Do you have an example? @urbank typically the functional approach is say creating a new collection based on a functional transformation of the original. So something like newcoll = checksomething(oldcoll)


where newcoll is what you’d want to do something with based on your ‘flag’ in the imperative world


eoliphant: Hmm... sorry, but I'm not quite clear on what checksomething does/returns. For some reason I'm having difficulty interpreting this sentence: > where newcoll is what you’d want to do something with based on your ‘flag’ in the imperative world As for an example: I'm running reduce over some state to do a transformation, but if this transformation results in let's say nilfor one of the key value pairs, I have to do some other action after the reduce. I suppose one way would be to reduce over a tuple, where one element is the state I'm changing, and the other holds the equivalent of a flag. But that's perhaps too literal a mapping from the imperative version. Or maybe not.


sorry if it wasn’t clear. checksomething could be a filter, etc. hmm, well a reduction is going from many to one, so there’d be no nil for a specific entry per-se. your ‘reducer’ would just need to handle these cases based on your requrements. You might want to say ‘prefilter’ the collection to look for these ‘bad’ cases, then apply the reduce to the ‘good’ collection, etc In the simplest case, I guess you just ignore the bad ones. If you actually need to take action, then you can use a filtered ‘bad’ collection and act on that.


Having a tuple, or even a hash full of state values in an accumulator in reduce is petty normal


true enough the ‘one’ can be some aggregate


in fact, it's so common that transduce even expects your function to support a arity 1, which gets your actual final state out of your accumulator


A prefilter works a lot of the time, but I think I have a case where a tuple/hashmap in the reduce would be a better solution


when I run "java -jar foobar.jar" where does the resource "/" correspond to? is it the root of the di4rectory when I unzio foobar.jar ?


it's the classpath


which follows the structure of the jar, yes, but also can be manipulated by arguments to the java command or by environment settings etc.


(wrap-resource ... "public") ;; works in repl, works in jar (wrap-resource ... "/public/") ;; works in repl, fails in jar


oh - I think I misremembered about leading slashes - I don't know what they would indicate actually


leading slash roots it to the ‘top’ of the classpath. “public” alone is relative to the location where it’s being referenced, generally speaking. Now having said that functions/methods may do some other interpretation internally



+user=> (io/resource "clojure/core.clj")
#object[ 0x115667d "jar:file:/home/justin/bin/bench!/clojure/core.clj"]
+user=> (io/resource "/clojure/core.clj")


with a classpath, what is "the location it is being referenced" ?


i always use the leading slash to avoid any ambiguity. I beieve that the first would get resolved to <current package/namespace>/clojure/core.clj


namespaces aren't parts of the classpath


can you show me an example of resolving something that starts with / ?


fair enough, I’m newer to clojure lol. But from a ‘pure’ JVM/Java perspective, thats the usual behavior


and I thought io/resource was just a thin wrapper around


the relatve Java/JVM api


it is - I'm asking an honest question


because clearly a couple things I thought I knew about this are wrong


ok actualy ugh.. I’m looking at some code I just wrote.. I created a clojure wrapper that would parse Avro .idl files


(defn parse-protocol-idl
  "Parse an avro protocol inputstream"
  (with-open [stream (io/input-stream (io/resource protocol-res))]
    (let [idl (Idl. stream)
          protocol (.CompilationUnit idl)]
But I called it like this:
(avroprot/parse-protocol-idl "BOOT-INF/classes/authorization.avdl")
and it works fine. Ah.. hmm, if it calls getSystemResource then it would start at the classloader root, and that should work..


that's not a leading slash though


yeah but by attempting to use the Context or System classloader then it works


just looking at the source


(defn ^URL resource
  "Returns the URL for a named resource. Use the context class loader
   if no loader is specified."
  {:added "1.2"}
  ([n] (resource n (.getContextClassLoader (Thread/currentThread))))
  ([n ^ClassLoader loader] (.getResource loader n)))


ok that makes more sense now, by using the contextclassloader, that ‘roots’ it though im not sure how to explain qqq’s issue based on what we see here


so is there any context where using a leading / on the resource would find what I'm looking for?


i need to play with it, but based on the way io/resource is defined, not sure why leading slash wouldn’t work


that's funny because I can't seem to get a string with a leading slash to find anything


leading slash means it’s absolute, but the contextclassloader unless there’s some custom behavior or something should also ‘start’ at the root so an unquaified path should start there as well


yeah i’m going to modifiy the code i have


to see if it works


I need to learn a lot more about classloaders and such...


they are a PITA lol


especially once you start doing servlet containers, etc


modularity's so often a mess isn't it


OSGI etc was a clunky attempt to clean it up, now the modules, etc in Java 9 are supposed to help. But it’s apparently a huge point of contention among the spec leads


yeah, java 9 looks like it'll be a huge problem for clojure


and even more so the tooling, leiningen in particular


yeah i think in the long run it will be helpful, but the impact to existing tooling etc may be a pain


sorry if it wasn’t clear. checksomething could be a filter, etc. hmm, well a reduction is going from many to one, so there’d be no nil for a specific entry per-se. your ‘reducer’ would just need to handle these cases based on your requrements. You might want to say ‘prefilter’ the collection to look for these ‘bad’ cases, then apply the reduce to the ‘good’ collection, etc In the simplest case, I guess you just ignore the bad ones. If you actually need to take action, then you can use a filtered ‘bad’ collection and act on that.

Alex Miller (Clojure team)22:06:39

@noisesmith I don't see Java 9 as a huge problem at all

Alex Miller (Clojure team)22:06:23

There are some minor things to smooth over but they don't seem like a big deal