On Aug 12, 2009, at 2:02 PM, tsuraan wrote:
> I didn't put it in yet, but I was thinking of just having nil in the
> type vector for unhinted variables, so you could have
>
> (defn foo {:signature [ String String nil ]} [ a b c ] ...)
>
> and then c wouldn't be hinted. I hadn't thought of destructuring at
> all; I'm guessing that it could be done with
I'd think _ would be more idiomatic for those that like the haskell-
esque style...?
> (defn foo {:signature [{:bar Mytype} nil nil nil]} [{blah :foo mt-obj
> :bar} a b c] ...)
>
> but that's getting pretty ugly on its own. I'm not sure if it would
> be a win to try to do anything fancy like that. I'm also not sure
> what the destructuring assignment syntax is for maps right now, so
> what I wrote might be total nonsense, syntactically. I hope the idea
> is clear, anyhow.
Yeah, I think supporting a parallel argument specification is probably
not tenable. On the other hand, performing a relatively simple
transformation to a set of destructuring forms is probably pretty
straightforward -- I don't even think :as, :keys, etc would require
any special treatment.
>> - 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.
>
> I'd hate to see somebody do it, but it's currently valid to define
> variables with colons in them, so there could be code out in the wild
> with those definition forms already. Other than that, I like the
> looks of it. I think the macro would be easy as well, so long as
> you're comfortable munging variable names :)
Well, that's one benefit/motivation to just have another def form,
rather than trying to make defn support everyone's preferred variation/
style.
I knocked out a quickie implementation that appears to work with the
couple of use cases I've thrown at it so far (pasted at the end of
this msg).
Just a little exposition:
com.snowtide.clojure.utils=> (binding [*print-meta* true]
(prn (macroexpand '(deft a [Long:a b
{[Integer:c] :c} {:keys [Double:d]}] (+ a b c d)))))
(def #^{:arglists (quote ([#^Long a b {[#^Integer c] :c} {:keys
[#^Double d]}]))} a (clojure.core/fn ([#^Long a b {[#^Integer c] :c}
{:keys [#^Double d]}] #^{:line 159} (+ a b c d))))
I *think* I've gotten the :tag metadata right (which I've burned
myself on before, e.g. putting Class objects in :tag slots instead of
symbols, etc), as this fn compiles without reflection warnings:
(deft a
[String:b [Double:c :as java.util.List:list] {java.util.Random:d :d}]
(.toCharArray b)
(.size list)
(.floatValue c)
(.nextInt d))
A couple of nice things about this:
- it doesn't interfere with 'normal' type hints (e.g. #^Foo and Foo:b
can coexist in the same declaration if you want to be silly about
things)
- I think this kind of hinting could be bolted right into the existing
destructuring functionality if Rich were so inclined (though I
wouldn't bet on that). This would allow you to use Foo:bar hints in
any binding-form (e.g. let, fn, for, etc etc).
Cheers,
- Chas
-----------
(defn- decorate-hinted-symbol
[sym]
(let [[type arg] (.split (name sym) ":")]
(if arg
(with-meta (symbol arg) {:tag (symbol type)})
sym)))
(defn- decorate-hinted-args
[args]
(cond
(vector? args) (vec (map decorate-hinted-args args))
(map? args) (into {} (map decorate-hinted-args args))
(symbol? args) (decorate-hinted-symbol args)
(keyword? args) args
:else (throw (Exception. (str args)))))
(defmacro deft
[name args & body]
`(defn ~name
~(decorate-hinted-args args)
~...@body))
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---