This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-06-04
Channels
- # admin-announcements (1)
- # alda (2)
- # beginners (52)
- # boot (8)
- # cider (14)
- # cljs-dev (7)
- # cljsrn (5)
- # clojure (4)
- # clojure-belgium (2)
- # clojure-brasil (1)
- # clojure-dev (8)
- # clojure-greece (6)
- # clojure-russia (34)
- # clojure-spec (42)
- # clojurescript (20)
- # cursive (5)
- # funcool (1)
- # hoplon (313)
- # immutant (1)
- # lambdaisland (24)
- # mount (1)
- # om (26)
- # perun (1)
- # planck (2)
- # proton (1)
- # protorepl (6)
- # pure-frame (15)
- # re-frame (14)
- # specter (17)
- # spirituality-ethics (1)
I've been looking for good practices when it comes to error handling in clojure/clojurescript, and it seems like the try
catch
pattern is standard. Am I missing a better way? Thanks.
hi guys, i am developing a websocket server with clojure, but i have a problem i can not do a 'broadcast' between users connected in websocket. Anyone already done it?
@renan: What’s the front end? ClojureScript?
If so, have you looked at Sente? That supports broadcasting, as far as I remember.
@seancorfield: In back end, I was using the Immutant, because this not work the 'broadcast', i'll see the Sente, thanks 😁
I'd probably start with something small and lightweight like http-kit -- unless you need all of the features Immutant and JBoss bring? @renan
I'm really liking the freedom that moving away from big Java style containers brings.
@seancorfield: Not, In my case just test, but I have other problem now is running JAR's files of Lucene with Clojure 😅
Hmm, Lucene and Solr are on my list. I hope they work okay with Clojure!
@seancorfield: I found little dependencies... and not support the latest version of Lucene.. and my experience with Solr not very good, i don't like Solr 😅
@mtorres yes try catch with ExceptionInfo for conveying data with the errors
and some macro helpers to make it work with core.async
hey folks, in terms of practical conventions when is it appropriate to use def
vs defn
is there a case where using def
over defn
or vice versa is an antipattern?
what do you mean? defn
is sugar over def
for defining functions, you should always use defn
over def
when defining functions, unless you cannot for very specific reasons.
Essentially the only reason I will not use defn
when defining a fn in a var is if I want the fn to close over some other values that I don’t want to be vars, or don’t want to pay the var lookup tax to access
What I’m trying to understand is the difference between passing the outcome of a function to a function and calling a function on a function directly.
I’m afraid I don’t follow that, do you have a pair of examples?
Well, sum
is a fn of two vars, so neither example should work
In the latter example, square-of-sum
is a var whose value is 16
def
defines a var of arbitrary value
defn
defines a var that is a fn, which is the most common kind of var
(defn [x] …)
is essentially equivalent to (def (fn [x] …))
@dmbennett: are you familiar with other programming languages other than clojure? your question doesn't make much sense, in java what you're asking would be the difference between e.g.
public static long squareOfSums(long x) { return x * x; }
public static long val = squareOfSums(2+2);
and
public static long squareOfSums = (2+2)*(2+2);
Alright, so in trying to clarify my question, so that its more sensible: is it preferred to call a function on a function, or set a var to the outcome of a function and then call a function on that variable?
alright so "call a function on a function" does not mean what you think it means -- in clojure functions are values themselves so that phrase would mean "passing a function as an argument to a function"
what I seem to understand you asking is "should I def
intermediate values or should I inline the expression" to which the answer is: it depends.
def
is for values that you need globally and you will reuse. intermediate values are not that.
if you want to name an intermediate value to avoid nesting too many calls, look at let
ok, I think that addresses my question, thanks for being patient and teaching me through my own opaqueness.
In cases where side effects are necessary, how do you indicate that their occurring?
Take the case where you create a postgres database. I can think of 2 approaches to draw attention to the side effective.
1. Comment the code — WARNING SIDE EFFECT: db create
2. return a handle/connection to the database.
I think these might be the only option regardless of the side effect. As I think of necessary side only being necessary when your changing something that you need to persist past the programs execution (though I would be interested to hear counter examples).
When I have var fns that have side effects, I usually use the trailing !
convention
Though almost always when I have code that has side effects, I’ll look to encapsulate it behind a protocol
@donaldball: > Though almost always when I have code that has side effects, I’ll look to encapsulate it behind a protocol could you explain a bit what that means? or what the benefit is?
Sure thing. Clojure protocols are coherent groups of fns that operate on one or more things. An example might be:
(defprotocol UserStore
(load [_ id])
(save! [_ id user])
(delete! [_ id]))
(defrecord Database [db]
UserStore
(load [_ id]
(first (jdbc/query db ["select * from users where id = ?" id])))
...)
(defn build-memory-user-store
[]
(let [state (atom {})]
(reify UserStore
(load [_ id] (get @state id))
...)))
The advantages are that it decouples the callers from the implementation details, and in particular for protocols with side effects, allows you to reify local implementations for use in tests or in development.
The disadvantages are the same as with anything that adds a layer of abstraction: it hides implementation details from the call sites, making it potentially more difficult to understand and debug, particularly if the abstraction is awkward or poorly conceived.
I generally extract protocols from spike or legacy code, but tastes differ. I’m given to understand core.async was initially presented by Rich as two or three protocols with no impls.
(Immutable data structures are my favorite part of clojure, but protocols are a close second.)
(map (partial select-keys [:created]) histories)
I think
Ah, no. select-keys
takes the arguments the other way round
(map #(select-keys % [:created]) histories)
mapv
if you really want a vector back instead of a sequence @dmbennett