Scheme - Optional arguments and default values

不想你离开。 提交于 2019-12-10 21:10:09

问题


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!


回答1:


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!



回答2:


@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.

  1. The arguments can be called in either order
  2. The last name can be specified without the first name


来源:https://stackoverflow.com/questions/36914415/scheme-optional-arguments-and-default-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!