Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python equivalent of quote in lisp

In python what is the equivalent of the quote operator? I am finding the need to delay evaluation. For example, suppose in the following lisp psuedocode I have:

a = '(func, 'g)
g = something
(eval a)

What I am doing is deferring evaluation of g till a later time. This is necessary because I want to define g later. What is the equivalent idea of this psuedocode in python?

like image 794
CodeKingPlusPlus Avatar asked Aug 15 '13 19:08

CodeKingPlusPlus


2 Answers

a = lambda: func(g)
g = something
a()

This isn't quite the most literal translation - the most literal translation would use a string and eval - but it's probably the best fit. Quoting probably isn't what you wanted in Lisp anyway; you probably wanted to delay something or create a lambda. Note that func and g are closure variables in the lambda function, rather than symbols, so if you call a from an environment with different bindings for func or g, it'll still use the variables from a's environment of definition.

like image 182
user2357112 supports Monica Avatar answered Oct 03 '22 04:10

user2357112 supports Monica


Using eval for delaying evaluation is bad, both in Lisp and Python.

in Python, and in Lisp, you can delay evaluation using a closure:

def print_it(x):
    def f():
        print g(x)
    return f

f = print_it(42)

def g(x):
   return x * x

f()

Please note that what is captured in a closure is not the value of a variable, but the variable itself and this is sometimes surprising:

fa = []

for x in range(10):
    def g():
        print x
    fa.append(g)

for f in fa:
    f() # all of them will print 9

x = 42

fa[0]() # the output will be 42

to solve this problem (that can also be present in Common Lisp) you may see things like:

for x in range(10):
    def g(x = x):
        print x
    fa.append(g)

or (in CL) things like

(let ((a a))
  (lambda () (print a)))

Python also has a lambda special form for anonymous functions, but they are limited to one single expression and cannot contain any statement. A locally def-ined function instead is a regular function without any limitations.

for x in range(10):
    # print is a statement in Python 2.x and cannot be in a lambda
    fa.append(lambda x=x: sys.stdout.write(str(x) + "\n"))

Finally Python 2.x has a syntax limitation and closed-over variables are read-only because if there is an assignment (or augmented-assignment) in a function there are only two possibilities:

  1. The variable is a global (and has been previously declared so with global x)
  2. The variable is a local

and in particular it's ruled out that a variable being assigned could be a local of an enclosing function scope.

Python 3.x removed this limitation by providing a new possible declaration nonlocal x and now the famous adder example can be implemented as

def adder(x):
    def f(y):
        nonlocal x
        x += y
        return x
    return f
like image 25
6502 Avatar answered Oct 03 '22 06:10

6502