clojure.contrib.str-utils is one of the first libs I wrote, and it's
showing its age. I decided to try to start fresh, incorporating some
ideas discussed on the list. In general, I'm trying to provide an
efficient, functional API for string manipulation.
My new attempt is creatively named clojure.contrib.str-utils2.
One big change: you can't (use ...) it. That's because it reuses some
of the names in clojure.core. For example, it defines "take" and
"drop" specifically for strings.
You have to (require '[clojure.contrib.str-utils :as s]) then call
functions like s/take, s/drop. If everybody hates this, I'll change
it, but it would require adding prefixes on a bunch of functions.
Many of these functions are much faster than the equivalent using
sequences. For example, str-utils2/escape is 5-10 times faster than
(apply str (map f "foo"))
Eventually, I'd like to replace the old clojure.contrib.str-utils.
Let me know what you think.
-Stuart Sierra
Me too. I think it would be helpful to have a recommended
namespace alias to help keep different people's code a bit
more uniform.
I use (require '[clojure.contrib.str-utils2 :as str2]) for
now and would recommend just 'str' if the lib name changes.
--Chouser
> I use (require '[clojure.contrib.str-utils2 :as str2]) for
> now and would recommend just 'str' if the lib name changes.
Except, of course, since there is already a str function, 'str' would
be a bad alias.
'strutils' or 'str-utils' sound fine to me, but I'm not so great at
the name game.
I'm in favor of str-utils2 replacing str-utils, though.
Dan
For me, I'd like it if the core functions had the "data" as the first
argument, but have a special function—I can't come up with a better
name than "partial-2"—so that (partial-2 function opt1 opt2 opt3) is
equivalent to (fn [data] (function data opt1 opt2 opt3)). That way, I
could do things like (map (partial-2 s/split #"\n" 30) vector-of-strs)
without breaking .
> Hi,
>
> Disclaimer: personal opinion following...
I think that's all we have when it comes to matters of style :-)
> I'm sorry. I don't get the elegance of point-free style.
>
> In mathematics f denotes the function, while f(x) denotes the value f
> takes over x. This is actually a nice and easy to understand notation.
> But why do I have to clutter my clojure code with `partial`s and
> `comp`s because of that? In Haskell, where `partial` is automatic and
> `comp` is a dot, this is maybe elegant. But not here.
>
> I don't know, whether this example is contorted on purpose, but I
> really had to very slowly step through it to see what's going on.
>
>> (map (comp (partial map (comp #(str2/drop % 2)
>> #(str2/take % 5)))
>> #(str2/split % #"\t"))
>> (split a-string #"[\n\r]"))
>
> This is almost self-explaining:
>
> (map (fn [part-numbers]
> (map #(-> % (str2/take 5) (str2/drop 2))
> (str2/split part-numbers #"\t")))
> (str2/split a-string #"[\n\r]"))
I agree wholeheartedly with Meikel. -> is very straightforward for me
to understand.
Outside of matters of style, changing the expected arguments of ->
would make at least two things impossible:
- use of variadic fns, e.g. (-> data (my-fn arg1 arg2 ... argN) keys
last)
- use of host platform fns (this is incredibly useful with
ByteBuffers, etc) (-> bytebuffer (.put other-data) .flip (.position
23) (.limit 89))
Back to matters of style, and agreeing with Jon upthread, doesn't #()
provide a superset of partial's functionality, with more 'literal',
easier-to-read code?
Cheers,
- Chas
Regards,
--
Michel