2

After reading Lisp in Your Language, I've been trying to follow along in Python. Everything works until I get to variable assignment and scoping.

The final call has me stumped. It seems that in javascript, one can create a new scope object and assign or bind objects to that new scope, instead of using "this". In the example linked:

// use existing local scope or create a new one
scope = scope || {};

[...]

// call the function with these arguments
// and expose scope as this
return fn.apply(scope, args);

In Python, that doesn't seem to be possible in the same way. I had been calling return fn(*args) before this point, but now I am stumped as to how I can write the equivalent code.

Any ideas or suggestions?

Gist of my updated code

EDIT: I've found a solution for this problem, at least for now:

# defined outside of the function
global scope_dict
scope_dict = {}

def pl_def(name, value):
    global scope_dict
    scope_dict[name] = value
    return scope_dict[name]

[...]

# use existing scope inside the function
global scope_dict
scope = scope_dict

# resolve all our new string names from our scope
def symbol_check(symbol):
    if isinstance(symbol, list):
        return symbol
    elif symbol in scope:
        return scope[symbol]
    else:
        return symbol
expression = [symbol_check(x) for x in rawExpr]

[...]

# call the function with these arguments
return fn(*args)
Noah Bogart
  • 1,703
  • 1
  • 16
  • 24
  • Easiest is to run functions, which have their own local namespaces. If you explicitly want to creates scopes, you can use `exec()`. – mdurant Sep 10 '15 at 16:03

2 Answers2

1

In the code on the page you linked to, scope is just an object -- there's nothing special about it. But in JS, you can access properties of an object using bracket notation as well as dot notation:

//these are equivalent
obj.prop
obj['prop']

In Python, to get a property of a 'regular' object, you have to use dot notation or getattr().

Since the scope object in the example is just being treated as a container, you could use a dict instead, and then the code might work without too many other modifications. Coincidentally, {} creates an empty object in JS, but creates an empty dict in Python.

1.618
  • 1,765
  • 16
  • 26
  • Thanks! Your comment about using a `dict` pointed me in the right direction. I've edited the Question with my solution. – Noah Bogart Sep 10 '15 at 18:12
0

You cannot replicate it 100% in python because function objects do not have a this (self in python) defined like they do in javascript.

$ python3
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03)
>>> def no_scope():
...   print(self)
...
>>> no_scope()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in no_scope
NameError: name 'self' is not defined

In javascript via node

$ node
> function scope() {
... console.log(this);
... }
undefined
> scope()
{ DTRACE_NET_SERVER_CONNECTION: [Function],
  DTRACE_NET_STREAM_END: [Function],
  DTRACE_NET_SOCKET_READ: [Function],
  DTRACE_NET_SOCKET_WRITE: [Function],
  // ... etc
Josh J
  • 6,813
  • 3
  • 25
  • 47