[Grace-core] Dialect

Timothy Jones Timothy.Jones at ecs.vuw.ac.nz
Sun Aug 12 21:59:24 PDT 2012


I've built an incomplete implementation of dialect into Minigrace which
adds a `dialect` statement into the language. It's used in the same way
as inherits.

This is the example program I've been using to test it out:

> def greeter = object {
>   method hello {
>     print "hello"
>   }
> }
>
> dialect greeter
>
> hello

With my extension, this program now prints out "hello" (the rest of this
assumes that this is how dialect is expected to work, let me know if I'm
wrong).

In Minigrace all method calls are resolved to a particular receiver, so
the implementation just cheats. It clones all the methods in the given
object, sets their accessibility annotation to private, and then
attaches them to the module. This achieves the desired effect.

Working on this raised some interesting questions about how the
specifics of how dialect works.


1. Where is this statement allowed?

Requiring it to be the first thing in a module seems a bit restrictive,
because we might just want to define a local dialect (as above).
Moreover, you can basically achieve the same effect of execution before
the dialect is declared with some kind of block expression:

> dialect {
>   // Dialect not yet declared
>   object {... }
> }.apply

If we say that dialect does not have to be the first statement in a
module, it raises some extra problems:


1 (b). Does the placement of dialect matter?

Basically, which version of the method do we have here:

> method hello { print "a" }
>
> dialect greeter
>
> // Which method does this call?
> hello

My suggestion would be that methods that are actually declared in the
local scope always take precedence.


1 (c). Should the dialect take effect only after it appears?

If so, this wouldn't work:

> hello
>
> dialect greeter


1 (d). Can the dialect declaration be nested inside another scope?

> object {
>   dialect greeter
>   method hi { hello }
> }

I can see this being potentially useful.


1 (e). Can you use multiple dialects?

If so, then are ambiguous calls just an error?


2. Where are the methods actually placed?

In Grace every accessible value must be found either on self or
somewhere in an outer object. I don't think that attaching the methods
to the module itself makes sense. I think it would make more sense to
have an `outer` value accessible in the module's top scope that refers
directly to the dialect object (which is the standard prelude if no
dialect is explicitly declared).

> dialect platform.greeter
>
> outer.hello

This also means that methods and values declared in the top scope with
the same name as a method in the dialect take priority by the existing
lookup semantics.


3. What about standard methods?

If the `greeter` object is a standard object, it has the standard object
methods like `asString`. Should these be imported as well?

The way that the lookup works is important here. The module object (self
in the top scope) also has these methods on them, so if `self.asString`
takes priority over `outer.asString` (or however the dialect is
implemented) then this isn't a problem. Otherwise dialects should
probably inherit from `done` or magically not import these methods.


I think that's it. I would like to address these issues before merging
the implementation into Minigrace proper.

Tim



More information about the Grace-core mailing list