Hacker News new | past | comments | ask | show | jobs | submit login

In all seriousness, the only reason I use Python over Lua is for the library. Lua is far more flexible and extensible, but it has a very sore lack of standard libraries like you can find with Python. But I keep my fingers crossed, and continue to use Lua as an interpreter inside my C apps, where the lack of libraries is a non-issue because everything I need to use is a custom API exported from C.



> but it has a very sore lack of standard libraries like you can find with Python

Agreed. I find it quite a bit more elegant overall, and I decided to just jump in and do my throwaway scripts in Lua and see how much of a difference that makes. If I like it enough to write a few small libraries along the way, everybody wins.

Lua has tail-call elimination, coroutines, closures, and lambdas. I'm pretty sure Python has none of these, except for (possibly) a limited form of coroutines. (The Python lambda is too crippled, its closures are broken.) Lua is also one of the most deliberately portable languages I've seen, too. I have a hunch it would be a great language for bootstrapping a Lisp or Scheme compiler, though I haven't tried this yet.


Python closures work well. (The lambda is syntactically crippled.)


   >>> def makeAdder(x):
   	def inc(y):
   		return y+x
   	return inc
   
   >>> f = makeAdder(3)
   >>> f(4)
   7
So far, so good.

   >>> def makeAdder2(x):
   	v = x
   	def inc(y):
   		v += y
   		return v
   	return inc
   
   >>> f2 = makeAdder2(3)
   >>> f2(4)
   
   Traceback (most recent call last):
     File "<pyshell#15>", line 1, in <module>
       f2(4)
     File "<pyshell#13>", line 4, in inc
       v += y
   UnboundLocalError: local variable 'v' referenced before assignment
   >>>
It looks like you can't mutate variables in a closure. Am I doing it wrong? If you really can't, that seriously limits their power.

--

In Lua:

  > function adder(x)
      local v = x
      function inc(y)
          v = v + y
          return v
          end
      return inc
      end
  >> >> >> >> >> >> >> > f = adder(3)
  > =f(4)
  7
  > =f(4)
  11
  > =f(4)
  15
  >
Works fine. (Also, the syntax is really clean.)


Python 3.0 fixes this with the nonlocal statement. However, you are correct that this doesn't work in Python 2.5 and earlier.


Ok, thanks.


Argh - I can't get the formatting to work.

def makeAdder2(x):

    v = [x,]
    def inc(y):
        v[0] += y
   	return v[0]
    return inc
works just fine in all pythons with closures (2.0 and above?)

def makeAdder2(x):

    def inc(y, v=[x,]):
        v[0] += y
   	return v[0]
    return inc
Also works and provides a mechanism for resetting the state.


Interesting. So keeping a reference to a list with the value works, but the value directly doesn't? Thanks for the note.

Good to know it's possible, though I'd rather it handle closures / lexical scoping directly.


You may need to add a 'global' statement or something similiar. If you are going to mutate a variable in a function Python assumes that you want to create a new variable in that scope.

Generally I do not mutate variables as far as possible, so I have not hit this problem myself, yet. Perhaps there is someone more knowledgeable about Python to step in.


But it's not a global variable, it's scoped within the closure. So, this means Python doesn't have lexical scoping?


It has. Just the syntax was a bit awkward when modifying variables of higher scope. See sibling comment.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: