This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-02-23
Channels
- # admin-announcements (1)
- # announcements (1)
- # beginners (222)
- # boot (210)
- # cider (26)
- # cljs-dev (50)
- # cljsrn (19)
- # clojure (243)
- # clojure-art (12)
- # clojure-finland (1)
- # clojure-poland (43)
- # clojure-russia (46)
- # clojure-sg (13)
- # clojurescript (60)
- # core-async (14)
- # css (11)
- # datomic (9)
- # devcards (9)
- # dirac (2)
- # editors (13)
- # emacs (5)
- # euroclojure (1)
- # events (3)
- # hoplon (76)
- # immutant (10)
- # job (1)
- # jobs (2)
- # keechma (1)
- # ldnclj (33)
- # lein-figwheel (1)
- # leiningen (20)
- # luminus (26)
- # mount (31)
- # om (105)
- # onyx (56)
- # parinfer (29)
- # perun (12)
- # proton (1)
- # re-frame (14)
- # reagent (5)
- # sydney (1)
- # yada (15)
Oddly, i feel this might be the best place to ask this question. Whats a good resource (book, blog, course, etc...) for learning java (v8 is perfered)? I picked out "Java for the impatient" and "java a beginners guide". I'm not enjoying the later as much as i would have hoped.Though im only on the first chapter.
Hi there, i was wondering if anybody can tell me about return statements in clojure? As in me creating a function that returns something. I googled it but it didnt really turn up anything except for a person saying there is no return statement in clojure.
is that true?
As a lisp, clojure doesn’t have statements, only expressions
would i be able to get a function to return a list?
ive done java but im new to clojure and lisp
Yes, clojure fns return values, including lists. You might want to skim through an introductory guide, e.g. http://www.braveclojure.com/introduction/
ive read that, but im looking for the way to return the list, may i ask whats the keyword for returning values? like if i wanted to return "List X" in java it be " return X", whats the clojure equivalent of "return" ?
jack_liang: there is no keyword for returning values. Clojure has “implicit return values"
an example, to return the list [1 2 3]
from a function
(fn [] [1 2 3])
or to return the string “hello” from a function
(fn [] “hello”)
as long as your return value is the last expression in your funtion, it will be returned implicitly, does that make sense?
sort of
so lets say i have (fn [] (println "Jeff") (def ret ("jeff")))
does that return the value "jeff" ?
(fn []
;; do anything with Jeff you want here
“Jeff”)
do you have a clojure repl available that you can play around with? That will help a lot I thiink
im more comfortable editing a clj file and just running it
hey @jack_liang it's tricky to come from java- from that perspective, clojure does a lot of stuff implicitly, whereas in java it's all done explicitly. return statements are one example. if statements are another- the else part of an if in clojure is implicit. one has to retrain one's eyes to read what are referred to as "forms" into the syntax that you're familiar with
anyway- in your example, the second "jeff"- in ("jeff")- will cause clojure's compiler to complain, because it will want to treat the string "jeff" as a function. but strings aren't functions in clojure.
if you change it to (fn [] (println "Jeff") (def ret "jeff"))
so will the following work? (fn [] (println "Jeff") (def ret "jeff") ret)
well- what you get from that is a function- which, if executed, will print "Jeff" (to System.out in java terms) and return "jeff" to whatever calls the function
ok thanks
so i can just leave the variable at the end of the function and if looking for return value, that variable will be the value
well, variables are another thing that work differently in clojure than java. the (def ret "jeff") creates a kind of global variable called "ret"
it's better to create local variables, using the let statement
(let [ret "jeff"] ret)
so essentially (fn [] (println "Jeff") (let [ret "jeff"] ret) ret)
get rid of the second "ret"
(fn [] (println "Jeff") (let [ret "jeff"] ret) )
the lifetime of the "ret" in the (let ) block is only to the closing paren of the let
like that?
so if i left that second let, i suppose compiler complains that it doesnt know what the hell the second ret is?
correct- if you left in that second "ret", the compiler would complain. that symbol went out of scope at the close of its defining let
so for local instances, do i have to nest lets for each local instance?
no, you can include multiple "bindings" within a single let
(let [a "jack" b "jeff" c "jonah"] b)
will return "jeff"
but within that closing paren, variables a, b and c have values
a has value "jack"
b has value "jeff"
c has value "jonah"
thank you , you are very helpful
i think i got the gist of it
sure thing. it can be tricky to retrain the eyes to read things in the clojure/lisp manner, but once you get there it's pretty cool
good luck!
thank you!
i mean "def c" to "println"
def
creates a top-level "global" binding.
Remember there really are no "variables" in Clojure -- you don't "assign" to vars, like you would in other languages.
may i ask how you would go about this? what im trying to do is traverse a list of contraction words and replace the existing contraction words in the string with the base words, like replacing can't with cannot
The closest construct to what I think you're trying to do is (loop [bindings... ] (if (end-condition) result-expr (recur updated arguments)))
Since you want to work on a sequence of words and just replace each word with either its expanded version or itself, you probably want map
...
In general, in Clojure, you work on whole collections rather than "iterating" / "looping" like you would in imperative languages.
how would you work on a whole collection ? when i hear a phrase like that, i think looping, I come from a background of java
map
/ filter
/ reduce
.
I think for your problem you'd want a hash map from contracted words to their expanded form {"can't" "cannot", "won't" "will not", ...}
and then you'd map over the collection like this: (map #(if-let [expanded (contractions %)] expanded %) word-list)
where contractions
is that hash map with all the contractions and their expanded forms
You generally use map
when the result collection has the same number of elements as the input collection. You use reduce
when you're going to a different type of result -- a different collection type or a "reduced" collection (such as aggregating / counting values). And filter
when you just want to remove some elements that match some condition.
Does that help?
Coming from Java to Clojure can be a big, confusing change. Pretty much everything you're used to in Java is... different in Clojure. No variables, no mutable data (well, mostly no mutable data), so no side effects (for the most part) and no loops in the Java sense...
are the # and % actually part of the syntax in your snippet?
sorry, yea they are
#( ... % ... )
is an anonymous function.
You could say (fn [word] (if-let [expanded (contractions word)] expanded word))
i see
Would this look simpler to you: (fn [word] (get contractions word word))
?
get
takes a collection and a key, and a default value...
I wasn't sure whether the explicit if
would be easier to follow...
oh i understood, took me a min cuz of the if-let but i understood
i noticed you used "word-list", if i had a sentence, wouldn't i have to tokenize it into a list to use the map implementation you mentioned?
(str/split sentence #" ")
or something more sophisticated...
so yes id have to have it in list form somehow before i can use implementation
i do have a tokenizing method so that wont be too hard
Ah, so you were replacing substrings in place? Hmm, well, then you could reduce
over the contractions
and do it that way...
Originally i have "I can't walk" and after replacing, i was hoping to have "I cannot walk"
(reduce (fn [s w] (str/replace s w (contractions w))) sentence (keys contractions))
(keys contractions)
gives you the sequence of contracted words -- the keys -- of the contractions hash map
So that expression starts with the sentence
as the initial value and a collection of contracted words, and "reduces" that by replacing each contracted word by the expanded equivalent...
(sorry for the edits, I'm doing this in my head, rather than a REPL like I should be!)
its alright, im just happy somebody responds at 1:23am
for the record, I dont use repl whe i probably should, i edit the clj file and run via cmd
Experimenting in the REPL is a great way to learn how various Clojure functions work.
i never really got the gist of repl, i mean...entering code 1 line at a time? Gets messy
Clojure isn't line-based tho', it's form-based. It's designed to be compiled and executed one form at a time.
i might have been going about it wrong then, ill give it a shot, but nothin beats an old fashion editor! at least in my opinion
@jack_liang: The best Clojure experience is an editor with a built-in REPL where you can write code and evaluate it with just a key stroke... Since you're coming from Java, are you used to Eclipse or IntelliJ?
ive used both
but for some reason, intellij wont print so i opted for notepad++ and cmd
For Eclipse, there's Counter Clock Wise, and for IntelliJ, there's Cursive.
i feel like it wont print for a very stupid reason but i cant put my finger on it
Based on the code you showed earlier, I suspect you're running foul of a couple of things: 1. (println "whatever")
evaluates to nil
(even tho' it prints the string, it's result is nil
); 2. if you have a lazy sequence and don't consume the values, you won't get the side effects of any functions in those expressions either.
im sorry, consume the values?
you mean using the values?
For example (let [s (map println [1 2 3 4 5])] "Hi!")
-- evaluates to "Hi!"
but prints nothing because s
is not "consumed" so map
's value is never evaluated.
i see
sorry, maybe its time to go to bed for me. Thank you for educating me in the mysterious and somewhat confusing ways of clojure.
You're welcome! Folks here are all very helpful around the clock!
Are transducers always evaluated eagerly? Or can I create a lazy sequence with them?
lets say for some reason I would like a function that gives me all of the even squares of the natural numbers
(def even-squares (into [] (comp (filter even?) (map #(* % %))) (iterate inc 1)))
if I then do (take 10 even-squares) it will hang as it seems to try to create all of the even squares before taking the first ten
(def even-squares [n] (into [] (comp (filter even?) (map #(* % %)) (take n)) (iterate inc 1)))
that seems to fix the issue, but then I do not have a way to take about the whole sequence, but rather some sub sequence of the whole
into []
is an eager reduction.
so if I changed into [] with sequence would that change things?
Try it and see.
According to its docstring, sequence
will not force a lazy seq and it returns a lazy seq.
yeah it seems to work! thank you
(after midnight here and I've been traveling all day so I'm out)
OK, cool.
How would you accurately time something like that?
if I would like to benchmark the time it takes to generate the sequence
(defn even-squares [n] (take n (sequence (comp (filter even?) (map #(* % %))) (iterate inc 1)))) (defn even-squares-2 [n] (take n ((comp (partial filter even?) (partial map #(* % %))) (iterate inc 1)))) (do (time (even-squares 1000000)) (println "even-squares")) (do (time (even-squares-2 1000000)) (println "even-squares-2"))
I tried doing that
but I am getting garbage times that are impossible
Elapsed time: 0.059917 for even-squares
0.226008ms for even-squares-2
@adamkowalski: You need to realize the lazy seq. (`dorun` e.g)
thank you now I am getting 282ms for the transducer version and 588ms for compose and partial version
can you still use things like pmap with transducers
totally newbie quiestion: how can i perform basic javascript:
let arr = [{title: “Tiltle”, value: 33}. {title: “Another”, value: 11} … ]
arr.map(i => {
return {
title: i.title.toUppercase(),
value: i.value++
})
i try to do same in clojure, but not sure i’m doing it right
this must be very easy, but i’m kinda stuck
(into [] (map #({:title (:title upper-case)
:id (inc id)}
%) arr))))
this obviously fails
Mmm maybe (into [] (map (fn [{:keys [title value]}] {:title (clojure.string/upper-case title) :value (inc value)}) arr))
yeah, i’m looking into this, thanks!
Could I ask for some quick help from anyone hopefully this is question is not that Garden specific. I am trying to use pseudo elements. When I do this (defpseudoelement after)
and run this (css [:body after {:background 'blue}])
in the repl I get back this "body, ::after {\n background: blue;\n}"
. Not sure how to stop the comma from after body.
@olegakbarov: maybe this is a little more readable (into [] (map #(-> % (update :title clojure.string/upper-case) (update :value inc)) arr))
yea, this looks nice
i try this, but it throws in repl:
(map #({:title (-> % :title .toUpperCase) :value (-> % inc}) arr)
I think it's because you can't just put a map in first position in the form, it has to be a function
this last notation, i don’t quite get it
I'm not entirely sure you can put js methods in a threading macro like this, but I've never tried
or like this, but not as short as the ones above
(->> arr
(map (fn [e] ((comp
#(update-in % [:title] clojure.string/upper-case)
#(update-in % [:value] inc)) e))))
oh wow
i’m really surpirised, that it takes quite an effort to perfrom such a trivial operation
yeah this do works! 😃
i use this pattern all of the time in JS/React, need to get to the bottom of this in Clojure
update-in
is cool and works (thanks again) but there have to be an easier way
(map #(into {} [[:title (-> (clojure.string/upper-case (% :title)))] [:value (-> (inc (% :value)))]]) arr)
I think some of what @stuartsierra says in http://stuartsierra.com/2015/06/10/clojure-donts-heisenparameter is that you should strive to write functions which operate on one thing.
So for the problem above, I’d write a function like (defn frobnicate [{:keys [title value]}] {:title (clojure.string/upper-case title) :value (inc value)})
which may or may not be more or less performant than the other solutions, but I’d leave that for the day when it becomes a proven problem.
i’ve just came up to similar approach!
moved function that processes item in map to separate function
(defn process [item] {:title (-> item :title .toUpperCase) …})
(into [] (map process arr))
hehe, cool
one caveat — i want to drop some existing values
so i have raw database data — with timestamps and stuff, and i want just to pull some values and format them
(thanks for mapv, i’ll take a look)
let’s see 😊
Hey everyone, been working with Clojure past few months (coming from a Java background). One of the few things that I dont comprehend yet is how do you really design large, complex multi layered systems in Clojure? Have you come across a good guide or book that deals with this subject. Thanks for your advice.
@moizsj: there is quite neat talk from Clojure/West on how Walmart uses Clojure https://www.youtube.com/watch?v=av9Xi6CNqq4
a propos select-keys
, I find I agree to the comment on the bottom of this page https://clojuredocs.org/clojure.core/select-keys
which is why I’d really like to see flip
in clojure https://www.haskell.org/hoogle/?hoogle=flip
Hello, how can I test the equality of regexes since simple patterns such as this fail:
(is (= (re-pattern "ab\\?c") (re-pattern "ab\\?c")))
hey @urbanslug: (str ...) on the results of re-pattern should return the original string used to create the pattern object. e.g. (= (str (re-pattern ...) (str (re-pattern ...)))
@urbanslug: @jonahbenton is right. str effectively calls .toString on the java.util.regex.Pattern that re-pattern returns. So, I guess the other question is why is the hash code of a java.util.regex.Pattern different for the same pattern?
Found the JDK issue: https://bugs.openjdk.java.net/browse/JDK-7163589
Is there a way to specify you want to install phantomjs in your project.clj? It doesn't seem to be where lein gets its deps.
found a blog post w/ clojure & phantomjs usage: http://blog.testdouble.com/posts/2015-10-12-configure-leiningen-for-clojurescript-and-clojure-testing.html
is it a good idea to use :pre and :post conditions as a type checking mechanism? or is this going to cause performance problems?
like if I have a function which expects a vector should I have a (defn my-function [my-vector] {:pre [(vector? my-vector)]} (do-something-with my-vector))
@adamkowalski: : you can do that or if you need more complex checking most people use Prismatic’s Schema library. You can decide when to use schema and take the performance hit.
interesting, and what about core.typed?
as far as I know that only works with clojure but not clojurescript right? but pre/post and schema works with both?
most in the community seem to be okay with schema as a sort of contracts rather than types setup
ok well i’m just glad to know it seems like there are a few options to validate your code, because sometimes purely dynamic languages seem to be a little scary to me
Yeah that is fair. I tend to find that when I am working toward a solution I don’t want anything to get in they way. Then when I know exactly what code should do I “lock it down” with schema checks if necessary.
yeah that makes sense, but I think that generally what ends up happening without a type system is that you end up relying more on TDD to compensate
not saying that is good or bad, but I think that in the long run having a way to make certain assertions about what your code can and cannot do can actually save you time in the long term
Yeah, to each their own. Dynamic vs. Static has been debated endlessly. In the end most of my issues don’t have anything to do the code but rather the complex interactions of a large systems. I do enjoy some of the benefits of typed code but in general find that I am much more productive in a dynamic environment.
I definitely see the appeal of dynamic languages and they are certainly starting to grow on me, especially with features like transducers which I don’t know how you could express in a type system
and with things like property based testing it makes it much simpler to check the things that could actually go wrong with your program in addition to unit testing
but when I was learning Haskell, one thing I loved is how I could look at the type signature of a function and immediately know exactly what I could put into a function, and what I could expect to get out
with clojure, it is generally up to the discretion of the author to have valuable doc strings, and well named functions/parameters that state the purpose of the function
which is why I would like to try out either pre/post or core.typed or schema for validation, but I dont know if this will be removed in production so I do not pay a performance penalty or if these things stay and will always be ran.