Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Keyword arguments done right (in Clojure) (stuartsierra.com)
26 points by cemerick on Jan 15, 2010 | hide | past | favorite | 6 comments


The article describes a reasonable approach, but requires passing keyword arguments into a function as a separate map. I wrote a macro, let-kw, which allows a more natural calling convention: (my-fun req1 req2 :kw1 kw1-val :kw2 kw2-val)

I opened a ticket so let-kw would be considered for clojure-contrib inclusion (http://www.assembla.com/spaces/clojure-contrib/tickets/51-Ad...). The actual (final) macro source is posted on the Clojure mailing list (http://groups.google.com/group/clojure/msg/3ee695696c5ea1ec).


This bothered me too at first but it works pretty well in practice, especially if you mix 1-2 "normal" parameters with a map of optional ones.


This highlights one of my biggest problems with lisp and macros. Every personal preference of every coder results in a macro that changes the basic symantics of the language. If I were to pick up code that used this macro, now I have to lean a new function call syntax. Just one macro to change the function call symantics, and just one DSL isn't a problem, but multiply that by every coder's interpretation of "natural calling convention" and every domain's DSL and next thing you know, you don't even recognize the language anymore. The original author usually thinks it make code "cleaner" and more readable, but I find that it rarely does.


1. As cemerick pointed out, let-kw operates inside the function definition. It does not change any semantics.

2. Most keyword arguments for Clojure's built-in functions follow the calling convention which let-kw makes easy, whereas the pass-in-a-separate-map convention is not used in clojure.core anywhere (that I can think of).

3. I've heard this type of anti-DSL argument before, but no one making it has ever linked to a (source-available) project where this caused a problem. Frankly, I've never heard of a dailywtf-type horror story about this, either. Do you actually have some evidence to support your view?


I don't find the linked macro particularly compelling -- however, that macro doesn't change anything about the semantics of anything, it just automates the processing of arguments. Any function is always free to interpret its arguments however it wants, and a lot of clojure fns already accept & args consisting of key-value pairs that are turned into maps at runtime and then inspected.


I wonder how they combine rest args with keyword args. Here's how I do this in my arc macros:

  (paginate '/search' 10
      ;; optional keyword args
      nextcopy "Next →" prevcopy "← Prev"
    :do
      ;; body
      (preprocess docs)
      (each doc (cut docs start-index end-index)
        (render-doc doc)))
More details: http://arclanguage.org/item?id=10692




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: