Fork me on GitHub
#clojure
<
2018-03-03
>
aaelony00:03:05

@dominicm maybe take a look at onyx or tesser libs?

dominicm08:03:24

I don't really need threading or anything like that. I just need a way to group a collection, which may be slow to produce, into batches of a defined size.

emccue00:03:35

Is there a performant way to try and wrangle a clojure object to a java class

emccue00:03:53

my current approach is using Jackson and cheshire and serializing through json

emccue00:03:49

But I cant help but feel like theirs a better option than basically going through a java version of JSON.parse(JSON.stringify(..))

tianshu03:03:17

maybe it's better for cli to provide a error message rather than throw a NullPointerException when there's no -main?

noisesmith04:03:15

@emccue everything in jvm clojure is an instance of some java class - what class do you need to create?

emccue04:03:26

POJOs from other parts of the codebase

greglook04:03:25

I would just write coercion functions. If you really want to get fancy, write a macro that loads the class, uses reflection, and writes your coercion functions for you.

emccue04:03:46

well I want that fancy version but without me doing any work

emccue04:03:10

The coercion functions wont work for the particular use case

noisesmith05:03:25

sadly clojure only makes it easy to create objects implementing a defined interface

noisesmith05:03:51

you coul use defprotocol to define the methods you want to implement then reify that protocol, but that's a little odd

emccue05:03:49

welp, jsonifying it is

kenrestivo08:03:12

smells like transducers to me

roti09:03:42

does array-map keep the insertion order of keys?

schmee11:03:10

does anyone know of a good collection of Clojure benchmark code?

schmee11:03:23

I want to experiment a bit with the compiler and I need a way to measure my results

Alex Miller (Clojure team)14:03:03

Andy Fingerhut has a repo with some fine grained benchmarks. Maybe too fine.

schmee14:03:00

perfect, thanks alex! 😄

triss16:03:41

is anyone aware of any writing about passing maps instead of single arguments in Clojure? I want to know when it is and isn’t a good idea.

sundarj18:03:10

only https://stuartsierra.com/2010/01/15/keyword-arguments-in-clojure, which is a little outdated because Clojure now has built-in support for keyword arguments

schmee17:03:54

I added a print statement to https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L3706 (InvokeExpr#emit) just to get an understanding of what’s going on

schmee17:03:02

now, at the repl, I see this:

user=> (defn foo [a b] (+ a b 3))
#'user/foo
user=> (foo 1 2)
fn -> EMIT name:user$eval8278 internal name:user$eval8278 thisName: null
6

schmee17:03:22

so code is getting emitted. my question is: where the heck does this bytecode end up?

schmee17:03:18

all bytecode has to be in some sort of class, right?

schmee17:03:51

looking at how the repl is defined in main.clj, I see this at the beginning of defn repl:

(let [cl (.getContextClassLoader (Thread/currentThread))]
    (.setContextClassLoader (Thread/currentThread) (clojure.lang.DynamicClassLoader. cl)))
I guess this might be a piece of the puzzle?

bronsa17:03:56

the bytecode is loaded straight into memory by the classloader

bronsa17:03:21

this is where it happens

chouser17:03:06

Who loves fragile unit tests? raises hand

bajrachar17:03:30

Is this a good way to implement prefix tries (for autocomplete for example) in clojure - https://gist.github.com/joelkuiper/a422cea41a26c9a3e2b35ac3abbb06f8

schmee17:03:04

@bronsa ahh, thanks! Is this bytecode the same as a class file, more or less?

bronsa17:03:18

exactly the same

bronsa17:03:29

except it just gets loaded into memory instead of being written to a file and loaded from it

schmee17:03:35

So when the class loader loads the class, it has to get "evaled" somehow? How do you know which method you're supposed to call on the resulting class?

bronsa17:03:24

the class is an IFn, the compiler invokes its invoke method

schmee17:03:36

Now it's clear, thanks a ton for putting up with my endless compiler questions :)

schmee17:03:07

I guess the class loading machinery has it's work cut out for it when dealing with Clojure... And I don't even want to think about the security implications of class loading 😂

schmee17:03:48

So basically, Java has runtime eval just like clojure, did not know 🙂

chouser17:03:11

@schmee The JVM does, yeah. The JVM is much more dynamic than the Java source language might lead you to believe.

bronsa17:03:14

classloading is how stuff like RMI is possible

schmee17:03:51

Java gets a lot of hate, but the more I dig into Java, the JVM, and Clojure the more impressed I get

emccue17:03:43

interjecting a little

schmee17:03:50

So much exciting stuff on the horizon: value types, vector api, pattern matching, graal... Good times for JVM langs!

emccue17:03:22

how do I give a type hint to clojure that a method on genclass returns a List of another class

emccue17:03:45

:methods [[get [] java.util.List]]

emccue17:03:59

its for gen-class

emccue18:03:04

so java can see it

bronsa18:03:04

generics are just a synctactic feature of java

emccue18:03:51

thats a bummer because I want to play nice with the java side of things

emccue18:03:38

There has to be SOME information i could give so my gen'ed classes dont just get seen as returning ungenerified lists

bronsa18:03:48

it will return List<Object>

emccue18:03:09

Which isnt really that helpful

bronsa18:03:32

¯\(ツ)

emccue19:03:50

Not making it easy to weasel clojure into my codebase

emccue19:03:58

Im also getting package ... does not exist error when compiling through maven

emccue19:03:28

using this library and the example config

emccue19:03:11

so uhh, if anyone hasnt been able to switch to leiningen

emccue19:03:25

help appreciated

dominicm19:03:22

Is there anything tying ClassLoader hierarchies and Clojure? I'm not interested in isolating clojure versions particularly, nor in total isolation, I want an actual hierarchy.

hiredman19:03:38

I am pretty sure it is all or nothing

hiredman19:03:40

the jvm really doesn't want two classes with the same name visible from the same place in the cassloader hierarchy, so to do things like pass clojure data around between runtimes you would still need to serialize and de-serialize which is as good a definition for isolation as there is

hiredman19:03:14

I put that name thing badly

hiredman19:03:22

what I mean is, runtime 1 won't be able to treat a PHM from runtime 2 as a PHM, but, depending on what you are doing it would likely recognize the PHM as a java.util.Map impl

dominicm19:03:17

@hiredman if they shared a clojure, that would be fine though right?

dominicm19:03:57

I'm not certain if that's even possible, but just as a possibility.

hiredman19:03:34

Then what is different between whatever you are proposing and just normally running Clojure?

seancorfield19:03:06

@emccue Not sure if it'll help your quest but all the Contrib libraries are built and tested with Maven at the moment so maybe look at the pom.xml files there?

hiredman19:03:29

If they share a Clojure runtime, they are the same clojure and there is no difference hierarchy or isolated or whatever

dominicm19:03:25

@hiredman I want to isolate some dependencies of a dependency.

hiredman19:03:33

Clojure names are globally visible within the Clojure runtime

hiredman20:03:44

And clojure code, unless explicitly written in a way to do otherwise, will all lookup classes the same way

emccue20:03:32

@seancorfield Thats helpful and ill look through some more of them now

emccue20:03:49

Ive gotten it to the point where calling mvn clojure:compile works fine, but It doesnt seem like its hooking in to the regular compile cycle

seancorfield20:03:44

The very little I know about Maven, I've learned from dealing with pom.xml files in the various Contrib libs that I maintain ¯\(ツ)

seancorfield20:03:35

@emccue Something else to look at would be the pom.xml generated by clj for a deps.edn project, but I'm not sure whether it generates a complete compile/test XML file for that...

zentrope20:03:42

Is there a way to unquote-splice a temp-var in a macro?

zentrope20:03:04

`(let [x# [:a :b :c]] ~@x#)  

sundarj20:03:05

x# in a syntax quote just generates a random symbol

sundarj20:03:15

user=> `x#
x__11__auto__
user=> `(x# x#)
(x__14__auto__ x__14__auto__)

zentrope20:03:09

Right. But I want to fill it with a list, then splice that into something else later.

zentrope20:03:39

I suppose the macro could just use an atom.

sundarj20:03:48

then you need to execute a let, not merely return one to be executed at runtime

zentrope20:03:39

I suppose I could have two macros, one computes the result-set, the other expands it as needed.

sundarj20:03:37

user=> (defmacro foo [] (let [x [1 2 3]] `(let [x# ~x] x#)))
#'user/foo
user=> (macroexpand-1 '(foo))
(clojure.core/let [x__168__auto__ [1 2 3]] x__168__auto__)
user=> (foo)
[1 2 3]

zentrope20:03:39

I think my error was wanting the macro to return multiple values, rather than a list of some sort.

zentrope20:03:44

Anyway, thanks!

emccue20:03:14

I feel like people who know less about maven live happier lives

dominicm20:03:01

@hiredman I see. That makes sense. A bit frustrating for me. My use case probably could work with a fully nested clojure, although the performance penalty might be a frustration. It's a shame I can't use shim dandy, as it's so interested in isolation.

dominicm20:03:47

@hiredman it might just be easier to use Mr. Anderson tbh

emccue20:03:09

how do I un-namespace a var in a macro

sundarj21:03:30

is the var a symbol? because then you can do

user=> (symbol (name 'foo/bar))
bar

emccue20:03:40

right now im getting com.NDA.factories/ProductGenerators

emccue20:03:00

I want to get out just ProductGenerators