David
David

Reputation: 147

lisp (scheme) function that works with and without an argument

I'm working on an assignment where I have to construct a function which takes a single argument and returns various things. However, it is also supposed to do something when it is evaluated without an argument and I don't know how to do this. Does anyone know how one would go about implementing such a function? Could I perhaps set a condition that if it is evaluated with an argument it does x and if there is no argument it does y?

Upvotes: 1

Views: 1171

Answers (2)

Sylwester
Sylwester

Reputation: 48775

Scheme, as in R5RS compliant, R6RS, and R7RS:

(define (proc . arg-rest)
  (define arg
    (if (null? arg-rest)
        'default-arg1
        (car arg-rest)))

  ;; use arg 
  arg)

(proc)   ; ==> 'default-arg1
(proc 1) ; ==> 1

If the parameters are not a proper list then the dotted symbol represent the rest of the arguments as a list. The example above takes no mandatory arguments. For completeness here are one with one mandatory:

(define (proc man1 . arg-rest)
  ...)

SRFI-89 Optional positional and named parameters is an extension to R5RS. Many implementations come with many SRFIs already implemented and those who don't can take the reference implementation. Some implementations even works like this with define, but it is not portable.

(define* (proc (arg 'default-arg1))
  ;; use arg 
  arg)

(define* (proc man1 (arg 'default-arg1))
  ...)

SRFI-16 Case lambda is an alternative and is shipped with R6RS:

(define proc  
  (case-lambda 
    (() (proc 'default-arg1))
    ((arg) 
     ;; use arg
     arg)))

(define proc  
  (case-lambda 
    ((man1) (proc man1 'default-arg1))
    ((man1 arg) 
     ...)))

And since you have tagged LISP I'll add Common Lisp version of positional optional arguments:

(defun fun (&optional (arg 'default-arg1))
  arg)

(defun fun (man1 &optional (arg 'default-arg1))
  ...)

Upvotes: 1

Will Ness
Will Ness

Reputation: 71119

You can use the form

(define g (lambda args ...body...))

for that. args will be bound to the list of all the supplied arguments in the function call. You can analyze it and take appropriate decisions inside your function's ...body....

A famous and very nice example is

(lambda args args)              

What's the name of this function?

Another syntax for defining such functions is

(define (g . args) args)

And to define a function that must get, say, at least two arguments, you'd write

(define (foo a b . c) ...body...)

; (define foo (lambda (a b . c) ...body...))

where a will be the first argument, b the second, and c will be the list of all the rest of arguments in the function call (possibly empty).

Upvotes: 4

Related Questions