Hi Gregor,

Now my very first question ;)

If I have a list of string's, how can i recursivly iterate over that list and 
compose a single string out of the elements of that list?
>
> ...
>
> I think I can use string-append, right?
> But how could I do that? Is there a idiomatic way to do that in Racket?
>

In the special case where you have a list of strings, you can use "apply", as follows:

 (apply string-append mylist)

This works because "string-append" can take any number of arguments, and "apply" calls the procedure on the list of arguments.

In general, though, you may need to do iteration while accumulating. There's a few ways to do this. One is to write a recursive procedure:

(define (append-many-strings strings)
  (cond
    [(null? strings) ""]
    [else (string-append (car strings)
                         (append-many-strings (cdr strings)))]))

To make this into real iteration, it should be transformed to be tail-recursive. This can be done with an accumulator:

(define (append-many-strings-tail strings acc)
  (cond
    [(null? strings) acc]
    [else (append-many-strings-tail (cdr strings)
                                    (string-append acc (car strings)))]))

(append-many-strings-tail mylist "")

Because the recursive call to "append-many-strings-tail" occurs as the very last thing done in the procedure, it won't require stack space at runtime.

The pattern of replacing each "cons" in a list with a function call is captured in a procedure called foldr:

(define (append-many-strings-foldr strings)
  (foldr string-append "" strings))

(append-many-strings-foldr mylist)

This version is equivalent to append-many-strings above. This style is more common in other functional languages than it is in Racket, in my experience.

Probably the most idiomatic way to do it in Racket is with a for/fold form:

(define (append-many-strings-for/fold strings)
  (for/fold ([result ""])
            ([s strings])
    (string-append result s)))

This version will work for inputs that are not a list, because for/fold can draw elements from any arbitrary kind of sequence. It also runs iteratively, without using lots of space at runtime.

I'd encourage you to check out the excellent documentation for each of these ways of doing it.

/David

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to