2

In R5RS Scheme how do you display multiple parameters, with a single call? my implementation below works, but adds extra parentheses and spaces.

#!/usr/bin/env racket
#lang r5rs
(define (display-all . rest) (display rest))
(display-all "I " "have " "a " "lovely " "bunch " "of " "coconuts\n")

results in

owner@K53TA:~$ ./Template.ss
(I  have  a  lovely  bunch  of  coconuts
)
Jack
  • 2,223
  • 13
  • 23
GlassGhost
  • 16,906
  • 5
  • 32
  • 45

2 Answers2

7

Simplest:

(define (display-all . vs)
  (for-each display vs))

Note the use of for-each instead of map - for-each is the same thing but assumes you're only calling the function for side-effects, so instead of returning a list of results (using map with display would return a list of voids) it just returns void.

This can get annoying if you want to display non-string things and have spacing between them, for instance if you want (display-all 12 "bananas") to display the string "12 bananas" you have to manually turn the number into a string and add the space yourself. It would be easier to just add spaces in-between elements of the list:

(define (insert-between v xs)
  (cond ((null? xs) xs)
        ((null? (cdr xs)) xs)
        (else (cons (car xs)
                    (cons v (insert-between v (cdr xs)))))))

(define (display-all . vs)
  (for-each display (insert-between " " vs)))

Now calling this:

(display-all "blah" 4 "bloo")

does what you'd expect. If you don't want the spaces inserted automatically, you can specify another argument as the separator object and use it however you need. Here's a version that accepts a separator object:

(define (display-all sep . vs)
  (for-each display (insert-between sep vs)))

This approach would make more sense in a version of scheme that supports optional and keyword arguments however, so you could default it to either a space or the empty string and not interfere with the rest-args.

Jack
  • 2,223
  • 13
  • 23
  • Thank you for a GREAT answer. Only using the 1st implementation though, it feels more flexible; if I wanted spaces in there, I'd put them in there. Then again, maybe I will find a use for the 2nd impl. later. – GlassGhost Oct 24 '14 at 04:21
2

If all the arguments are string, just use apply and string-append. both are in r5rs

#!/usr/bin/env racket
#lang r5rs
(define (display-all . rest) (display (apply string-append rest)))
(display-all "I " "have " "a " "lovely " "bunch " "of " "coconuts\n")
ymonad
  • 11,710
  • 1
  • 38
  • 49
  • Display accepts non-string arguments, while this version only works with strings. Still works, but it's important to note that distinction. – Jack Oct 24 '14 at 01:28