The proposal is that the trim functions (trim, triml, and trimr) would get a second arity with a function {{trim?}}:
[trim? ^CharSequence s]
{{trim?}} comes first to support partial.
New doc string would be:
"Removes characters from both ends of string.
If trim? is omitted white space is removed. When supplied it accepts
a character and returns true if the character should be removed."
Example test:
(deftest t-trim
(is (= "foo" (s/trim " foo \r\n")))
(is (= "bar" (s/trim "\u2000bar\t \u2002")))
;; Additional test
(is (= "bar" (s/trim "$%#\u2000bar\t \u2002%$#"
#(or (Character/isWhitespace %) ((set "$#%") %))))))
Similar to Python's strip -
https://docs.python.org/2/library/stdtypes.html#str.strip
*Approach:* The proposed solution isn't very DRY but it follows the design guidelines at the top of the file, more exactly point 3:
"3. Functions take advantage of String implementation details to
write high-performing loop/recurs instead of using higher-order
functions. (This is not idiomatic in general-purpose application
code.)"
First I had a solution in which I replaced Character/isWhitespace from the current implementation by calling pred. pred was defaulted to an is-whitespace? function.
That code is of course nicer, even trim-newline could just call into trimr, removing a lot of duplication, but it adds the overhead of always calling a function, instead of calling Character/isWhitespace directly.
The only way I can see to have optimised and DRYer code is to use macros, but I don't think that it will necessary lead to nicer code.
Given the existing design style of the other functions in string.clj I felt that the best solution would be to just simply duplicate in favour of optimised code.