--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
"bc"
Am 08.12.2010 um 23:05 schrieb Surgo:
> That's a fair criticism. I suppose that I'm not necessarily looking
> for specifically String manipulation abstractions (I can just do a
> (.substr "abc" 1) to get "bc" as a String after all), but rather
> looking for an abstraction that takes something that's addressable as
> a sequence and returns it in the same format or type instead of a seq.
Namespaces to the rescue:
(ns your.name.space
(:refer-clojure :exclude (first rest)))
(defprotocol MySeq
(first [this])
(rest [this]))
(extend-protocol MySeq
String
(first [this] (.charAt this 0))
(rest [this] (subs this 1))
Object
(first [this] (clojure.core/first this))
(rest [this] (clojure.core/rest this)))
Now use first and rest as normal. Here some examples:
your.name.space=> (first "abc")
\a
your.name.space=> (rest "abc")
"bc"
your.name.space=> (first [1 2 3])
1
your.name.space=> (rest [1 2 3])
(2 3)
Sincerely
Meikel
> That's a fair criticism. I suppose that I'm not necessarily looking
> for specifically String manipulation abstractions (I can just do a
> (.substr "abc" 1) to get "bc" as a String after all), but rather
> looking for an abstraction that takes something that's addressable as
> a sequence and returns it in the same format or type instead of a seq.
So something like an inverse to (seq)? You could write such a thing, though it would have to know about each type (seq) knows about. More importantly, it would have to somehow know what type the thing originally was, since there's no difference between e.g. (seq "abc") and (seq [\a \b \c]). You'd either have to store the type when calling (seq) and manually pass it when calling the inverse function, or else I suppose you could write a wrapper for (seq) that adds metadata about what type the thing originally was.
Incidentally, while testing this last idea, I was surprised to find that :type metadata is treated specially:
=> (with-meta '() {:type (type [])})
[]
I assume this means :type is used internally by Clojure somehow. I notice clojure.org says that metadata "is used to convey information to the compiler about types", but ought there be a list of "reserved" metadata?
On Dec 8, 2010, at 4:05 PM, Surgo wrote:So something like an inverse to (seq)? You could write such a thing, though it would have to know about each type (seq) knows about. More importantly, it would have to somehow know what type the thing originally was, since there's no difference between e.g. (seq "abc") and (seq [\a \b \c]). You'd either have to store the type when calling (seq) and manually pass it when calling the inverse function, or else I suppose you could write a wrapper for (seq) that adds metadata about what type the thing originally was.
> That's a fair criticism. I suppose that I'm not necessarily looking
> for specifically String manipulation abstractions (I can just do a
> (.substr "abc" 1) to get "bc" as a String after all), but rather
> looking for an abstraction that takes something that's addressable as
> a sequence and returns it in the same format or type instead of a seq.
Incidentally, while testing this last idea, I was surprised to find that :type metadata is treated specially:
=> (with-meta '() {:type (type [])})
[]
I assume this means :type is used internally by Clojure somehow. I notice clojure.org says that metadata "is used to convey information to the compiler about types", but ought there be a list of "reserved" metadata?
Am 08.12.2010 um 23:53 schrieb Laurent PETIT:
> Meikel showed the way, though it's different enough in semantics to deserve its own protocol and not override (in fact replace, in his example) existing concepts.
Well, this showed up the second time in two days, so I thought I'd write it up in an email. However: I strongly discourage doing such things. I would scratch a project working internally like that from my dependency list. (luckily the effects of such a protocol are limited to opt-in namespaces)
Listen to Laurent! He is an experienced clojurian. This is a different thing. Name it differently! Handle it differently!
As the way Clojure works:
Listen to Rich! He has probably thought more about this, than anyone else ever will. If something is not the way you expect it to be or something is missing, then there is almost surely a reason for this fact. If you still think, that something should be changed, lobby for the change on the mailing list.
Sincerely
Meikel
On Wed, Dec 8, 2010 at 2:00 PM, Laurent PETIT <lauren...@gmail.com> wrote:
>> (def test "abc")
>> (first test)
>> > \a
>> (rest test)
>> > (\b \c)
>> (string? (rest test))
>> > false
>>
>> It would be really helpful if first/rest returned strings (or a
>> character in the case of first), not lists, when given string input.
>> Is there a design reason for the current behaviour and, if so, are
>> there equivalent built-in functions that do the right thing for
>> strings?
>
> (first "abc") gives you a character.
>
> (rest anything) returns a seq, by definition. It's not about Strings, it's
> the contract of rest. A String is not a seq, but it's viewable as a seq, in
> which case each element of the seq will be a character of the String.
This behaviour would be a lot easier to deal with if into worked with strings.
-Phil