Closed gavinking closed 11 years ago
Well I meant to use them only when necessary, so you keep @Person
but add @<Integer|Float>
well that doesn't really fit into the scheme I outlined above. How would you handle Map.Entry.key?
Sent from my iPhone
On 15/05/2013, at 12:38 PM, Tako Schotanus notifications@github.com wrote:
Well I meant to use them only when necessary, so you keep @Person but add @<Integer|Float>
— Reply to this email directly or view it on GitHub.
and stuff like String|Map.Entry?
Sent from my iPhone
On 15/05/2013, at 12:38 PM, Tako Schotanus notifications@github.com wrote:
Well I meant to use them only when necessary, so you keep @Person but add @<Integer|Float>
— Reply to this email directly or view it on GitHub.
Well couldn't you still do the following?
@<String|Map.Entry>
Or combine the suggestions?
@`String|Map.Entry`
That way you keep the short version for many cases and only use the grouping when necessary.
I suggested the < >
only because it's already used with type grouping, but of course in this case it's not only used with types (as seen with Map.Entry.key
), so maybe we could use @
and @( )
and not have to use the last free symbol we have :)
The two approaches are quite different. I don't see how they mix, except confusingly.
Sent from my iPhone
On 15/05/2013, at 1:22 PM, Tako Schotanus notifications@github.com wrote:
Well couldn't you still do the following?
@<String|Map.Entry> Or combine the suggestions?
@
String|Map.Entry
That way you keep the short version for many cases and only use the grouping when necessary. I suggested the < > only because it's already used with type grouping, but of course in this case it's not only used with types (as seen with Map.Entry.key), so maybe we could use @ and @( ) and not have to use the last free symbol we have :)— Reply to this email directly or view it on GitHub.
I mean the approach of using backticks for meta model references of your suggestion with the optional grouping of my suggestion. But I don't care about the character used for grouping, I'm just suggesting it could be optional. In my idea the @
remains the character for access to the meta model.
I think you're missing the point.
Would you let people write both:
Map@Entry
Map.Entry@key
And
@<Map.Entry>
@<Map.Entry.key>
That be very confusing, right?
Anyway, it seems to me that best combination of readability and power comes from using backticks. Then we wind up with different syntax for metamodel references and function references:
Person
is an expression of type Person(String)
.
`Person`
is an expression of type Class<Person,[String]>
.
Person.name
is an expression of type String(Person)
.
`Person.name`
is an expression of type Member<Person,Value<String>>
.
Person.say
is an expression of type Void(String)(Person)
.
`Person.say`
is an expression of type Member<Person,Function<Void,[String]>>
.
The grammar for a metamodel reference would be:
"`" Type | (QualifiedType|GroupedType) "." MemberName TypeArguments? "`"
Which works out very nicely because it let's us write things as interesting as:
`<Integer|Float>.negativeValue`
Best of all, we don't need any kind of "reference" types or "metatype constructors".
Oh I almost forgot there is also the question of how to get a reference to a value. For toplevels/locals, the following works:
`process`
which is of type Value<Process>
.
But what about for attributes? I suppose the following is workable:
`process.arguments`
which would be of type Value<String[]>
. But I preferred process@arguments
which is what would be natural with the infix @
syntax.
The issue is that the infix @
lets me write shit like (1+1)@negativeValue
whereas that sort of thing would probably not work with the backtick-quoted syntax.
I suppose this is an option:
process.`arguments`
But, well, now it's getting a bit messy...
I still think @< >
is an option, as long as you only use it for grouping of types, so you can use it for @<Integer|Float>
and @<String|Map.Entry>
but you can simply use process@arguments
(although if you want you could write process@<arguments>
which would mean the same but is unnecessary). It's not that confusing, is it?
Person.name
is an expression of typeString(Person)
.
Mmmm, how do that work out for variables then?
WDYM?
Sent from my iPhone
On 15/05/2013, at 3:32 PM, Stéphane Épardaud notifications@github.com wrote:
Person.name is an expression of type String(Person).
Mmmm, how do that work out for variables then?
— Reply to this email directly or view it on GitHub.
Well, references would only be read-only. We used to have the notion of Gettable
/Settable
at some point.
Well sure, we still have Value and MutableValue.
Sent from my iPhone
On 15/05/2013, at 3:39 PM, Stéphane Épardaud notifications@github.com wrote:
Well, references would only be read-only. We used to have the notion of Gettable/Settable at some point.
— Reply to this email directly or view it on GitHub.
Oh, I suppose I meant person.name
rather than Person.name
.
BTW, whatever the syntax, will we be able to do List<Person>@method<Foo>
?
Oh, I suppose I meant
person.name
rather thanPerson.name
.
According to this comment you could write:
MutableValue<String> name = `person.name`;
BTW, whatever the syntax, will we be able to do
List<Person>@method<Foo>
?
According to the grammar above, you would be able to write:
Member<List<Person>,Function<Foo,[Foo]>> method = `List<Person>.method<Foo>`;
Cool.
Is a keyword model(List<Person>)
out of the question?
Will we get package and module literals too?
Well, there's 2 issues with that:
@
can't do, and it's natural precedence is less convenient. I guess you can argue that model(some.stuff)
(or more likely (model some.stuff)
) is easier on the eyes than @(some.stuff)
, but I don't find it an improvement over backticks.see (model(Foo), model(Bar))
doesn't read nicely at all.Will we get package and module literals too?
If we can decide what the syntax would be. Unfortunately we can't just use this:
`ceylon.language`
We're going to need something weird like, perhaps:
`module ceylon.language`
Unfortunately we can't just use
ceylon.language
Why not?
Perhaps ceylon.language
is a metamodel ref to the package ceylon.language
and ceylon.language/0.5
to the module?
Ideally I'd also have a metamodel ref to the current module and current package, but we don't have anything like that for the current type. Though in the case of the current type, we have a way to access it via model(this)
. Well, perhaps module.this
and package.this
would work? I suppose it goes against the outer
keyword, but that one already has an issue with not being able to obtain the outer's outer so perhaps that keyword is flawed too.
I've just pushed support for type literals (not type members yet). Aw fuck this issue is closed and not even about type literals. Where's the issue about type literals then?
Belatedly, I've noticed a potential inconsistency in the syntax for qualified types and metamodel references.
In principal, if we defined the metamodel type
Class
to have a member type,Iterator
, for example, then the following phenomenon would occur:Iterable.Iterator it
would refer to the member type ofIterable
, butIterable.Iterator()
would refer to the member type ofClass
.This is not an actual ambiguity as such, but it's certainly undesirable. Of course, it's a phenomenon that will never occur in practice, if we simply don't define any member classes of the metamodel types.
A second related observation is that with the introduction of the syntax
Iterable::Iterator
in #403 we have gained a second redundant way to express a qualified type. This is also undesirable, I believe.There's three ways to handle this that I can see:
Iterable.Iterator
, and.
is much easier on the eyes than::
or@
. It's not especially strange that type-level operators have slightly different semantics to value-level operators—just look at|
and&
. Hell, we didn't even notice this wrinkle until now, so the chance of anyone else actually noticing it is somewhere in the range-1p..+1p
.::
for qualifying types: we now have a totally reasonable and unambiguous syntax for writing qualified types. The semantics of #403'sFoo::Bar
is a simply much better and more natural fit here than the semantics of.
. We're be adopting a really strained second interpretation of.
, just because we think it looks slightly prettier, and because we're used to it. Why have two totally synonymous ways to qualify a type name?@
: we already need that for attribute references. Why not force you to write, for example@Iterator.Iterable()
, making it completely unambiguous that you're talking about the metamodel here. ThenIterator.Iterable
could mean exactly the same thing wherever it appears.I'm quite uncertain which option I prefer. Option 2, perhaps.