This page is no longer maintained — Please continue to the home page at www.scala-lang.org

InfixExpr

11 replies
E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.

Hi All

The infix expression is defined in SLS as follows[1]:

InfixExpr ::= PrefixExpr
| InfixExpr id [nl] InfixExpr

I wonder, why not to allow an optional newline also before ´id´ (id denotes an infix operator here):

InfixExpr ::= PrefixExpr
| InfixExpr [nl] id [nl] InfixExpr

This would allow for constructions that are currently not accepted by compiler or interpreted not as
expected (that in turn is often a cause of irritations):

1) val x = "Hello"
+ "world"

2) 5
-
3

3) Or, in parser combinators we must actually place the ´|´ combinator at the end of the line or
enclose the whole expression in parentheses to "disallow newlines [to be treated as semicolons]".
With the proposed change we could write as it's usually done in EBNF-like notations:

def myParser = "(" ~ expr ~ ")"
| variable
| number

The implementation shouldn't be difficult, inserting

newLineOptWhenFollowing(isIdent)

before this line [2] should do the work.

What do you think about?

--
EL

[1] SLS v2.9: §6.12 Prefix, Infix, and Postfix Operations, p.83

[2]
https://github.com/scala/scala/blob/v2.9.1/src/compiler/scala/tools/nsc/...

d_m
Joined: 2010-11-11,
User offline. Last seen 35 weeks 2 days ago.
Re: InfixExpr

On Sun, Feb 12, 2012 at 04:20:56AM +0100, Eugen Labun wrote:
> I wonder, why not to allow an optional newline also before ´id´ (id denotes an infix operator here):
>
> InfixExpr ::= PrefixExpr
> | InfixExpr [nl] id [nl] InfixExpr

Hi Eugen,

I don't think this change is as simple as you might imagine. It would
totally change the way semi-colon inference works, right?

It would also create ambiguities between continued lines and
free-standing unary operators. Consider:

class Foo(var a:Int) {
def bar(b:Int) = {
a = 2 * b
-a
}
}

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: InfixExpr

For consistency, the same could be done in two other places with the same pattern:
´InfixType´ and ´Pattern3´:

before:

InfixType ::= CompoundType { id [nl] CompoundType }

Pattern3 ::= SimplePattern
| SimplePattern { id [nl] SimplePattern }

after:

InfixType ::= CompoundType { [nl] id [nl] CompoundType }

Pattern3 ::= SimplePattern
| SimplePattern { [nl] id [nl] SimplePattern }

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: InfixExpr

Hi Erik,

On 2012-02-12 04:51, Erik Osheim wrote:
> On Sun, Feb 12, 2012 at 04:20:56AM +0100, Eugen Labun wrote:
> I don't think this change is as simple as you might imagine. It would
> totally change the way semi-colon inference works, right?

Yep.

> It would also create ambiguities between continued lines and
> free-standing unary operators. Consider:
>
> class Foo(var a:Int) {
> def bar(b:Int) = {
> a = 2 * b
> -a
> }
> }

Yes, a good point... Intuitivelly, the method's body should be comprised of two expressions...

Additional idea: an expressions must
1) either not contain newlines at all,
2) or (optional) newlines are allowed in both places: before and after infix operators.

Would it work?

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: InfixExpr

> Additional idea: an expressions must
> 1) either not contain newlines at all,
> 2) or (optional) newlines are allowed in both places: before and after infix operators.

Argh. And how to distinguish between?..

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: InfixExpr

OK, the whole was suspiciously simple.
I thought it must have been a simple case that justifies the current SLS definition, and you Erik
showed me that. Thank you.

E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: InfixExpr

On 2012-02-12 04:20, Eugen Labun wrote:
> "disallow newlines [to be treated as semicolons]"

should be read as

"disallow newlines [to be treated as ´nl´ tokens]"

andrevandelft
Joined: 2010-02-07,
User offline. Last seen 34 weeks 1 day ago.
Re: InfixExpr

In my C# and Java life, I never put an infix operator at the end of a
line; lines often start with an infix operator.
I really miss this ability in Scala.
So if the objections that Eugen raise, could be resolved, I would
welcome that very much.

On 12 feb, 04:51, Erik Osheim wrote:
> On Sun, Feb 12, 2012 at 04:20:56AM +0100, Eugen Labun wrote:
> > I wonder, why not to allow an optional newline also before id (id denotes an infix operator here):
>
> >   InfixExpr   ::= PrefixExpr
> >                 | InfixExpr [nl] id [nl] InfixExpr
>
> Hi Eugen,
>
> I don't think this change is as simple as you might imagine. It would
> totally change the way semi-colon inference works, right?
>
> It would also create ambiguities between continued lines and
> free-standing unary operators. Consider:
>
> class Foo(var a:Int) {
>   def bar(b:Int) = {
>     a = 2 * b
>     -a
>   }
>
> }
>

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: InfixExpr
2012/2/12 André van Delft <andre.vandelft@gmail.com>
In my C# and Java life, I never put an infix operator at the end of a
line; lines often start with an infix operator.
I really miss this ability in Scala.
So if the objections that Eugen raise, could be resolved, I would
welcome that very much.

Common practice is the use parentheses to avoid unwanted semicolon inference:
val a = (1  + 1  + 1)
-jason
E. Labun
Joined: 2010-06-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: InfixExpr

On 2012-02-12 12:27, Jason Zaugg wrote:
> 2012/2/12 André van Delft >
>
> In my C# and Java life, I never put an infix operator at the end of a
> line; lines often start with an infix operator.
> I really miss this ability in Scala.
> So if the objections that Eugen raise, could be resolved, I would
> welcome that very much.
>
>
> Common practice is the use parentheses to avoid unwanted semicolon inference:
>
> val a = (1
> + 1
> + 1
> )
>
> -jason

That is what I currently do also with parsers:

def myParser = ( "(" ~ expr ~ ")"
| variable
| number
)

and wanted just avoid that.

(Parentheses disable that the newline-symbols generate ´nl´ tokens [1]. So, the parser doesn't see
any ´nl´s inside parentheses, and InfixExpr succeeds.)

andrevandelft
Joined: 2010-02-07,
User offline. Last seen 34 weeks 1 day ago.
Re: InfixExpr

The option of using parentheses reduces the problem.
Still, I hate parentheses. So I would hope rules will be changed
so that all infix operators may start on a new line.

On 12 feb, 12:27, Jason Zaugg wrote:
> 2012/2/12 André van Delft
>
> > In my C# and Java life, I never put an infix operator at the end of a
> > line; lines often start with an infix operator.
> > I really miss this ability in Scala.
> > So if the objections that Eugen raise, could be resolved, I would
> > welcome that very much.
>
> Common practice is the use parentheses to avoid unwanted semicolon
> inference:
>
> val a = (1
>   + 1
>   + 1
> )
>
> -jason

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: InfixExpr

2012/2/12 André van Delft :
> The option of using parentheses reduces the problem.
> Still, I hate parentheses. So I would hope rules will be changed
> so that all infix operators may start on a new line.

You can have that without operator notation:

val x = list
.map
.filter
.sum

>
> On 12 feb, 12:27, Jason Zaugg wrote:
>> 2012/2/12 André van Delft
>>
>> > In my C# and Java life, I never put an infix operator at the end of a
>> > line; lines often start with an infix operator.
>> > I really miss this ability in Scala.
>> > So if the objections that Eugen raise, could be resolved, I would
>> > welcome that very much.
>>
>> Common practice is the use parentheses to avoid unwanted semicolon
>> inference:
>>
>> val a = (1
>>   + 1
>>   + 1
>> )
>>
>> -jason

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland