Functions

First class objects

Functions can be constructed as first class objects and assigned to variables as

f = function(a, b, c) {
  -- function body
}

which translates to the Lua code

-- Lua code --

f = function(a, b, c)
  -- function body
end

Curly brackets are optional if the block contains a single statement:

f = function(a, b, c) return true
f = function(a, b, c)
  return true

Methods

Hurdy provides syntactic sugar for functions meant as methods of tables. The code

f = method(a, b, c) {
  -- function body
}

is equivalent to

f = function(self, a, b, c) {
  -- function body
}

Functions with no arguments

Functions with no arguments can be constructed with the shorthand syntax

f = @{
  -- function body
}

which is equivalent to

f = function() {
  -- function body
}

Function and method calls

Function and method calls have the same syntax as in Lua:

f()
t.f()
t:f() -- equivalent to t.f(t)

Variadic functions

The rules for variadic functions are the same as in Lua: they are defined by adding ... as the last argument of a function or method. The rules for accessing ... from the function body are the same as in Lua.

f = function(...) {
  var x, y = ...
  print(x - y)
}

Default values for arguments

Hurdy allows the specification of a default value for an argument of a function, which is used if nil is passed to that argument. The syntax for assining default arguments is

f = function(x=1, y, z=v) {
  -- function body
}

and is equivalent to

f = function(x, y, z) {
  if x == nil { x = 1 }
  if z == nil { z = v }
  -- function body
}

The default value can be any valid expression (including variable names, table fields, function calls, function costructors, and table constructors).

Warning

There are a few caveats to keep in mind when using default values for arguments:

  • Since the assignment is done inside the function, using the argument names as identifiers will not use the variable that was in scope outside of the function.

    var x = 3
    
    var f = function(x=x) {
      print(x)
    }
    
    f() -- prints nil
    
  • The expressions passed as default arguments are evaluated for each argument, one at the time, even if the same expression is passed to multiple arguments.

    var x = 0
    
    var increase = function() {
      x = x + 1
      return x
    }
    
    var f = function(x=increase(), y=increase()) {
      print(x, y)
    }
    
    
    f() -- prints 1, 2
    

Declaration statements

In addition to function constructors as expressions that can be assigned to variables, functions and methods can be declared as statements using the following syntaxes:

var function f(a, b, c) { -* function body *- }
var method m(a, b, c) { -* function body *- }

-- equivalent to:

var f
f = function(a, b, c) { -* function body *- }

var m
m = method(a, b, c) { -* function body *- }
global function f(a, b, c) { -* function body *- }
global method m(a, b, c) { -* function body *- }

-- equivalent to:

global f
f = function(a, b, c) { -* function body *- }

global m
m = method(a, b, c) { -* function body *- }
function f(a, b, c) { -* function body *- }
method m(a, b, c) { -* function body *- }

-- equivalent to:

f = function(a, b, c) { -* function body *- }
m = method(a, b, c) { -* function body *- }

-- only valid if f and m have already been declared!