Skip to content

Notes on Function Calls

Daniel edited this page May 7, 2019 · 3 revisions

Functions

// a function with 4 arguments
f1 := func(a, b, c, d) {}

// a function with 3 arguments including a variadic argument 'c'
f2 := func(a, b, c...) {}

Function Calls

f1(1, 2, 3, 4)    // ok
f1(1, 2, 3)       // illegal
f1(1, 2, 3, 4, 5) // illegal

f2(1)             // illegal
f2(1, 2)          // ok: c = []
f2(1, 2, 3)       // ok: c = [3]
f2(1, 2, 3, 4)    // ok: c = [3, 4]

Function Calls with Spread Syntax

a := [1, 2, 3] 
f1(a...)          // error: f1(1, 2, 3)
f1(1, a...)       // ok: f1(1, 1, 2, 3)

f2(a...)          // ok: a = 1, b = 2, c = [3]
f2(1, a...)       // ok: a = 1, b = 1, c = [2, 3]
f2(1, 2, a...)    // ok: a = 1, b = 2, c = [1, 2, 3]

Some Examples

// reduce(collection, reduceFn [, initial])
reduce := func(x, a...) {
  if len(a) == 0 { return }
  } else if len(a) == 1 {
    return doReduce(x, a[0], undefined)
  } else {
    return doReduce(x, a[1], a[2])
  }
}

doReduce := func(x, f, i) {
  // ...
}

// Q: Would be easier if we allow JS-like syntax?
reduce2 := func(x, f, i) {
  // 'i' can be skipped: reduce2(x, f)
  s := is_undefined(i) ? x[0] : i
  si := is_undefined(i) ? 0 : 1
  for _, v in x[si:] {
    f(s, v)
  }
}
bind := func(f, a...) {
  return func(b...) {
    return f([a..., b...]...)
  }
}

class1 := {
  n: 0,
  inc: func(self, d) {
    self.n += d
  }
}

a := new(class1)   // make instance 'a' of type 'class1' using 'new' builtin (or expression)
a.inc(10)          // a.n == 10
a.inc(4)           // a.n == 14

// 'new' will be implemented in Go
// but it would look like this
new := func(proto) {
  instance := copy(proto)
  for k, v in proto {
    if is_function(v) {
      instance[k] = bind(instance, v)
    }
  }
  return instance
}
Clone this wiki locally