Fork me on GitHub
#beginners
<
2016-04-08
>
puhrez01:04:51

what’s more clojurian? default args with & {:keys …} or [….] OR multiple arities

Tim01:04:38

I think they are both ok

Alex Miller (Clojure team)02:04:07

the former has been found to be kind of annoying if you need to call into another layer down with the same style

Alex Miller (Clojure team)02:04:38

generally I tend towards passing an explicit map

Alex Miller (Clojure team)02:04:07

except if you have an outer-most api layer that humans will likely type at a repl, where I will use the kwargs style

Alex Miller (Clojure team)02:04:15

b/c it's good for people

Alex Miller (Clojure team)02:04:37

multiple arities can also be good for people (but is more brittle)

seancorfield03:04:56

You can always do both:

(defn func
  ([opts] (... opts ...)) ; opts is a hash map
  ([k v & kvs] (func (apply hash-map k v kvs))))

seancorfield03:04:22

(off the top of my head, not even typed into a REPL so excuse any errors etc)

Alex Miller (Clojure team)04:04:30

the worst of all worlds :)

seancorfield04:04:41

Hahaha... or the best simple_smile

seancorfield04:04:33

It's certainly not something I'd do as a matter of course. It's useful as a way to migrate from one approach to the other when you realize the {:keys [...]} approach doesn't "scale" simple_smile

urbanslug08:04:58

Want to pass a def two names.

urbanslug09:04:26

Like (def default-user free-plan <string>)

urbanslug09:04:32

Is this doable?

urbanslug09:04:41

Bind a string to two names?

dev-hartmann09:04:22

@urbanslug: def as a special form takes only one symbol and has no multiple arities

dev-hartmann09:04:55

@urbanslug: if you try, you'll get a RuntimeException: to many arguments

urbanslug09:04:03

Yeah, that’s what the books say. Was hoping there was a workaround.

dev-hartmann09:04:17

user=> (def test-user free-plan "user") CompilerException java.lang.RuntimeException: Too many arguments to def, compiling: [...]

dev-hartmann09:04:35

@urbanslug: (def test-user (def free-plan "string"))

dev-hartmann09:04:05

@urbanslug: works, but test-user points to the free-plan, not it's value

dev-hartmann09:04:03

@urbanslug: user=> free-plan "string" user=> test-user #'user/free-plan

urbanslug09:04:57

Cool that’s what I want.

urbanslug09:04:07

To reuse the specific string.

dev-hartmann09:04:07

@urbanslug: user=> (var-get test-user) "string"

dev-hartmann09:04:33

@urbanslug: this will help you get the specific value, when you need it

isaac_cambron14:04:26

@urbanslug would pretty easy to make a macro called defmulti or somesuch

bronsa15:04:32

defmulti already exists in clojure and it's used to define multimethods

isaac_cambron17:04:44

sure, poor naming by me

isaac_cambron18:04:07

I'm sure there's a way better way to write this, but:

product=> (defmacro defdef [val & names] (let [named (map (fn [n] `(def ~n ~val)) names)] `(do ~@named)))
#'product/defdef
product=> (macroexpand '(defdef "hello" foo bar))
(do (def foo "hello") (def bar "hello"))
product=> (defdef "hello!" foo bar)
#'product/bar
product=> foo
"hello!"
product=> bar
"hello!"

seancorfield18:04:21

Why would you want to do that? (I guess I missed your justification)

isaac_cambron21:04:10

No idea - somebody was just asking how to do it

roberto21:04:58

yeah, not sure that is a good idea.