# Tests of Starlark 'function'
# option:set

# TODO(adonovan):
# - add some introspection functions for looking at function values
#   and test that functions have correct position, free vars, names of locals, etc.
# - move the hard-coded tests of parameter passing from eval_test.go to here.

load("assert.star", "assert", "freeze")

# Test lexical scope and closures:
def outer(x):
   def inner(y):
     return x + x + y # multiple occurrences of x should create only 1 freevar
   return inner

z = outer(3)
assert.eq(z(5), 11)
assert.eq(z(7), 13)
z2 = outer(4)
assert.eq(z2(5), 13)
assert.eq(z2(7), 15)
assert.eq(z(5), 11)
assert.eq(z(7), 13)

# Function name
assert.eq(str(outer), '<function outer>')
assert.eq(str(z), '<function inner>')
assert.eq(str(str), '<built-in function str>')
assert.eq(str("".startswith), '<built-in method startswith of string value>')

# Stateful closure
def squares():
    x = [0]
    def f():
      x[0] += 1
      return x[0] * x[0]
    return f

sq = squares()
assert.eq(sq(), 1)
assert.eq(sq(), 4)
assert.eq(sq(), 9)
assert.eq(sq(), 16)

# Freezing a closure
sq2 = freeze(sq)
assert.fails(sq2, "frozen list")

# recursion detection, simple
def fib(x):
  if x < 2:
    return x
  return fib(x-2) + fib(x-1)
assert.fails(lambda: fib(10), "function fib called recursively")

# recursion detection, advanced
#
# A simplistic recursion check that looks for repeated calls to the
# same function value will not detect recursion using the Y
# combinator, which creates a new closure at each step of the
# recursion.  To truly prohibit recursion, the dynamic check must look
# for repeated calls of the same syntactic function body.
Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
fibgen = lambda fib: lambda x: (x if x<2 else fib(x-1)+fib(x-2))
fib2 = Y(fibgen)
assert.fails(lambda: [fib2(x) for x in range(10)], "function lambda called recursively")

# However, this stricter check outlaws many useful programs
# that are still bounded, and creates a hazard because
# helper functions such as map below cannot be used to
# call functions that themselves use map:
def map(f, seq): return [f(x) for x in seq]
def double(x): return x+x
assert.eq(map(double, [1, 2, 3]), [2, 4, 6])
assert.eq(map(double, ["a", "b", "c"]), ["aa", "bb", "cc"])
def mapdouble(x): return map(double, x)
assert.fails(lambda: map(mapdouble, ([1, 2, 3], ["a", "b", "c"])),
             'function map called recursively')
# With the -recursion option it would yield [[2, 4, 6], ["aa", "bb", "cc"]].

# call of function not through its name
# (regression test for parsing suffixes of primary expressions)
hf = hasfields()
hf.x = [len]
assert.eq(hf.x[0]("abc"), 3)
def f():
   return lambda: 1
assert.eq(f()(), 1)
assert.eq(["abc"][0][0].upper(), "A")

# functions may be recursively defined,
# so long as they don't dynamically recur.
calls = []
def yin(x):
  calls.append("yin")
  if x:
    yang(False)

def yang(x):
  calls.append("yang")
  if x:
    yin(False)

yin(True)
assert.eq(calls, ["yin", "yang"])

calls.clear()
yang(True)
assert.eq(calls, ["yang", "yin"])


# builtin_function_or_method use identity equivalence.
closures = set(["".count for _ in range(10)])
assert.eq(len(closures), 10)

---
# Default values of function parameters are mutable.
load("assert.star", "assert", "freeze")

def f(x=[0]):
  return x

assert.eq(f(), [0])

f().append(1)
assert.eq(f(), [0, 1])

# Freezing a function value freezes its parameter defaults.
freeze(f)
assert.fails(lambda: f().append(2), "cannot append to frozen list")

---
# This is a well known corner case of parsing in Python.
load("assert.star", "assert")

f = lambda x: 1 if x else 0
assert.eq(f(True), 1)
assert.eq(f(False), 0)

x = True
f2 = (lambda x: 1) if x else 0
assert.eq(f2(123), 1)

tf = lambda: True, lambda: False
assert.true(tf[0]())
assert.true(not tf[1]())

---
# Missing parameters are correctly reported
# in functions of more than 64 parameters.
# (This tests a corner case of the implementation:
# we avoid a map allocation for <64 parameters)

load("assert.star", "assert")

def f(a, b, c, d, e, f, g, h,
      i, j, k, l, m, n, o, p,
      q, r, s, t, u, v, w, x,
      y, z, A, B, C, D, E, F,
      G, H, I, J, K, L, M, N,
      O, P, Q, R, S, T, U, V,
      W, X, Y, Z, aa, bb, cc, dd,
      ee, ff, gg, hh, ii, jj, kk, ll,
      mm):
  pass

assert.fails(lambda: f(
    1, 2, 3, 4, 5, 6, 7, 8,
    9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23, 24,
    25, 26, 27, 28, 29, 30, 31, 32,
    33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48,
    49, 50, 51, 52, 53, 54, 55, 56,
    57, 58, 59, 60, 61, 62, 63, 64), "missing 1 argument \\(mm\\)")

assert.fails(lambda: f(
    1, 2, 3, 4, 5, 6, 7, 8,
    9, 10, 11, 12, 13, 14, 15, 16,
    17, 18, 19, 20, 21, 22, 23, 24,
    25, 26, 27, 28, 29, 30, 31, 32,
    33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48,
    49, 50, 51, 52, 53, 54, 55, 56,
    57, 58, 59, 60, 61, 62, 63, 64, 65,
    mm = 100), 'multiple values for parameter "mm"')

---
# Regression test for github.com/google/starlark-go/issues/21,
# which concerns dynamic checks.
# Related: https://github.com/bazelbuild/starlark/issues/21,
# which concerns static checks.

load("assert.star", "assert")

def f(*args, **kwargs):
  return args, kwargs

assert.eq(f(x=1, y=2), ((), {"x": 1, "y": 2}))
assert.fails(lambda: f(x=1, **dict(x=2)), 'multiple values for parameter "x"')

def g(x, y):
  return x, y

assert.eq(g(1, y=2), (1, 2))
assert.fails(lambda: g(1, y=2, **{'y': 3}), 'multiple values for parameter "y"')

---
# Regression test for a bug in CALL_VAR_KW.

load("assert.star", "assert")

def f(a, b, x, y):
  return a+b+x+y

assert.eq(f(*("a", "b"), **dict(y="y", x="x")) + ".", 'abxy.')
---
# Order of evaluation of function arguments.
# Regression test for github.com/google/skylark/issues/135.
load("assert.star", "assert")

r = []

def id(x):
  r.append(x)
  return x

def f(*args, **kwargs):
  return (args, kwargs)

y = f(id(1), id(2), x=id(3), *[id(4)], **dict(z=id(5)))
assert.eq(y, ((1, 2, 4), dict(x=3, z=5)))

# This matches Python2 and Starlark-in-Java, but not Python3 [1 2 4 3 6].
# *args and *kwargs are evaluated last.
# (Python[23] also allows keyword arguments after *args.)
# See github.com/bazelbuild/starlark#13 for spec change.
assert.eq(r, [1, 2, 3, 4, 5])

---
# option:recursion
# See github.com/bazelbuild/starlark#170
load("assert.star", "assert")

def a():
    list = []
    def b(n):
        list.append(n)
        if n > 0:
            b(n - 1) # recursive reference to b

    b(3)
    return list

assert.eq(a(), [3, 2, 1, 0])

def c():
    list = []
    x = 1
    def d():
      list.append(x) # this use of x observes both assignments
    d()
    x = 2
    d()
    return list

assert.eq(c(), [1, 2])

def e():
    def f():
      return x # forward reference ok: x is a closure cell
    x = 1
    return f()

assert.eq(e(), 1)

---
load("assert.star", "assert")

def e():
    x = 1
    def f():
      print(x) # this reference to x fails
      x = 3    # because this assignment makes x local to f
    f()

assert.fails(e, "local variable x referenced before assignment")

def f():
    def inner():
        return x
    if False:
        x = 0
    return x # fails (x is an uninitialized cell of this function)

assert.fails(f, "local variable x referenced before assignment")

def g():
    def inner():
        return x # fails (x is an uninitialized cell of the enclosing function)
    if False:
        x = 0
    return inner()

assert.fails(g, "local variable x referenced before assignment")

---
# A trailing comma is allowed in any function definition or call.
# This reduces the need to edit neighboring lines when editing defs
# or calls splayed across multiple lines.

def a(x,): pass
def b(x, y=None, ): pass
def c(x, y=None, *args, ): pass
def d(x, y=None, *args, z=None, ): pass
def e(x, y=None, *args, z=None, **kwargs, ): pass

a(1,)
b(1, y=2, )
#c(1, *[], )
#d(1, *[], z=None, )
#e(1, *[], z=None, *{}, )
