Scopes and the Properties Pattern

October 20, 2008

Background

Read this first. It’ll take about half an hour, but it’s worth it. Note that it in turn recommends you read Godel, Escher, Bach: An Eternal Golden Braid, which is a six-month project, but worth it too. Come back when you’re ready.

Now, I’m very lucky to have help understanding the article. I learned a little bit of JavaScript back in the day, so I already knew about the Prototype Pattern. I even knew about the “Array-Map surjection” even though I didn’t know that’s what it was called.

Wait, you don’t know about the Array-Map surjection? You didn’t read the article, did you? Go back and read it!

Idea Seed

One day I was idly dreaming about the Properties Pattern and it occurred to me that scopes and symbol tables use the pattern in most programming languages. A variable declaration is a “put.” A defined? (in languages that support it) is a “has.” A variable access is a “get.” Function calls introduce a new Property List and set the parent to the current scope. Undef (in languages that support it) is a “remove.”

I thought about whether it would be useful to make this explicit. It occurred to me that “big differences” between programming language constructs, like between dynamic and lexical scoping and between functions and macros, are really small differences in how the property lists are being modified. Maybe we could make a programming language that gave us power over these things.

Pre-emptive Defensive Digression

Stop right there. You’re thinking about all the things that are wrong with the idea. You’re thinking about all the similar, failed projects with similar concepts. Work with me here. Let’s get into Yes, Yes mode. Think about “How can we make this meaningful and good?” 

I’ll admit I don’t know anything about programming languages. Maybe this is basic stuff that I’m stupidly rediscovering. Maybe this is a dangerously fuzzy idea that can never be made concrete. I’m having fun thinking about it. Go read someone smarter’s blog.

Examples

Let’s look at scopes as instances of the properties pattern. When you define a new function, you create a new empty property list (“symbol table”) with its parent set to the current property list. 

Here’s the difference between lexical and dynamic scoping. In a lexically-scoped language, a function call takes the function and leaves its parent alone. In a dynamic language, a function call sets the function’s parent to be the caller’s scope. That’s it.

What if you could do f.scope.parent := currentScope()? What if you could choose whether to call functions lexically or dynamically depending on the problem at hand? What if you could do f.scope.parent := thatScopeOverThere()?

I don’t know either.

What’s a function call, really, if you think of it as operations on variable names? Don’t think about mathematical formalisms for programming languages. Forget higher-level abstractions of machine instructions for a moment. A program is a bunch of operations on variable names and you make programming scale by tucking away those variable names into scopes. You control the scopes with “macros” (hygienic and non-hygienic and preprocessor) and “functions” and “objects” and “closures” and “threads” and “processes” and “continuations”. The point is, at some level of abstraction, we’re just playing with scopes and names. Object-oriented programming especially: What are “inheritance hierarchies”, “polymorphism” and “classes” and so on but rules and systems for playing with scopes?

What’s the difference between a macro call and a function call? Between a hygienic macro and a non-hygienic macro? They’re all just different ways of tweaking the scope/property lists. What if we made these tweaks user-accessible and explicit?

Help wanted.

Part Two

Or, While I’m on the Topic of Crazy Programming Language Ideas.

Look at those operations that form the crux of the Properties Pattern: get, put, delete and has.

They look a lot like those HTTP verbs we keep hearing about in the context of RESTful resources.

Hm. 

Let’s get crazy.

What if we make a “programming environment” where the “symbol table” is the Web Itself? Variables are HTTP URLs? Types are optional, and they’re MIME types? First-order functions are web services?


op +;        # http://ops.gnu.org/+
op /;         # http://ops.gnu.org/div
op reduce;  #http://ops.gnu.org/reduce
add_list = part_func_app(reduce(+,int(0)))

def_service len(*lst): 
#http://bigexpensivecompany.bad/len
    reduce(fn(accum new) (+ accum 1),0, lst)

def_service avg(*lst): 
#http://bigexpensivecompany.bad/avg
    /(add_list(lst), len)

def_service SQL(query,*db_connection): 
#http://bigexpensivecompany.bad/SQL
    /* elided */

average-manager-salary = 
  avg(SQL("SELECT salary FROM emp_salary", 
http://intranet.bec.bad/db/hr/managers.conn))
# http://bec.bad/careers/resources/average-manager-salary


GET /index.html HTTP/1.1
 Host: http://ops.gnu.org/avg?
    p1=
      http://bec.bad/SQL?
        p1=SELECT+salary+FROM+emp_salary&
        p2=
          http://intranet.bec.bad/db/hr/managers.conn

.
.
.

 HTTP/1.1 200 OK
 Date: Mon, 23 May 2005 22:38:34 GMT
 Server: Apache/1.3.3.7 (Unix)  (Red-Hat/Linux)
 Last-Modified: Mon, 23 May 2005 22:38:34 GMT
 Etag: "3f80f-1b6-3e1cb03b"
 Accept-Ranges: bytes
 Connection: close
 Content-Type: x-s-web/x-currency-xml; charset=UTF-8

<currency type="USD" 
          timestamp="Mon, 23 May 2005 22:38:34 GMT">
136400
</currency>

Advertisements
%d bloggers like this: