question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

new syntax for model and declaration references

See original GitHub issue

After 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, and class 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:closed
  • Created 6 years ago
  • Comments:54 (50 by maintainers)

github_iconTop GitHub Comments

5reactions
gavinkingcommented, Aug 25, 2017

But trust me folks, you’re going to appreciate being able to write:

throws (class Exception, "when something bad happens")
restricted (module, module my.tests)
function foo() { ... }
3reactions
gavinkingcommented, Aug 24, 2017

what about something like: Person::name for model

it doesn’t work for complex types, for example ^Integer|Float.

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:

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();

I admit that’s not terrible.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reference declaration - cppreference.com
Syntax. A reference variable declaration is any simple declaration whose declarator has the form. & attr( ...
Read more >
Declaration statements - var, ref local variables, and ref fields
Declarations introduce a new variable. These statements include `var`, `ref` locals, and `ref` fields. In addition to declaring a new ...
Read more >
Documentation - Declaration Reference - TypeScript
This guide is structured by showing documentation for some API, along with sample usage of that API, and explaining how to write the...
Read more >
new operator - JavaScript - MDN Web Docs - Mozilla
The new operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has...
Read more >
RFC: Syntax for "declaration references" (hyperlinks) · Issue #9
Anyway, I suggest a new syntax to distinguish different node kinds by a TypeScript style type conversion operator. It's more familiar with ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found