llm
Download
78 lines 2.4 KiBTomoModified 2026-09-29 raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
func make_adder(x:Int -> func(y:Int->Int))
    return func(y:Int) x + y

func suffix_fn(fn:func(t:Text->Text), suffix:Text -> func(t:Text->Text))
    return func(t:Text) fn(t)++suffix

func mul_func(n:Int, fn:func(x:Int->Int) -> func(x:Int->Int))
    return func(x:Int) n*fn(x)

test "lambdas and higher-order functions"
    >> add_one := func(x:Int) x + 1
    >> add_one(10)
    assert add_one(10) == 11
    >> shout := func(msg:Text) say("$(msg.upper())!")
    shout("hello")
    >> asdf := add_one
    >> asdf(99)
    assert asdf(99) == 100
    >> add_100 := make_adder(100)
    >> add_100(5)
    assert add_100(5) == 105
    >> shout2 := suffix_fn(func(t:Text) t.upper(), "!")
    >> shout2("hello")
    assert shout2("hello") == "HELLO!"
    >> abs100 := mul_func(100, Int.abs)
    >> abs100(-5)
    assert abs100(-5) == 500

test "nested lambdas"
    # Test nested lambdas:
    >> outer := "Hello"
    >> fn := func()
        return func()
            return func()
                defer say("$outer")
                return outer
    >> fn()()()
    assert fn()()() == "Hello"

test "local declarations in a lambda with a declared return type"
    # A lambda that declares a local and then explicitly returns used to report
    # the local as already defined: typechecking the `return` re-derived the
    # lambda's return type, which re-typechecked the body in a scope that
    # already held the declarations made ahead of the return.
    >> counted := func(t:Text -> Int)
        trimmed := t.trim()
        n := trimmed.length
        return n + 1
    >> counted("  abc  ")
    assert counted("  abc  ") == 4

    # The same body without an explicit `return`, and with the return type
    # inferred rather than declared, always worked; keep both covered:
    >> implicit := func(t:Text -> Int)
        trimmed := t.trim()
        trimmed.length
    assert implicit("  abc  ") == 3

    >> inferred := func(t:Text)
        trimmed := t.trim()
        return trimmed.length
    assert inferred("  abc  ") == 3

    # Declarations of container types go through the same path:
    >> tallied := func(k:Int -> Int)
        counts := {1: 10, 2: 20}
        return counts[k] or 0
    assert tallied(2) == 20
    assert tallied(99) == 0

test "a lambda still can't shadow an outer variable"
    shadowed := "outer"
    assert shadowed == "outer"
    nope := func(-> Int)
        shadowed := "inner"
        return shadowed.length
    >> nope()
fails_compile "has already been defined"