https://codeberg.org/fakefred/wikt-cli/src/branch/pipes
loc nearly tripled, so has cursedness
nevertheless, having fun implementing pipes with #python
also just so that you're aware, if you do
def out_func():
funcs = []
for x in [0, 1]:
var = x
def in_func():
return var
funcs.append(in_func)
return funcs
print([f() for f in out_func()])
this looks like it's gonna print [0, 1] but it's not. It's gonna give you [1, 1]. #python
@fakefred always a classic
@trickster @fakefred Just checking I understand: this might work properly if out_func was a generator rather than returning a list right?
@padraic_padraic @fakefred this happens because of the operational semantics in Python
def out_func():
funcs = []
for x in [0, 1]:
def in_func():
return x
funcs.append(in_func)
return funcs
`in_func` is a closure that closes over the `x` reference
every iteration in the `for` modifies `x` in place, it does not create a new `x` binding, so, of course, because all created closures point to the same x, the last version of x is the one that is returned, always
@padraic_padraic @fakefred this applies to any variable created or mutated inside of the `for`, because all vars are reused at every iteration
@trickster @fakefred Perfect explanation, thankee tricky
@padraic_padraic @fakefred but wait, there's more!
default arguments for functions are captured on the spot, so this piece of code can actually be made to work like this:
def out_func():
funcs = []
for x in [0, 1]:
def in_func(x=x):
return x
funcs.append(in_func)
return funcs
print([f() for f in out_func()])
# => [0, 1]
@trickster @fakefred Ah yeah, that I've heard of, because of this wild behaviour: https://nikos7am.com/posts/mutable-default-arguments/
Which soem people abuse to add memoisation
I'm once again feeling the urge to learn rust