Fork me on GitHub
#clojure
<
2018-08-08
>
richiardiandrea05:08:46

Is there any Jira about having conditional requires as a feature? Like configurable conditional reader features. I have some place where it could be really handy and cleaner so that I do not pollute the code with namespaces I do not want at compile time

john14:08:20

I did this with reader tagged literals #my/require-if (pred (:req... foo) (:req... bar))

john14:08:57

Then used closure-defines to signal whether I'm pulling deps from a module based dep graph or a monolithically compiled project.

john14:08:43

if closure-defines contains :modular true then instead require the namespaces that lazily load modules as necessary.

john14:08:40

I think using a macro directly would mess with the ns declaration validation

john14:08:21

But maybe not... I didn't test that method

john15:08:01

Oh, and sorry all that module talk was about the CLJS side 😆

richiardiandrea15:08:31

Soooo wirst of all great thank you! Is this working only with modules? Finally I am using shadow, are you using the vanilla compiler?

john17:08:21

Vanilla CLJS

richiardiandrea17:08:18

I wonder if @U05224H0W can confirm or deny this approach is working in shadow-cljs as well

john17:08:20

Doesn't matter whether your using modules or not, but modules are what made this compile-time thing necessary for me.

john17:08:09

in co.edn I've got a :closure-defines {my.conf/modular true}. In data_readers.cljc I've got {if/mod mod-base.macros/if-mod} and in mod-base.macros I've got:

(defn if-env [[if-str? then? else?]]
  (if (-> env/*compiler* deref :options :closure-defines (get if-str?))
    then?
    else?))

(defn if-mod [[then? else?]]
  (if-env
    ["my.conf.modular"
     then?
     else?]))

thheller17:08:46

and no there is no JIRA ticket about this. there was a "discussion" a while ago but that never went anywhere either. https://groups.google.com/d/msg/clojure-dev/8YJJM8lJuQs/hR5_vUZPCQAJ

john17:08:41

Then the namespace declaration goes:

#if/mod
[(ns mod-one.lazy
   (:require-macros [mod-base.macros :refer [defxmod]]))
 (ns mod-one.lazy
   (:require-macros [mod-base.macros :refer [defxmod]])
   (:require [mod-one.main :as main]))]

john17:08:57

probably not the cleanest way to structure it

john17:08:01

But it works

richiardiandrea18:08:02

that feature is awesome @U05224H0W that's exactly what I need

richiardiandrea18:08:07

but props to @U050PJ2EU and thanks for coming up with this very creating way of doing it!

richiardiandrea18:08:41

I think you should write a blog post (or delegate to someone who is willing to write it...like me :D) that compares the two solutions

john18:08:10

By all means! I think it's moreorless an accident that it works. There's probably a lot of other tricks waiting to be found down that road. But in cases where a macro could instead be used, that probably makes more sense.

john18:08:41

That'd be awesome if you wrote up a blog post about it. I'm slacking on my blogging. Gotta get another static site up on a gh-pages.

john18:08:34

I was using medium but their policies seem egregious now days.

richiardiandrea18:08:54

if you let me, I think I have some time this weekend to put it up

richiardiandrea18:08:08

and it is a controversial one so probably worth writing 😄

john18:08:14

Should be fun! 🙂 lemme know if you want help reviewing it. Making an if-node version should be pretty easy if it can be pulled out of the compiler env

puzzler06:08:40

I'm looking through some Clojure code that has been decompiled to Java, looking for places to make performance improvements. I can't figure out how Clojure decides whether to call a function by its invoke or invokeStatic method. Can someone point me to an explanation of how this works? Thanks.

Alex Miller (Clojure team)12:08:27

invokeStatic is used when aot compiling with direct linking. invoke is used otherwise (more common)

Alex Miller (Clojure team)12:08:36

https://clojure.org/reference/compilation is probably the only place I can think of with docs about direct linking

ammazza07:08:49

G'day I have a doubt about transducers style. Let me start with a silly example:

ammazza07:08:20

So silly-transducer1 needs to be a function that returns a transducer, to capture the extra parameter n. What about silly-transducer2? I could save 1 level of nesting, having directly (silly-transducer2 [rf] ... but then users would have to pay attention to the different way of using them. Is there a style rule about this?

miikka08:08:39

@ammazza I haven't heard anybody give rules about this, but I'd make silly-transducer2 a function for consistency.

👍 4
ammazza08:08:15

Thanks @miikka. In the meantime I also found another reason for being consistent. The outermost wrapper can be used as in clojure/core to provide a Version that, if given a collection, applies the transducer to build a lazy seq. An example is dedupe https://github.com/clojure/clojure/blob/clojure-1.9.0/src/clj/clojure/core.clj#L7575

isaac11:08:06

there has an bug on core.async --- writing still blocked even if chan closed!

hjrnunes11:08:16

I need to inject a var from project.clj to be available during compile-time. Any ideas?

puzzler12:08:58

Is there a way at run-time to discover the return type tag, if any, on a function?

Alex Miller (Clojure team)13:08:14

what problem are you actually trying to solve?

puzzler13:08:09

I'm trying to write a library where the user supplies a function that can either return a double or an implementation of a protocol. It's very performance-sensitive, so some of the more dynamic ways I've tried to address this were too slow, so I was hoping to do some analysis of the function they supply ahead of time, and wrap it in the appropriate wrapper. Possibly I can see if it implements OODOD or vs OODOO or whatever the distinction is. That's the kind of thing I was thinking of. I'll continue to benchmark some other options too.

puzzler13:08:00

Speaking of which, is there any way in Clojure to make calling an interface method defined via definterface similar to the way you call protocol functions defined via defprotocol? I really need primitive return types on some of the functions so can't use protocols for those (at least, that's my understanding that there's no way to provide primitive type hints on a protocol), but I fear that if my library requires a mixture of implementing and calling interfaces and protocols, some with imports at the top, and some with namespaces, some looking like functions and some looking like .method, that would be thoroughly confusing.

roti14:08:23

for the sequence returning operations, like map, are there performance guarantees for resulting sequences? for ex. does (map inc [1 2 3]) return a sequence which has fast index lookup, like vectors?

orestis14:08:22

No, map returns a seq, which is lazy.

orestis14:08:38

You might be interested in mapv though, which returns a vector.

wilkerlucio14:08:38

you can use mapv to get a vector have the fast lookup

henrik14:08:45

Yes, be aware though, that mapv is not lazy.

roti14:08:27

yes, but I don't have a similar thing for hashmaps 🙂

roti14:08:07

@henrik thanks, so it's what I suspected. so with a sequence you are basically like with a list

henrik14:08:12

@roti Yes, but lazy sequences can be very performant given certain circumstances, since they’re only realized when absolutely needed.

mikerod15:08:06

@roti have you looked at transducers? It provides the ability to use these transformation functions, like map, in a collection independent way

mikerod15:08:50

Eg (into {} (map f) m)