[Grace-core] "Object Algebras" in Grace

James Noble kjx at ecs.vuw.ac.nz
Fri Jun 29 19:43:40 PDT 2012


Hi all 

Here's a somewhat random email that's been in draft since Beijing.
Realizing I could talk to WIlliam about this tomorrow encouraged
me to send this today L-) 

J

-----

I've been talking to people about Bruno & William's Object Algebra paper at ECOOP.

(version here http://www.cs.utexas.edu/~wcook/Drafts/2012/ecoop2012.pdf)

one thing I noticed is that this is similar to the newspeak module 
design - a module is a class, it's constructor takes the "platform"
which is basically a factory for every object in the program

http://bracha.org/newspeak-modules.pdf

my big question - since we're talking about a somewhat similar design for Grace -
is how e.g. this relates to the kind of nesting / implicit parameterisation you get
with object nesting / family polymorphism?  The context is that we're looking at
module design for Grace, and are wondering how to do it.  

I also typed up a small implementation of half of the example in the paper in Grace.
(Half because that's as far as I got in Beijing; there'd be no problem doing the rest)
Currently without types because our generic typechecker isn't done yet.
But this does work, and shows the topology.  One odd aspect 
of this implementation - it's not about object algebras per se, but
rather about Grace's "encoding" of classes as objects - a classes-as-methods
encoding would make object algebras' code a little cleaner still.

In Grace you write "factory.lit(3)" as a "constructor" call but that is defined 
in terms of "Lit.new(3)" the "new" method to a class.

Of course, I guess one could call the sole constructor "lit" too,
so you'd write Lit.lit(3).

hmm...

James


This should work if you cut & paste into the top-left box of 
http://homepages.ecs.vuw.ac.nz/~mwh/minigrace/js/



// "Fig.1 An object-oriented encoding of integer expressions"

type Exp  = { eval } 

print "basic composite data"
class Lit.new(n : Number) -> Exp {
  def eval = n
}

class Add.new(l',r') -> Exp {
  def l = l'
  def r = r'
  method eval {l.eval+ r.eval}
}

print "used direcly"
print ( Add.new(Lit.new(3), Lit.new(5)).eval )


print "Fig.2  Visitor interface for arithmetic expressions (also an object algebra interface)"
type IntAlg<A> = {
  lit(x : Number) -> A
  add(e1 : A, e2 : A) -> A 
}

print "Fig.3. Using an object algebra as a factory"
class IntFactory.new -> IntAlg<Exp> { 
  method lit(x : Number) -> Exp { Lit.new(x) }
  method add(e1 : Exp, e2 : Exp) -> Exp {  Add.new(e1, e2) }
}


print "used via a factory"
def f = IntFactory.new
print ( f.add(f.lit(3), f.lit(5)).eval )

print "a function parametric in the factory - types omitted as  grace doesn't do generic"
method exp(v) {return v.add(v.lit(3), v.lit(5))}

print "called function with factory"
print (exp(f).eval)

print "Fig.4 A retroactive implementation of printing for arithmetic expressions"

type Print = { 
  printString -> String
}

class IntPrint.new {
  method lit(x : Number) { 
    return object { method printString -> String {return "{x}"} } }
  method add(e1 : Print, e2 : Print) {
    return object { method printString -> String {return "{e1.printString} + {e2.printString}"} } }
}

def p = IntPrint.new
print (exp(p).printString)

print "Fig.5 Adding a printing operation"

class Print2.new {
  method lit(x : Number) {return "{x}"}
  method add(e1 : Print, e2 : Print) {return "{e1} + {e2}"}
}

def print2 = Print2.new
print (print2.lit(333))

print "Fig. 6 Adding boolean expressions"

class Bool.new(b : Boolean) -> Exp {
  def eval = b
}

class Iff.new(e1',e2',e3')  {
  def e1 = e1'
  def e2 = e2'
  def e3 = e3'
  method eval {if (e1.eval) then {e2.eval} else {e3.eval}}
}

print "done"



More information about the Grace-core mailing list