[prev in list] [next in list] [prev in thread] [next in thread] 

List:       groovy-jsr
Subject:    Re: [groovy-jsr] static versus dynamic typing policy
From:       John Rose <john.rose00 () sbcglobal ! net>
Date:       2005-01-29 11:53:52
Message-ID: 71FF7299-71EC-11D9-9EAE-000D93505406 () sbcglobal ! net
[Download RAW message or body]

On Jan 28, 2005, at 23:20, jstrachan wrote:
> Just a quick thought I had while replying to a mail that I figured 
> belonged in its own thread.
>
> A common reaction to optional static typing seems to be 'oh no, folks 
> will get confused if things behave differently'. So I'm trying to 
> ensure that whenever we introduce static typing into Groovy, things 
> behave as if they are dynamic - its just that
>
> (i) the compiler can give you better compile time errors (catching 
> more  typeos)
>
> (ii) the implementation *may* figure out some more optimal way of 
> implementing the method dispatch - whether it does or doesn't should 
> not affect the semantics of the program.

In the 'Builder Ideas' thread I just posted some questions and 
suggestions which interfere slightly with this principle.

Boiled down to the essentials, my basic question is, do we allow Groovy 
API designers to overload and override the dot '.' operator completely?

I think we want to do this, so that (for example) GPath expressions are 
simple in syntax 'x.y' but profound in domain-specific meaning ('y' is 
an XML name).

The catch is, how can we give complete control to GPath to overload 
dot, and at the same time insist that 'x.toString()' always calls the 
Object virtual method?

(The problem is simplest to state in terms of Object methods like 
'toString'.  It may apply to other types also.)

Here are some possible answers:

0. "Don't fall into that snakepit, children":  Users should know that 
the XML names 'toString', 'hashCode', 'equals', 'wait', and (I forget 
the rest) are off limits when using Groovy GPath and/or builders.  A 
non-starter, I think.

1. Make Java access be dispensible:  Some objects can wrest control of 
dot '.' away from emulation of Java, and if they override 'toString', 
then Groovy cannot access 'Object.toString' anymore.  Static/dynamic 
consistency is paramount.

2. Allow Groovy and Java views to diverge slightly:  Some objects wrest 
control of dot '.' away from Java.  Casting them back to the static 
type 'Object' returns control to Java semantics.  This is the only 
difference between static and dynamic typing.

3. Deny that the problem can happen:  Hmmm.  None of our use-cases 
would actually call 'toString' on no arguments, though they might call 
'toString' with a closure body or some other argument.  So maybe we 
dodge the bullet in all cases, and nobody will ever notice it if our 
builders and path exprs. have a hole in their namespaces.  (Although an 
XML element with no body and no attributes named 'toString' looks a lot 
like a no-argument call.)

4. Add special pleading to the language:  Make our builder syntax use a 
GenericMarkup interface, if it is found on the builder.  That interface 
(unlike GroovyObject) is not obligated to give specific treatment to 
'toString'.  Also, make GPath use some special syntax that triggers 
consultation of a GenericPath interface.  Complicates 'with' and spoils 
the magic simplicity of GPath.

I like #2.  It bends the consistency principle, slightly.  And 
tolerably?  Anybody care to illustrate the downside with an 
anti-use-case?

BTW, this discussion may interact also with the desirable feature of 
allowing maps to be coerced to multi-method interfaces.  Example:
    [next: {computeElement}, hasNext:{!noMoreElements}] as Iterator

(This is not the same as coercing a bare closure to a single-method 
interface, which is also important to Java interconnectivity.)

An easy way to account for this is to note that (1) maps have 
virtualized slots named according their keys, and (2) calling a method 
M on an object, if that object has no such method, will instead fetch a 
property M, and call M (e.g., as a closure).

The stress test of this concept, however, is to attempt to wrap the 
interface java.util.Map, in this way, around a Groovy map.
Can that be done?  If not, does this point up bugs that will prevent 
Groovy maps from plugging into other interfaces?

(Another thought experiment:  What is the most graceful way to wrap an 
AbstractList around a set of named closures, to create a List 
implementation from Groovy?)

-- John


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic