What's in a (str)?

In Clojure there are usually many ways to do things, and I love this. For example, most of the time the same task can be accomplished with map, for, loop, or reduce; other factors than “can this work?” come into play. That’s why I was perplexed when I was playing around recently and couldn’t find a way to reproduce the string concatenation behavior of (str) with any combination of cons/conj, reduce, apply, etc. Am I just too new to these fundamental functions, or is special stuff going on with str?

I am not sure what you are trying to do exactly. An example with expected and actual output would help, but as an example the following works as expected:

(reduce str "" [ "a" "b" "c"])

One possible point of confusion might be that strings can also be iterated over. Try for example:

(reduce #(str %1 "," %2) "" "ab")
1 Like

So basically I’d like to produce any of those outputs you mention but without using the str function anywhere in the call. I had wondered whether strings as sequences of characters could be manipulated like other sequences, but I suspect there is some special treatment going on that differentiates them from simply being collections of Chars.

I guess dropping to a Java.util.StringBuilder is considered cheating? :slightly_smiling_face: Doing that, you could iterate over the collection with any of those constructs and call the append method in each iteration.

I haven’t looked at the source for str, so I do not know what actually happens there.

1 Like

The String type is “special” insofar as it is seqable? and when you call seq on it, you get a clojure.lang.StringSeq which implements the sequence abstraction. Sequence operations on that will generally yield a lazy seq or similar. To get a String back from that sequence, you need to join all the elements of the sequence together. You can use str or clojure.string/join or some Java interop.

1 Like

Basically the str function constructs a string. And the reason you can’t create a string any other way is because Clojure Strings are Java Strings. So it’s not possible to construct a string without using Java’s string constructors, thus interop.

Clojure treats Java strings as sequence of chars, but Java Strings are not simple sequence of chars. They’re a special class that’s handled specially by the runtime.

1 Like

Thanks for the replies! That confirms my suspicion that strings were, under the hood, interop-y and with “Object” special provisions despite our best attempts at being data-driven

A quick peek at the source code for str confirms our suspicions as well :smiley:

1 Like