Fork me on GitHub

I am implementing a protocol with method foo which takes two params, but I am not using any of them in the implementation.. Does this throw an error when method calls tries to match implementation ? (def protocol ISim (foo [a b])) (defrecord Sim ISim (foo [a b] (list 1 2 )))


So long as it has two params when you call it (foo one two) you’ll be fine.


yeah thought so..thanks @jeff.engebretsen .. But I was wondering because code is throwing this exception 'java.lang.IllegalArgumentException: No implementation of method: :foo of protocol: #'org.sim/ISim found for class: clojure.lang.PersistentHashMap at clojure.core$cacheprotocol_fn.invoke (core_deftype.clj:554)'


It’s saying that PersistentHashMap doesn’t have a foo method. You need to pass an ISim as the first param. (foo (Sim.) “param2”)


“Call foo on (Sim.) with arg ‘param2’"


Question regarding protocols: is it always assumed that the first parameter to a method is a record or some other "object" that implements the protocol?


Yes >The resulting functions dispatch on the type of their first argument, and thus must have at least one argument.


For clarity you could call the first arg ‘this’.


(defrecord Sim ISim (foo [this b] (list 1 2)))


Neat, thanks!


@payal: you mentioned that you aren't using either of your parameters, but it seems to be implicit that you must at least use the first of them based on @jeff.engebretsen answer above


When calling the function you must pass in the object that has the function. But in the implementation you don’t have to use any of the args.


Yes, sorry, that's what I was trying to get at. "Use" meaning "pass in as an argument"


In this instance you must pass two args all the time since that’s how it’s defined. If you wanted to make the arguments optional you’d have to provide a single arg option (so you only pass the object). Or put the other args behind an & for a var-arg approach.


Thanks @tdaudelin and @jeff.engebretsen .. I modified implementation to `(defrecord Sim ISim (foo [this b] (list 1 2 )))` and calling it accordingly.


hope it works


Hi y'all. Can anyone tell me if there's something like gensym for keywords? I know one can just do (keyword (gensym "foo")), but my understanding is that this will only guarantee uniqueness with respect to symbols, not other keywords. The use case here is adding data-derived map keys to existing maps without creating clashes...


i think the answer here is namespaced keywords to prevent clashes, but not sure how to auto create like a gensym


interesting. my particular use case is in extracting features from text for machine learning. I'm making up an abstraction (currently called a "featurizer"), the idea being that you pass in a vector of maps of text and existing features + any function that returns an array of features from text (tokenizers, stemmers, regex searches, weird parsers whev.) and returns a map with the new features added. So I suppose I could just fake namespaces by appending the name of the featurizer function to each thus-created key...


@gowder maybe you could store your features in a vector instead (?) or maybe doing something like this: (zipmap (range) yer-features) or if this is almost ok but u really want keywords for the keys (zipmap (map keyword (range)) yer-features)