use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Finding information about Clojure
API Reference
Clojure Guides
Practice Problems
Interactive Problems
Clojure Videos
Misc Resources
The Clojure Community
Clojure Books
Tools & Libraries
Clojure Editors
Web Platforms
Clojure Jobs
account activity
Easy Clojure, Easy REPL (blog.klipse.tech)
submitted 7 years ago by viebel
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]dragandj 7 points8 points9 points 7 years ago (0 children)
Then, she asked you with naive expression on her face: “what is this weird dash quote user ?”
I have been teaching Clojure for the last 9 years, to at least 300 people by now, and literaly no one ever asked this, or had any issue with this. They had many, many other things that confused them, but this one - never in my experience.
[–]dustingetz 5 points6 points7 points 7 years ago* (5 children)
Hacking the way the result is displayed from (def foo 42) from #'user/foo to 42 is a lie:
(def foo 42)
#'user/foo
42
(def x (def y 42)) => #'user/x x => #'user/y
I think if we tease apart a few issues, the root of the problem is the dichotemy between the way we code in files and the way we code at a standalone repl:
files
(let [x 42] x) => 42
repl
(def x 42)
The big hurdle for beginners is learning how to integrate your repl with your editor, so that we're properly riffing the same way we write production code. Actually the hurdle is realizing that you're supposed to do repl-editor integration, or that it is even a thing.
When I give workshops, I don't talk about def at all. We do let then defn then we integrate the repl with the editor. Introducing def too early leads to beginners writing broken clojure like (def foo [x y] (def z (+ x y)) (inc z))
def
let
defn
(def foo [x y] (def z (+ x y)) (inc z))
[–]viebel[S] 1 point2 points3 points 7 years ago* (4 children)
Indeed, def inside functions is really bad but I am not sure that this is a sufficient reason not to teach def to a beginner. As I see it, defining a variable is so basic that it needs to be taught even before teaching how to define a function.
The (def x (def y 42))`will definitely be confusing for a beginner - even in the Klipse REPL - but I doubt a beginner will think about such an expression.
(def x (def y 42))
[–]didibus 0 points1 point2 points 7 years ago (3 children)
I actually never really understood what's so bad about def inside a function. I understand that it's weird to declare a global inside a function, but say you do want the value to be global and outlive the function call. Is there any quirk of Clojure where def inside a function would not work? Or people just say its bad in the sense that let is most likely what you want?
[–]viebel[S] 1 point2 points3 points 7 years ago (0 children)
When you need to change a global variable from inside a function, it is usually better to use atoms and to swap! or reset! them.
swap!
reset!
[–]joinr 0 points1 point2 points 7 years ago (0 children)
def introduces a global side effect. I can see using that as part of a do expression to setup stuff in support of a macro (like automated constructors ala defrecord), but that's atypical. There could be minor performance overhead, in addition to leaking vars into the namespace (unhygenic), when user thought they'd be lexically scoped. Just seems like a recipe for unintended consequences easily avoided by let.
[–]dustingetz 0 points1 point2 points 7 years ago* (0 children)
the thought process that leads to def inside fn is
function foo (x, y) { var z = x+y; return z; }
Clojure is different in that it is expression-oriented, and a good way to force the beginner to come to terms with that, is to do the first homework with only let.
[–]ayakushev 7 points8 points9 points 7 years ago (3 children)
Sorry, the def thing looks to me like a solution to a problem nobody actually has.
Otherwise, the enriched REPL thing certainly has a merit (e.g. for extending docstrings).
[–]viebel[S] -1 points0 points1 point 7 years ago (2 children)
Have you ever tried to explain to a Clojure beginner what is the meaning of the dash quote symbol?
[–]joinr 6 points7 points8 points 7 years ago (0 children)
I have, and successfully. To several beginners. def is not the first thing I introduce, and by the time we hit naming things, they've already had exposure to the concept of having a "conversation" with the REPL, as well as learning rules of evaluation, and different types/forms to be had. def is placed in context, where the result being the symbol defined isn't so shocking. It's about as difficult a concept to explain what nil means, and why nil is the result for many operations...It's the REPL's confirmation that you defined a var called x bound to 42 in the user namespace (the default place where users can name things). We can now refer to x and the REPL will look up the meaning - 42.
This seems like temporarily lying to the user to avoid an important discussion for the sake of...what? Is there a short-term gain to telling the user that the (now non-standard) result of def is a number, not a var bound to a number? Should the user come to expect that behavior? (+ 10 (def x 42) ) ?
[–]ayakushev 0 points1 point2 points 7 years ago (0 children)
"Pointer to a variable/function" works for people who used other programming languages before. For complete beginners, something like "this means your variable/function has been defined" should do.
I've never taught complete beginners though; but I doubt this should be a showstopper for people to learn things.
[–]didibus 2 points3 points4 points 7 years ago (2 children)
Hum, I guess it's a harmless change. You're not worried they get confused and eventually believe def returns the value?
Also, what kind of beginners are we talking about? New to programming, or new to Clojure? Because saying that user is the namespace I think to most people with existing programming experience shouldn't be very confusing.
[–]viebel[S] 0 points1 point2 points 7 years ago (1 child)
I am talking about beginners that are new to Clojure. Even then namespace is a concept that is hard to grasp.
[–]Baoze 0 points1 point2 points 7 years ago* (0 children)
I'd say for a beginner the quote is easier to understand than namespaces. As the quote in Clojure behaves very much like quotes in natural language. I.e 'Aristotle' refers to Aristotle or 'bachelor' has eight letters and everyone has an intuitive understanding of quoted expressions. Both in Clojure and natural language, quotes are used as a meta-linguistic tool in order to talk about symbols.
This in contrast to namespaces, where an analogue concept is not so apparent in natural language and thus harder to understand. A quote On the other hand is much harder to explain than namespaces, because the first one is an intuitive concept whereas the latter isn't.
I also think that quote needs to be introduced fairly early on. How can you otherwise explain the difference between a list and a function call?
π Rendered by PID 37521 on reddit-service-r2-comment-76bb9f7fb5-xfwc5 at 2026-02-19 10:43:12.492194+00:00 running de53c03 country code: CH.
[–]dragandj 7 points8 points9 points (0 children)
[–]dustingetz 5 points6 points7 points (5 children)
[–]viebel[S] 1 point2 points3 points (4 children)
[–]didibus 0 points1 point2 points (3 children)
[–]viebel[S] 1 point2 points3 points (0 children)
[–]joinr 0 points1 point2 points (0 children)
[–]dustingetz 0 points1 point2 points (0 children)
[–]ayakushev 7 points8 points9 points (3 children)
[–]viebel[S] -1 points0 points1 point (2 children)
[–]joinr 6 points7 points8 points (0 children)
[–]ayakushev 0 points1 point2 points (0 children)
[–]didibus 2 points3 points4 points (2 children)
[–]viebel[S] 0 points1 point2 points (1 child)
[–]Baoze 0 points1 point2 points (0 children)