This is an interesting path to take.  I'm not at all familiar with  
haskell, but a couple of thoughts anyway :-) :

- There's already a lot of moving parts to type hinting, so adding  
this optional approach into defn seems like it'd lead to unintended  
consequences.  That said, there's absolutely nothing wrong with an  
alternative def form (defh? as in 'define hinted fn') -- there's  
plenty of them throughout contrib and elsewhere.

- Remember destructuring, and along with that, one of the nice thing  
about in-place hints, as opposed to a separate definition of expected  
types, is that the definitions can be sparse, e.g.:

(defn foo [{blah :foo #^MyType mt-obj :bar} a b c] ...)

It doesn't look like your macro supports hinting destructured args  
(understandably enough, doing so given the :signatures approach would  
likely be very difficult).

- The thing I don't like about the current type hints is (IMO) the  
distracting quality of '#^'.  What about something like:

(defh foo [String:s unhinted-arg {int:a :a}] ...) or
(defh foo [s:String unhinted-arg {a:int :a}] ...)

That's far more visually-appealing to me, and has the nice advantages  
of being inline in the case of destructuring and supporting sparse  
hinting easily.  I'll bet the macro would end up being pretty simple,  
as well.

Cheers,

- Chas

On Aug 12, 2009, at 12:37 PM, tsuraan wrote:

>
> I'd like to add a :signature entry to the attr-map of defn, that
> provides a haskell-style type signature to functions of the
> single-arglist-body form.  I find the the normal way of providing
> hints to a function:
>
> (defn [ #^Class1 var1 #^Class2 var2 #^Class3 var3] ... )
>
> is way too noisy, and the variables get lost between the types.  What
> I'd like instead is to be able to specify the signature in the
> function metadata:
>
> (defn {:signature [ Class1 Class2 Class3 ReturnType ]}
>  [ var1 var2 var3 ]
>  ...)
>
> I've written a little patch to defn that annotates the arguments
> correctly (I think).  I'm not sure where the metadata for marking up a
> function's return type goes (Is it on the (cons `fn fdecl) part?), but
> it probably wouldn't be hard if I knew what I was doing :)
>
> Anyhow, a revised defn (I've called it defn+ to avoid clashes) is as  
> follows:
>
> (defn zip [ a b ] (map vector a b))
> (def
>
> #^{:doc "Same as (def name (fn [params* ] exprs*)) or (def
>    name (fn ([params* ] exprs*)+)) with any doc-string or attrs added
>    to the var metadata"
>    :arglists '([name doc-string? attr-map? [params*] body]
>                [name doc-string? attr-map? ([params*] body)+ attr- 
> map?])}
> defn+ (fn defn+ [name & fdecl]
>        (let [m (if (string? (first fdecl))
>                  {:doc (first fdecl)}
>                  {})
>              fdecl (if (string? (first fdecl))
>                      (next fdecl)
>                      fdecl)
>              m (if (map? (first fdecl))
>                  (conj m (first fdecl))
>                  m)
>              fdecl (if (map? (first fdecl))
>                      (next fdecl)
>                      fdecl)
>              fdecl (if (vector? (first fdecl))
>                      (if (:signature m)
>                        ; we'll apply the types in the signature  
> vector as the
>                        ; :tag metadata for each argument
>                        (list
>                          (cons
>                            (apply vector
>                              (for [[ tag var ]
>                                    (zip (:signature m) (first fdecl))]
>                                (with-meta var {:tag tag})))
>                            (rest fdecl)))
>                        (list fdecl))
>                      fdecl)
>              m (if (map? (last fdecl))
>                  (conj m (last fdecl))
>                  m)
>              fdecl (if (map? (last fdecl))
>                      (butlast fdecl)
>                      fdecl)
>              m (conj {:arglists (list 'quote (sigs fdecl))} m)]
>          (list 'def (with-meta name (conj (if (meta name) (meta  
> name) {}) m))
>                (cons `fn fdecl)))))
>
> (. (var defn+) (setMacro))
>
> Is this something that people would think is worthwhile?  I really
> prefer haskell's type signatures to clojure's inline hints, but maybe
> it's just something that people get used to.  Anyhow, my first attempt
> at macro hacking, so kind criticism would also be welcome w.r.t.
> style, correctness, etc.
>
> >


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to