Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

Interesting; when you define a function (or anything) in a breakloop, does it get saved to source? (or is there an option to?)

I'm trying to imagine using this style of programming in Python, but the type-redefinition problem is still there



sort by: page size:

I assume this also makes it possible to reload a function/file when not in the middle of a breakpoint? That is something that is super-useful in lisp (reloading under both situations that is), but AFAICT impossible in vanilla python due to the way imports work.

You do realise you can define a function inside another function in python, right?

How does that work in practice? Python stores local variables in the stack frame with a compiler-calculated index. Do you have a growable stack frame? Add stack frames for every loop iteration?

I don't think the Python compiler is to know if a loop variable is closed over and then adjust the code generation. So this change would likely introduce a lot of complexity, or be a pessimisation in the normal case.

I think the simple, although less helpful, semantics are clearly better here. FWIW I don't think this comes up in practice very much. Maybe because callbacks in Python APIs aren't common (and its not due to this).


That's tame. Here's a scary example [1] (redefining a (built in) function in the middle of a running coroutine):

  def foo(x):
    yield len(x)
    yield len(x)
  >>> g = foo(range(5))
  >>> g.next()
  5
  >>> len = lambda y: 8
  >>> g.next()
  8
This causes problems when trying to implement an efficient python. You have to re-lookup your function bindings every time.

[1]: Example taken from Colin's Unladen Swallow presentation http://llvm.org/devmtg/2009-10/Winter_UnladenSwallowLLVM.pdf


So would you in C if you do not redeclare the variable inside of the block. Also in JavaScript (although in JavaScript the type is not declared; in C it is). I don't know how it is working in Python, though.

I once had the surprising experience of having to help a postdoc with a PhD in mechanical engineering wrap his head around a block of Python code he was reading that looked like:

    x = f0()
    x = f1(x)
He was just mentally blocked on how all of these things could be true at the same time, and/or on how a variable could be used in setting its own value, since assigning a new value to x would change the value that had been passed to f1! His intuition was that this meant some kind of recursion-to-stability was at play.

All he needed was to be informed that this could be equivalently represented as

    x = f0()
    y = f1(x)
or

    x = f1(f0())

Isn't this behavior in Python already via the functools module? Can't look it up right now but I'm pretty sure it's there.

Yes, I just meant to point out that there is a way to do closures in Python 2.x. Looks like here the author wants a function that saves its internal state, i.e., a generator.

In case i ever find myself designing a programming language, what facilities would Python have to support in order to allow 'let' to work? It seems to me that in theory Hy could solve the problem with which variables are to be marked 'nonlocal' by doing a lot of additional code analysis (is this correct?).

I gather that the main remaining problem is that break, continue, yield, async, await work differently if you covertly introduce a new function scope. Would it be sufficient if scopes could have explicit labels and break, continue, yield took an argument that said which label to break/continue/yield out of? Would that solve the problem with async, await too?

If Hy did extensive code analysis to determine where to introduce 'nonlocal', and if Python's break/continue/yield took this extra argument, would implementation of 'let' by Hy then become possible or are there still additional impediments that i am missing?


This is cool. Appreciate the trip down memory lane with the python2 syntax as well. I think the effect might be more incongruent in python3 code where pseudo expressions like print have been formalised into functions.

The biggest issue is python's indentation stuff doesn't work in a function parameter list, so you get stuck with single line lambdas only or defining a temp named function before using then in an unnatural way.

Python has implicit declarations, which lead to a world of hurt because you can't directly modify variables in arbitrary scopes. Python 3 has nonlocal, but that only extends the number of function scopes you can refer to to three.

I think having implicit declarations is probably the worst mistake Python made. It just makes things so much more confusing.


Python, by necessity, is more Haskell-ish. I was primarily considering Haskell as opposed to C++, where multiple functions share a name and differ by parameter types. This sort of situation is a true nightmare to debug, and I believe is responsible for some of the backlash against user-defined operators in general.

It's a feature that I learned to use in Python and one that I consistently now miss in other languages (rust, java, typescript, javascript).

I've accidentally done this in Python, though I didn't know functions could do that. Wasn't fun debugging. It's like "We've made this super-easy language where you don't need a main function, but if you don't have one all kinds of unintentional shit will happen to your code"

Part that bothers me about Python is no special binding form, that is you could just do x = 3 to add x variable to my environment, and second is not-strict lexical scoping.

From other perceptive, these usually bother me when my functions are larger, and ideally functions should be small. So I take it as sign that I should probably break down my function.

And yeah, tail calls! I expect that from a modern language with functional programming features. Unfortunately it seems there are no plans to add them in Python


That's because the whole problem is trivial in Python. What he's talking about is jumping to the correct version of an overloaded function and similar.

I enjoy how much complete control Python enables. It’s fun to turn it into what resembles a different language.

I want to make a library where you never ever call functions with fn() notation. But just utilize accessors and absolutely bastardize dicts.


I was happy to see “Nested local functions or classes are fine”

Being a mostly Lisp developer, I like to nest local functions in order to close over locally defined variables. Glad that is considered OK in Python.

next

Legal | privacy