Fork me on GitHub
#clojure
<
2018-07-19
>
myguidingstar10:07:30

is there an anonymous version of multimethod?

myguidingstar10:07:08

something that doesn't coupled with a var

myguidingstar10:07:18

eg (let [my-mm (get-from-somewhere)] (defmethod my-mm ...))

myguidingstar10:07:09

and call it (let [my-mm (get-from-somewhere)] (my-mm ...))

bronsa10:07:39

not via a public api

bronsa10:07:21

user=> (defn foo [x] (let [mm (doto (clojure.lang.MultiFn. "mm" :x :default #'clojure.core/global-hierarchy) (.addMethod 1 (fn [_] (println "hit"))) (.addMethod :default (fn [_] (println "miss"))))] (mm x)))
#'user/foo
user=> (foo {:x 1})
hit
nil
user=> (foo {:x 2})
miss
nil
`

👍 1
bronsa10:07:36

it’s ugly but if you really need to this works

chrisblom11:07:42

try manifold.deferred/on-realized

chrisblom11:07:22

ah ok, yes in that case (d/chain result (fn [x] (println "done") x)) should work

chrisblom12:07:09

i’m not sure i understand. So you do a http request and get deferred response, and you want to print something before the reponse is realized?

chrisblom12:07:32

ok, i don’t know of any hooks in manifold that could achieve that

scknkkrer13:07:21

I want to implement an clojure interpreter in c++. And one of these project goals is education. I am a CS student. Where I have to start, and documentation or book ? Thanks already.

lispyclouds13:07:38

@scknkkrer Are you supposed to write the lexer and parser by hand? If not, I would suggest using a parser generator like Bison or ANTLR with the Clojure grammar. ANTLR can generate the lexer and parser in C++

scknkkrer13:07:04

I want to understand the most deeply dark side of clojure or more of that, lisp. I always wonder when they foots seperated from the ground ? When they are starting to fly ? And how much structs I have to implement in compiler side or self-generated language ?

scknkkrer13:07:19

@rahul080327 :face_with_rolling_eyes:

alexmiller13:07:31

you should read Structure and Interpretation of Computer Programs

😄 3
lispyclouds13:07:38

In that case I'd suggest writing a LISP interpreter first. Its one of the oldest and most solved problem. Clojure is dialect of LISP and is a bit different from other LISPs. Also if you havent had LISP exposure before try reading https://mitpress.mit.edu/books/structure-and-interpretation-computer-programs

scknkkrer13:07:59

@alexmiller I will. Ok guys. Thanks so much, I think this book will give me a basic understanding about what I want. I will share my project when it is ready. 😊

scknkkrer13:07:30

Thanks again.

mpenet14:07:39

TIL that (contains? a-set x) is nearly twice as slow as (a-set x). I know it's technically not the same operation but close enough for it to be surprising

alexmiller16:07:36

I did a quick check on set of size 100 for element in the set with criterium and saw 87 ns for contains and 49 ns for set as function, so not quite twice as slow. Differences are like the var invocation overhead and the boolean coercion.

mpenet16:07:28

Yes that's roughly what I concluded too.

mpenet14:07:44

hitting .invoke directly seems to allow to bypass a number of type check from contains? (and the rest of the chain). Calling .contains on the set is ~ equivalent to invoke

OctarineSorcerer15:07:42

Does anyone know why (diff ['not-shared 'shared] ['shared]) produces [[not-shared shared] [shared] nil]? I'd expect it to produce [[not-shared] nil [shared], going by https://clojuredocs.org/clojure.data/diff

reborg15:07:04

Vectors are compared positionally, you probably want (diff #{'not-shared 'shared} #{'shared})

OctarineSorcerer15:07:40

Ah, thank you very much!

scknkkrer16:07:50

Thanks. I will look at this.

razum2um16:07:13

I started to mentor people in clojure and found out that there’s no online code/edn formatter (some links to http://pretty-print.net are dead) Am I missing smth?

dominicm17:07:20

Using Leiningen, is it possible to specify custom manifest attributes?

dominicm17:07:17

Found it, only key value pairs though, which isn't right

borkdude17:07:50

anyone here using clj-http’s async stuff?

Timo Freiberg19:07:44

what do you guys use for test coverage? i don't know anything other than cloverage which seems like it needs some work

Timo Freiberg19:07:38

mainly, it doesn't work in java 10, apparently because it's transitive dynapath dependency is out of date. the dependency is pulled in by bultitude, whose maintainer died 😕

Timo Freiberg19:07:56

it looks to me like correcting the dependency in a fork (which already exists: https://github.com/tobias/bultitude, branch: dynapath-0.2.4) would fix the issue, so i'm confused: is nobody using cloverage? or only with java <9, so they don't encounter that issue?

andy.fingerhut19:07:46

I would guess there is still mostly Java <9 usage out there.

andy.fingerhut19:07:36

For Clojure users, I don't know if there is much advantage to moving to the latest versions of the JVM, and for reasons like you point out, sometimes disadvantages/pain.

andy.fingerhut19:07:11

The State of Clojure Survey from early 2018 says this: "Uptake of Java 1.9, released last year, has been a bit slower with only 29% adopting Java 1.9 so far and 88% of developers using Java 1.8. Only 6% of developers are using Java 1.7 and less than 1% are still using Java 1.6." http://blog.cognitect.com/blog/2017/1/31/clojure-2018-results

✔️ 1
hiredman19:07:05

I would not say nobody is using cloverage, but I would be surprised if it is in widespread use

✔️ 1
hiredman19:07:39

the last person I recall asking about it is now the second most active commiter on it

roklenarcic20:07:06

Why does loop-recur fail compilation in some cases?

roklenarcic20:07:29

I thought I could recur from anywhere inside loop statement

hiredman20:07:44

when it fails to compile, the exception will say something like "can only recur from tail position" which is exactly what the restriction is

roklenarcic20:07:47

(if queue-ns
            (recur (update version-streams queue-ns rest)
              (conj linearized (get-in ns-defs [queue-ns ::ver-map (get heads queue-ns)])))
            (throw (ex-info "Error loading versions" {:type ::linearization ::heads heads ::progress linearized})))

roklenarcic20:07:56

oh that's great formatting

roklenarcic20:07:07

(if queue-ns
            (recur (update version-streams queue-ns rest)
              (conj linearized (get-in ns-defs [queue-ns ::ver-map (get heads queue-ns)])))
            (throw (ex-info "Error loading versions" {:type ::linearization ::heads heads ::progress linearized})))))

hiredman20:07:20

you likely have something after the if

hiredman20:07:29

so the if is not itself in the tail

roklenarcic20:07:43

that is right

hiredman20:07:51

the return is the tail

roklenarcic20:07:27

I fixed it now

hiredman20:07:38

https://gist.github.com/hiredman/815406099e7ff4ba676103091b14d70d something similar came up the clojure irc channel a while back

ghadi20:07:16

we're getting continuations soon :party:

ghadi20:07:46

for some value of soon

ghadi20:07:04

Brian Goetz said they're surprisingly far along

noisesmith20:07:11

wow, that's awesome

johnj21:07:42

@andy.fingerhut the new standard http client may be a good reason to use java 11

bja21:07:10

are symbols that aren't referenced cleared in some manner by the compiler?

bja21:07:32

trying to figure out why

(def F "party time")

(defn -main []
  (-> "F"
      symbol
      resolve
      deref
      println))
throws an NPE on the deref call

hiredman21:07:53

because that isn't how namespaces work

hiredman21:07:36

resolve resolves relative to *ns*, *ns* is almost never what you expect at runtime

hiredman21:07:48

likely user or clojure.core

bja21:07:31

even if right above I have (ns foo)?

hiredman21:07:17

the compiler pushes a value to *ns* while compiling a namespace, so *ns* will be foo while compiling the namespace, then the compiler pops the value of *ns* so it may be anything while code is actually running

bja21:07:18

answering my own question: yes, even if I have (ns foo) in the file

hiredman21:07:19

the repl iterleaves compile time and runtime preserving compilation state between calls to the compiler so it behaves kind of differently

bja21:07:55

so I need to actually in-ns if I want to do this thing (for nebulous reasons at this point)

bja21:07:04

i.e. (in-ns 'foo)

hiredman21:07:06

no, use ns-resolve

hiredman21:07:46

in-ns is something you call at the repl to fiddle with compiler state, you shouldn't be calling it in the middle of a function

bja21:07:04

I was going to call it at the top of -main, but fair enough

emccue22:07:37

is there a built in way to do this?

noisesmith22:07:50

no, this is a variant I use while debugging

Clojure 1.9.0
(ins)user=> (defmacro locals [] (into {} (map (juxt (comp keyword name) identity)) (keys &env)))
#'user/locals
(ins)user=> (locals)
{}
(ins)user=> (let [a 0 b 1] (locals))
{:a 0, :b 1}
(ins)user=> ((fn [x] (let [a 0 b 1] (locals))) :function-arg)
{:x :function-arg, :a 0, :b 1}

emccue23:07:03

okay, second question

emccue23:07:25

how can i accomplish something similar to this in with ring/compojure

noisesmith23:07:04

last I checked the compojure router doesn't do reverse routing

noisesmith23:07:25

this is why bidi was invented, other routing libs do it too

emccue23:07:04

compojure is just what was in all the ring tutorials

emccue23:07:35

is there a reference on the features/drawbacks of different web-libs