lyl
lyl

Reputation: 293

How to construct a function with a default argument

To make a function with default argument, I tried this:

f: function [a b] [either unset? :b [a + 1] [a + b]]
f 5
f 3 5

then I receive this message *** Script Error: f is missing its b argument.
So, what shall I do?

Upvotes: 0

Views: 152

Answers (2)

9214
9214

Reputation: 2193

There's a trick to implement variable-arity functions that some of the built-ins use, most notably help:

>> ? help
...
ARGUMENTS:
     'word        [any-type!]

Specify your argument as quoted and belonging to any-type! typeset. Or, alternatively, list the allowed types and include unset! in it.

>> foo: func [a 'b [unset! integer!]][a + do pick [1 b] unset? :b]
== func [a 'b [unset! integer!]][a + do pick [1 b] unset? :b]
>> foo 5
== 6
>> foo 3 5
== 8

This, however, comes at a certain price:

  • Optional arguments must come in succession after the mandatory ones.
  • All such function calls within a script now need to be wrapped in parentheses, because otherwise there's no way for the interpreter to guess where your variadic expression ends.
  • You lose the benefits of type-checking, since any-type! accepts any argument; ' in front of the argument also enforces specific semantics, which makes such variadic functions even more cumbersome.
  • Your code becomes unidiomatic: the conventional way to address the need for optional arguments is via refinements. Variadic functions are usually implemented with a single block! argument, which might even be dialected.

Such an approach is justified only for user-facing polymorphic functions, intended to be used from command-line prompt (such as help) or any other kind of interface that provides clear-cut boundaries for typed expressions (e.g. end of the line, special terminating symbol), and even then the number of optional arguments is kept at minimum.

Upvotes: 2

Maciej Łoziński
Maciej Łoziński

Reputation: 883

You can use a refinement. See: http://helpin.red/Functions.html

For example:

>> increase: function [a /add b] [either none? b [a + 1] [a + b]]
== func [a /add b][either none? b [a + 1] [a + b]]
>> increase 3
== 4
>> increase/add 3 5
== 8

Upvotes: 2

Related Questions