Clojurians
#clojure
<
2016-03-23
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

tcrawley00:03:13

@danielsz: you are hitting https://github.com/clojars/clojars-web/issues/514 - I'll deploy the fix for that tonight

tcrawley00:03:15

the workaround is to rm -rf ~/.m2/repository/org/danielsz/system/0.3.0-SNAPSHOT

danielsz00:03:28

@tcrawley: Thank you!

tom01:03:25

For developing a publically available REST API, what tools are most often used? I assume liberator is still favored.

tcrawley01:03:28

@danielsz: that issue is now fixed in production, sorry it tripped you up

danielsz01:03:50

@tcrawley no problem at all, thank you so much for the quick response. Big relief :-)

jindrichm10:03:42

Can you extend a multimethod by creating an alias for an existing dispatch key?

rauh10:03:06

@jindrichm: That's what :hierarchy option in multimethods is for. Also allows to add/remove "aliases" during runtime.

jindrichm10:03:22

@rauh: That only works when the dispatch value can be derived, right? Moreover, you cannot extend third-party multimethod.

rauh10:03:14

@jindrichm: 2x correct :simple_smile:. You probably could mess with get-method and then dynamically add it.

schaueho10:03:15

any multimethod definition that can only return a fixed set of values is broken by design, IMHO -- not that this would help you, though

jindrichm10:03:35

@schaueho: What do you mean by returning a fixed set of values?

schaueho10:03:11

e.g. if the dispatch method would only ever return :a, :stuck_out_tongue: or :c, regardless of the dispatch value

schaueho10:03:29

maybe I misunderstand the problem you're trying to solve

jindrichm10:03:55

That's not the problem I want to solve. There's a third-party multimethod dispatching on strings, for which I want to reuse implementation for a specific dispatch value.

jindrichm10:03:39

@rauh: Thanks, using get-method works (albeit it's a bit ugly).

nielsk11:03:41

Is there any way to remove a previously extended type from a clojure protocol ?

nielsk12:03:26

I thought I could do it by changing the implementation of the function to identity, but of course that would still catch the interface

nielsk12:03:06

Perhaps clearer: In an external namespace a protocol function is defined for clojure.lang.Associative, which will handle maps, vectors and map entries. However, I only want it to handle Maps (IPersistentMap ?)

nielsk12:03:33

So I need to retract the extend-type for Associative

nielsk12:03:50

And extend-type for IPersistentMap

jcromartie12:03:05

this is really weird. I'm getting the same compiler error no matter what is in a file

jcromartie12:03:18

CompilerException java.lang.IllegalArgumentException: Parameter declaration missing, compiling:([REDACTED].clj:12:1)

jcromartie12:03:48

I had a duplicate file with the same namespace in my test sources

danielgrosse13:03:09

How can I archive this (nth (:children (nth (:children (nth menu-h 0)) 1)) 1) with a clojure function, to process arbitrary depths?

rm13:03:37

archive?

jindrichm13:03:49

You meant "achieve"?

rm13:03:38

maybe you want get-in

rm13:03:58

> (get-in {:x [{:y 3}]} [:x 0 :y])
3

nkraft14:03:57

Anyone here tried using GravityLabs Goose (https://github.com/GravityLabs/goose) with Clojure? There used to be some ports and/or wrappers, but they've all gone unmaintained. If not, got a Clojure alternative to Goose for content extraction?

fasiha14:03:54

@danielgrosse: what @rm said get-in, or even with threading macro: (-> menu-h (nth 0) :children (nth 1) :children (nth 1)). Or do you mean you want to somehow automate the construction of that "path"?

fasiha14:03:19

Question: I've been happily using transit-cljs for json+transit parsing, so I'm looking at transit-clj for JSON parsing on the backend. I've worked through the transit-clj readme and can now convert a JSON string to Clojure data, viz.: (transit/read (transit/reader (ByteArrayInputStream. (.getBytes "{\"name\":\"Donald\",\"age\":19}")) :json)) I can certainly do this. But because it just seems more baroque than the ClojureScript version, I wanted to confirm that this is indeed how I ought to be parsing JSON with Transit in Clojure. Specifically, if I have a file containing thousands of lines, each containing valid JSON ("line-delimited JSON"), that I ought to be converting each line's string to a byte array, then a ByteArrayInputStream, then a transit reader, before invoking transit/read

danielgrosse14:03:01

@fasiha @rm Thanks for the advises. I want to build the command by a given vector [0 1 3] where each number is the position in the structure.

fasiha14:03:05

@danielgrosse: try this: (get-in MY-MAP (flatten (map #(vector % :children) [0 1 3]))), replace MY-MAP with your actual map, and [0 1 3] with your path. To see how this works:

cljs.user=> (flatten (map #(vector % :children) [0 1 3]))
(0 :children 1 :children 3 :children)

fasiha14:03:16

(You could build that path vector many ways, e.g., instead of flatten and map, you could probably use into)

danielgrosse15:03:28

@fasiha: thank you very much. This is genious

bostonaholic15:03:44

@fasiha: @danielgrosse (mapcat #(vector % :children) [0 1 3])

rauh15:03:00

Another one would be (interleave [..] (repeat :children))

danielgrosse15:03:20

When I want to follow a path through a nested map, how can I gather information on each object into a new map?

jstew15:03:12

@danielgrosse: You're probably going to end up using clojure.walk, or something like spectre (https://github.com/nathanmarz/specter).

roberto15:03:21

I’m trying to implement a protocol that is in a different ns using extend, but it isn’t working for me. I might be missing something obvious. E.g:

(ns prots.blues
  (:require [prots.protocols :as p]))

(deftype BluesPlayer [fname lname]
  p/Speaks
  (speak [this] "HOO"))

(extend BluesPlayer
  p/Rocks
  {:rocks (fn [this] "HOOOO")})

(def wolf (BluesPlayer. "Wolfy" "Howls"))
I can do (.speaks wolf), but (.rocks wolf) throws an exception if I implement p/Rocks when I declare the BluesPlayer` type, then it works. I’m on clojure 1.8

nielsk16:03:18

@roberto Look at the curly braces around :rocks, plus you made :rocks a keyword instead of the function name symbol

nielsk16:03:06

I find it easier to use extend-type when extending in another namespace (extend-type BluesPlayer p/Rocks (rocks [_] "HOOOO"))

roberto16:03:07

extend-type didn’t work either

roberto16:03:21

I used extend because extend-type wraps around extend anyway

roberto16:03:39

was just trying to get something working and figure out what was the issue, so I went one layer lower

roberto16:03:27

I think the issue has to do with the protocol being in a different namespace

roberto16:03:49

if I put the protocol in the same namespace, then extend and extend-type work

nielsk16:03:56

Nah, just been extending protocols in another namespace for half a day and it works quite alright

roberto16:03:08

what version of clojure are you using?

nielsk16:03:38

1.7, trying out in 1.8 now

nielsk17:03:03

OK, works in both versions

nielsk17:03:16

Took a while because I autoimported the wrong Java class

nielsk17:03:09

So what I did was require the namespace the protocol is in under an alias, and referred the protocol function name

roberto17:03:16

oh, do you have to do anything special to the files with the protocols? Like maybe do a :gen-class ?

nielsk17:03:00

(:require [clojure.java.jmx :as jmx :refer [objects->data]])

roberto17:03:20

I wonder if that is the expected behavior

roberto17:03:31

will try that, thank you for you help

nielsk17:03:48

Then my extend-type was something like this: (extend-type ArrayType jmx/Destract (objects->data [cd] (bean cd)))

nielsk17:03:04

Refer seems not to be necessary, this works as well (extend-type ArrayType jmx/Destract (jmx/objects->data [cd] (bean cd)))

roberto17:03:00

hmmm, this is frustrating, it isn’t working for me

nielsk17:03:45

Somehow I didnt expect your BluesPlayer to have two protocols

nielsk17:03:43

Usually it's one protocol, like IMakeMusic, with speak and rock as functions inside that protocol

roberto17:03:22

yeah, i was trying to see if this works http://davedellacosta.com/cljs-protocols

roberto17:03:41

that shows that you can extend a type with multiple protocols

roberto17:03:56

that works fine for me, it just doesn’t work when I extract protocols into their own files. I’ll take a break from this for now. It was just an academic exercise I was trying.

dimovich17:03:48

how can I remove a span tag with a specific class from html using enlive?

dimovich17:03:52

or maybe other solutions

borkdude18:03:26

I think Clojure can sometimes be faster than Scala at run time because Clojure needs to allocate less anonymous functions. Am I correct? Example: https://gist.github.com/borkdude/2772ccead843832c0956 Every time you update the map inside the atom you need to allocate an anonymous function. In clojure you can just pass assoc + args, no overhead.

urbanslug19:03:31

How can I run tests on https://github.com/dakrone/lein-bikeshed if lein test doesn’t work?

urbanslug19:03:17

lein test fails which is weird

urbanslug19:03:27

Anyway I’ll look into that

urbanslug19:03:02

Okay, it’s clear that they’re written to fail, why is this?

fommil19:03:23

can destructuring be used in a binding form?

fommil19:03:02

my usecase is that I have some dynamic variables that I want to set to be equal to the value of some keys in an .edn file and I don't want to repeat myself too much

nberger19:03:11

@urbanslug: I think it's just to serve as an example of "bad formatted files, with trailing newlines". Running lein bikeshed on the project shows (among other stuff):

[...]
Checking for files ending in blank lines.
Badly formatted files:
/home/nicolas/projects/lein-bikeshed/test/bikeshed/core_test.clj
/home/nicolas/projects/lein-bikeshed/test/bikeshed/core_test.cljs
[...]

nberger19:03:51

so it's not actual tests, just example "totally broken" files

nberger20:03:19

(to run lein bikeshed I first added :plugins [[lein-bikeshed "0.3.0"]])

fommil20:03:10

looks like destructuring can't be used in a binding

fommil20:03:33

has to be wrapped in an outer let

fommil20:03:36

that's a shame

fommil20:03:18

about to write my first midje tests, for a channel. This is where all hell breaks loose in Scala (testing async code). I'm hoping for the best here... any advice?

isaac_cambron20:03:02

@fommil that's right about binding. You can see the relevant code here: https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L1849

isaac_cambron20:03:18

My advice re: midje + core.async is just to <!! the channel and check the value on it. What you don't want to do is assert inside the async thread

fommil20:03:30

@isaac_cambron: cool thanks, I started doing that it's good to get the approach confirmed. Can clojure run tests in parallel? I can see this slowing things down if I'm blocking everywhere.

fommil20:03:46

is there an alternative to core/time that returns the time?

fommil20:03:06

(my test is asserting on minimal timings of things)

isaac_cambron20:03:26

There System/nanoTime

isaac_cambron20:03:36

I've never run tests in parallel, though I'm sure there's a way

fommil20:03:52

yeah but that's just now. core/time takes a function to wrap

fommil20:03:15

I can write my own

fommil20:03:09

my first clojure macro :simple_smile:

fommil20:03:40

heh, I was about to ask some questions about midje, then I realised they have 80 pages on their wiki

fommil21:03:08

is there a better notation than this for a midje assertion? (just {:result :ping :time (partial <= 50.0)}). The partial is a bit ugly

fommil21:03:34

the partial also reads the wrong way round

fommil21:03:53

(this asserts that the LHS takes at last 50 milliseconds, but reads as "at most")

fommil21:03:58

#(<= 50 %) is nicer

akjetma21:03:45

is there a way to define a destructuring in a single place? for example, when working with sente i find that i’m doing this all over the place

(let [{[ev-id ev-data] :event :as message} (<! chsk-recv)]
  …)

akjetma21:03:47

doing something like this feels weird

(defn -ev-id
  [{[ev-id] :event}]
  ev-id)

(defn -ev-data
  [{[_ ev-data] :event}]
  ev-data)

codonnell21:03:48

@akjetma: maybe you could define a kind of middleware that transforms your arguments into a more convenient format

fommil21:03:01

@akjetma: I'd also like to know the answer. I'd considered maybe writing a macro with explicit named parameters

fommil21:03:11

there's a name for those kinds of macros...

fommil21:03:19

a sort of intentional variable capture

fommil21:03:39

now, a macro that could automatically generate such a macro