I'm currently looking into Scheme, and the way I have understood it, procedures can take an arbitrary number of arguments.
I have been trying to play around with this, but I'm struggling to grasp the concept.
For instance, say I want to write a welcome message, based on information provided by the user.
If user provides a first and last name, the program shout write:
Welcome, <FIRST> <LAST>!
;; <FIRST> = "Julius", <LAST>= "Caesar"
Welcome, Julius Caesar!
Otherwise, the program should refer to a default value, specified as:
Welcome, Anonymous Person!
I have the following outline for my code, but struggling with how to finalise this.
(define (welcome . args)
(let (('first <user_first>/"Anonymous")
('last <user_last>/"Person"))
(display (string-append "Welcome, " first " " last "!"))))
Example usage:
(welcome) ;;no arguments
--> Welcome, Anonymous Person!
(welcome 'first "John") ;;one argument
--> Welcome, John Person!
(welcome 'first "John" 'last "Doe") ;;two arguments
--> Welcome, John Doe!
Any help is highly appreciated!
In Racket, they way to do this would be using keyword arguments. You can define a function with keyword arguments my writing #:keyword argument-id
when declaring the arguments:
(define (welcome #:first first-name #:last last-name)
(display (string-append "Welcome, " first-name " " last-name "!")))
Which you can call like this:
> (welcome #:first "John" #:last "Doe")
Welcome, John Doe!
However, what you want is to make them optional. To do that, you can write #:keyword [argument-id default-value]
in the argument declaration.
(define (welcome #:first [first-name "Anonymous"] #:last [last-name "Person"])
(display (string-append "Welcome, " first-name " " last-name "!")))
So that if you don't use that keyword in a certain function call, it is filled with the default value.
> (welcome)
Welcome, Anonymous Person!
> (welcome #:first "John")
Welcome, John Person!
> (welcome #:first "John" #:last "Doe")
Welcome, John Doe!
> (welcome #:last "Doe" #:first "John")
Welcome, John Doe!
@Alex Knauth's answer is great. That's something I didn't know about.
Here's an alternative, though it's not quite as flexible
(define (welcome (first "Anonymous") (last "Person"))
(displayln (string-append "Welcome, " first " " last "!")))
This works pretty nicely with your basic requirements
> (welcome)
Welcome, Anonymous Person!
> (welcome "John")
Welcome, John Person!
> (welcome "John" "Doe")
Welcome, John Doe!
However, Alex's solution has two distinct advantages.
- The arguments can be called in either order
- The last name can be specified without the first name