[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