Functions
Functions must be declared before they are used and so must be written on top of your program. However, this is not required if a function is called from within another function.
native! func Red-by-example MyCode4fun
Variables inside a function created with func are global. They are the seen by the entire program.
A function is created with func as follows:
<function name>: func [<argument1> <argument2> ... <argument n>] [ <actions performed on arguments>]
Red []
mysum: func [a b] [a + b]
print mysum 3 4
7
Demonstrating that variables are global:
Red []
mysum: func [a b] [
mynumber: a + b
print mynumber
]
mynumber: 20
mysum 3 4
print mynumber
7
7
native! function Red-by-example MyCode4fun
function makes its variables local, i.e. it hides (shades) the variables inside it from the rest of the program.
Same program as above, only using function instead of func:
Red []
mysum: function [a b] [
mynumber: a + b
print mynumber
]
mynumber: 20
mysum 3 4
print mynumber
Different results:
7
20
Forcing variables to be global with /extern refinement:
Red []
myfunc: function [/extern a b] [
a: 22
b: 33
]
a: 7
b: 9
myfunc
print a
print b
22
33
Defining the argument type:
You can force your arguments to be of a certain datatype:
Red []
mysum: function [a [integer!] b[integer!]] [print a + b]
print mysum 3.2 4 ; oops! 3.2 is a float!
*** Script Error: mysum does not allow float! for its a argument
*** Where: mysum
*** Stack: mysum
You may allow multiple datatypes:
Red []
mysum: function [a [integer! float!] b[integer!]] [print a + b]
print mysum 3.2 4
7.2
Or use an upper class of datatypes:
Red []
mysum: function [a [number!] b[number!]] [print a + b]
print mysum 3.2 4
7.2
Documenting your functions
A description of your function may be included by placing a string inside the argument block before the arguments. Also, you may also add explanations about your arguments as a string after the restriction block. These descriptions and explanations will show when you ask for help on your own function.
Red [ ]
sum: func [
"Adds two integers, floats or pairs"
a [integer! float! pair!] "Fisrt number"
b [integer!] "Next Number - must be integer"
][
a + b
]
print "This is my function's help:"
print ? sum
This is my function's help:
USAGE:
SUM a b
DESCRIPTION:
Adds two integers, floats or pairs.
SUM is a function! value.
ARGUMENTS:
a [integer! float! pair!] "Fisrt number."
b [integer!] "Next Number - must be integer."
>> sum 5 8,4
*** Script Error: sum does not allow float! for its b argument
*** Where: sum
*** Stack: sum
>> sum 2x3 4
== 6x7
Returning values from functions: native! return Red-by-example MyCode4fun
The return value of a function is either the last value evaluated by the function or one explicitly determined by the word return:
Last evaluation example:
Red []
myfunc: function [] [
8 + 9
3 + 3
print "got here" ; this executes
10 + 5 ; this is returned
]
print myfunc
got here
15
return example:
Red []
myfunc: function [] [
8 + 9
return 3 + 3 ; this is returned
print "never got here" ; NOT executed
10 + 5
]
print myfunc
6
Creating your own refinements:
You can create refinements to you functions, like the native refinements of Red: <myfunction>/<myrefinement>. The refinements are boolean values that are checked by the function:
Red []
myfunc: function [a /up b /down c] [
if up [print a + b]
if down [print a - c]
]
myfunc/up 10 3
myfunc/down 10 3
13
7
Note that arguments are not mandatory for refinements.
A more complete example:
Red [ ]
sum: func [
"Adds two integers, floats or pairs"
a [integer! float! pair!] "Fisrt number"
b [integer!] "Next Number - must be integer"
/average "Average instead of add"
][
either average [a + b / 2] [a + b]
]
print "This is my function help:"
print ? sum
print "Using add with 10 and 16:"
prin "sum = " print sum 10 16
prin "sum/average = " print sum/average 10 16
This is my function help:
USAGE:
SUM a b
DESCRIPTION:
Adds two integers, floats or pairs.
SUM is a function! value.
ARGUMENTS:
a [integer! float! pair!] "Fisrt number."
b [integer!] "Next Number - must be integer."
REFINEMENTS:
/average => Average instead of add.
Using add with 10 and 16:
sum = 26
sum/average = 13
Assigning functions to words (variables)
To assign a function to a variable (a word) you must precede the function with a colon: <word>: :<function>
>> mysum: func [a b] [a + b]
== func [a b][a + b]
>> a: :mysum
== func [a b][a + b]
>> a 3 9
== 12
native! does Red-by-example MyCode4fun
If your function just do something with no arguments and no local variables, create it with the word does :
Red []
greeting: does [
print "Hello"
print "Stranger"
]
greeting
Hello
Stranger
native! has Red-by-example MyCode4fun
If your routine uses no external arguments but has local variables, use the word has. has turns the argument into a local variable. Compare the three programs below. The first uses has with no argument, hence "number"is a global variable. The second gives "number" as argument, making it local. And the third shows that a function with argument need that argument to be sent by the calling event.
native! exit Red-by-example MyCode4fun
Exits a function without returning any values.