This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # aws (1)
- # beginners (70)
- # boot (12)
- # calva (45)
- # cider (45)
- # clara (1)
- # cljdoc (10)
- # cljs-dev (133)
- # clojure (315)
- # clojure-dev (2)
- # clojure-europe (2)
- # clojure-italy (16)
- # clojure-nl (1)
- # clojure-spec (23)
- # clojure-uk (19)
- # clojurescript (48)
- # cursive (11)
- # data-science (5)
- # datomic (18)
- # figwheel-main (3)
- # fulcro (18)
- # graphql (14)
- # jackdaw (1)
- # juxt (1)
- # kaocha (1)
- # off-topic (10)
- # other-languages (3)
- # pathom (2)
- # pedestal (7)
- # re-frame (23)
- # reagent (1)
- # reitit (4)
- # ring-swagger (12)
- # rum (4)
- # shadow-cljs (26)
- # specter (6)
- # speculative (12)
- # tools-deps (44)
- # vim (8)
- # yada (2)
def always creates a global var, unlike, for example, in scheme, where define can create local bindings
i am reading the clojure
fn macro and i saw this symbol
fn* been used but can't find where it has been define or implement
Despite this page claiming
fn is a "special form" https://clojure.org/reference/special_forms#fn it's actually
fn* that is the special form and
fn is "just" a macro that wraps that special form.
@quieterkali See https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L7103 for where
fn* is handled directly in the Clojure compiler.
FN symbol is created here https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L47
It's similar to how
let is described as a "special form" too but it's actually a macro wrapper around
let* which is built into the compiler.
I would still consider let, fn, etc to be the special forms (and let*, fn* to be implementation details of how the compiler works)
Yeah, it's just kind of odd for folks when they run
source on something that is documented as a special form and it prints out regular old Clojure code 🙂
I am having some trouble parsing the advice here: https://stuartsierra.com/2015/04/26/clojure-donts-concat. I understand that if you call concat with long lists/many arguments that there is a risk of StackOverflow, but what is then the ideomatic way to concatenate lists?
Yeah but I don’t understand why I would want that more, I read it like 10 times :’). He uses
into to accumulate into a collection, but thats not lazy at all right
The main thing to bear in mind is, if you find yourself reaching for
concat, just think carefully about how it will be realized -- and whether you really need laziness or not.
As the article says, it can seem like the obvious, simple solution -- and if you're working with small lists or realizing just a single
concat call you'll be fine. But if you're not careful, it can bite you.
Right thank you, I got a review comment saying that
concat is bad, so I went replacing it with
into, but I kept wondering whether thats also not equally bad because its non-lazy. So, its a pick-your-poison kinda deal
The other thing to watch out for with laziness is that many lazy sequences are "chunked" so you'll get blocks of 32 items realized, rather than just the exact number you might expect...
Yeah so if they are very computationally heavy per element, you have a chance of realising 32 at once, right
(take-while #(< % 10) (map #(do (println %) %) (range 100))) will print 0, 1, .. 31 and then return
(0 1 .. 9)
Right, that gets frustrating when you have a lazy-seq finding & realising large prime numbers 😉
Reading over Stuart's article again, and the comments, and I'd forgotten that
core.cache had a bug caused by
concat (mentioned in the comments, and the JIRA issue points back to that article), that was one of the first things I fixed when I took over the library https://github.com/clojure/core.cache/commit/0f7ef2294c76284949e681e4b620f07c7dbc1f06
when you say “very computationally heavy per element” above, that should set off all kinds of alarms - this is a case where you want fine-grained control about when things are realized. You should never (well, no absolutes, but rarely) use lazy sequences for something like that, where you inherently give up control over when things are realized. It’s better to use loop/recur with explicit termination conditions for stuff like that.
I'm looking to implement some symbol pattern like
add-pin* or similar, to indicate that a function should have passed some sort of authentication beforehand. Anyone have any ideas on characters that can symbolize something like "danger", "pay attention"? Or just suitable characters to use for it?
add-pin! to indicate there are side effects you need to worry about?
one "trick" is giving it a weird, excessively long and discriptive name, then give the function that does the proper checking before calling it a normal and readable name
but this is the sort of thing where I'd definitely use regular old doc strings and code comments too
hm, I see. Yeah, I currently have my
db functions just act directly on the "db", but then provide other functions, basically wrapping the db functions, only actually calling them if authorized correctly. It's those wrapper functions I'm looking to name
➜ home git:(master) ✗ clj Clojure 1.10.0 user=> (defn add-pin🔒  ) #'user/add-pin🔒 user=>
hi, i'd like to be able to attach a repl to a running uberjar (or something running from
lein run in dev) - is there an example somewhere i could check out? thanks very much!
@hoopes If you just need a Socket REPL, you can start the uberjar up with an additional JVM option that tells Clojure to start a Socket REPL server as it starts the application up.
If you need an nREPL Server, you can start one programmatically (see the nREPL repo for details).
You can point unravel/unrepl at a Socket REPL. You can connection Atom (editor) to a Socket REPL via the Chlorine plugin.
Here's how to have your application start its own nREPL Server https://github.com/clojure/tools.nrepl#embedding-nrepl-starting-a-server
The nice thing about the JVM option and Socket REPL is that you can even get a Socket REPL into a Java application if it happens to use Clojure for anything internally 🙂
(we have legacy JVM apps that use Clojure libraries and that's how we start a Socket REPL inside them for debugging)