This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-01
Channels
- # announcements (10)
- # aws (1)
- # babashka (19)
- # beginners (104)
- # calva (50)
- # cider (17)
- # cljs-dev (135)
- # cljsrn (56)
- # clojure (240)
- # clojure-dev (4)
- # clojure-europe (19)
- # clojure-nl (2)
- # clojure-uk (7)
- # clojurescript (22)
- # conjure (2)
- # css (1)
- # cursive (10)
- # data-science (1)
- # datomic (60)
- # emacs (2)
- # events (2)
- # exercism (1)
- # figwheel-main (3)
- # fulcro (13)
- # graalvm (5)
- # gratitude (1)
- # inf-clojure (4)
- # introduce-yourself (5)
- # jobs-discuss (21)
- # lsp (36)
- # malli (6)
- # meander (8)
- # missionary (12)
- # off-topic (14)
- # pathom (13)
- # pedestal (10)
- # polylith (42)
- # re-frame (5)
- # reagent (12)
- # reitit (3)
- # releases (8)
- # sci (10)
- # shadow-cljs (37)
- # sql (5)
- # tools-deps (6)
A future will stay in memory until it can be garbage collected. So if you no longer have a reference to it, the gc process will free the memory for you.
I have seen below code in compojure
(defn- wrap-response [handler]
(fn
([request]
(response/render (handler request) request))
([request respond raise]
(response/send (handler request) request respond raise))))
In above code, we are not passing any values to the request, only handler is a single argument, What values go inside request here and called function is
(-> handler
(wrap-response))
Yes, the wrap-response
takes a handler, and returns a modified handler. A handler is a function that takes a request and returns a response. When you start the web server (with something like run-jetty
) you pass it the handler that will be called for each request that comes in over the network. The request is a map that will conform to the ring spec (which is here: https://github.com/ring-clojure/ring/blob/master/SPEC) so if you want to test the handler, you can create a request pretty easily with a literal data structure. Maybe something like:
(is (= 200 (:status (handler {:uri "/ping"}))))
Make sense?I wanted to know how it calls line (response/render (handler request) request))
, we are not passing any value to request
right? and passing single argument handler
in the below code
(defn- wrap-response [handler]
(fn
([request]
(println (handler request) request))
([request respond raise]
(println (handler request) request respond raise))))
(defn calling-extend-protocol [x]
(wrap-response "abc"))
(calling-extend-protocol "df")
how it calls the println method ?@U0P0TMEFJ any help?
when you run (-> handler (wrap-response))
you get a function back. You pass that function to jetty and it is responsible for running it. If you want to run it yourself, you need to get that function and call it
(let [h (-> handler wrap-response)]
(h request))
in your code, this
(defn- wrap-response [handler]
(fn
([request]
(println (handler request) request))
([request respond raise]
(println (handler request) request respond raise))))
will not produce a valid handler, since it will return nil
(defn- wrap-response [handler]
(fn
([request]
(prn 'request-> request)
(handler request))
([request respond raise]
(prn 'request-> request 'respond-> respond 'raise-> raise)
(handler request respond raise))))
that will print some debug and then delegate to handler
and you can use it like this:
(let [h (wrap-response (constantly {:status 200 :body "success"}))]
(h {:uri "/request"}))
that will return {:status 200, :body "success"}
and print request-> {:uri "/request"}
at the repl/terminal/wherever your setup is printing stdout.it might help to see what it looks like to do this to normal code:
(ins)user=> (defn wrap-double-n [f] (fn [n] (f (* 2 n))))
#'user/wrap-double-n
(ins)user=> (def foo (wrap-double-n inc))
#'user/foo
(ins)user=> (foo 1)
3
a middleware modifies some function by making a new version which either pre-process or post-processes values (or does some side effect in there...)@U051SS2EU Thanks , I understood it now!
https://i.imgur.com/TRGy17u.png tyring to invoke clojure from a java (kotlin) app and String/format throws. What am I doing wrong?
it was fixed by doing
var req = Clojure.`var`("clojure.core","require")
req.invoke(Clojure.read("com.github.benjaminasdf.idlelib.compsearch"))
val fn = Clojure.`var`("com.github.benjaminasdf.idlelib.compsearch", "get-re-str")
instead of invoke-static
. I was not aware that there is a difference. Can somebody point me towards it?
just as a general comment: write the code you ran (in text, use a snippet or triple-back-quote) and the result you got. that will make it easier for people to help
I'm a bit naive on this topic, but for ease of Clojure development, is WSL 2 fine? Or is it worth it to set up dual boot on my Windows machine?
I am a beginner myself so I haven't used it in anger but I think WSL2 is really good for Clojure. Especially combined with Vscode and Calva.
Yes WSL2 will likely give you the smoothest experience because you'll be able to use the same shell commands as Linux/MacOS. There is also a #clj-on-windows channel if you need more help.
My Windows setup is: VS Code on Windows (11) with the Remote-WSL2 extension; WSL2 with Ubuntu running all of my Clojure CLI, REPLs, other stuff. It's a very slick setup. VS Code + Calva is great!
I also have Docker for Windows installed (with the WSL2 integration) and run MySQL, Elastic Search, and Redis via Docker on WSL2 (`docker-compose up`) so I only have my Clojure source code and REPL running directly on WSL2.
Thank you all for the input and resources. I'm going to work on setting up my dev environment. VS Code + Calva seems neat. When I was originally toying around with Clojure I was trying to learn emacs at the same time which was a bit much for me.
@U02CV35U6AH Yeah, I usually recommend folks don't try to learn both Clojure and Emacs at the same time 🙂 In general, if the editor you already know best has a decent Clojure integration, that's the best thing to use.
Can any one suggest me link to understand clojure.walk
please, I was going through the clojure documentation and I am not able to understand it properly
1. Asking someone if they have read the source, and even suggesting that they read the source is not insisting that they must read the source
Hey all, not sure if this is the right place to ask, but can anyone recommend some good Clojure talks for someone newish to clojure? Ive seen a few but wondering if there are specific ones I should watch as a newbie
I have a list I was building, but haven't updated in a while, not all clojure specific, but a good helping of rhickey talk's peppered in:
#+TITLE: Software, a Deconstruction
1.
2. Simple Made Easy
3.
4.
5.
6. (Engineering(,) A Path to Science: "I don't want to die in a language I can't understand")
7.
8. (Jonathan Blow on Software Quality)
9. (Reasoning about performance)
10. (The Coming War on General Computation)
11.
12. (What, Where And When Is Risk In System Design)
13.
14. (Creativity In Management)
15. (Hammock Driven Developement)
16.
17.
18.
19.
20.
21. (Are We There Yet - Rich Hickey)
Thanks for the responses everyone! Got some good stuff to watch over memorial weekend now 🙂
Clojure 10 big ideas video is excellent https://practical.li/clojure/concepts/
I also recommend these videos by Rich Hickey https://practical.li/clojure/concepts/clojure-made-simple.html
https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj 130 or so lines, walk is the main function, everything else builds on it
hey everyone, i am a beginner
(defn func
([] sentence)
([name] (str sentence name)))
(func "harshit")
is this code wrong ?Can you describe what sentence
is doing?
oh sorry
(def sentence "And the Golden Grouse And the Pobble who")
sentence is just a string
In that case, the code looks reasonable to me. Why are you asking?
hmm i tried running it with vscode clojure extension
but it gives me an error
specifically a syntax error compiling
what's the error?
(ns markov-elear.generator)
(def sentence "And the Golden Grouse And the Pobble who")
(defn func
([] sentence)
([name] (str sentence name)))
(func "harshit")
(defn -main
"I don't do a whole lot."
[x]
(println ( str x "Hello, World!")))
;; keyword? functions
(odd? 2) ; false
(even? 2) ; true
;; long short signed unsigned int
;; double float
is there something wrong in the entire file ?
it says syntax error compiling at (c:\.........\generator.clj:2:1)
I have replaced the path with .......
(ns markov-elear.generator)
(def sentence "And the Golden Grouse And the Pobble who")
(defn func
([] sentence)
([name] (str sentence name)))
(func "harshit")
(defn -main
"I don't do a whole lot."
[x]
(println ( str x "Hello, World!")))
;; keyword? functions
(odd? 2) ; false
(even? 2) ; true
;; long short signed unsigned int
;; double float
this is all
ohh yeah
that was it
thanks man :thumbsup:
can i also ask something else
whenever i do lein run
in my project directory.
it says
No :main namespace specified in project.clj.
this is my project.clj
(defproject markov-elear "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url ""
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url " "}
:dependencies [[org.clojure/clojure "1.10.1"]]
:repl-options {:init-ns markov-elear.generator})
It's just like it says, you need a :main
entry in there
The sample project.clj has an example of this... kind of.
It has EVERYTHING, so it's kind of a lot
you can also get that sample in a terminal with lein help sample
- if you are comfortable with paging / searching in terminal
But the comment above it should explain things well
thanks i will try this out
@U051SS2EU omg really? I wish I knew that 5 years ago.
lein help
has a lot of great content, which is weird for a CLI utility
thanks everyone it works now :thumbsup:
@harsjoshi1614 the number one thing to internalize early about clojure is that running it "batch mode" -- i.e. type some stuff, hit save, then lein run
-- is hampering your abilities by 99%
using your editor of choice (vs code, emacs, vim, whatever), connect to a live REPL
for example, in emacs, I hit a shortcut key, and it evaluates a small part of my program, the form surrounding my cursor
i was wondering why all the tutorials were so hell bent on using a live REPL shortcut key for evaluation
now i know
your feedback cycle with the editor-connected REPL will be faster than in any other language
yeah i never noticed this thing working with other languages lol
but it is actually a lot of time switching to you terminal and running the command to see the output with every little change
@harsjoshi1614 You might find a couple of my videos interesting from that point of view https://www.youtube.com/watch?v=gIoadGfm5T8 (long, shows how I can build an app from scratch while it is running in the REPL) and https://www.youtube.com/c/SeanCorfield_A some shorter videos showing a similar workflow for different things. Stu Halloway also has a great video called REPL-Driven Development https://vimeo.com/223309989
The #practicalli channel and associated videos might also be very interesting to you in terms of effectively leveraging the REPL.
This overview of repl driven development is a good place to start. The workflow is applicable to any Clojure aware editor https://youtu.be/NDrpclY54E0
thanks i will check them all out !
Check my vid out too! 😃 https://www.youtube.com/watch?v=d0K1oaFGvuQ It is not fancy in anyway, just me trying to use a familiar and simple problem to demonstrate an Interactive Programming workflow.
@U0ETXRFEW That's a lovely demo! Exactly the workflow I try to convey when teaching newcomers. Oddly, I find that structural editing blows peoples' minds first. The power of REPL-orientation takes a little longer to digest (requires drills and practice).
As an aside, I also like to use tiny examples because they make it easy to illustrate Clojure's power to model the same domain in vastly different ways. And to also show how they can fall out of REPL experiments, like you've shown so nicely.
I did https://gist.github.com/adityaathalye/cd3f275086285f15e384ad3707d9cc16#file-crackle_poppers-clj-L150:
• cond
(usual imperative style),
• or
(short-circuit, but still imperative),
• juxt
(closer to choice / alts-like concept),
• lookup table (arithmetic domain), and
• a functional encoding of the arithmetic domain (infinite sequence).
After seeing your video I realized I missed multimethods / polymorphic dispatch / message-passing!
Thanks! I get very curious about those five ways, butt the link seems to take me to something unrelated?
@U0ETXRFEW Sorry, "CracklePop" = "FizzBuzz". It was in response to a question someone had posed where they called it CracklePop instead of FizzBuzz. (And then I couldn't resist putting a very obtuse and very pointless reference to https://plato.stanford.edu/entries/popper/ in there 😅 ).
This overview of repl driven development is a good place to start. The workflow is applicable to any Clojure aware editor https://youtu.be/NDrpclY54E0