Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minor refactoring on 'definedp' #9

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions src/py/env.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# The `Environment` class represents the dynamic environment of McCarthy's original Lisp. The creation of
# this class is actually an interesting story. As many of you probably know, [Paul Graham wrote a paper and
# code for McCarthy's original Lisp](http://www.paulgraham.com/rootsoflisp.html) and it was my first exposure to
# The `Environment` class represents the dynamic environment of McCarthy's original Lisp. The creation of
# this class is actually an interesting story. As many of you probably know, [Paul Graham wrote a paper and
# code for McCarthy's original Lisp](http://www.paulgraham.com/rootsoflisp.html) and it was my first exposure to
# the stark simplicity of the language. The simplicity is breath-taking!
#
# However, while playing around with the code I found that in using the core functions (i.e. `null.`, `not.`, etc.)
# I was not experiencing the full effect of the original. That is, the original Lisp was dynamically scoped, but
# the Common Lisp used to implement and run (CLisp in the latter case) Graham's code was lexically scoped. Therefore,
# However, while playing around with the code I found that in using the core functions (i.e. `null.`, `not.`, etc.)
# I was not experiencing the full effect of the original. That is, the original Lisp was dynamically scoped, but
# the Common Lisp used to implement and run (CLisp in the latter case) Graham's code was lexically scoped. Therefore,
# by attempting to write high-level functions using only the magnificent 7 and Graham's core functions in the Common Lisp
# I was taking advantage of lexical scope; something not available to McCarthy and company. Of course, the whole reason
# that Graham wrote `eval.` was to enforce dynamic scoping (he used a list of symbol-value pairs where the dynamic variables
# were added to its front when introduced). However, that was extremely cumbersome to use:
#
#
# (eval. 'a '((a 1) (a 2)))
# ;=> 1
#
# So I then implemented a simple REPL in Common Lisp that fed input into `eval.` and maintained the current environment list.
# That was fun, but I wasn't sure that I was learning anything at all. Therefore, years later I came across the simple
# REPL and decided to try to implement my own core environment for the magnificent 7 to truly get a feel for what it took
# to build a simple language up from scratch. I suppose if I were a real manly guy then I would have found an IBM 704, but
# to build a simple language up from scratch. I suppose if I were a real manly guy then I would have found an IBM 704, but
# that would be totally insane. (email me if you have one that you'd like to sell for cheap)
#
# Anyway, the point of this is that I needed to start with creating an `Environment` that provided dynamic scoping, and the
Expand Down Expand Up @@ -56,11 +56,8 @@ def set(self, key, value):
self.binds[key] = value

def definedp(self, key):
if key in self.binds.keys():
return True
return key in self.binds.keys()

return False

# Push a new binding by creating a new Env
#
# Dynamic scope works like a stack. Whenever a variable is created it's binding is pushed onto a
Expand All @@ -69,7 +66,7 @@ def definedp(self, key):
#
# (label a nil)
# (label frobnicate (lambda () (cons a nil)))
#
#
# ((lambda (a)
# (frobnicate))
# (quote x))
Expand All @@ -82,7 +79,7 @@ def definedp(self, key):
# | ------- |
# | a = nil |
# +---------+
#
#
# Meaning that when accessing `a`, `frobnicate` will get the binding at the top of the stack, producing the result `(x)`. This push/pop
# can become difficult, so people have to do all kinds of tricks to avoid confusion (i.e. pseudo-namespace via variable naming schemes).
#
Expand Down