This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # adventofcode (7)
- # announcements (31)
- # babashka (15)
- # beginners (14)
- # calva (45)
- # circleci (6)
- # clj-new (7)
- # clojure (27)
- # clojure-europe (19)
- # clojure-france (2)
- # clojure-gamedev (4)
- # clojure-uk (2)
- # clojurescript (26)
- # conjure (14)
- # data-science (6)
- # depstar (4)
- # emacs (13)
- # events (1)
- # fulcro (20)
- # graalvm (2)
- # hoplon (30)
- # joker (11)
- # london-clojurians (1)
- # malli (26)
- # pathom (2)
- # re-frame (13)
- # reagent (8)
- # reclojure (3)
- # reveal (8)
- # robots (4)
- # shadow-cljs (29)
- # sql (5)
- # tools-deps (28)
- # vim (4)
A question about functions and their metadata: Why is the metadata of a function (e.g. docstring) attached to the var that refers to the function and not to the function itself?
I’d go philosophical and say that it’s not metadata if a function, but metadata of the var. You can attach metadata to an anonymous function, but what is the practical use of it?
Yeah but with metadata on vars, in case you need to create a var that refers an existing function, you loose metadata.
(defn foo "A func" ) (def bar foo) (:doc (meta #'bar)); => nil
You’re right. Looks like it was just the simpler way to do it initially and simpler to understand (not to remember which properties belong to var, like :dynamic, and which belong to fn). def’ing the functions with another name also breaks many editors’ intellisense, so I guess it is just assumed that if you’re doing it, you know the implications and know how to deal with them :)
I'd say that if you
(def foo bar) you explicitly state that you want a different name. If you wanted the same thing, you could have used the same thing. It makes sense to me that different names have different metadata.
> Why is the metadata of a function (e.g. docstring) attached to the var that refers to the function and not to the function itself?
Because vars can contain any kind of
Object, not limited to functions. Not all Objects are IMetas.
So a different approach wouldn't be nearly as homogeneous
(def bar #'foo) is a bit better, although
:doc, :arglists metadata won't be copied. It's possible to create a thin macro that does so
(the Potemkin lib does that, but also a lot more which is why it fell out of fashion)
defalias in https://github.com/ptaoussanis/encore/blob/4c97d9564b2075901cb1f17313ec238fb9d6f0c2/src/taoensso/encore.cljc#L374 But it https://github.com/ptaoussanis/encore/issues in ClojureScript
I am currently working on this library https://github.com/rollacaster/org-parser-tree and I allow to customize it using mulitmethods: https://github.com/rollacaster/org-parser-tree#customizations I haven't seen any other libraries adding customizations with multi-methods, and I was wondering if there is a reason for that e.g. some better approach?
At least HoneySQL does this. But in v2 @U04V70XH6 has made a switch from multimethods to atoms. I don't know why though.
I know of two potential reasons not to use multimethods, or at least not to use them directly:
- They're slower (which is a cost with no gain if you don't need their flexibility)
- There might be a need to def more than one method to extend something in a meaningful way. In this case, you either have to put the onus on the users to make sure that they call
defmethod for all the required multimethods, or you have to create an interface that allows to do it with one call thus removing the potential to leave the system is a partially customized state, but it will hide multimethods from users so you might as well use something else
Ah, another tiny reason - users will have to make sure that the namespaces with all the relevant
defmethod calls are loaded before the very first usage of your library.
They used to be a lot slower due to a gap in default path caching that gave them that reputation but that has now been long fixed
I have this question that is kinda bugging me, it's not strictly related to clojure but it's part of a clojure project. Currently I'm running a hobby project on docker and I have a frontend server that pushes messages to a backend node (via rabbitMQ) that computes stuff and the UI will poll the frontend server for the result. At some point the backend runs some tasks that use up all of the CPUs. I was hoping to scale horizontally on the number of backend nodes, but now that I think about it, since all containers could do the same heavy task at once this could kill my CPU, right? Would it be a better idea to just have multiple consumer threads in one clojure process and schedule around a fixed thread pool?
java threads plus immutable data already gives you a lot of isolation, the difference is downtime and redundancy
scaling, I'd split things based on their coupling in infrastructure scaling
it's definitely a win to put more things in one clojure process, since the jvm and clojure itself have significant overhead
Thanks for the insight. It's a hobby project but I don't really want it to go down as soon as it gets the slightest traction. I think I'll split the CPUs into two JVMs for at least some redundancy and then create 1 consumer per thread and use a shared claypoole pool for the heavy tasks
one approach is to have a generic "worker" which can do tasks for various parts of the system, with a shared input (via a queue service), it's like the normalized version of the program
of course, for something that will only be for a hobby where downtime doesn't matter? you could put it all in one jvm
Ok, this will sound a little silly, but could someone please verify something for me? I think the last example in the https://clojuredocs.org/clojure.core/juxt is incorrect, in that it claims to return a list of vectors instead of a vector of lists. I would appreciate a sanity check before I change things! What it says:
What I believe happens:
(def split-by (juxt filter remove)) (split-by pos? [-1 -2 4 5 3 -9]) => ([4 5 3] [-1 -2 -9])
(def split-by (juxt filter remove)) (split-by pos? [-1 -2 4 5 3 -9]) => [(4 5 3) (-1 -2 -9)]
I get the same result as you, and that seems to be aligned with what the docs for juxt say