This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-05-27
Channels
- # aws (7)
- # babashka (145)
- # beginners (83)
- # calva (18)
- # cider (11)
- # clara (9)
- # clj-kondo (59)
- # cljdoc (4)
- # cljs-dev (4)
- # cljsrn (11)
- # clojure (168)
- # clojure-australia (21)
- # clojure-dev (5)
- # clojure-europe (46)
- # clojure-italy (3)
- # clojure-nl (10)
- # clojure-taiwan (1)
- # clojure-uk (55)
- # clojurescript (85)
- # clojureverse-ops (1)
- # code-reviews (3)
- # conjure (22)
- # cursive (3)
- # datahike (3)
- # datomic (4)
- # emacs (5)
- # helix (20)
- # jackdaw (1)
- # jobs (2)
- # jobs-discuss (7)
- # lsp (1)
- # malli (5)
- # off-topic (85)
- # other-languages (4)
- # practicalli (4)
- # reitit (2)
- # releases (2)
- # sci (62)
- # shadow-cljs (181)
- # testing (5)
- # tools-deps (15)
- # xtdb (31)
Add a memoize and you're golden
Can you show me?
(Although I don't think its entirely applicable to this, as you'd have to re-write it in a recursive manner)
I don't think memoizing factorial is actually helpful? I guess if you are calling factorial on a large number of small values it could help
Can you show me?
Why does ->
expand to this particular result in this example?:
user => (macroexpand '(-> [1 2 3 4] (reverse) (drop 2)))
(drop (reverse [1 2 3 4]) 2)
the https://clojuredocs.org/clojure.core/-%3E say that
the first form as the
second item in second form
I thought the first form was (reverse [1 2 3 4)
and that it would be passed to drop as the second item
(I expected)
(drop 2 (reverse [1 2 3 4]))
(drop 2 (reverse [1 2 3 4]))
this is the form of three forms: drop
, 2
, (reverse [1 2 3 4])
->
Is thread first. It takes the result of the previous line and feeds it into the first argument position in the following form.
(-> [1 2 3 4] ;; call this o
(reverse) ;; this line becomes (reverse o), o is in te second location in this form. This is evaluated and lets still
;; call the result o
(drop 2)) ;; this line becomes (drop o 2)
Which obviously doesn't work. Rather than thinking of second position in the form, think of it instead as it makes the previous result the first argument in the next line.You could use thread last in your example
(->> [1 2 3 4]
(reverse)
(drop 2))
=> (2 1)
Now the result of each line is being fed into the final argument position in the following line.Thank you @U013YN3T4DA. That’s what I thought, but the docs wording is confusing. Doesn’t saying
feeds it into the first argument position in the following form.
sound very different from what the docs say:
inserts the first form as the
second item in second form
if (drop 2)
is considered the second form and o
is the first form, isn’t the second item’s location drop 2 o
(vs actual: (`drop o 2)` ).
It makes sense the way you say it, but how I’m reading the docs, I’m still backwardsConsider the form a list, in the case of (drop 2 o), o is the third item in the list. In the case of (drop o 2),o is the second item.
I agree docs are confusing tho, i hardly ever go to docstring to understand a function
ohhhh that makes much more sense (considering it a list) now this doc line makes sense
making a list of it if it is not a
list already
Thank you StuartIf I'm correct, Leiningen doesn't have any "watch" support by default? If I would like to automatically rerun tests when files change for example
You can achieve this via lein-auto
https://github.com/weavejester/lein-auto
usually this is responsibility of a test runner. For example https://github.com/lambdaisland/kaocha can “watch” for changed files and run subset of your tests affected but the change
thank you both
i’ve had success with https://github.com/jakemcc/lein-test-refresh too
Thanks. I went with Kaocha, it was easy to set up and use
I love this video. Are there any other good example videos of people debugging and troubleshooting? One of the hardest parts about learning Clojure so far is that the error messages are basically written in Java and I don't know Java, so seeing more examples of troubleshooting would be great. Right now i feel like my only response to troubleshooting in a lot of cases is to ask someone for help. https://youtu.be/lPczdxHt43g
I'm trying to require closh.zero.macros inside a babashka script,
(require '[closh.zero.macros :as closh])
When I run, in the shell,
bb ./file.clj
I get:
----- Error --------------------------------------------------------------------Type: java.lang.Exception
Message: Could not find namespace: closh.zero.macros.
Location: 3:1
At the same time, if I go to the closh shell,
(sh )
autocompletes to
closh.zero.macros/sh
Could I interop them? I have a bunch of custom-written functions, and I'm struggling calling them. Basically, I have to eval one by one, right now. That's the underline thing I want to solve
Is there any way to refer to clojure.lang.Keyword in a shorter form? I'm practicing multimethods for the first time and would like to dispatch on a class of keyword or number. Using Number works as expected, but Keyword doesn't seem to exist without the full name of clojure.lang.Keyword.
Cool, that seems to do the trick. I tried using a [clojure.lang :refer [Keyword]
, but that didn't work 😀
It looks like you are trying to required the class via the ns form. If so, try (ns my-ns (:import [clojure.lang Keyword]))
instead.
I am trying to make an SPA based off of leiningen’s reagent template. They have the server set up so that all pages are handled by an index handler that mounts a loading page.
(defn loading-page []
(html5
(head)
[:body {:class "body-container"}
mount-target
(include-js "/js/app.js")
[:script "spotify_client.core.init_BANG_()"]]))
(defn index-handler
[_request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (loading-page)})
I’d like to continue to use this handler for additional pages in my app because I need the script for core.cljs to run on all pages. However, I need to do some things (like make API calls, parse the response params from authenticating to the API, and returning a different response based on whether the user is authenticated) before returning a response map with an html body. Do I need to use a different handler? How do I go about integrating the new handler (if so) with the SPA template?Why isn’t this working? Anybody who knows Specter that could help me out here?
all the :case1
entries are numbers, and MAP-VALS
expects maps
Is there some way to exclude stuff? I was looking for it in the documentation and struggling. See the bottom bit of code, which doesn’t work
I thought any function would work as a filter predicate
#(not= % :name)
Hmm that still doesn’t filter out the names
So you want to select a set of keys that doesn't include name?
I want the output here to exclude :name 1, :name 2, etc. but keep all of the cases and their values. Desired output below.
[{:case1 600, :case2 800, :case3 1000}
{:case1 1000, :case2 900, :case3 800}
{:case1 800, :case2 700, :case3 700}
{:case1 800, :case2 1000, :case3 1000}]
(s/select [:employees ALL (s/view #(dissoc % :name))] employees)
Awesome. So if I understand this correctly, :employees ALL will take me to a map of all of the employee data, and then view allows me to apply the dissoc function to the resulting list?
Yeah, basically. I'd make a key distinction that it doesn't take you to a map, but navigates you to every map. Specter is kinda weird in that it has ways to deal with "collections" but individually by way of navigation.
Is there some way to get better error messages? I'm editing a babashka script, running some things in my repl. I often get messages like: > clojure.lang.ExceptionInfo: No implementation of method: :as-file of protocol: #'http://clojure.java.io/Coercions found for class: clojure.lang.Keyword Is there some way to get line numbers or something in the error message?
@borkdude Babashka. Started it using :IcedInstantConnect babashka
with it set to nrepl.
That's from vim-iced: https://liquidz.github.io/vim-iced/#_connecting_socket_repl
ah right, yeah in nREPL you don't get the errors you get when running it on the command line
Hmm, so I'd be better off using socket repl? I thought nrepl would be the preferred option as it returns data.
No, nREPL is fine, it just needs to do better on the error handling there I think.
To explain the error though:
When you call
on a something, it tries to convert that something to a file.
This conversion is implemented using a protocol called Coercions
. But there is no implementation of that protocol for the Keyword type.
Yeah, I understand the error and can debug it, but without line numbers it's quite a hunt sometimes. Do you have some suggestions for getting better debugging hints when I run into situations like this?
@randumbo I think this is a specific issue with how nREPL is implemented in babashka: https://github.com/babashka/babashka.nrepl/issues/40 You should get better errors when you execute the script from the command line, so that might be the best debugging for now
Unrelated to my previous question..
I understand that doseq
is basically for when I need to loop over something and produce side effects in the body. Is it weird that I often have nested doseqs when I need to iterate over an inner list?
I’d like to add an item to a collection within a map and return the map with the new collection. If I use conj
it’ll return just the collection. Is there an idiomatic way to update a collection w/i a map whilst returning the map? Thank you
@U01JYKT6ENL (update the-map :coll conj new-item)
you can arbitrarily mix & match further nesting, :when
or :while
clauses, and :let
clauses
This website has some nice examples: https://clojuredocs.org/clojure.core/doseq
@randumbo supposing you have a list of lists of numbers
(doseq [l z :when (> (count l) 3)
n l :while (< n 5)]
(println n))
z is the list of lists
that will iterate through the elements of z
filtering out any that are shorter than 4
for each of those it will iterate through the numbers in that list and print them until it encounters one >= 5
same as what you're doing with nesting doseq
s