Functions are user-defined abstractions.

There is no explicit return statement. The value returned is the result of the last expression evaluated meaning that conditional expressions such as if and cond can effect where the function returns from in the source code.

You can declare zero or more parameters to the function.

define (desc a) {
  if (a lt 0) "negative" "positive"

define (foo v) {
  printf "%d + 10 is %s\n" v (desc (v + 10))
  printf "%d - 10 is %s\n" v (desc (v - 10))

foo 5
foo 15
$ idio simple-function
5 + 10 is positive
5 - 10 is negative
15 + 10 is positive
15 - 10 is positive

The expression used for the body of a function is usually a block to combine a sequence of actions but can be any expression:

define (true-constant) #t

define (true-string) "true"

define (return-arg a) a

define (add a b) (a + b)

printf "(true-constant) is %s\n" (true-constant)
printf "(true-string)   is %s\n" (true-string)
printf "(return-arg 7)  is %s\n" (return-arg 7)
printf "(add 7 13)      is %s\n" (add 7 13)
$ idio function-bodies
(true-constant) is #t
(true-string)   is true
(return-arg 7)  is 7
(add 7 13)      is 20

Variadic Functions

A function can declare its final parameter as variadic by separating it with &. Any arguments supplied to the function over and above the named formal parameters will be bundled into a list and be available through the final parameter. If no arguments over and above the named formal parameters were supplied the variadic parameter will have the value #n (the empty list).

define (desc a) {
  if (a lt 0) "negative" "positive"

define (foo base & mods) {
  if (null? mods) {
    printf "base is %d\n" base
  } {
    for mod in mods {
      printf "%d + %d is %s\n" base mod (desc (base + mod))

foo 5 10 -10
foo 15
$ idio variadic-function
5 + 10 is positive
5 + -10 is negative
base is 15

Anonymous Functions

Where a function is only going to be used once we don’t need to declare a named function (and pollute the namespace) but can pass an anonymous function in situ.

An anonymous function is declared as:

function (params) body

although as it is almost always an argument to something else it will be wrapped in parentheses: (function (params) body).

The for looping construct we’ve been using is just syntactic sugar around for-each:

for var in vals body

for-each (function (var) body) vals

For example:

vals := '(1 2 3)

for val in vals {
  printf "val is %d\n" val

for-each (function (val) {
  printf "val is %d\n" val
}) vals
$ idio anonymous-function
val is 1
val is 2
val is 3
val is 1
val is 2
val is 3

Last built at 2024-05-19T06:11:39Z+0000 from 77077af (dev) for Idio 0.3