This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-14
Channels
- # 100-days-of-code (4)
- # announcements (1)
- # beginners (63)
- # boot (22)
- # braveandtrue (104)
- # calva (3)
- # cider (12)
- # cljs-dev (53)
- # cljsjs (3)
- # cljsrn (1)
- # clojure (180)
- # clojure-dev (14)
- # clojure-italy (4)
- # clojure-nl (11)
- # clojure-spec (15)
- # clojure-uk (60)
- # clojure-ukraine (1)
- # clojurescript (118)
- # clojutre (3)
- # core-async (12)
- # core-logic (17)
- # cursive (19)
- # datomic (45)
- # devcards (4)
- # emacs (7)
- # figwheel-main (218)
- # fulcro (27)
- # funcool (3)
- # graphql (1)
- # jobs (4)
- # leiningen (57)
- # off-topic (71)
- # pedestal (2)
- # portkey (17)
- # re-frame (5)
- # reitit (4)
- # remote-jobs (2)
- # ring (11)
- # rum (2)
- # shadow-cljs (14)
- # specter (11)
- # sql (34)
- # tools-deps (23)
quick question! I’m new to clojure and was taking a guess at how iterate
might be implemented with mutable internal state, but this does not seem to work
(defn iterate [f x]
(def next x)
(fn []
(let [current next]
(def next (f current))
current)))
what’s the right way to do something like this (higher-order function with mutable internal state)?I think you'd wanna use an atom
for that
a def
inside a fn is a no-no, even though it technically works
also realize now that iterate
returns a lazy-sequence, so isn’t exactly what I was thinking but a learning experience nonetheless
@forrest.akin Yeah, using an atom
it is a good learning exercise to produce something like
cljs.user=> (def iterate-f (iterate inc 1))
#'cljs.user/iterate-f
cljs.user=> (iterate-f)
2
cljs.user=> (iterate-f)
3
Ahh, I see your original definition pretty much behaved that way, apart from a difference in how things start up 🙂
Because def
always declares a top-level (global) var @forrest.akin -- you want let
for local bindings.
thanks all, this is what finally worked
(defn iterate [f x]
(let [next (atom x)]
(fn []
(let [current next]
(swap! next (fn [current] (f current)))
(deref current)))))
(def inc-one (iterate (fn [x] (+ x 1)) 0))
was confused for awhile by all the memory references in the console; my first lisp so keep on forgetting I need those parens to evaluate my expression 😂
and the last piece was figuring out that I have to use deref to actually get the value out of the atom
Yeah, the whole thing can be simplified down to use one let as well
(defn iterate [f x]
(let [state (atom x)]
(fn []
(swap! state f))))
That's not quite the same @mfikes -- @forrest.akin wants the old value back, not the new one.
(defn iterate [f x]
(let [state (atom x)]
(fn []
(first (swap-vals! state f)))))
swap-vals!
returns a pair of old value, new value.
@forrest.akin Like this?
(! 539)-> clj
Clojure 1.9.0
(defn iterate [f x]
(let [state (atom x)]
(fn []
(first (swap-vals! state f)))))
WARNING: iterate already refers to: #'clojure.core/iterate in namespace: user, being replaced by: #'user/iterate
#'user/iterate
user=> (def inc-one (iterate inc 0))
#'user/inc-one
user=> (inc-one)
0
user=> (inc-one)
1
user=> (inc-one)
2
user=>

To fix up Forrest's earlier version you'd need to deref earlier:
(defn iterate [f x]
(let [next (atom x)]
(fn []
(let [current @next]
(swap! next (fn [current] (f current)))
current))))
Ah, good catch!
oh, right because I was assigning current to the atom instead of the value, so my swap effected both
Another side point worth mentioning is that for some stateful functions, you can use volatiles, but for now it is probably better to just stick with atoms
(A volatile is much like an atom, but with slightly weaker semantics but better performance in some use cases)
You might as well switch to 1.9 -- it's been out for ages now and Alpha releases of 1.10 are already available.
Clojure is very stable, so it's usually pretty easy to upgrade and stay on the very latest version. We've been deploying Alpha builds to production for over seven years now 🙂
as does http://repl.it :thinking_face:
Wow, I'm a bit surprised the latest Leiningen still fires up a 1.8 REPL :shocked_face_with_exploding_head:
(I was on Leiningen 2.7.1 so I wouldn't have been surprised there -- but I just ran lein upgrade
to get 2.8.1 and it's still a Clojure 1.8 REPL...)
Is this true? https://www.pastery.net/kznmqd/
how so?
you could write the Javascript example in a functional way that would be pretty much exactly like Clojure
and you could write the Clojure one in an imperative way (using atoms and loop
) and it would look like the JS one
looks really ugly though 😄
but yeah makes sense
How do I log incoming requests coming through a compojure Ring handler so that I can debug why it's returning a nil response.
@grierson A trick I’m using all the time: https://blog.michielborkent.nl/2017/05/25/inline-def-debugging/

You can find how to get the request here: https://github.com/weavejester/compojure/wiki/Destructuring-Syntax
Im learning Ring, and when I call the second app expression in the comment block I get a NPE error. But I can't see the shape of the request so I can't see the cause.
@borkdude Hey, I tried your inline def but it's saying it's unable to resolve symbol.
be sure to read this first if you’re not familiar with working in a REPL: https://clojure.org/guides/repl/introduction
an ordinary prn/println should work just as well, but then you only have the printed value, which should suffice if it’s just a small map
since you’re getting a null pointer, it’s likely that x or y are nil, which you should see in the prn
you already put there
@grierson I took a look at the ring spec: https://github.com/ring-clojure/ring/blob/master/SPEC
maybe try query-string and then x=1&y=2
?
@borkdude I worked it out, compojure destructing was looking for a key :request because I added GET '/math' [request] (handler request)
just needed to call the handler. Thank you for your help
what kind of channel?
you can use poll!
that returns nil if nothing is immediately consumed, then you can do what you like with that
Do I need create the macros in clojure part and call with require-macros
from clojurescript? as in this post http://blog.fikesfarm.com/posts/2016-01-05-clojurescript-macros-calling-functions.html