Skip navigation

Scope ⊇ {Module, Method, Function, Class}

In Ruby, we have Modules, Classes and Methods; in Erlang, Modules and Functions; in C++, Functions, Classes, and Namespaces. I want to introduce another bit o’ terminology, inspired both by my experiences with Erlang and the ‘let’ construct in Lisp and Haskell.

The Scope is an environment in which a set of assignments exists. Essentially, that’s what a module, method, function, class or namespace is providing us — well, that and a thread of execution. I imagine scopes to be a little like functions, though they’d have to provide a destructor — an idea we will discuss in another post. Here is an example, with syntax features from Erlang, Ruby and Python:

foo(a, b, c) ->
  gamma = a + b
  rho = b + c
  gamma * rho

foo::bar(a, b, c) ->
  gamma = a * a

What does this accomplish? Well, foo spits outs a number. As for foo::bar, it does the same thing as foo except with gamma equal to a * a. What I’m talking about is ‘function inheritance’. If we rigidly enforce single assignment, then we can say that function inheritance is deferring to statements in the child function if the left hand side matches. The statement:

gamma = a * b

is taken as a truth statement and not an assigment operation. In Erlang, a = b is a ‘match expression’ that halts execution if it fails.

My real reason for doing this, though, is not to think up ways to rewrite variable definitions. I want to ‘inherit’ message handling code:

foo(a, b, c) ->
  receive
    'a' -> a
    'b' -> b
    'c' -> c 
  'done'

foo(a, b) ->
  receive
    'c' -> 'no such luck'

foo::bar(a, b) ->
  receive
    'bar' -> 'i am bar!'

In this example, for extra coolness, I have added multi-arity definitions of the same function as well as inheritance. What I’d like this example to do is:

  • create a three argument version of foo that receives some messages
  • create a two argument version of foo that redefines the way one message is handled
  • create a subscope of foo, which automagically subscopes foo/2 and not foo/3, to handle the additional message ‘bar’ as well as all the others

Now here are some questions:

  • How is recursion meaningful in this framework?
  • What is the order of execution for functions and their children. Do we assign first, then run code in the child, then run code in the parent?
  • What expressions besides assignments can be rewritten in the parent? Will it work with <? What about other booleans? Is -> in receive a kind of ‘match’?
  • How do we reference specific components of the parent scope (the sum of all scopes leading up to this one)? Is parent:: good enough?
Advertisements

Post a Comment

You must be logged in to post a comment.
%d bloggers like this: