new syntax for model and declaration references
See original GitHub issueAfter extensive practical experience, I’ve grown to dislike our syntax for metamodel references. In favor of the backticks:
- they’re a visually lightweight element syntactically, making them quite easy to read, and
- they delimit both start and end of the expression, allowing me to clearly write stuff like
`Float.plus`.name
and`Integer|Float`
.
However:
- I find them surprisingly clumsy to type, and
- I essentially never need to directly access attributes of a metamodel reference.
Today I was able to convince ANTLR to accept a different grammar, which I find myself liking better:
- no backticks around declaration references, so simply
class String
instead of`class String`
- a prefix
@
instead of backticks for model references, so@String
instead of`String`
and@Float.plus
instead of`Float.plus`
.
As I have currently implemented this, the @
or class
has a very low precedence, so @Integer|Float
is correct, but you have to write (@Float.plus).name
or (class String).name
.
I probably can mess with the grammar some more to give @
a somewhat higher precedence, and then you would have to write @<Integer|Float>
, but you would still need the parens in (@Float.plus).name
, so I’m not sure if it’s worth it. Also keywords like class
and function
naturally look like low-precedence “operators”.
My conclusions from this work:
- Dropping the backticks from declaration references seems like a clear win to me. I think I should merge at least that much of this work.
- The
@
as a replacement for / alternative to backticks for model references is somewhat more marginal. But it certainly makes criteria queries easier to type.
value results
= let (criteria = em.createCriteria(),
person = criteria.from(@Person),
address = person.join(@Person.address))
criteria
.where(
like(person.get(@Person.name), "Gavin%"),
address.get(@Address.state).equalTo("CA"))
.orderBy(
asc(address.get(@Address.zip)),
desc(person.get(@Person.name)))
.select(construct(@NameAgeAndCity,
with3(person.get(@Person.name),
person.get(@Person.age),
address.get(@Address.city))))
.getResults();
Remaining work to be done includes:
- support plain
module
,package
, andclass
as simplified forms of`module`
,`package`
, and`class`
, - decide the final precedence of
@
, and - check that this work doesn’t stomp on #3791 (should be fine).
Finally, we could consider simplifying the syntax for declaration references even further, to @@String
instead of class String
. But I dunno, that doesn’t look much like Ceylon to me…
Reactions?
Issue Analytics
- State:
- Created 6 years ago
- Comments:54 (50 by maintainers)
Top GitHub Comments
But trust me folks, you’re going to appreciate being able to write:
I mean you would have to write stuff like
::<Integer|Float>
to get a model ref for a type. Pretty ugly, but perhaps it’s not so terrible.So, @DiegoCoronel, here’s what my code example looks like with your suggestion:
I admit that’s not terrible.