[Grace-core] "Object Algebras" in Grace

Bruno Oliveira bruno at ropas.snu.ac.kr
Fri Jul 13 01:24:10 PDT 2012


Hi everyone,

I am sorry to get back to you on this so late; but I have been busy for the past few weeks.
However I've been slowly thinking about nesting, family polymorphism and object algebras. 

I've come up with an encoding that uses object algebras to achieve the late binding typical 
of family polymorphism approaches like virtual classes. The encoding uses Java's nested 
classes. The code goes in annexe. 

The main ideas are:

1) Use generic parameters to abstract over the types of the "virtual classes". These bounds
are covariantly refined in extensions of the original family.

2) Use object algebra interfaces (factories) to abstract over the uses of constructors of virtual 
classes. A family will include one such object algebra interface, and it will also have an 
abstract method f() which returns a reference to an object algebra.

3) When extending a family, we should override the abstract method f(). This uses refines the 
return type of f(), so that we can use the object algebra interface in the extended family. 

4) To tie everything up we need Concrete classes that implement object algebras and the 
method f().

Some notes:

- With a language extension quite a few details could be generated automatically. This could 
be nice to have in a new language (say Grace :)). Still the encoding is not too heavy, I think.

- This pattern has some advantages in terms of better exploiting inheritance than the way 
we use object algebras in the ECOOP paper. For example, in the extended family, we 
extend expression with pretty printing and inherit evaluation. This is a bit tricky with the solution
presented at ECOOP. 
 
- One could argue that OO programmers would feel more comfortable using this style.

About the code:

The code is a solution to the expression problem written in a virtual classes style.
There's a base family, which contains the interface for expressions and classes for literals 
and addition. Expressions support eval(). 

Then we extend this family and add pretty printing support to expressions, and a subtraction
variant. 

A few variations instantiate the family classes.


I haven't tried examples with more nesting, but I expect that the same pattern applies easily, 
in a recursive fashion.

I think this may be worthwhile exploring a bit more and perhaps writing something up. Do let me 
know of comments, questions or limitations. 

I'd like to see how this encoding compares to existing virtual classes/nested inheritance approaches. 
There are quite a few variations on the theme in the literature, and I am not entirely sure how this 
encoding compares to many of these. I will look more closely at your paper on Tribe James. 

Best,

Bruno Oliveira

-------------- next part --------------
A non-text attachment was scrubbed...
Name: Test.java
Type: application/octet-stream
Size: 4376 bytes
Desc: not available
URL: <https://mailhost.cecs.pdx.edu/mailman/private/grace-core/attachments/20120713/d3185da0/attachment.obj>
-------------- next part --------------
 



On Jun 30, 2012, at 10:43 AM, James Noble wrote:

> 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