Regular scheme does not allow adding strings with +, but from my experience with python that is a very intuitive way of working with strings - and I think it contributes to making string-manipulation easier with python.

But guile offers a way to do so by using GOOPS, the Guile Object Oriented Programming System:

(use-modules (oop goops)) ( define-method ( + (x <string> ) (y <string> ) . e) ( if (equal? '() e) (string-append x y) ; else (apply + (append (list (string-append x y)) e)) )) ; and the error case ( define-method ( + (x <string> ) (y <number> )) (throw 'mixed-strings-and-numbers-exception (format "+ cannot be used with mixed type input: x ~a y ~a" x y)))

And this gives you the full python-behaviour.

But as Mark Weaver states, this is actually a problem for systems using prefix notation, because different from python scheme allows for an empty call to +:

(+) ; this returns 0 (apply + '()) ; also returns 0, but here you might not know whether ; the list is empty, because you might get it from ; somewhere else!

And GOOPS changes + globally, so that every bit of code I use would suddenly see a changed (+), which might break existing error-handling:

( let ((foo 1)(bar "2" )) (catch 'wrong-type-arg ( lambda () (+ foo bar)) ; checked ( lambda (key . args) ; handler for wrong types (format #f "foo or bar is not a number!" ))))

And this actually applies to all code running in the same process:

<Arne```> mark_weaver: I have a question to be really, really sure (as in “I’m certain that I can misunderstand anything if it even has a minuscle amount of ambiguity”): When I add a method with GOOPS, does that affect libraries I use? When I release a module which adds a method with GOOPS, and someone uses that module, does that affect other modules he or she uses? [09:41] <mark_weaver> when you add a method to any generic function (such as +) with GOOPS, you are effectively mutating that generic function. Anything thing else in the system that uses that generic function is affected, yes. [09:43] <mark_weaver> in this case, if you add string concatenation to +, that will affect + for all users of + throughout the guile process.

And this is due to the added flexibility we get from prefix-notation:

<mark_weaver> Using + for that is likely to lead to bugs, where you do something like (apply + <list>) which works just fine as long as <list> has at least one element, otherwise it breaks. [05:16] <mark_weaver> note that this issue doesn't arise with infix languages, because theres no way to use infix '+' with zero arguments. [05:19]

Later, Mark noted two things which are better ideas, I think:

<mark_weaver> now, list concatenation (append), string concatenation (string-append), and vector concatenation *are* conceptually the same thing. combining all of those things into a ++ operator would be much more defensible. [00:39] <mark_weaver> although you'd still have a problem of what to return when passed zero arguments. [00:40] <mark_weaver> that reminds me of another place where there'd be a conflict with combining these two concepts into one: one might reasonably decide to extend numerical addition to vectors and lists, by adding successive elements together, e.g. (lambda (x y) (map + x y)) [00:42]

So, why not just adjust append to also append strings, and + to apply to lists of lists and do vector addition?

++ looks pretty dangerous for me: Intuitively I would have thought that it does vector addition…

<mark_weaver> Arne`: fair enough. If you keep those two concepts separate, I have no further complaints. I'll just note that (append) returns '().