This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-01-19
Channels
- # aatree (33)
- # admin-announcements (70)
- # alda (6)
- # aleph (2)
- # announcements (6)
- # aws (7)
- # beginners (40)
- # bitcoin (1)
- # boot (138)
- # cider (24)
- # cljs-dev (9)
- # cljsjs (18)
- # cljsrn (35)
- # clojars (4)
- # clojure (211)
- # clojure-art (4)
- # clojure-austria (2)
- # clojure-hamburg (8)
- # clojure-russia (66)
- # clojure-sg (3)
- # clojured (1)
- # clojurescript (73)
- # cursive (9)
- # datomic (124)
- # dirac (8)
- # editors (3)
- # emacs (13)
- # euroclojure (10)
- # hoplon (207)
- # jobs (4)
- # ldnclj (27)
- # lein-figwheel (3)
- # leiningen (10)
- # mount (5)
- # music (1)
- # off-topic (9)
- # om (92)
- # onyx (36)
- # perun (30)
- # proton (47)
- # re-frame (11)
- # reagent (11)
- # ring-swagger (7)
- # yada (2)
@mkunikow: thanks
@alexmiller: do you have any update on the state of clojure survey?
I wrote a long thing and other people are editing it but they're busy so... It's coming
@jfntn yes, extend* require protocols. if you need a class whose superclass is SomeDeftype which implements SomeJavaInterface, look at :gen-class, though you will have to be careful about compilation order; if hopefully you just need an instance that does the same then look at proxy
hi guys in clojure how can we define defmethod in another namespace separated from defmulti ?
@jonahbenton: makes sense, looks like I won’t be able to do this without an instance-level wrapper… Thanks for the explanation!
@nxqd: the defmulti is a function var just like any other - just refer it in your ns then use a defmethod like usual
@alexmiller: thanks
I have a ring handler that spits out other ring handlers (thus requiring to be called twice on a request to get a response) — is there a better way of doing this?
@mheld: here's my understanding of ring handlers. A handler should take the request map and return a response map. It should not return another handler. A 'middleware' function should take some args (often including a handler) and return a handler. The handler which the middleware function creates will either modify the the request map before passing it to the original handler, or the response map which it receives from the handler. Or the middleware can do more complex stuff -- pick one of a list of handlers to use, log some stuff, check authentication, etc. For example:
(defn hello-handler
"Says hello to someone"
[req]
{:body (str "Hello, " (:name req))})
=> #'user/hello-handler
(defn make-loud
"Middleware to convert :name param to uppercase. This function takes a handler, and returns a new handler"
[handler]
(fn [req]
(->> (update req :name clojure.string/upper-case)
(handler))))
=> #'user/make-loud
(def root-handler
(make-loud hello-handler))
=> #'user/root-handler
(root-handler {:name "Steve"})
=> {:body "Hello, STEVE"}
@sashton: I get that, but for some reason if I don’t I get a liberator.core$resource$fn__29104 cannot be cast to java.util.Map error
I haven't used bidi, but I'm guessing it would be something like this:
(def root-handler
(make-loud
(make-handler ["/hello" hello-handler])))
make-handler searches through the keys of the route hash to find the right handler for the action, then calls that handler on the request
(user-handler {:uri "/api/users/119" :params {:id 119}}) -> #object[liberator.core$resource$fn__29104 0x4ede08e6 "liberator.core$resource$fn__29104@4ede08e6"]
what if you change handler-map to:
(def handler-map
{:user (fn [req] {:body "found a user"})})
Then run it again. Any difference?A parameterized resource, which is defined using (defresource name [param & params] ...) does not define a ring handler function like a regular resource but a function that produces a ring handler.
I'm managing a websocket-client connection with aleph, aleph returns a duplex stream, how would you store and manage this state? In an agent? I would need to periodically check if the websocket connection is still open and reset it where necessary.
welcome @immoh @luiz @last.khajiit @buntha @cl0jurian @danielytics and everyone else who hasn't been welcomed yet
@meow: thanks
thank you
hey @jethroksy, could use an agent but from a semantics perspective it may be a better use case for an atom. It's more of a stateless resource, in the sense that sending some data over a websocket doesn't yield a new websocket.
@jonahbenton: got it. I'm currently spinning off 2 go loops, one to constantly ping, and another to constantly check for replies, if not swap! the atom with a new ws connection.
@jethroksy: cool, sounds good.
need some help, having such a sequence '({:a 1, 😛 2} {:a 3, 😛 4}) how to get {:avg-a 2, :avg-b 3}
(when (seq numbers) …) may be more idiomatic
yeah, using (when (seq numbers) …)
is definitely more idiomatic. Otherwise this is a place where I wish we had a viable Option type in Clojure
i was thinking
{:average-temperature (average (keep :temperature measured-values))
:average-rain (average (keep :rain measured-values))}
yeah but this code repeatition, maybe would create fn
from defn avg [kw] (average (keep kw measured-values)
keep it simple. better to use small composable functions. 1 helper (average) then a calculation (the map) made out of core function
i feel like there should be a corollary to premature optimization is the root of all evil
:
I've noticed that a lot of my code combines apply / merge / map. I'm building JSON config files. So I map
an fn on some values, then combine the many little maps into a big map with apply merge
. Is there an elegant way to combine these?
reduce
?
would have to see some examples @bradford
sure. like
{:google_pubsub_subscription (apply merge (create-subs g a-graph))}
and (defn create-subs [g a-graph]
(map #(create-sub g % a-graph) (:sinks a-graph)))
ghadi: the thing you helped me came from here https://github.com/kosecki123/netatmo-parser that's a very first clojure code I wrote
bradford: I think part of the same advice above to @kosecki applies. There is nothing wrong with assembling a bunch of core functions, though there may be some more idiomatic way to string them together.
regarding your second function create-subs
, all it does is apply a function to a collection
better to make it a function of an item itself, rather than mapping over the collection
I’m struggling to see how you aren’t clobbering everything at the :sinks
key when you do that merge
(and whatever other keys are duplicated)
@ghadi: Good point, though what do you mean 'make it a function of an item itself'? And @ddellacosta, I actually want to clobber the :sinks key. This file format I'm generated wants {:a 1 😛 2 :c 3} instead of [{:a 1} {:b 2} {:c 3}], if that's what you mean?
Generally if the body of your function is (map some-calculation collection)
you should simply make the body the calculation itself
Hi, I have been trying to wrap my head around Factual’s durable-queue and I seem to be misunderstanding something. I have 2 async/go-loops - one of these keeps inserting and the other keeps reading from the queue. Is this the wrong pattern? Should I synchronize access to the queues?
@ghadi: I'm sorry -- how do I apply a function to a collection without map
? I have the feeling I'm about to slap my forehead here.
Use map
by all means, just don't use it in the body of the function. Move it to the part of the code that consumes this fn
Oh! Got it. Thank you! I wish there was a "Ideomatic Clojure Best Practices" kinda thing. I guess equivalent to OOP "Design Patterns", but not as cringe-worthy.
Imagine you have two transformations that have to happen. If you don't explicitly map the first transformation, you can simply smush them together with comp
and then use map.
@bradford: you should definately check the "The Joy of Clojure" book, it contains a lot of great examples
@kosecki: Thanks! I picked up "For the Brave and True" and "Clojure Programming", everyone recommends "Joy" as well.
the design pattern in question here is sorta "single-responsibility principle". Do one thing (transform an item) rather than N things (transform each item)
Whaaaa I can order "The Joy of Clojure" and get it delivered today. What is this wizardry.
Did someone say "design patterns"? I found this a pretty good read re: that - http://mishadoff.com/blog/clojure-design-patterns/
Well it's not GoF's fault that some languages need bandaids for essential functionality : V
Clojure 1.8 is now available! http://blog.cognitect.com/blog/2016/1/19/clojure-18
🍰 Congratulations!
Many thanks to all the contributors!
anyone know of a good example of a non-toy open source thing on github that uses component and has a lot of tests?
@cfleming: probably already on your radar but it would be nice if types / records appeared in the Project Structure list in Cursive
If I have this code:
(map
(fn [d] {:group_name (.getGroupId d)
:jar_name (.getArtifactId d)
:version (.getVersion d)
:scope (or (.getScope d) "compile")})
(.getDependencies model))
and (.getDependencies model)
returns java.util.List<Dependency>
, should/could Clojure be able to pick up that d
is a Dependency
? I’m having to typehint the function to avoid reflection warnings, but I wondered if it’s possible to know this without type hinting.I think type erasure will delete the generic
would Clojure know it if it wasn't the case? I doubt that also:
user=> (map (fn [s] (.length s)) ["foo" "bar"])
Reflection warning, /private/var/folders/7t/gpzjxhts24d5wvqys1dfvrd80000gn/T/form-init2551413801351333897.clj:1:14 - reference to field length can't be resolved.
(3 3)
And it's also somewhat language-dependent. IIRC Scala does something to ensure you can query and instantiate generic types at runtime.
@ghadi: would my example be any different from @danielcompton in terms of reflection?
there's very very limited type inference. But typically in my experience, if you hint the argument, then chains of calls within the body infer types properly.
Clojure inference is very limited, since it's a dynamic language at core. How can you ensure your vector will contain only elements of a single type at compile-time with Clojure?
If you can't do so, you can't also infer that s
will receive arguments of type that have a length
method.
even if you would have a homogenous collection, Clojure would not infer it I think, because of well yeah, type erasure
these things are hardly pain points, except when you're doing a lot of iterations and need the performance
What I mean is that in Clojure you can't even ensure at compile time that a collection is homogenous.
So even if clojure properly infers something at compile or runtime, it still emits casts. Arguments in clojure are either Object
or long
or double
Yeah, this also; all Clojure functions are generic over types and there's no monomorphisation in Clojure.
@ghadi: if I understand correctly there's no way to overload over type hints in plain Clojure, yes?
no type overloading, period; multimethods and protocols use different dispatch method from fns
but the type based dispatch of a protocol is about the best you can do
@ghadi: what I mean is that means (defn whatever [^int arg] ...) (defn whatever [^double arg] ...)
is illegal in Clojure, yes?
(I could be wrong... I guess it still has to emit casts)
it's not illegal, the latter just replaces the former
Didn't think it was, but that tidbit about about the only three types of arguments seem to mean you can't overload like that.
@jaen: but if you write an overloaded arity function like (fn ([x] ....) ([x] ....)) then you'll get an error
CompilerException java.lang.IllegalArgumentException: Only long and double primitives are supported... compilig...
Didn't need to write any performance-sensitive code so far so don't know typehinting ins&outs.
regarding typehints, if you hint ^Dependency as the argument, it changes nothing about the signature of the compiled code. It's still an Object parameter
> it changes nothing about the signature of the compiled code. It's still an Object parameter Yeah, that was basically the intent of my question - if the type signature of the method stays the same you can't overload.
(shit will fail with a ClassCastException later in the body when you use the arg if it's the wrong hint)
Anyway that's an interesting thing to be aware of that typehints are just basically casts.
@borkdude: that's correct. you can typehint any subclass of Object, but the signature of the method is still Object
@ghadi: but nothing fails because of a cast. or is it only casted when doing interop?
it remains to be seen how Clojure will handle Value Types when they arrive (probably Java 10).
Is https://github.com/clojurewerkz/titanium still being updated, or should I seek out something else for Graph-y Database-y things?
@dnolen: Yeah, definitely - there’s a bunch of stuff missing from the structure view right now (e.g. multimethod implementations)
Right now I'm using Loom, which is v. cool but doesn't let me write queries, just traverse.
@borkdude: I think I need something a bit more graph-y, so I can answer questions like "Give me all nodes with in-degree 2 with :label 'user'"
I think you can do graph-y stuff with query functions - https://hashrocket.com/blog/posts/using-datomic-as-a-graph-database - but not sure if that's good enough for you.
@dnolen: you can follow at https://github.com/cursive-ide/cursive/labels/Structure%20View, and https://github.com/cursive-ide/cursive/issues/559
@danielcompton: ah cool thanks
@bradford: Might not be what you're looking for but there's always RDF and SPARQL... You can express precisely that kind of thing with a SPARQL property path ( https://www.w3.org/TR/sparql11-property-paths/ ) - http://rdf4j.org/
@bradford: rdf4j has in memory (and disk backed) sparql repositories too
@bradford: this is very low level but maybe that's what you want: https://github.com/thi-ng/trio/ ?
Speaking of graphs, I would really like an ad hoc in memory graph-like heap, similar to what @bbloom has been ranting about
But it has practical applications: Most of writing a compiler is creating graphs and trees
@ghadi: agreed... that would be pretty sweet
you can always peer pressure @bbloom to write a post... but then it takes him away from being the fucking Nostradamus of the community
Re: Clojure 1.8, is direct linking always 'on' or on by default (with a global switch to toggle it)? Putting ^:redef
on everything if dereferencing behavior was wanted isn't too scalable...
@rickmoynihan @martinklepsch Thank you! Will poke.
OK, sounds good, but I guess that begs the question then of how to turn it on?