This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-30
Channels
- # adventofcode (3)
- # announcements (4)
- # babashka (42)
- # beginners (56)
- # biff (23)
- # cider (8)
- # clj-yaml (2)
- # cljdoc (16)
- # clojure (83)
- # clojure-europe (52)
- # clojure-nl (3)
- # clojure-norway (4)
- # clojure-sweden (2)
- # clojure-uk (2)
- # clojurebridge (1)
- # clojurescript (2)
- # cloverage (1)
- # cursive (11)
- # data-oriented-programming (1)
- # deps-new (2)
- # dev-tooling (2)
- # emacs (3)
- # etaoin (4)
- # events (5)
- # fulcro (5)
- # gratitude (3)
- # java (3)
- # jobs (1)
- # jobs-discuss (1)
- # joyride (33)
- # malli (16)
- # music (1)
- # nbb (1)
- # nrepl (4)
- # nyc (1)
- # off-topic (25)
- # pathom (8)
- # re-frame (1)
- # reitit (7)
- # remote-jobs (2)
- # shadow-cljs (6)
- # tools-deps (9)
https://clojure.org/guides/spec#_instrumentation_and_testing, is there a faster way to instrument every function in a project that has an associated spec fdef than doing it one at a time? Maybe at the level of a namespace?
Check out the https://clojure.github.io/spec.alpha/clojure.spec.test.alpha-api.html#clojure.spec.test.alpha/instrument for instrument
:
Usage: (instrument)
(instrument sym-or-syms)
(instrument sym-or-syms opts)
Instruments the vars named by sym-or-syms, a symbol or collection
of symbols, or all instrumentable vars if sym-or-syms is not
specified.
Just use (instrument)
and all fdefs
will be instrumented.It’s an error:
user=> (def arr (make-array String 8))
#'user/arr
user=> (aset arr 0 42)
Execution error (ArrayStoreException) at jdk.internal.reflect.DirectMethodHandleAccessor/null (DirectMethodHandleAccessor.java:104).
java.lang.Long
How can I prevent naming collisions in two different protocols which share a function name that are implemented in two different defrecord
s ? If I use the same name I get a warning that the second record is redefining the function from the first, which makes sense. Is there some mechanism with protocols that allows me to not clobber a method definition in a different defrecord
from a different protocol
that looks like diamond problem
I don’t believe that is possible. A protocol will end up defining a function in the same namespace. You should be getting a redefinition error
Well there are a number of associated functions / the entire defrecord it may as well all be in a different namespace 🤷
is this your problem
user=> (defprotocol P1 (f [_]))
P1
user=> (defprotocol P2 (f [_]))
Warning: protocol #'user/P2 is overwriting method f of protocol P1
P2
i guess putting all the commons of 2 protocols in another one and then subtype that will work?
there are no subtypes. you need to separate the protocol definitions into different namespaces
nor is there type composition?
well I think that depends on what you mean
one object can extend multiple protocols and/or implement multiple interfaces
composition as in “composition over inheritance”
Protocols are different from interfaces (deliberately ignoring that defprotocol
creates an interface for different reasons). There is no inheritance. You cannot make a protocol extend another one. When you extend a type to satisfy a protocol, you do not subtype the protocol.
In Java, classes/interfaces serve multiple purposes. One of them is namespaces. Two interfaces can have the same method name, since they are namespaced to the interface.
In Clojure, these purposes are split into different concepts. Protocols provide polymorphism, but not namespacing. This is what namespaces are for. “Methods” defined by protocols are put in the current namespace.
When you extend a protocol, you only register an implementation for the protocol’s dispatch mechanism. You do not “inherit” the functions, they will not be copied to the current namespace.
Other than Java, you can extend two protocols that define the same function name unambiguously:
(deftype Impl []
foo/Protocol
(example [])
bar/Protocol
(example []))
Now Impl
satisfies both foo/Protocol
and bar/Protocol
. To call the “example” method for Impl
, you will need to use the respective namespaces. (example impl)
will not work (there is no example
var in the current namespace), but (foo/example impl)
and (bar/example impl)
will, without name conflicts.Hi All, a simple question on how to achieve this:
{:metrics [(when some-boolean? {:name "Forecasted"})
{:aga 39}]}
I want to include the first element conditionally, it's currently including null which I don't want there.....
I tried with conj and merge but same behavior
the collection is a vector of MapsAnd you don't have to start with []
:
{:metrics (cond-> [{:age 39}]
true (conj {:name "Forecasted"}))}
@U01RL1YV4P7 - thanks for your response, will it change the order of the elements in vector I need to keep them in same order
Good catch- so use @U0P0TMEFJ's solution. Anyway, are you sure that a vector of maps with one entry is the best structure for your task?
Sure @U01RL1YV4P7 thanks again, the actual code has 200+ elements, I just gave a sample to understand the requirement 🙂
Whats the purpose of “ret” here? https://clojuredocs.org/clojure.core/amap
it's named so you could potentially use it in expr
don't know if anyone ever actually does so
this long pre-dates my involvement with Clojure so I am only guessing, but generally if we need a name that the caller of the macro may need to use, we let them name it (otherwise you're in anaphoric macro land). I think proxy
is the only exception to this general rule (with this
)