Fork me on GitHub
#clojure
<
2019-10-15
>
kenny00:10:31

Oh, cool. I like that.

kenny00:10:49

Mind if I use that @ghadi?

ghadi00:10:08

Be my guest

ghadi00:10:03

It could use transients to go faster

danielcompton01:10:02

Is there a cleaner way of building up a stack of transducers where sometimes you want to disable some transducers?

(into []
      (apply 
       comp
       (remove nil?
               [(map inc)
                (when false
                  (map inc))]))
      (range 10))

vemv02:10:15

Possibly obvious one

(into []
      (apply
       comp
       (cond-> [(map inc)]
         false (conj (map inc))))
      (range 10))

👍 4
jaawerth03:10:36

(if false (map inc) identity) should do it. you could shorten it by defining a util function ala #(if %1 %2 identity)

hiredman03:10:45

I've used something analogous to cond for conditionally doing transducers stuff, it took a bunch of predicates and transducers and only called the reducing function if the predicate matched. That is conditional per item, instead of conditional upfront on the whole pipeline. And I don't entirely recall the implementation, it might have been tricky

Setzer2209:10:38

Hi all! I'm having trouble with setting up my mixed clojure/java project with leiningen. Is this the channel to ask this sort of stuff? 😅

Setzer2209:10:39

great! so the thing is, I've already followed the guide on https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md and I've been able to run/compile my project with lein javac, lein run and lein compile. However, when running lein uberjar, I get a bunch of errors about missing dependencies during the javac phase (note that it works when I run lein javac on its own). It looks as if during the uberjar phase dependencies were not available to the java compiler...

Setzer2209:10:36

nevermind... figured it out! I had my dependencies declared unde the :dev profile... 😅

duckie 4
schmee09:10:28

good ol’ rubber ducking, the solution to most problems 😄

borkdude13:10:25

I'm trying to AOT this file, but I'm getting a warning on .val being unresolved when I start lein repl: https://gist.github.com/borkdude/d85586985aa264431b3b10a794f97602

borkdude13:10:31

Not sure why. Any help would be appreciated.

bronsa13:10:52

is the double definition an attempt to forward-declare the class for the addVar type signature?

bronsa13:10:11

that won't work

borkdude13:10:24

what's the proper solution to that?

bronsa13:10:37

don't use genclass

borkdude13:10:53

you mean... write it in Java?

borkdude13:10:20

if I were to use tools.deps instead of lein, how would I compile the java, using a bash script I guess?

borkdude13:10:28

btw the code does work when calling from Java

bronsa13:10:11

lein must be doing something funky if that code compiles

bronsa13:10:38

[~]> cat test.clj
(ns test)
(gen-class :name test.C)
(gen-class :name test.C :methods [["m" [] test.C]])
[~]> clj
Clojure 1.10.1
user=> (compile 'test)
Unexpected error (ClassNotFoundException) macroexpanding gen-class at (test.clj:3:1).
test.C

borkdude13:10:48

I actually got this solution from stackoverflow and it was marked as the accepted answer https://stackoverflow.com/questions/29329798/clojure-gen-class-returning-own-class so maybe someone should comment there 😉

bronsa14:10:09

don't think I have a SO account unfortunately

bronsa14:10:08

I think it may work in lein cause lein adds the compile-path to the classpath

bronsa14:10:32

yeah that's it -- genclass does only AOT so that class in a normal clojure environment is not available during compilation of the next forms

bronsa14:10:41

https://clojure.atlassian.net/browse/CLJ-2343 would make that code compile on non-lein environments

bronsa14:10:55

but still you have the problem of the compiled class referring to the wrong in-memory one

bronsa14:10:12

if you did an AOT compilation phase and then loaded the code it would technically work

bronsa14:10:21

but that's a recipe for disaster

bronsa14:10:23

(you'd get around the reflection error by declaring the val field in the first genclass)

bronsa14:10:30

which probably "works" in lein right now

bronsa14:10:34

but by "works" I mean you're exploiting a shadowing bug during compilation in order to compile a correct artifact

bronsa14:10:56

it's super subtle and dangerous

bronsa14:10:24

this "shadowing during compilation" trick is precisely how deftype does forward declaration internally, except there it's guarded by the compiler and can't escape

bronsa14:10:37

while in this case you're doing it manually and leaving the declared instance around during compilation

borkdude14:10:01

hmmm thanks. I'll still go with Java 😉

bronsa14:10:54

but even if you manage to somehow compile that, you'll get into all sorts of weird scenarios

bronsa14:10:59

as you're seeing

borkdude14:10:22

yeah, I'll go the java route. thank you

bronsa14:10:06

TBH genclass could be extended to handle this scenario

bronsa14:10:26

deftype supports it

bronsa14:10:37

altho it requires quite a bit of ugly boilerplate during compilation (there's some double compilation involved)

borkdude14:10:25

genclass is pretty limited if it doesn't support this

borkdude14:10:53

mainly useful for creating an invokable main probably

bronsa14:10:00

genclass is not a very useful good construct IMO :)

bronsa14:10:57

usually takes longer to understand the correct incantation to do something than it takes to generate a proxy class in java manually

✔️ 4
borkdude14:10:21

lesson learned 🙂

octahedrion14:10:02

is anyone aware of a library that provides 'reverse destructuring` ? What I have in mind is something like this: (structure (range 8) [[[] []] []]) => [[[0 1] [2 3]] [4 5 6 7]]

dpsutton14:10:04

that's neat but i don't see any information conveying to put 2 in the first two vectors

octahedrion14:10:08

is takes a sequence and a data structure and returns the sequence conformed to the given structure

dpsutton14:10:51

so [[[0 1 2] [3 4]] [5 6 7]] also fits that shape?

octahedrion14:10:37

- @dpsutton true, I've assumed an even fit there

octahedrion14:10:54

- I guess there're many solutions

octahedrion14:10:05

another example:

octahedrion14:10:15

(structure (range 8) [[[] #{}] {}])
=> [[[0 1] #{3 2}] {4 5, 6 7}]

octahedrion14:10:50

and I imagine it could also be made to work with predicates like odd? etc too

dpsutton14:10:51

so that would error on (range 9)

octahedrion14:10:28

it would truncate I guess, or pad with nil

dpsutton14:10:26

you could look into meander. quite possible to do it there i think

octahedrion14:10:33

@dpsutton I didn't know about Meander - thanks!

👍 4
Jimmy Miller20:10:45

Feel free to join #meander if you have any questions.

dpsutton20:10:33

also a great talk about motivations and some use cases from strange loop (https://www.youtube.com/watch?v=9fhnJpCgtUw). given by @U5K8NTHEZ here

😁 4
Jakub Holý (HolyJak)15:10:17

Hi! Is there a better way to get the max of a collection of Comparable elements than Collections/max (which sadly fails on empty cols)? Thank you!

andy.fingerhut15:10:17

Kinda depends on what value you expect to get back when you give it an empty collection, yes? The medley function linked returns nil. Some people might expect Double/NEGATIVE_INFINITY

Jakub Holý (HolyJak)15:10:35

Neg infinity only makes sense of the elements are numbers :) Nil is ideal. Thanks Jan, but I'd prefer not to add a lib for this...

vlaaad15:10:34

You can just copy a function

👍 4
lilactown18:10:41

is there a way to tell slurp / input-stream not to follow 302 redirects?

lilactown18:10:52

w.r.t. http calls

noisesmith19:10:18

I'd use the underlying JVM API via interop or a proper http lib, I am sure it's not an explicitly supported option

bfabry19:10:40

clj-http would make that pretty easy

4
bfabry19:10:00

(http/get "" :redirect-strategy :none) appears to be the thing

lilactown19:10:27

cool. the clj-tagsoup lib I’m using uses slurp under the hood I think, but I’ll just do the fetching myself and pass it as a string I guess

Alex Miller (Clojure team)19:10:03

ouch, someone fix clj-tagsoup if it depends on slurp

noisesmith19:10:02

maybe you could also get an inputstream from a proper http lib and slurp would do the right thing with that, but agreed, building on slurp is weird

dpsutton19:10:43

i don't see slurp in that lib

dpsutton19:10:54

@noisesmith is that last committer

noisesmith19:10:00

haha, honestly I forgot I contributed to that project - I was fixing a bug at work and passed the fix back upstream

noisesmith19:10:30

I should have changed that try/catch into with-open while I was at it

Ivan Fedorov20:10:09

hey) do we know of a project to generate wieldy java classes from namespaces? just a facading proxy java class with all static members. I know about implementing interfaces, so I’m asking specifically on this code gen.

borkdude20:10:23

@ognivo what about :gen-class?

Ivan Fedorov21:10:15

I’m sorry, I mean java sources generation

cfleming20:10:22

If I want to try to load a namespace and catch an exception if it’s not available, which is the best exception to catch? FileNotFoundException?

borkdude20:10:21

reminds me of:

user=> (requiring-resolve 'foo/bar)
Execution error (FileNotFoundException) at user/eval166 (REPL:1).

borkdude20:10:44

or just require for that matter.

borkdude20:10:31

CLJS seems to throw an ExceptionInfo

cfleming20:10:46

Yes, I only care about Clojure in this case.

cfleming20:10:22

If I (require 'foo.bar) I get FNFE, but I wasn’t sure if that was always the case - there are a lot of paths there.

Ivan Fedorov21:10:15

I’m sorry, I mean java sources generation

noisesmith21:10:36

clojure doesn't do java code gen - I sure somebody has a lib out there somewhere that does it, but clojure generates jvm byte code directly

borkdude21:10:16

horrible idea: pass the clojure code through the ClojureScript compiler and then squint really hard because JavaScript is almost Java 😛

😄 4
borkdude21:10:28

@sogaiu haven't check it out, but will now