This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-26
Channels
- # beginners (145)
- # boot (19)
- # calva (61)
- # cider (33)
- # cljs-dev (15)
- # cljsrn (16)
- # clojure (35)
- # clojure-dev (39)
- # clojure-russia (2)
- # clojure-spec (10)
- # clojure-uk (7)
- # clojurescript (5)
- # cursive (14)
- # data-science (1)
- # datomic (3)
- # figwheel-main (9)
- # fulcro (46)
- # jobs (4)
- # off-topic (8)
- # quil (6)
- # re-frame (5)
- # shadow-cljs (70)
- # spacemacs (3)
- # speculative (2)
- # tools-deps (2)
Can I do a defmethod
based on runtime state from component / integrant?
In other words, when is having defmethod
not at top level justified, if at all?
a defmethod mutates a multimethod and adds a method to it, and the only way to create a multimethod that clojure exposes is via defmulti, which creates a var containing a multimethod
so using defmethod, or defmulti outside of the global scope (not as a toplevel form) is at least questionable
I'm looking to turn an arbitrary block of ones and zeros into the corresponding number
@shawx538 This should work if you need larger numbers (Long/parseLong "10101010101" 2)
hey guys, i am playing at trying to understand some clojure source code, and i need help to understand the or
implementation. can you guys go through each line of the or
body and explain it to me, please
(defmacro or
"Evaluates exprs one at a time, from left to right. If a form
returns a logical true value, or returns that value and doesn't
evaluate any of the other expressions, otherwise it returns the
value of the last expression. (or) returns nil."
{:added "1.0"}
([] nil)
([x] x)
([x & next]
`(let [or# ~x]
(if or# or# (or ~@next)))))
for some how, i think be able to read the source code and understand it can help me to get a better understanding of clojure
So yeah, four functions or macros you can provide any number of arity implementations. That there is a macro, so it's going to have some more complex syntax
If that much makes sense, what else seems mysterious about it still? The if
? The let
binding?
A lot of the extra punctuation is there because it's a macro. Macros are functions that write other functions, like templates
yeah i read that they are kind of functions but are not evaluated or something like that
That or would return to nil from the last println, because it'll keep calling itself until it gets a truthy value or runs out of things
Until you reach an else with a single element in the or like (or false)
and that will call the one arity or, which just returns the value passed in
Inside a quoted form, an unquote symbol will grab the thing from the outside, compiling environment.
So (or 1 2 3)
after all expansions becomes:
(let [v 1]
(if v
v
(let [g 2]
(if g
g
3))))
Inside a quoted form, an unquote symbol will grab the thing from the outside, compiling environment.
So like, in the or
form:
(defmacro or
([] nil)
([x] x)
([x & next]
`(let [or# ~x] ;; <- syntax quote starts on this line with the ` symbol
(if or# or# (or ~@next))))) ;; <- a syntax unquote starts on this one with the ~ symbol
~@
is a "splicing unquote," which will remove the parenthesis from around whatever's being unquoted
the #
symbol attaches some extra metadata to the or
variable so that it does not clash with other instances of or variables that may be recursively defined, so that it doesn't clobber itself
usage of the word "or" for that variable in the let binding is probably unhelpful from an understanding perspective
y#
perhaps, since x
is already being used in the outside context, which would just add to the confusion π
It's normally called from within a macro... and specifically, from within a form that is being syntax quoted
thank you very much @john and @didibus, you've taught me a lot in such a short time π
also study the when
macro:
(defmacro when
[test & body]
(list 'if test (cons 'do body)))
also check out if-not
:
(defmacro if-not
([test then] `(if-not ~test ~then nil))
([test then else]
`(if (not ~test) ~then ~else)))
Just remember, everything inside a ()
is a form. Everything inside a syntax quoted form ()` is a like a future form. It turns into a present form after being evaluated once. Anything unquoted within a quoted future form, will be injected into the future form from the present form.
so, in the above if-not
macro, test, then and else are all existing as their present values in the present macro form
the if and the not, within the syntax quoted form, do not exist as present values... you can think of them like strings
everything between the ` and the ~ is like a string. Everything inside the form or value to the right of the unquote symbol will be pulled out of the present form and written into the template, like concatenating present and future values together.
so test, then and ~else are pulling the present values and pasting them into a string that will become a form that looks like an if statement with the test cond negated.
@john πππβοΈ you're explanation did really help, i am going to keep it somewhere close and read it again again again again π
@john FYI, for single backticks:
`()
(defmacro if-not
"Evaluates test. If logical false, evaluates and returns then expr,
otherwise else expr, if supplied, else nil."
{:added "1.0"}
([test then] `(if-not ~test ~then nil)) ====> so this line will end up calling this one (if (not ~test) ~then ~else) ?
([test then else]
`(if (not ~test) ~then ~else)))
(with else
bound to nil
)
but i1ve look for if
implementation in clojure and didn't find one. so is the clojure if
using the java one?
if
is a special form in Clojure, so it's built into the compiler.
huummm sorry @seancorfield i don't know what you mean by that π
"special form" means a primitive within the language
So you won't really find a definition, except in the documentation or deep in the source code of the compiler itself.
(but that page shows just how small the core language really is -- everything else in Clojure is built on top of those special forms)
(defmacro when
"Evaluates test. If logical true, evaluates body in an implicit do."
{:added "1.0"}
[test & body]
(list 'if test (cons 'do body))) ===> (if test (do body))
(when true (prn "Maflany" (prn 1) (prn 2) (prn 3)))
=> (list 'if true (cons 'do (prn "Maflany" (prn 1) (prn 2) (prn 3))))
=> (if true (do (prn "Maflany" (prn 1) (prn 2) (prn 3))))
Almost. Since a macro deals with code, it's as if the value of body
was quoted: (list 'if true (cons 'do '(prn "Maflany" (prn 1) (prn 2) (prn 3))))
-- note the '
before the prn
form.
But, yeah, the end result is as if you had typed in that code (if true (do ...))
The is at the heart of Clojure's (Lisp's) "code is data" mantra.
@quieterkali I only meant in terms of your code substitution -- you wrote (list 'if true (cons 'do (prn "Maflany" (prn 1) (prn 2) (prn 3))))
but that's not the same as (list 'if true (cons 'do '(prn "Maflany" (prn 1) (prn 2) (prn 3))))
The former would evaluate the (prn ...)
form before making the list. The latter will leave it as code.
With a macro, your arguments are code so they are substituted as-is -- as if they were quoted forms, rather than forms to be evaluated.
It's a subtle point, but it's important with macros.
hey @seancorfield, so you mean since my body
was a form so it should had take quoted
to not be evaluated so early, but is it was only a variable, a literal like 42 "string" or any other
then he wouldn't need a quote
. Am i right?
Correct. Strings, numbers, keywords all evaluate to themselves
I'm looking at the java-time clojure wrapper and they use this for their documentation:
(refer-clojure :exclude [range iterate format max min])
(use 'java-time)
how do I include the library behind a alias like (datetime/max ...)
or (datetime/local-date ...)
?Hi, is there any way to run use-fixtures
just once for the whole testing session? I want to do integration testing and starting/stopping for each ns seems like a bad idea (?). Actually I'm not sure about this, can someone give me some feedback.
global testing fixtures donβt exist in vanilla clojure.test, but https://github.com/circleci/circleci.test has it
for integration testing I use something different, just wrap run-tests with my own function, not using fixtures
Hi guys! I have some problems with getting cider to work with clojurescript and figwheel and I must admit it's getting kind of frustrating. Would someone be able to help me?
My hiccup's rendering with weird characters for commas and quotes like this Γ’β¬β. What did I do wrong? The data's coming from a mysql DB.
MySQL defaults to latin1 encoding where as the rest of the world usually assumes unicode/UTF-8 these days
Hello everyone, could someone tell me is it possible to configure project with frontend and backend at same time? If it is, how can i do that?
My problem in cider is that I can get cider to start an nrepl, but if I use figwheel as repl type it open the website, but then I have a prompt saying "STDIN:" in the minibuffer at the bottom. Inside that minibuffer I can interact with the clojurescript repl but I can't send any sexp from my core.cljs buffer in emacs to the figwheel repl.
And if I use the newer figwheel-main repl type (and a project created with lein new figwheel-main) cider still opens up the website and tries to create a figwheel repl, but the last thing printed in the cider-repl is "Opening URL http://localhost:9500" and after that nothing happens.