Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

if expressions #3609

Closed
CeylonMigrationBot opened this issue Dec 18, 2012 · 24 comments
Closed

if expressions #3609

CeylonMigrationBot opened this issue Dec 18, 2012 · 24 comments

Comments

@CeylonMigrationBot
Copy link

[@gavinking] By considering the grammar of the language, and the precedences of its symbols, I arrived at the following syntax as the only really reasonable way to accommodate exists, nonempty, and is Type within the expression syntax.

if (exists x0=xs[0]) then x0.y 
if (nonempty xs) then xs.first else 0.0
if (is Person p) then p.name else p.string

All of the above would be expressions, at the same precedence level as the existing then/else operators.

Notes:

  • The if condition can be any one of the usual kinds of conditions in Ceylon: exists, nonempty, is Type, or boolean.
  • The else clause is optional. If it is missing, the whole expression evaluates to null.
  • The then clause is required.

The then keyword is necessary to help disambiguate the comprehensions syntax. The following expressions are all different:

[ for (x in xs) if (exists x) x.y ]
[ for (x in xs) if (exists x) then x.y ]
[ for (x in xs) if (exists x) then x.y else 1 ]

The first expression filters out input elements which are null. The second expression results in a null resulting element for each null input element. The third expression results in the value 1 for each null input element.

Additional advantages of then are:

  • It helps make explicit the precedence of the whole construct, and that the operands that follow then and else are disjunction expression, not full expressions.
  • It makes the syntax symmetric, in that both operands are preceded by a keyword.
  • It makes the syntax more consistent with the existing then/else operators.

The parens are needed because of the existing relative precedence of = vs. then/else.

This proposal would give @FroMage a piece of his #3563. To be clear, this would be a feature for Ceylon 1.1.

[Migrated from ceylon/ceylon-spec#503]
[Closed at 2014-11-16 18:07:34]

@CeylonMigrationBot
Copy link
Author

[@gavinking] When we do this and #3662, I think we should consider also supporting assert expressions:

String firstArg => assert(exists arg=process.arguments.first) arg.lowercased;

@CeylonMigrationBot
Copy link
Author

[@tombentley] My only concern is that the similarity between

[ for (x in xs) if (exists x) x.y ]

and

[ for (x in xs) if (exists x) then x.y ]

will result in bugs (when the code is written) and misinterpretation (when it's read).

@CeylonMigrationBot
Copy link
Author

[@gavinking] @tombentley Wellyes, but fortunately that's the kind of bug the typechecker can catch.

@CeylonMigrationBot
Copy link
Author

[@ncorai] Would if expressions accept condition lists, e.g. if (exists a, exists c = a.b, c > 0) then c else 0

@CeylonMigrationBot
Copy link
Author

[@gavinking] @ncorai I assume so. That would be regular.

@CeylonMigrationBot
Copy link
Author

[@gavinking] Now implemented in the inline branch. Need a volunteer to impl support in the backend.

@CeylonMigrationBot
Copy link
Author

[@sgalles] Now, I was wondering if it could be useful to have an inline throw
For instance :

Nothing error(String msg)  {
        throw AssertionError(msg);
}
{Integer*} numbers = "1 2 3".split().map((e) => parseInteger(e) else error("'``e``' can not be parsed"));

It's nice, but sometimes maybe I'd like to to write :

{Integer*} numbers2 = "1 2 3".split().map((e) => parseInteger(e) else throw AssertionError("``e`` should be a number"));

@CeylonMigrationBot
Copy link
Author

[@quintesse] @sgalles definitely, but people seemed very much against it in this old discussion: #3757

@CeylonMigrationBot
Copy link
Author

[@sgalles] Oh, thanks @quintesse I had missed this discussion

@CeylonMigrationBot
Copy link
Author

[@FroMage] So what's the syntax?

@CeylonMigrationBot
Copy link
Author

[@gavinking] if (whatever) then foo else bar

@CeylonMigrationBot
Copy link
Author

[@FroMage] Are any branches optional?

@CeylonMigrationBot
Copy link
Author

[@gavinking]

Are any branches optional?

No.

@CeylonMigrationBot
Copy link
Author

[@quintesse]

No.

That's not what you put in the issue description, why did you change your mind?

@CeylonMigrationBot
Copy link
Author

[@luolong] What would be the return type of the if extpression without else?

@CeylonMigrationBot
Copy link
Author

[@gavinking] Well the type of if (whatever) then foo could be Foo? but I think obligating people to explicitly write if (whatever) then foo else null isn't a bad thing in this case.

@CeylonMigrationBot
Copy link
Author

[@ncorai] I've always thought the distinction between
[ for (x in xs) if (exists x) x.y ] and
[ for (x in xs) if (exists x) then x.y ]
was hard to parse so I'd tend to agree with not having the else clause optional.

@CeylonMigrationBot
Copy link
Author

[@jvasileff] What is the status if then/else in light of this? The reason I ask is that one of the first things I did with Ceylon was to naively write a contains method that can reduce to:

function contains(T item) => // Evaluates to true!
         true  then false // if lt, search left subtree
    else false then false // else if gt, search right subtree
    else true;            // else must be == this node

which of course is missing a set of parenthesis and produces incorrect results.

I don't have a strong opinion on this, and I do like the brevity of then/else. But if if/then/else winds up being seen as a safer or easier to read replacement, then I think else should be optional.

@CeylonMigrationBot
Copy link
Author

[@FroMage] This is done for JVM, need to be done for JS before we can merge, @chochos.

@CeylonMigrationBot
Copy link
Author

[@chochos] Are these new condition expressions going to do type narrowing as well?

@CeylonMigrationBot
Copy link
Author

[@chochos] Done for JS.

@CeylonMigrationBot
Copy link
Author

[@chochos] Um... the else doesn't seem to be optional...

@CeylonMigrationBot
Copy link
Author

[@gavinking] Right. It's not optional.

@CeylonMigrationBot
Copy link
Author

[@gavinking] Done.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants