This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-12-06
Channels
- # adventofcode (181)
- # aws (6)
- # beginners (112)
- # boot (38)
- # cider (11)
- # cljs-dev (12)
- # cljsrn (2)
- # clojure (187)
- # clojure-greece (31)
- # clojure-italy (19)
- # clojure-new-zealand (1)
- # clojure-poland (1)
- # clojure-spec (20)
- # clojure-uk (114)
- # clojurescript (97)
- # core-logic (25)
- # cursive (3)
- # data-science (17)
- # datascript (3)
- # datomic (23)
- # defnpodcast (1)
- # duct (5)
- # emacs (3)
- # fulcro (299)
- # graphql (108)
- # jobs (1)
- # juxt (4)
- # lein-figwheel (7)
- # leiningen (1)
- # lumo (9)
- # nrepl (2)
- # off-topic (10)
- # om (2)
- # onyx (36)
- # pedestal (1)
- # perun (3)
- # re-frame (14)
- # reagent (12)
- # ring (2)
- # rum (11)
- # shadow-cljs (6)
- # spacemacs (4)
- # unrepl (8)
when i run lein figwheel
, the resulting REPL that i have access to - how do i navigate in it? i can't use arrow keys to navigate within the block i'm typing, or pressing up arrow doesn't reveal last command, etc
@aconanlai calling it as rlwrap lein figwheel
will give you typical readline stuff like up-arrow for history. Stuff like navigating between lines depends on the environment. For stuff like that, I'd recommend starting figwheel from inside an editor/IDE instead of from a terminal.
(you many need to install rlwrap if you don't already have it -- see https://github.com/hanslub42/rlwrap )
Hi everyone, is fdef
in spec doesn't actually validate the input and output of the function when the function is called?
I'm having some problem with my code, and if I run it in cider-debug I can see what the problem is, but I dont understand why.
(loop [sheet spreadsheet
checksum 0]
(if (empty? sheet) checksum
(recur (rest sheet) (+ checksum (calculate-list (first sheet)))))
it is indeed working now. So the order of the loop and the recur need to be the same.
Hi guys, how to avoid nesting during error checking?
(defn foo [x y z]
(if (< x 0)
(throw (IllegalArgumentException. "Positive x is required"))
(if (> y 0)
(throw (IllegalArgumentException. "Negative y is required"))
(if (= y -100)
(throw (IllegalArgumentException. "Y -100 is prohibited."))
(if (or (< z 0) (> z 100))
(throw (IllegalArgumentException. "Z in (range 101) is required"))
(* x y z))))))
@ghsgd2 If only checking the args, I use pre conditions like this:
(defn foo
[x y z]
{:pre [(< x 0) (> y 0) (= y -100) (or (< z 0) (> z 100))]}
(* x y z))
thank you, @rahul080327!
Is it a good coding style to count :bar
the following way (is that optimized by compiler)?
(count (filter #(= % :bar) [:foo :bar :bar :foo :foobar]))
@ghsgd2 if you want to keep your messages for the exceptions and also avoid nesting, I’d recommend the cond
function:
user=> (defn foo[x y z]
#_=> (cond
#_=> (< x 0) (throw (IllegalArgumentException. "Positive x is required"))
#_=> (> y 0) (throw (IllegalArgumentException. "Negative y is required"))
...
#_=> :else (* x y z)))
#'user/foo
user=> (foo -1 2 3)
IllegalArgumentException Positive x is required user$foo.invokeStatic (:3)
@tonywang897
>`(:bar (frequencies [:foo :bar :bar :foo :foobar]))`
but it will be doing unneeded work computing frequencies of :foo
and :foobar
@sammy.castaneda90 that's an option, thank you!
@ghsgd2 1. Exceptions stop evaluations of the function, so no need for an else
. You can just do (when x (throw...)) (all good to go)
2. (count (filter ...))
won't be optimized by the compiler. It'll generate the sequence lazily. If you need performance you'd have to reduce this yourself or use transducers.
@rauh 1. So it will be (do (when x (throw...)) (when y (throw...)) (all good to go))
.
2. I. e. reduce
or transducers.
I see. Thank you a lot!
@diginomad none of the lazy sequence has been realized because it hasn’t been used. It’s lazy in the sense that it won’t do anything with the [1 2 3] at all until you actually use it by passing it as an argument to a function like seq
lazy-seq is a macro that wraps the body into a fn. in that case the fn is (fn [] [1 2 3])
you can see it if you type (macroexpand ’(lazy-seq [1 2 3])) into your repl
no, it returns a clojure.lang.LazySeq object
if you’re using a repl it makes things like lazy seqs a little harder to understand because the repl will automatically realize the sequence to print it to the screen.
I think a quick rule of thumb is that if you’ve never used the lazy seq anywhere besides where you’re binding it, then it hasn’t been realized.
well, if the list already exists in memory somewhere, then wrapping it into a lazy sequence doesn’t really do a whole lot. in the lazy-seq case, if you’re wrapping a vector in a lazy-seq then that vector is completely held in memory.
it really depends on where you’re getting the list from. For instance, if you’re reading it from a file, then it’s definitely possible to read it from the file as a lazy sequence.
The main thing to remember about lazy seqs is that if you expect (prn foo)
to give you [1 2 3]
and instead it gives you LazySeq@84038
, you need to put a doall
around foo
to realize it into the actual values you’re expecting.
And of course to make sure the value of foo
won’t go bOOM.
How could it be realized if it's printed as LazySeq@7c42?
> (realized? (doall (map #(inc %) [1 2 3])))
true
> (str (doall (map #(inc %) [1 2 3])))
"clojure.lang.LazySeq@7c42"
Wow, that surprises me
seq
works
(str (seq (map #(inc %) [1 2 3])))
=> "(2 3 4)"
but I would have expected doall
to return a realized value.
@manutter51 I expected too. Thank you!
Use pr-str
pr is for printing as readable data
@alexmiller Curious:
(pr-str (map #(do (println "hello world")(inc %)) [1 2 3]))
"(hello world\nhello world\nhello world\n2 3 4)"
It captures System.out output too.Yes, it will for the -str variant. If realizing your data structure has side effects, then you should realize it first
Is there a function or idiom for mapping conditionally? e.g.
(map-when odd? #(* % 2) [1 2 3])) -> [2 2 6]
I don’t know about idiom per se but there’s #(cond-> % (odd? %) (* 2))
as a function
(yeah, that's what I was typing in as the answer!)
And that's another case where I'd reach for the predicate-threading variant we have in our "util" library at work: (map #(condp-> % odd? (* 2)) [1 2 3])
🙂
oh nice - I’ve wanted to write condp-> but also wasn’t sure of the name
We've had condp->
and condp->>
for ages in our code base -- they can be so useful! Another one of our utilities I use a lot is flip
(modeled after Haskell) which is like partial
except you omit the first argument.
At some point I hope we'll open source the namespace that has those things in it...
It also has dissoc-all
and interleave-all
.
a coworker named flip
qartial
since q
is flipped p
Anything in particular you looking to do with core.match or just curious about leaving it out?
Not specially, but I thought pattern matching was the functional way of solving a basic problem I'm having
I'm writing a cli that can do different actions, with different parameters, for example action1 arg1 arg2
and action2 arg1 arg2 arg3
I thought that match was an easy way to both dispatch each action to it's corresponding function and verify that they had the correct arguments
@dromar56 If you just want to dispatch on a string for the action and handle those cases separately, a multimethod might be a reasonable approach -- if you don't want the full-on argument parsing of tools.cli
(which is geared much more to Posix-style command lines).
Yes since it's a learning project I think I'll use destructuring and multimethod for now
(I maintain tools.cli
but I'm perfectly happy to point folks at simpler solutions 🙂 )
So I got this:
(defmulti action-dispatch first)
(defmethod action-dispatch "action1" [[action arg1 arg2]]
(if (and (string? arg1)
((every-pred number? pos?) arg2))
(do-something action arg1 arg2)
(print-usage)))
(defmethod action-dispatch "action2" [[action arg1 arg2 arg3]]
(if (and (string? arg1)
(string? arg2)
((every-pred number? pos?) arg3))
(do-something-else action arg1 arg2)
(print-usage)))
(defmethod action-dispatch :default [_]
(print-usage))
Oh I guess I could remove all calls to print-usage and instead do something like (when-not (action-dispatch args) (print-usage))
you could make a dispatch function that either returns ::error or (first arg1) then have a single dispatch to print your usage
then do all the validation in the dispatch
maybe that’s hacky
Command line arguments are all strings so I wouldn't expect number?
to return true...
It would be a long dispatch function, since it has differents kinds of arguments for each action
Convert, (Long/parseLong arg2)
and catch exceptions. Not cast.
@dromar56 what about two multimethods - one for action-dispatch and antother for validating the action
and both could dispatch on the first item in the coll
then (if (validate args) (dispatch args) (print-usage))
Convert, (Long/parseLong arg2)
and catch exceptions. Not cast.
or (defprotocol IAction (validate [this arglist]) (execute [this arglist])) and select some instance of IAction based on the first item in the arglist (?)
that seems nice @noisesmith, I will try the defprotocol method since I haven't used it yet
then you’d have like (def action1 (reify IAction (validate [this args] (and (string? (first args) …)) (execute [this args] (do-something …))
one for each action
haha sometimes I forget what channel I’m in
I’m just going to leave this here to hopefully get us back on track lol https://www.braveclojure.com/