seq-lang / seq

A high-performance, Pythonic language for bioinformatics

Home Page:https://seq-lang.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug(?)] Functions returned by other functions cannot access enclosing environment

jalfje opened this issue · comments

Minimal working example:

def foo(v):
    value = v
    def bar():
        return value 
    return bar

baz = foo(2)
print baz()

This works in python, printing "2". However, it does not work in seq (with seqc test.seq), giving the error

test.seq:4:16: error: identifier 'value' not found

Is this an intentionally unsupported feature of seq? If so, I'd argue that it should be included, so that functions can be used as first-class objects in a more useful way.

Hi @jalfje

We are actually thinking about this feature. However, the only way to do it is to actually capture a variable and return a partial function (e.g. return bar(..., v)). This might lead to some surprises (partial functions do not share the same type as normal function pointers as they have to hold the captured values; however, they behave the same way).

Would this approach work for you?

@inumanag I think that that would work, though I'm not familiar with partial functions so I don't totally know how the semantics of that would look. Essentially, I want to be able to call a function and have it maintain some state between calls in a way that is invisible to the caller. To clarify my understanding, would such a partial function be usable like the following snippet? If so, then they would work for the purpose that I was thinking of.

def foo(v):
    value = v
    def bar():
        value += 1
        return value 
    return bar(..., value)

baz = foo(1)
print baz() # prints 2
print baz() # prints 3

That actually would not work. Unlike Python, Seq has a concept of value and reference types. Integers are value types, so bar(..., value) would store the value, not the reference (all internal types and tuple/record types are values; classes are reference types). You would either need to box this type (e.g. Box(value)) or use a class type instead.

Fixed in #132.

Capture is slightly different than in Python: value (tuple) types are copied, not referenced when captured. Other types behave as in Python.