This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-12-09
Channels
- # adventofcode (93)
- # announcements (11)
- # babashka (7)
- # babashka-sci-dev (17)
- # beginners (73)
- # biff (7)
- # calva (3)
- # cider (1)
- # clj-kondo (160)
- # clj-together (12)
- # clojure (44)
- # clojure-art (2)
- # clojure-europe (12)
- # clojure-losangeles (1)
- # clojure-nl (3)
- # clojure-norway (22)
- # clojure-uk (2)
- # clojurescript (8)
- # clr (1)
- # cursive (6)
- # data-science (1)
- # datomic (1)
- # emacs (6)
- # events (1)
- # exercism (1)
- # fulcro (6)
- # graphql (2)
- # introduce-yourself (1)
- # lsp (18)
- # nrepl (7)
- # off-topic (45)
- # polylith (25)
- # portal (25)
- # practicalli (3)
- # re-frame (14)
- # reagent (28)
- # reitit (2)
- # releases (2)
- # shadow-cljs (73)
- # sql (11)
- # tools-deps (12)
- # transit (4)
- # xtdb (4)
; somebody please explain me what's happening here:
(= #(reverse %) '(1 1)) ; => false
; I was thinking it will eval to (= 1 1)
(= 1 1) ; => true
; but (= #(reverse %) '(1 1)) ; => false
; or it will eval to (= nil '(1 1)) ???
Did you mean (apply = (#(reverse %) '(1 1)))
?
Because what your code is doing is comparing equality between a function and a list
another question: ;; why comparing operator is allowed with only one args? (= 3) ;=> true (= nil) ;=> true (= false) ;=> true (=) ;=> ArtityException wrong number of arguments
I think this question was asked yesterday somewhere also. Answer was:
Probably to play well with apply
i.e.
(apply = [1 2 3])
(apply = [1])
Thought the 0 arg case is troublesome
You sometimes get situations where you want to do something like this:
(filter (partial apply =) [[1 2] [5 5] [2 3]]) ;=> [5 5]
I’m looking at the clojure doc for reify. I don’t see the sentence that says what the function does. just lots of text about how to call it. Am I missing something?
first sentence sums it up to me > reify creates an object implementing a protocol or interface.
reify is a macro with the following structure:
this is the first sentence that I see.I think the http://clojuredocs.org text is missing some lines.
could that be true?
looks like alex clarified your exact confusion recently and the clojuredocs site hasn’t updated https://github.com/clojure/clojure/commit/e1220832d900745727cf5a1b69f4a6cd664f1443
so does reify create a singleton object which for which the named function can be called with it as an argument?
singleton usually means a globally unique single. And “named function” seems to imply only one. This returns an anonymous instance of an object that implements any number of protocols and interfaces you want.
match=> (let [r (reify
Object
(toString [_] "custom str implementation")
clojure.lang.Seqable
(seq [_] (seq [:custom :seq :implementation])))]
[(str r) (seq r)])
["custom str implementation" (:custom :seq :implementation)]
so instead of singleton i’d say “one off” or anonymous. and instead of “the named function” i’d say any number of functions defined in protocols or interfaces
I mean, technically it does return a globally unique instance, so singleton is not wrong. But singleton (as an oo pattern) often implies something about global state, which is not the case here, so not in that sense
aren’t all objects anonymous?
what does singleton normally apply about global state? For me a singleton object is an instance of a class for which there is no other instance of that class. is no other can be enforced by the programming language, or might be simply enforced by the programming conventions.
For anonymity, most classes have a name that is accessible to the programmer. These do have a name that you could get but the instance itself is the usual way to interact with it and use
Given a list of functions and a list of arguments, is there a simple way to return a list with results of evaluation of first function with first arg, second func with second arg, etc.? Like:
(XXX [inc dec] [1 9]) => [2 8]
Feels like sth trivial but can't figure it out...OK, thanks, though there would be something even simpler 😛
You could use an anonymous function to shorten it a little (map #(%1 %2) [inc dec] [1 9])
the (fn [x] ,,,)
form is just as anonymous as the #(,,,)
form. They are both unnamed functions. The latter is a reader macro that expands into the equivalent form
(read-string "#(+ 1 %)") ;; => (fn* [p1__24938#] (+ 1 p1__24938#))
it's a shorthand for the same thing : https://clojure.org/reference/reader#_dispatchI went on a different tack and made a function that deals with unknown number of fn's and args pairs. Also I made it extra lazy...
The answer given twice already would provide a much simpler signature than your fargs-pairs
. It equally allows for an unknown count of fns and args. And map
is already lazy.
(defn map-application [fs xs]
(map (fn [f x] (f x)) fs xs))
(map-application [inc dec str #(* 10 %)] [1 9 5 -3])
; => (2 8 "5" -30)
Yes, you lose the opportunity to check for fn?
. But this is likely not a great idea anyway. because idiomatic Clojure is full of "function calls" where you don't actually have a real function in hand.
E.g. You will find (:some-key some-map)
everywhere you look, but (fn? :some-key)
, not surprisingly, returns false
.
I know I would be super frustrated if I was trying to write code against your function, and found keywords were getting dropped as a "no-op".@U90R0EPHA aside, is there a function that returns if you can call something? i.e.
(callable? (fn [])) ;=> true
(callable? :key) ;=> true
(callable? {}) ;=> true
(callable? #{}) ;=> true
etc>And if you really wanted to check that, it still does not require describing your own recursion semantics. Just stick it inside the map function.
(defn map-application [fs xs]
(map (fn [f x] (if (ifn? f)
(f x)
(prn {:noop true :f f :x x})))
fs xs))
So, I've started to use integrant a few days back. Previously I had atoms peppered all over my files.
I define the config and all the init-key
and halt-key!
methods in a single file right now.
Was ok so far but now the config has 11 keys and keeps growing. Now I'm wondering if it's a good idea to put the methods close to their sources instead of a single central file.
What's the received wisdom on this?
My own preference is to have a single resources/config.edn
file with all the keys. Then initialise / halt all the services in a practicalli.service-name.service
namespace which also has a -main
that starts / shutdowns all the services
If also using aero, then I move the areo-reader parts into their own namespace and require that from service.
You can also look into using Aero with Redelay: • https://github.com/aroemers/redelay • https://github.com/juxt/aero You can define your state in a "redelay", which will feel similar to what you were doing with Atom, but will be much better because it does lifecycle start/stop/reset. And you put your configuration in Aero.
@U3JH98J4R Please correct me I'm wrong, I've just put the entire system state there 😄 Here's the list (This is typed, not copy pasted so maybe typos):
{:adapter/jetty {:port 8080 :join? false :allow-null-path-info true :handler (ig/ref :handler/main)}
:timbre/start nil
:handler/main {:sockets (ig/ref :user/websockets)}
:solace/message-receiver {:message-service (ig/ref :solace/message-service) :message-queue (ig/ref :publisher/message-queue)}
:solace/message-service {:props (ig/ref :solace/connection-properties)}
:solace/connection-properties nil
:publisher/message-queue nil
:publisher/instance {:message-queue (ig/ref :publisher/message-queue) :sockets (ig/ref :user/websockets)}
:user/websockets nil
:db/conn nil
:views/filter {:dbconn (ig/ref :db/conn)}
}
Right now it looks like the single atom in re-frame. All the state in a single place. But I'm beginning to worry this might not be how it's intended to be used 😄
i.e. instead of :db/conn
:views/filter
etc - have all the stuff as example.system/conn
, example.system/filter
@U3JH98J4R actually that’s what I had at first. Then I read the examples in integrant doc and gave everything different prefixes. 😆
you can also, to be clear, not use integrant and still not have atoms peppered across your code
integrant is doing two things • Automating the wiring code for starting the system and stopping the system • Giving a foundation for automating the repl workflow
(defn move-ordinate [head-ord tail-ord]
(condp apply [head-ord tail-ord] = tail-ord
< (dec tail-ord)
> (inc tail-ord)))
how does this work, the condp
and apply
part?
*-ord
are vectors like [0 0] for ordinatesThat’s pretty. It can be interpreted as…
Given the vector [head-ord tail-ord]
, run the following predicate tests and return the value associated with the first true result:
• (apply [head-ord tail-ord] =)
(are all elements in the vector equal?)
• (apply [head-ord tail-ord] <)
(is the vector sorted from smallest to largest?)
• (apply [head-ord tail-ord] >)
(is the vector sorted from largest to smallest?)
(println
(condp = value
1 "one"
2 "two"
3 "three"
(str "unexpected value, \"" value \")))
turns into (= 1 value) and not (= value 1)Can this block of code be made nicer?
(->> (map - prev curr)
(map #({2 1, -2 -1} % 0))
(map - prev))
you likely don't need the negating pass if you swap the order of the initial subtraction
If you want a single pass:
(map #({2 1, -2 -1} (- %2 %1) 0)
prev curr)