Fork me on GitHub
#clojure
<
2020-01-26
>
Ivan Koz07:01:15

can somebody explain why do we have two invoke for the functions, and why do we call static function from the instance method.

@Override
    public Object invoke(final Object coll) {
        return invokeStatic(coll);
    }

kulminaator07:01:17

interesting question ... in my head a function is just a function, like sinus or cosinus in math, very static 🙂

andy.fingerhut07:01:38

@nxtk I am guessing you are talking about the JVM byte code produced when the Clojure/Java compiler compiles a Clojure function? Or is that code you gave an excerpt from a Java source file inside the Clojure implementation somewhere?

kulminaator07:01:07

and i expect jit can cut a lot of corners if it has the inside information about the behavior being static

Ivan Koz07:01:35

@andy.fingerhut correct, emitted bytecode

andy.fingerhut07:01:01

I do not know the answer, but given it is Saturday evening/very early AM Sunday in the time zones where most Clojure devs live, you may need to wait a bit for a knowledgeable answer. Try in @clojure-dev if you don't get an answer here, keeping the time of week in mind.

andy.fingerhut07:01:19

I mean, ask any time you want -- just the answer may take time.

Ivan Koz07:01:47

yeah i think i will dup my question there

sogaiu07:01:11

i am interested in this too 🙂

Ivan Koz07:01:37

alright, let's monitor clojure-dev at this point =)

andy.fingerhut08:01:16

FYI, this also seems like a good question for http://ask.clojure.org, where the answer will be more easily findable in the future.

Ben Hammond08:01:46

I've done that when I wanted the possibility to hook into virtual functions

Ben Hammond08:01:11

The member method may be overridden by a subclass

Ben Hammond08:01:19

The static method may not

Ivan Koz08:01:40

i think we need it for closures support, which in case of clojure are passed as a constructor arguments to a function class

Ivan Koz09:01:24

so, closure val -> fn class constructor -> instance invoke -> static invoke(which contains actual implementation) actually nah, that can be done without static invoke

tdantas09:01:26

hey guys, probably super easy/quick for some of you. r/take-while is making my code not to run in parallel. as soon as I removed the take-while the code start doing the “computation” into different threads ( fork-join executor ) why take-while is doing that ? ( is that correct assume the problem is with take-while , or any other issue with my code )

(def ts (atom #{}))
  (defn stop? [_]
    (< (rand-int 100) 90))

  (defn conjj [a b]
    (swap! ts conj (.getName (Thread/currentThread)))
    (conj a b))

  (r/fold 2 (r/monoid conj vector)
          conjj
          (r/take-while stop? (into [] (partition-all 2 (take 200 (range)))))) ; => running on just 1 thread
  
  (println "n threads" (count @ts))
  (reset! ts #{})

  (r/fold 2
          (r/monoid conj vector)
          conjj
          (into [] (partition-all 2 (take 200 (range))))) ; => running into multiple threads

  (println "n threads" (count @ts))

tdantas09:01:18

Yeah , using from reducers @kulminaator

tdantas09:01:01

Sorry, wasn’t explicit , r is a alias for the reducers

tdantas09:01:52

Don’t know why is not doing in parallel

kulminaator10:01:44

wouldn't it be enormously unpredictable if it would do it in parallel ?

kulminaator10:01:55

or maybe i understood you wrong ... you would expect it to do it's work in parallel per partition ?

tdantas10:01:56

I thought it would do in parallel ... but maybe I do not understood properly

tdantas10:01:27

Thought the reducers would try to do it in parallel and combine later on

kulminaator10:01:45

the parameter that you ignore in your stop function

kulminaator10:01:05

is one partition of your initial collection

kulminaator10:01:45

if you handle those in parallel and decide to stop at any point ... i would think you get different results every time you execute this

kulminaator10:01:24

(i'm just confused by what you are trying to achieve, sorry)

kulminaator10:01:00

did you expect stop? function to be fed individual values from the initial collection ?

tdantas19:01:42

sorry @kulminaator, I had an emergency at morning. basically what I want to dois to read a huge file, process chunk of lines and as soon as I found what i’m looking for in the line, stop the process

tdantas19:01:36

how can I accomplish that in clojure way ?

kulminaator19:01:18

when stuff get's into i/o related latencies and threading i have reached out to core/async. maybe your case can just be solved by storing the results and checking need to stop in an atom ? i dont think multithreading will help you much there to be honest, unless your check is very cpu expensive reading from disk will always be slower than simple logic on the cpu.

tdantas19:01:19

every line I have to do some cpu intensive task, like cryptografic hash.

tdantas19:01:01

so , basically, my idea was to fetch in streaming the file and send to threads to process, stop as soon as I found what I’m looking for

tdantas19:01:26

but I’m not know how to do that ( I did in java through executor service with blocking queue. so I had 8 fixed thread consuming the queue )

padraic11:01:12

Looking to start a project that utilises a http and websocket client in both clj/cljs. I've looked into several implementations on the clojure side, http-kit, sente, aleph and all are either really complex or only direct to a server solution which is not what I'm after. The cljs side of things is a bit more straightfoward as would make sense given that the frontend domain is far more client orientated. Would anyone have advice for what is the best approach?

p-himik13:01:21

What issues did you find with Sente?

Setzer2213:01:15

If I have a primitive mutable local in a deftype , how can I set! it? I'm trying this but I get an error:

(deftype TypeA
    [^{:unsynchronized-mutable true :tag int} a]
  SomeProtocol
  (foo [_ new-val]
    (set! a ^int new-val)))
I get an error: Must assign primitive to primitive mutable: a I thought the type hint in new-val would be enough for the compiler to determine that new-val is a primitive int?

kulminaator13:01:06

but if you do (int new-val) instead it works ?

Setzer2213:01:34

you're right, it works!

penryu14:01:26

So I understand, this is because the reader interprets integer literals as Longs, not Integers, and needs explicit conversion to reassign to a variable tagged int, right?

Setzer2214:01:07

I'm not sure if that's the reason... new-val could be an int after all. I'd just need to cast it before calling foo, or obtain it from an interop method call.

Setzer2214:01:45

But anyway, what I'm expecting semantically from the code above is a cast (what should the code above do if passed something other than an int besides a ClassCastException?) So I guess having an explicit cast is the right answer. I still don't know why the original code won't work.

kulminaator14:01:09

maybe "gods of immutability" are just trying to prevent you from commiting a sin

12
😆 8
😅 8
☝️ 4
madstap16:01:04

given a multimethod and a dispatch value, is there a way to find out in which namespace the defmethod was defined?

dominicm17:01:44

I tried something similar a while ago and didn't have much luck. You can get the function which backs the multi method, and it might have a name which indicates the namespace

niwinz18:01:02

is there any way to set *warn-on-reflection* to true globally using tool.deps (and then, execute the repl)? (similar to the lein :global-vars)

andy.fingerhut18:01:10

I haven't heard of one, but could have missed it. You can try #tools-deps channel if you do not get an answer here.

delaguardo18:01:19

You can use --init-opt for that.

delaguardo18:01:28

clj -e "(set! *warn-on-reflection* true)"...

niwinz18:01:34

does not works...

niwinz18:01:06

i'm wrong the -e option works correctly but when i tried it first... didnt worked... strange! thanks!

Setzer2220:01:50

I ended up resorting to having a repl.clj script next to my deps.edn where I fire up a repl after doing initialization (like setting *warn-on-reflection*) . I find this approach better than relying on always passing the right command line args

Setzer2220:01:09

The script looks like this:

(require 'nrepl.cmdline)
(require 'my.project.core)

(do (println "Starting REPL")
    (set! *warn-on-reflection* true)
    (nrepl.cmdline/-main))

Setzer2220:01:34

And I call it like clj -A:repl-deps repl.clj (assuming a :repl-deps alias exists somewhere in your project or global deps.edn with the right nrepl dependencies)

❤️ 4