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

val 1 = 2 compiles

48 replies
Lex
Joined: 2010-02-28,
User offline. Last seen 42 years 45 weeks ago.

Surprisingly, the following compiles. However it does not produce a
val `1` but generates strange bytecode.

scala> object Foo { val 1 = 100 }
defined module Foo

The def version does not compile.

scala> object Foo { def 1 = 100 }
:1: error: identifier expected but integer literal found.
object Foo { def 1 = 100 }
^

Is this a bug or am I missing something?

Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Re: val 1 = 2 compiles

On Tue, Aug 23, 2011 at 11:05 AM, Aleksey Nikiforov wrote:
> Surprisingly, the following compiles. However it does not produce a
> val `1` but generates strange bytecode.
>
> scala> object Foo { val 1 = 100 }
> defined module Foo

BEST BUG EVER!!!

More fun:

scala> object O { val 1 = 2; def x = 1 }
defined module O

scala> O.x
scala.MatchError: 2 (of class java.lang.Integer)

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: val 1 = 2 compiles

Just tell me what's the ticket, so I can add it to my favorites. :-)

On Tue, Aug 23, 2011 at 12:22, Seth Tisue wrote:
> On Tue, Aug 23, 2011 at 11:05 AM, Aleksey Nikiforov wrote:
>> Surprisingly, the following compiles. However it does not produce a
>> val `1` but generates strange bytecode.
>>
>> scala> object Foo { val 1 = 100 }
>> defined module Foo
>
> BEST BUG EVER!!!
>
> More fun:
>
> scala> object O { val 1 = 2; def x = 1 }
> defined module O
>
> scala> O.x
> scala.MatchError: 2 (of class java.lang.Integer)
>
> --
> Seth Tisue | Northwestern University | http://tisue.net
> lead developer, NetLogo: http://ccl.northwestern.edu/netlogo/
>

Lex
Joined: 2010-02-28,
User offline. Last seen 42 years 45 weeks ago.
Re: val 1 = 2 compiles

Filed the ticket: https://issues.scala-lang.org/browse/SI-4939

On Tue, Aug 23, 2011 at 10:27 AM, Daniel Sobral wrote:
> Just tell me what's the ticket, so I can add it to my favorites. :-)

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: val 1 = 2 compiles

> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939

I don't see why that's a bug. The statement `val 1 = 2` is actually a
pattern match and roughly corresponds to

2 match { case 1 => ... }

Also, I don't understand to what kind of "shadowing" you refer to. The
MatchError occurs on `O.x` because objects are initialized lazily, and
the initialization is atomic. That means that on calling `O.x`, `O` is
initialized, thus the above pattern match is executed, yielding the
mentioned MatchError. Seems pretty much like behaviour as specified to me.

Lex
Joined: 2010-02-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: val 1 = 2 compiles

I am struggling to understand how that becomes a pattern match.
Clearly this is an not intuitive behavioral. Could you elaborate on
how exactly it becomes a pattern match and where this behavior could
be useful.

On Tue, Aug 23, 2011 at 12:53 PM, Lars Hupel wrote:
>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>
> I don't see why that's a bug. The statement `val 1 = 2` is actually a
> pattern match and roughly corresponds to
>
> 2 match { case 1 => ... }
>
> Also, I don't understand to what kind of "shadowing" you refer to. The
> MatchError occurs on `O.x` because objects are initialized lazily, and
> the initialization is atomic. That means that on calling `O.x`, `O` is
> initialized, thus the above pattern match is executed, yielding the
> mentioned MatchError. Seems pretty much like behaviour as specified to me.
>
>

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: val 1 = 2 compiles

The thing you write between `val` and `=` is in most cases just a plain
name of a variable, for example `val x = foo`. Actually, `x` is a bit
more than just a name, as it can be a pattern. Consider the similarity
between:

foo match { case x => doStuff(x) }

and

val x = foo
doStuff(x)

Everything (apart from `|`) which is allowed after `case` is also
allowed after `val` and is translated to a pattern match (at least as
far as I know).

Another example:

val (a, b) = (1,2)
println(a)
println(b)

vs.

(1, 2) match { case (a, b) =>
println(a)
println(b)
}

Both will produce exactly the same output, and I suspect the generated
byte code is also similar.

Now, as constants, or in this case, literals, are allowed in pattern
matches, they are also allowed in `val` definitions.

2 match { case 1 => }

vs.

val 1 = 2

Hope that helps. I agree with you that this might be confusing for
newcomers, but I think this behaviour should be kept for the sake of
symmetry.

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: Re: val 1 = 2 compiles

if 1 = 2 becomes a match, what's the name of the val? is it nameless?

Am 23.08.2011 19:59, schrieb Aleksey Nikiforov:
> I am struggling to understand how that becomes a pattern match.
> Clearly this is an not intuitive behavioral. Could you elaborate on
> how exactly it becomes a pattern match and where this behavior could
> be useful.
>
>
> On Tue, Aug 23, 2011 at 12:53 PM, Lars Hupel wrote:
>>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>> I don't see why that's a bug. The statement `val 1 = 2` is actually a
>> pattern match and roughly corresponds to
>>
>> 2 match { case 1 => ... }
>>
>> Also, I don't understand to what kind of "shadowing" you refer to. The
>> MatchError occurs on `O.x` because objects are initialized lazily, and
>> the initialization is atomic. That means that on calling `O.x`, `O` is
>> initialized, thus the above pattern match is executed, yielding the
>> mentioned MatchError. Seems pretty much like behaviour as specified to me.
>>
>>

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: val 1 = 2 compiles

> if 1 = 2 becomes a match, what's the name of the val? is it nameless?

There will be no val after that, as no identifier is specified.

Interestingly enough, I think there is a small asymmetry between pattern
matching and val definitions:

val F = 1

produces a new variable called `F` with value 1, whereas

1 match { case G => }

fails to compile with "error: not found: value G" (because in `case`
patterns upper case identifiers don't introduce a variable but rather
match against an existing one or an extractor).

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: Re: val 1 = 2 compiles


On 23 August 2011 19:17, Lars Hupel <hupel [at] in [dot] tum [dot] de> wrote:
> if 1 = 2 becomes a match, what's the name of the val? is it nameless?

There will be no val after that, as no identifier is specified.

Interestingly enough, I think there is a small asymmetry between pattern
matching and val definitions:

val F = 1

produces a new variable called `F` with value 1, whereas

1 match { case G => }

fails to compile with "error: not found: value G" (because in `case`
patterns upper case identifiers don't introduce a variable but rather
match against an existing one or an extractor).


Yet:
scala> val (X,Y) = (1,2)<console>:7: error: not found: value X <console>:7: error: not found: value Y

So it looks to be just that particular degenerate case where the two forms differ. Makes sense really, how else could we create uppercased values?
--
Kevin Wright
mail: kevin [dot] wright [at] scalatechnology [dot] com
gtalk / msn : kev [dot] lee [dot] wright [at] gmail [dot] com quora: http://www.quora.com/Kevin-Wrightgoogle+: http://gplus.to/thecoda
kev [dot] lee [dot] wright [at] gmail [dot] com twitter: @thecoda
vibe / skype: kev.lee.wrightsteam: kev_lee_wright
"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Re: Re: val 1 = 2 compiles

>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>
> I don't see why that's a bug. The statement `val 1 = 2` is actually a
> pattern match

Well damn. I'd feel worse for missing that if I weren't in such
illustrious company (Lex, Daniel).

It is both delicious and repellent. Scala is either to be lauded, or chided.

No-variable val definitions are even explicitly speced. See SLS 4.1:
"If p has no bound variables..." What is the purpose of allowing
this...? (I'm trying to keep an open mind.)

Surely it's a REPL bug, though that only one of the following produces an error:

scala> val 1 = 2

scala> { val 1 = 2 }
scala.MatchError: 2 (of class java.lang.Integer)

If the former had errored in the REPL, I would have known right away
that a pattern match was involved.

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: val 1 = 2 compiles

> Surely it's a REPL bug, though that only one of the following produces an error:
>
> scala> val 1 = 2
>
> scala> { val 1 = 2 }
> scala.MatchError: 2 (of class java.lang.Integer)
>
> If the former had errored in the REPL, I would have known right away
> that a pattern match was involved.

Yay, yet another new aspect in this story :)

The former prints

scala> val 1 = 2
:8: error: value x$1 is not a member of object $iw
`x$1`

which indicates that after the REPL is done with its REPL magic and
hands the string containing the statement (amongst other things) to the
compiler, it fails with an error, thus preventing the statement to be
executed at all. This is why no MatchError is thrown there.

What is more interesting is that the REPL thinks `1` is actually an
identifier, which qualifies as a bug imho.

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
RE: Re: val 1 = 2 compiles

Not quite...

In my example, x.a failed only when evaluated... that explains the Seth
example as well - the {} forced evaluation to return a value...

scala> object x { val a@1=2 }
defined module x

scala> x.a
scala.MatchError: 2 (of class java.lang.Integer)

does this mean that all matches are lazy?

For me the val 1=2 also fails with the same error though.

-----Original Message-----
From: scala-user [at] googlegroups [dot] com [mailto:scala-user [at] googlegroups [dot] com] On
Behalf Of Lars Hupel
Sent: August-23-11 2:48 PM
To: scala-user [at] googlegroups [dot] com
Subject: [scala-user] Re: val 1 = 2 compiles

> Surely it's a REPL bug, though that only one of the following produces an
error:
>
> scala> val 1 = 2
>
> scala> { val 1 = 2 }
> scala.MatchError: 2 (of class java.lang.Integer)
>
> If the former had errored in the REPL, I would have known right away
> that a pattern match was involved.

Yay, yet another new aspect in this story :)

The former prints

scala> val 1 = 2
:8: error: value x$1 is not a member of object $iw
`x$1`

which indicates that after the REPL is done with its REPL magic and hands
the string containing the statement (amongst other things) to the compiler,
it fails with an error, thus preventing the statement to be executed at all.
This is why no MatchError is thrown there.

What is more interesting is that the REPL thinks `1` is actually an
identifier, which qualifies as a bug imho.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: val 1 = 2 compiles

On Tue, Aug 23, 2011 at 15:37, Seth Tisue wrote:
>>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>>
>> I don't see why that's a bug. The statement `val 1 = 2` is actually a
>> pattern match
>
> Well damn. I'd feel worse for missing that if I weren't in such
> illustrious company (Lex, Daniel).

For whatever it is worth, I always thought that pattern matching on
"val" only applied if you added parenthesis, since "val X = 2" is
valid. Turns out it was an invalid assumption.

For that matter, pattern matching is _not_ the same among the three
places where it happens. We have "val X" being different than "case
X", and for (pat <- ...) does something different than both val and
match. Also, doesn't accept the same patterns -- for (x: Int <- ...)
is not valid, for instance.

Which is a bunch of excuses for not realizing what was going on. :-)
The error message was a bit deceiving as well, with that printing of
"2".

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
RE: Re: val 1 = 2 compiles

Why do you think val x=2 is different than case x?

scala> 2 match {
| case 1 => {}
| }
scala.MatchError: 2 (of class java.lang.Integer)
at .(:8)
at .()

ALSO
scala> for (x:Int <- 0 to 2) println(x)
0
1
2

BUT MORE INTERESTINGLY

scala> for (1 <- 0 to 2) println ("match... who?")
match... who?

scala>

COOL, HUH?

-----Original Message-----
From: scala-user [at] googlegroups [dot] com [mailto:scala-user [at] googlegroups [dot] com] On
Behalf Of Daniel Sobral
Sent: August-24-11 10:02 AM
To: Seth Tisue
Cc: scala-user [at] googlegroups [dot] com
Subject: Re: [scala-user] Re: val 1 = 2 compiles

On Tue, Aug 23, 2011 at 15:37, Seth Tisue wrote:
>>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>>
>> I don't see why that's a bug. The statement `val 1 = 2` is actually a
>> pattern match
>
> Well damn. I'd feel worse for missing that if I weren't in such
> illustrious company (Lex, Daniel).

For whatever it is worth, I always thought that pattern matching on "val"
only applied if you added parenthesis, since "val X = 2" is valid. Turns out
it was an invalid assumption.

For that matter, pattern matching is _not_ the same among the three places
where it happens. We have "val X" being different than "case X", and for
(pat <- ...) does something different than both val and match. Also, doesn't
accept the same patterns -- for (x: Int <- ...) is not valid, for instance.

Which is a bunch of excuses for not realizing what was going on. :-) The
error message was a bit deceiving as well, with that printing of "2".

--
Daniel C. Sobral

I travel to the future all the time.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: val 1 = 2 compiles

On Wed, Aug 24, 2011 at 11:12, Razvan Cojocaru wrote:
> Why do you think val x=2 is different than case x?

scala> 2 match { X => true }
:1: error: 'case' expected but identifier found.
2 match { X => true }
^

scala> val X = 2
X: Int = 2

>
> scala> 2 match {
>     | case 1 => {}
>     | }
> scala.MatchError: 2 (of class java.lang.Integer)
>        at .(:8)
>        at .()
>
> ALSO
> scala> for (x:Int <- 0 to 2) println(x)
> 0
> 1
> 2
>
> BUT MORE INTERESTINGLY
>
> scala> for (1 <- 0 to 2) println ("match... who?")
> match... who?

Yes, but,

scala> for (x <- List(1, 'a, 'b')) x match { case y: Int => println(y)
case _ => }
1

scala> for (y: Int <- List(1, 'a, 'b')) println(y)
:8: error: type mismatch;
found : Int => Unit
required: Any => ?
for (y: Int <- List(1, 'a, 'b')) println(y)
^

So, as you see, not all patterns are equal.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: val 1 = 2 compiles

On Wed, Aug 24, 2011 at 11:12, Razvan Cojocaru wrote:
> Why do you think val x=2 is different than case x?

Oops, posted incorrect code. Again:

scala> 2 match { case X => true }
:8: error: not found: value X
2 match { case X => true }
^

scala> val X = 2
X: Int = 2

scala> 2 match { case `an example` => true }
:8: error: not found: value an example
2 match { case `an example` => true }
^

scala> val `an example` = 2
an example: Int = 2

>
> scala> 2 match {
>     | case 1 => {}
>     | }
> scala.MatchError: 2 (of class java.lang.Integer)
>        at .(:8)
>        at .()
>
> ALSO
> scala> for (x:Int <- 0 to 2) println(x)
> 0
> 1
> 2
>
> BUT MORE INTERESTINGLY
>
> scala> for (1 <- 0 to 2) println ("match... who?")
> match... who?
>
> scala>
>
>
> COOL, HUH?
>
> -----Original Message-----
> From: scala-user [at] googlegroups [dot] com [mailto:scala-user [at] googlegroups [dot] com] On
> Behalf Of Daniel Sobral
> Sent: August-24-11 10:02 AM
> To: Seth Tisue
> Cc: scala-user [at] googlegroups [dot] com
> Subject: Re: [scala-user] Re: val 1 = 2 compiles
>
> On Tue, Aug 23, 2011 at 15:37, Seth Tisue wrote:
>>>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>>>
>>> I don't see why that's a bug. The statement `val 1 = 2` is actually a
>>> pattern match
>>
>> Well damn. I'd feel worse for missing that if I weren't in such
>> illustrious company (Lex, Daniel).
>
> For whatever it is worth, I always thought that pattern matching on "val"
> only applied if you added parenthesis, since "val X = 2" is valid. Turns out
> it was an invalid assumption.
>
> For that matter, pattern matching is _not_ the same among the three places
> where it happens. We have "val X" being different than "case X", and for
> (pat <- ...) does something different than both val and match. Also, doesn't
> accept the same patterns -- for (x: Int <- ...) is not valid, for instance.
>
> Which is a bunch of excuses for not realizing what was going on. :-) The
> error message was a bit deceiving as well, with that printing of "2".
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>
>

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
RE: Re: val 1 = 2 compiles

WTF?

scala> 2 match { case razvan => true }
res11: Boolean = true

scala> 2 match { case RAZVAN => true }
:8: error: not found: value RAZVAN
2 match { case RAZVAN => true }
^

scala> 2 match { case `RAZVAN` => true }
:8: error: not found: value RAZVAN
2 match { case `RAZVAN` => true }
^

scala>

-----Original Message-----
From: Razvan Cojocaru [mailto:pub [at] razie [dot] com]
Sent: August-24-11 10:12 AM
To: 'Daniel Sobral'; 'Seth Tisue'
Cc: scala-user [at] googlegroups [dot] com
Subject: RE: [scala-user] Re: val 1 = 2 compiles

Why do you think val x=2 is different than case x?

scala> 2 match {
| case 1 => {}
| }
scala.MatchError: 2 (of class java.lang.Integer)
at .(:8)
at .()

ALSO
scala> for (x:Int <- 0 to 2) println(x)
0
1
2

BUT MORE INTERESTINGLY

scala> for (1 <- 0 to 2) println ("match... who?")
match... who?

scala>

COOL, HUH?

-----Original Message-----
From: scala-user [at] googlegroups [dot] com [mailto:scala-user [at] googlegroups [dot] com] On
Behalf Of Daniel Sobral
Sent: August-24-11 10:02 AM
To: Seth Tisue
Cc: scala-user [at] googlegroups [dot] com
Subject: Re: [scala-user] Re: val 1 = 2 compiles

On Tue, Aug 23, 2011 at 15:37, Seth Tisue wrote:
>>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>>
>> I don't see why that's a bug. The statement `val 1 = 2` is actually a
>> pattern match
>
> Well damn. I'd feel worse for missing that if I weren't in such
> illustrious company (Lex, Daniel).

For whatever it is worth, I always thought that pattern matching on "val"
only applied if you added parenthesis, since "val X = 2" is valid. Turns out
it was an invalid assumption.

For that matter, pattern matching is _not_ the same among the three places
where it happens. We have "val X" being different than "case X", and for
(pat <- ...) does something different than both val and match. Also, doesn't
accept the same patterns -- for (x: Int <- ...) is not valid, for instance.

Which is a bunch of excuses for not realizing what was going on. :-) The
error message was a bit deceiving as well, with that printing of "2".

--
Daniel C. Sobral

I travel to the future all the time.

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
RE: Re: val 1 = 2 compiles

More WTF

scala> 2 match { case `razvan` => true }
:8: error: not found: value razvan
2 match { case `razvan` => true }
^

scala> 2 match { case razvanc => true }
res17: Boolean = true

it's clearly a syntax issue in the parser?

-----Original Message-----
From: Razvan Cojocaru [mailto:pub [at] razie [dot] com]
Sent: August-24-11 10:45 AM
To: 'Daniel Sobral'; 'Seth Tisue'
Cc: scala-user [at] googlegroups [dot] com
Subject: RE: [scala-user] Re: val 1 = 2 compiles

WTF?

scala> 2 match { case razvan => true }
res11: Boolean = true

scala> 2 match { case RAZVAN => true }
:8: error: not found: value RAZVAN
2 match { case RAZVAN => true }
^

scala> 2 match { case `RAZVAN` => true }
:8: error: not found: value RAZVAN
2 match { case `RAZVAN` => true }
^

scala>

-----Original Message-----
From: Razvan Cojocaru [mailto:pub [at] razie [dot] com]
Sent: August-24-11 10:12 AM
To: 'Daniel Sobral'; 'Seth Tisue'
Cc: scala-user [at] googlegroups [dot] com
Subject: RE: [scala-user] Re: val 1 = 2 compiles

Why do you think val x=2 is different than case x?

scala> 2 match {
| case 1 => {}
| }
scala.MatchError: 2 (of class java.lang.Integer)
at .(:8)
at .()

ALSO
scala> for (x:Int <- 0 to 2) println(x)
0
1
2

BUT MORE INTERESTINGLY

scala> for (1 <- 0 to 2) println ("match... who?")
match... who?

scala>

COOL, HUH?

-----Original Message-----
From: scala-user [at] googlegroups [dot] com [mailto:scala-user [at] googlegroups [dot] com] On
Behalf Of Daniel Sobral
Sent: August-24-11 10:02 AM
To: Seth Tisue
Cc: scala-user [at] googlegroups [dot] com
Subject: Re: [scala-user] Re: val 1 = 2 compiles

On Tue, Aug 23, 2011 at 15:37, Seth Tisue wrote:
>>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>>
>> I don't see why that's a bug. The statement `val 1 = 2` is actually a
>> pattern match
>
> Well damn. I'd feel worse for missing that if I weren't in such
> illustrious company (Lex, Daniel).

For whatever it is worth, I always thought that pattern matching on "val"
only applied if you added parenthesis, since "val X = 2" is valid. Turns out
it was an invalid assumption.

For that matter, pattern matching is _not_ the same among the three places
where it happens. We have "val X" being different than "case X", and for
(pat <- ...) does something different than both val and match. Also, doesn't
accept the same patterns -- for (x: Int <- ...) is not valid, for instance.

Which is a bunch of excuses for not realizing what was going on. :-) The
error message was a bit deceiving as well, with that printing of "2".

--
Daniel C. Sobral

I travel to the future all the time.

vpatryshev
Joined: 2009-02-16,
User offline. Last seen 1 year 24 weeks ago.
Re: Re: val 1 = 2 compiles
Wow...

for (x@List(a,b) <- List(0,1,"Z",(5,6),List("x", "y"))) {print("wow: " + x)}

Thanks,
-Vlad


On Wed, Aug 24, 2011 at 7:12 AM, Razvan Cojocaru <pub [at] razie [dot] com> wrote:
Why do you think val x=2 is different than case x?

scala> 2 match {
    | case 1 => {}
    | }
scala.MatchError: 2 (of class java.lang.Integer)
       at .<init>(<console>:8)
       at .<clinit>(<console>)

ALSO
scala> for (x:Int <- 0 to 2) println(x)
0
1
2

BUT MORE INTERESTINGLY

scala> for (1 <- 0 to 2) println ("match... who?")
match... who?

scala>


COOL, HUH?

-----Original Message-----
From: scala-user [at] googlegroups [dot] com [mailto:scala-user [at] googlegroups [dot] com] On
Behalf Of Daniel Sobral
Sent: August-24-11 10:02 AM
To: Seth Tisue
Cc: scala-user [at] googlegroups [dot] com
Subject: Re: [scala-user] Re: val 1 = 2 compiles

On Tue, Aug 23, 2011 at 15:37, Seth Tisue <seth [at] tisue [dot] net> wrote:
>>> Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
>>
>> I don't see why that's a bug. The statement `val 1 = 2` is actually a
>> pattern match
>
> Well damn. I'd feel worse for missing that if I weren't in such
> illustrious company (Lex, Daniel).

For whatever it is worth, I always thought that pattern matching on "val"
only applied if you added parenthesis, since "val X = 2" is valid. Turns out
it was an invalid assumption.

For that matter, pattern matching is _not_ the same among the three places
where it happens. We have "val X" being different than "case X", and for
(pat <- ...) does something different than both val and match. Also, doesn't
accept the same patterns -- for (x: Int <- ...) is not valid, for instance.

Which is a bunch of excuses for not realizing what was going on. :-) The
error message was a bit deceiving as well, with that printing of "2".

--
Daniel C. Sobral

I travel to the future all the time.


Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: val 1 = 2 compiles

On Wed, Aug 24, 2011 at 4:54 PM, Razvan Cojocaru wrote:
> More WTF
>
> scala> 2 match { case `razvan` => true }
> :8: error: not found: value razvan
>       2 match { case `razvan` => true }
>                      ^
>
> scala> 2 match { case razvanc => true }
> res17: Boolean = true
>
> it's clearly a syntax issue in the parser?
>
> -----Original Message-----
> From: Razvan Cojocaru [mailto:pub [at] razie [dot] com]
> Sent: August-24-11 10:45 AM
> To: 'Daniel Sobral'; 'Seth Tisue'
> Cc: scala-user [at] googlegroups [dot] com
> Subject: RE: [scala-user] Re: val 1 = 2 compiles
>
> WTF?
>
> scala> 2 match { case razvan => true }
> res11: Boolean = true
>
> scala> 2 match { case RAZVAN => true }
> :8: error: not found: value RAZVAN
>       2 match { case RAZVAN => true }
>                      ^
>
> scala> 2 match { case `RAZVAN` => true }
> :8: error: not found: value RAZVAN
>       2 match { case `RAZVAN` => true }
>                      ^

In a pattern, a capitalized identifier or a backtick quoted identifier
refers to a previously defined stable identifier (ie, a val). A
lowercase identifier introduces a new variable binding.

-jason

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: val 1 = 2 compiles

So... That's what's wrong with the parser then!

;)

Thanks,
Razvan

On 2011-08-24, at 11:25 AM, Jason Zaugg wrote:

> On Wed, Aug 24, 2011 at 4:54 PM, Razvan Cojocaru wrote:
>> More WTF
>>
>> scala> 2 match { case `razvan` => true }
>> :8: error: not found: value razvan
>> 2 match { case `razvan` => true }
>> ^
>>
>> scala> 2 match { case razvanc => true }
>> res17: Boolean = true
>>
>> it's clearly a syntax issue in the parser?
>>
>> -----Original Message-----
>> From: Razvan Cojocaru [mailto:pub [at] razie [dot] com]
>> Sent: August-24-11 10:45 AM
>> To: 'Daniel Sobral'; 'Seth Tisue'
>> Cc: scala-user [at] googlegroups [dot] com
>> Subject: RE: [scala-user] Re: val 1 = 2 compiles
>>
>> WTF?
>>
>> scala> 2 match { case razvan => true }
>> res11: Boolean = true
>>
>> scala> 2 match { case RAZVAN => true }
>> :8: error: not found: value RAZVAN
>> 2 match { case RAZVAN => true }
>> ^
>>
>> scala> 2 match { case `RAZVAN` => true }
>> :8: error: not found: value RAZVAN
>> 2 match { case `RAZVAN` => true }
>> ^
>
> In a pattern, a capitalized identifier or a backtick quoted identifier
> refers to a previously defined stable identifier (ie, a val). A
> lowercase identifier introduces a new variable binding.
>
> -jason

fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.
Re: Re: val 1 = 2 compiles

On 24/08/2011 16:01, Daniel Sobral wrote:
> For whatever it is worth, I always thought that pattern matching on
> "val" only applied if you added parenthesis, since "val X = 2" is
> valid. Turns out it was an invalid assumption.
>
> For that matter, pattern matching is _not_ the same among the three
> places where it happens. We have "val X" being different than "case
> X", and for (pat<- ...) does something different than both val and
> match. Also, doesn't accept the same patterns -- for (x: Int<- ...)
> is not valid, for instance.
>
> Which is a bunch of excuses for not realizing what was going on. :-)
> The error message was a bit deceiving as well, with that printing of
> "2".

Poor me who was thinking that Scala was less full of edge cases than
Java, but that one is a perfect counter example.

It seems to be a "feature" with a quite hight level of surprise, and a
really really small use case surface (well, if it is still surprising
among guys like Seth and Daniel today, well, it tells a lot).

The sole thing than a "val" may leads to such exception, without
warning, is quite deceptive. So, isn't this a perfect case for a
feature removal, or at least a syntax change ? Something that let other
people reading the code be alerted that "this not a regular assignement,
and it may fails".
What about "case val 1 = 2", or something alike ?

Moreover, I believe that Paul did things around that part of the
language some times ago, but I can't find them back, and so I can't
check if the question was already answered (I believe it was more likely
to be about the elimination of intermediary vals for val (a, b) = ....).

Cheers,

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: Re: val 1 = 2 compiles


On Thu, Aug 25, 2011 at 11:06 AM, Francois <fanf42 [at] gmail [dot] com> wrote:
On 24/08/2011 16:01, Daniel Sobral wrote:
For whatever it is worth, I always thought that pattern matching on
"val" only applied if you added parenthesis, since "val X = 2" is
valid. Turns out it was an invalid assumption.

For that matter, pattern matching is _not_ the same among the three
places where it happens. We have "val X" being different than "case
X", and for (pat<- ...) does something different than both val and
match. Also, doesn't accept the same patterns -- for (x: Int<- ...)
is not valid, for instance.

Which is a bunch of excuses for not realizing what was going on. :-)
The error message was a bit deceiving as well, with that printing of
"2".

Poor me who was thinking that Scala was less full of edge cases than Java, but that one is a perfect counter example.

It seems to be a "feature" with a quite hight level of surprise, and a really really small use case surface (well, if it is still surprising among guys like Seth and Daniel today, well, it tells a lot).

The sole thing than a "val" may leads to such exception, without warning, is quite deceptive.  So, isn't this a perfect case for a feature removal, or at least a syntax change ? Something that let other people reading the code be alerted that "this not a regular assignement, and it may fails".
What about "case val 1 = 2", or something alike ?

Moreover, I believe that Paul did things around that part of the language some times ago, but I can't find them back, and so I can't check if the question was already answered (I believe it was more likely to be about the elimination of intermediary vals for val (a, b) = ....).

Cheers,

I am not concerned. The fact that it took 8 years for people to notice is a good sign how rare this case is. I think any proposal to "fix" this would complicate the language for no practical gain.
Just to recap the rules:

A value definition is of the form

  val <pattern> = <expression>

  1 is a <pattern>

There is one edge case: If the pattern is a single variable (upper or lower case or backquoted), then it is always treated as a variable, not a constant. Otherwise, there would be no way to define such a value.

There sure is an error here, but, as other people have said, it seems to be in the REPL, where something should be evaluated but is not.

Cheers

 -- Martin

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Re: val 1 = 2 compiles

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 25/08/11 19:19, martin odersky wrote:
> I am not concerned. The fact that it took 8 years for people to notice is a
> good sign how rare this case is

It's also a phase that all haskell newbies come to, freak out, and some
of us just kick back smoking a pipe and watch the fun begin.

let 1 = 2 in 7
7

*takes a puff*

fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.
Re: Re: Re: val 1 = 2 compiles

On 25/08/2011 11:50, Tony Morris wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 25/08/11 19:19, martin odersky wrote:
>> I am not concerned. The fact that it took 8 years for people to notice is a
>> good sign how rare this case is
> It's also a phase that all haskell newbies come to, freak out, and some
> of us just kick back smoking a pipe and watch the fun begin.
>
> let 1 = 2 in 7
> 7
>
> *takes a puff*

Well, OK, so why not just let the newbies learn that elsewhere than in
their projects, for example in some reference manual (not the spec) ? If
it is a sound behaviour, let us know about its soundness and not be
surprised.

Thanks,

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Re: Re: val 1 = 2 compiles


On Thu, Aug 25, 2011 at 11:50 AM, Tony Morris <tonymorris [at] gmail [dot] com> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 25/08/11 19:19, martin odersky wrote:
> I am not concerned. The fact that it took 8 years for people to notice is a
> good sign how rare this case is

It's also a phase that all haskell newbies come to, freak out, and some
of us just kick back smoking a pipe and watch the fun begin.

let 1 = 2 in 7
7

*takes a puff*

Tony, that ain't no crack pipe I hope!
 

- --
Tony Morris
http://tmorris.net/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJOVhrRAAoJEPxHMY3rBz0PZuwH/1YdP0490MnYiRWyOQqWzBCw
ACYYK8Cugof1Vzlora9o1Vx2Mo9qmHSaKLJbryutmjfAHhmjYfFO/WT+tnogbXz9
2HjfDOwRy0n13V23J+pzDSZ2e28lDUoumDU87cFE4FhLsKfux80bVuQSa65sZOQU
PtBtWgN7qJoPtoZZHYSTVXt2gJzoFEhc9vXYED9E6ytZ8J8kBS5feiURrAodZaCD
PCDzu3AglWuy/LXmUnEgb6n08oCJowvSEgts+qidaDPdL1W2mBWtwKg0ZRzETmT7
7IW2hi0Lv2ltnBGv9t/2lgeGSIGhrOW17GKwIQvR0ShUofK6uDkK46XqPBj+M9A=
=Mro2
-----END PGP SIGNATURE-----



--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
Philippe Lhoste
Joined: 2010-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: val 1 = 2 compiles

On 25/08/2011 11:06, Francois wrote:
> It seems to be a "feature" with a quite hight level of surprise, and a really really small
> use case surface (well, if it is still surprising among guys like Seth and Daniel today,
> well, it tells a lot).
>
> The sole thing than a "val" may leads to such exception, without warning, is quite
> deceptive. So, isn't this a perfect case for a feature removal, or at least a syntax
> change ? Something that let other people reading the code be alerted that "this not a
> regular assignement, and it may fails".
> What about "case val 1 = 2", or something alike ?

If it is a REPL-only bug, I won't worry, REPL has some other surprises, where people
report strange behavior and other people tell them they cannot reproduce it in a .scala
file. It is not a punch toward the REPL, one just has to be aware of such surprises...

Honestly, the original code, val 1 = 2, can be written only by a beginner (perhaps),
somebody doing a typo, or somebody exploring corner cases... The result is surprising, but
as long as it can be explained simply...

The use case surface isn't so small, as it is often used (and shown) with tuples.
I found out also that I can write:
val List(_, t, _*) = x
although I don't know if it is more practical than
val t = x(1)
:-)

Hey, at least, this "bug" made some people (including me) aware (or reminded) of this val
= syntax, which is a good thing.

To "debate" on your proposal, perhaps a less breaking change would be to conform to
Daniel's expectation, that the pattern is matched only if it is surrounded between
parentheses.
Ie. val (a, b) = would work to match a tuple (ie. unchanging syntax of the most
common case), and one would have to write val (List(_, t, _*)) = to make it work.
But it looks a bit inconsistent with regard to tuples...
And given Martin's answer, I doubt this will change...

Nate Nystrom 2
Joined: 2011-01-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Re: val 1 = 2 compiles

On 25 Aug 2011, at 13:16, Philippe Lhoste wrote:

> On 25/08/2011 11:06, Francois wrote:
>> It seems to be a "feature" with a quite hight level of surprise, and a really really small
>> use case surface (well, if it is still surprising among guys like Seth and Daniel today,
>> well, it tells a lot).
>>
>> The sole thing than a "val" may leads to such exception, without warning, is quite
>> deceptive. So, isn't this a perfect case for a feature removal, or at least a syntax
>> change ? Something that let other people reading the code be alerted that "this not a
>> regular assignement, and it may fails".
>> What about "case val 1 = 2", or something alike ?
>
> If it is a REPL-only bug, I won't worry, REPL has some other surprises, where people report strange behavior and other people tell them they cannot reproduce it in a .scala file. It is not a punch toward the REPL, one just has to be aware of such surprises...
>
> Honestly, the original code, val 1 = 2, can be written only by a beginner (perhaps), somebody doing a typo, or somebody exploring corner cases... The result is surprising, but as long as it can be explained simply...
>
> The use case surface isn't so small, as it is often used (and shown) with tuples.
> I found out also that I can write:
> val List(_, t, _*) = x
> although I don't know if it is more practical than
> val t = x(1)
> :-)
>
> Hey, at least, this "bug" made some people (including me) aware (or reminded) of this val = syntax, which is a good thing.
>
>
> To "debate" on your proposal, perhaps a less breaking change would be to conform to Daniel's expectation, that the pattern is matched only if it is surrounded between parentheses.
> Ie. val (a, b) = would work to match a tuple (ie. unchanging syntax of the most common case), and one would have to write val (List(_, t, _*)) = to make it work.
> But it looks a bit inconsistent with regard to tuples...
> And given Martin's answer, I doubt this will change...

I agree that this isn't really a big deal, but perhaps Scala could disallow val definitions where the pattern doesn't bind any variables. This rule would disallow:

val 1 = 2
val (_, _) = x

But allow:

val List(_, t, _*) = x
val (x, y) = p
val x @ 1 = 2

Is there a use case for a val declaration that doesn't bind a variable?

Nate

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Re: val 1 = 2 compiles

On Thu, Aug 25, 2011 at 08:33, Nate Nystrom wrote:
>
> I agree that this isn't really a big deal, but perhaps Scala could disallow val definitions where the pattern doesn't bind any variables.  This rule would disallow:
>
> val 1 = 2
> val (_, _) = x
>
> But allow:
>
> val List(_, t, _*) = x
> val (x, y) = p
> val x @ 1 = 2
>
> Is there a use case for a val declaration that doesn't bind a variable?

Perhaps a _warning_ that there's no variable being binded. But...

Interestingly, one of paulp's side branch would probably accuse an
error on "val 1 = 2", since 1.type would be different than 2.type,
causing a compilation error.

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Re: val 1 = 2 compiles

> Perhaps a _warning_ that there's no variable being binded. But...

+1 for a warning

> Interestingly, one of paulp's side branch would probably accuse an
> error on "val 1 = 2", since 1.type would be different than 2.type,
> causing a compilation error.

I really like that idea. I wish there would be more singleton types
around. Which branch is that?

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Re: val 1 = 2 compiles

How can I retweet this ???

Thanks,
Razvan

On 2011-08-25, at 5:50 AM, Tony Morris wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 25/08/11 19:19, martin odersky wrote:
>> I am not concerned. The fact that it took 8 years for people to notice is a
>> good sign how rare this case is
>
> It's also a phase that all haskell newbies come to, freak out, and some
> of us just kick back smoking a pipe and watch the fun begin.
>
> let 1 = 2 in 7
> 7
>
> *takes a puff*
>
> - --
> Tony Morris
> http://tmorris.net/
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
>
> iQEcBAEBAgAGBQJOVhrRAAoJEPxHMY3rBz0PZuwH/1YdP0490MnYiRWyOQqWzBCw
> ACYYK8Cugof1Vzlora9o1Vx2Mo9qmHSaKLJbryutmjfAHhmjYfFO/WT+tnogbXz9
> 2HjfDOwRy0n13V23J+pzDSZ2e28lDUoumDU87cFE4FhLsKfux80bVuQSa65sZOQU
> PtBtWgN7qJoPtoZZHYSTVXt2gJzoFEhc9vXYED9E6ytZ8J8kBS5feiURrAodZaCD
> PCDzu3AglWuy/LXmUnEgb6n08oCJowvSEgts+qidaDPdL1W2mBWtwKg0ZRzETmT7
> 7IW2hi0Lv2ltnBGv9t/2lgeGSIGhrOW17GKwIQvR0ShUofK6uDkK46XqPBj+M9A=
> =Mro2
> -----END PGP SIGNATURE-----

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Re: val 1 = 2 compiles

It does call the unapply(), does it?

Thanks,
Razvan

On 2011-08-25, at 7:33 AM, Nate Nystrom wrote:

>
> On 25 Aug 2011, at 13:16, Philippe Lhoste wrote:
>
>> On 25/08/2011 11:06, Francois wrote:
>>> It seems to be a "feature" with a quite hight level of surprise, and a really really small
>>> use case surface (well, if it is still surprising among guys like Seth and Daniel today,
>>> well, it tells a lot).
>>>
>>> The sole thing than a "val" may leads to such exception, without warning, is quite
>>> deceptive. So, isn't this a perfect case for a feature removal, or at least a syntax
>>> change ? Something that let other people reading the code be alerted that "this not a
>>> regular assignement, and it may fails".
>>> What about "case val 1 = 2", or something alike ?
>>
>> If it is a REPL-only bug, I won't worry, REPL has some other surprises, where people report strange behavior and other people tell them they cannot reproduce it in a .scala file. It is not a punch toward the REPL, one just has to be aware of such surprises...
>>
>> Honestly, the original code, val 1 = 2, can be written only by a beginner (perhaps), somebody doing a typo, or somebody exploring corner cases... The result is surprising, but as long as it can be explained simply...
>>
>> The use case surface isn't so small, as it is often used (and shown) with tuples.
>> I found out also that I can write:
>> val List(_, t, _*) = x
>> although I don't know if it is more practical than
>> val t = x(1)
>> :-)
>>
>> Hey, at least, this "bug" made some people (including me) aware (or reminded) of this val = syntax, which is a good thing.
>>
>>
>> To "debate" on your proposal, perhaps a less breaking change would be to conform to Daniel's expectation, that the pattern is matched only if it is surrounded between parentheses.
>> Ie. val (a, b) = would work to match a tuple (ie. unchanging syntax of the most common case), and one would have to write val (List(_, t, _*)) = to make it work.
>> But it looks a bit inconsistent with regard to tuples...
>> And given Martin's answer, I doubt this will change...
>
>
> I agree that this isn't really a big deal, but perhaps Scala could disallow val definitions where the pattern doesn't bind any variables. This rule would disallow:
>
> val 1 = 2
> val (_, _) = x
>
> But allow:
>
> val List(_, t, _*) = x
> val (x, y) = p
> val x @ 1 = 2
>
> Is there a use case for a val declaration that doesn't bind a variable?
>
> Nate
>
>
>

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Re: val 1 = 2 compiles

On Thu, Aug 25, 2011 at 12:57, Lars Hupel wrote:
>> Perhaps a _warning_ that there's no variable being binded. But...
>
> +1 for a warning
>
>> Interestingly, one of paulp's side branch would probably accuse an
>> error on "val 1 = 2", since 1.type would be different than 2.type,
>> causing a compilation error.
>
> I really like that idea. I wish there would be more singleton types
> around. Which branch is that?

No clue. He usually says "I have a branch where x and y". I suppose
most of them are local, though you can always search at his github.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: Re: val 1 = 2 compiles

On 8/25/11 11:55 AM, Daniel Sobral wrote:
>> I really like that idea. I wish there would be more singleton types
>> around. Which branch is that?
>
> No clue. He usually says "I have a branch where x and y". I suppose
> most of them are local, though you can always search at his github.

I have been trying to move the more stable feature branches into the
repository below. This particular branch has been in there a while.

https://github.com/paulp/scala-dev/tree/literal-dependent-types

It doesn't do what you thought it might, but it was a reasonable
supposition (I had to check) and it could be made to do so; it's just a
matter of when you widen the types.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: Re: Re: val 1 = 2 compiles


On Thu, Aug 25, 2011 at 10:26 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:
On 8/25/11 11:55 AM, Daniel Sobral wrote:
I really like that idea. I wish there would be more singleton types
around. Which branch is that?

No clue. He usually says "I have a branch where x and y". I suppose
most of them are local, though you can always search at his github.

I have been trying to move the more stable feature branches into the repository below.  This particular branch has been in there a while.

https://github.com/paulp/scala-dev/tree/literal-dependent-types

It doesn't do what you thought it might, but it was a reasonable supposition (I had to check) and it could be made to do so; it's just a matter of when you widen the types.

You certainly do want to widen the types early, or the following would no longer compile:

  var x = 1     // don't infer a 1.type for the type of x!
  x += 1

Cheers

 -- Martin

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: Re: Re: val 1 = 2 compiles


On Thu, Aug 25, 2011 at 17:57, Lars Hupel <hupel [at] in [dot] tum [dot] de> wrote:
> Perhaps a _warning_ that there's no variable being binded. But...

+1 for a warning

> Interestingly, one of paulp's side branch would probably accuse an
> error on "val 1 = 2", since 1.type would be different than 2.type,
> causing a compilation error.

I really like that idea. I wish there would be more singleton types
around. Which branch is that?


Such a warning could only be issued if both sides of the definitionare compile-time constants. I don't see why somebody would ever write code like that.
For non-binding value definitions, they can be used as a kind ofassertion, checking the shape of a value.  List(List(_)) = xssI'm not arguing this is the best style :)
Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: Re: Re: val 1 = 2 compiles


On 26 August 2011 08:49, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:


On Thu, Aug 25, 2011 at 17:57, Lars Hupel <hupel [at] in [dot] tum [dot] de> wrote:
> Perhaps a _warning_ that there's no variable being binded. But...

+1 for a warning

> Interestingly, one of paulp's side branch would probably accuse an
> error on "val 1 = 2", since 1.type would be different than 2.type,
> causing a compilation error.

I really like that idea. I wish there would be more singleton types
around. Which branch is that?


Such a warning could only be issued if both sides of the definitionare compile-time constants. I don't see why somebody would ever write code like that.
For non-binding value definitions, they can be used as a kind ofassertion, checking the shape of a value.  List(List(_)) = xssI'm not arguing this is the best style :)

Ladies and Gentlemen... We have ourselves a use case!

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Re: val 1 = 2 compiles

>> For non-binding value definitions, they can be used as a kind of
>> assertion, checking the shape of a value.
>> List(List(_)) = xss
>> I'm not arguing this is the best style :)
>>
> Ladies and Gentlemen... We have ourselves a use case!

May I suggest something more expressive for that?

assertMatch(xss, { case List(List(_)) => })

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: Re: Re: val 1 = 2 compiles


On Fri, Aug 26, 2011 at 09:59, Lars Hupel <hupel [at] in [dot] tum [dot] de> wrote:
>> For non-binding value definitions, they can be used as a kind of
>> assertion, checking the shape of a value.
>>   List(List(_)) = xss
>> I'm not arguing this is the best style :)
>>
> Ladies and Gentlemen... We have ourselves a use case!

May I suggest something more expressive for that?

assertMatch(xss, { case List(List(_)) => })

 why writing 43 characters instead of 19? :-) 
Nate Nystrom 2
Joined: 2011-01-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Re: val 1 = 2 compiles

On 26 Aug 2011, at 09:59, Lars Hupel wrote:

>>> For non-binding value definitions, they can be used as a kind of
>>> assertion, checking the shape of a value.
>>> List(List(_)) = xss
>>> I'm not arguing this is the best style :)
>>>
>> Ladies and Gentlemen... We have ourselves a use case!
>
> May I suggest something more expressive for that?
>
> assertMatch(xss, { case List(List(_)) => })
>

Or:

val x @ List(List(_)) = xss

Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Re: Re: Re: val 1 = 2 compiles

On Thu, Aug 25, 2011 at 5:19 AM, martin odersky wrote:
> I am not concerned. The fact that it took 8 years for people to notice is a
> good sign how rare this case is. I think any proposal to "fix" this would
> complicate the language for no practical gain.
> Just to recap the rules:
> A value definition is of the form
>   val =
>   1 is a
> There is one edge case: If the pattern is a single variable (upper or lower
> case or backquoted), then it is always treated as a variable, not a
> constant. Otherwise, there would be no way to define such a value.

I actually agree this is of little importance. That said:

The actual spec is more complicated than your recap indicates. I think
disallowing "val 1 = 2" would actually make the language slightly
smaller, not larger.

Value definitions are governed by SLS 4.1 and there are four different cases:
0. pattern is a simple name or a name followed by a colon and a type
1. pattern has bound variables x1, ..., xn, where n > 1
2. p has a unique bound variable x
3. p has no bound variables

Each case is spec'ed separately. #3 is the "val 1 = 2" case, and it is
already handled as an edge case with its own special expansion: "If p
has no bound variables val p = e is expanded as e match { case p =>
()}". If this case were simply prohibited, the spec would actually get
a tiny bit shorter.

If this were being spec'ed for the first time today, we might outlaw
this edge case, but since it's already spec'ed, I doubt it's worth
changing.

In any case, this has been an interesting thread.

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
RE: Re: Re: val 1 = 2 compiles

The val 1=2 doesn't bother me much, it's a sort of natural extension of the
x@ syntax... where the x@ is missing, it being optional in the first place
and it thus unifies pattern matching behavior, if not syntax and I think it
in fact simplifies the perceived language even if it has to complicate the
spec...

The upper case/lower case/backquote convention in match/case bothers me -
this is not natural... and I expect to forget it again in the future :(

-----Original Message-----
From: scala-debate [at] googlegroups [dot] com [mailto:scala-debate [at] googlegroups [dot] com]
On Behalf Of Seth Tisue
Sent: August-26-11 11:37 AM
To: scala-debate
Cc: martin odersky
Subject: Re: [scala-debate] Re: [scala-user] Re: val 1 = 2 compiles

On Thu, Aug 25, 2011 at 5:19 AM, martin odersky
wrote:
> I am not concerned. The fact that it took 8 years for people to notice
> is a good sign how rare this case is. I think any proposal to "fix"
> this would complicate the language for no practical gain.
> Just to recap the rules:
> A value definition is of the form
>   val =
>   1 is a
> There is one edge case: If the pattern is a single variable (upper or
> lower case or backquoted), then it is always treated as a variable,
> not a constant. Otherwise, there would be no way to define such a value.

I actually agree this is of little importance. That said:

The actual spec is more complicated than your recap indicates. I think
disallowing "val 1 = 2" would actually make the language slightly smaller,
not larger.

Value definitions are governed by SLS 4.1 and there are four different
cases:
0. pattern is a simple name or a name followed by a colon and a type 1.
pattern has bound variables x1, ..., xn, where n > 1 2. p has a unique bound
variable x 3. p has no bound variables

Each case is spec'ed separately. #3 is the "val 1 = 2" case, and it is
already handled as an edge case with its own special expansion: "If p has no
bound variables val p = e is expanded as e match { case p => ()}". If this
case were simply prohibited, the spec would actually get a tiny bit shorter.

If this were being spec'ed for the first time today, we might outlaw this
edge case, but since it's already spec'ed, I doubt it's worth changing.

In any case, this has been an interesting thread.

--
Seth Tisue | Northwestern University | http://tisue.net lead developer,
NetLogo: http://ccl.northwestern.edu/netlogo/

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: Re: val 1 = 2 compiles

On 8/26/11 12:30 AM, martin odersky wrote:
> You certainly do want to widen the types early, or the following would
> no longer compile:
>
> var x = 1 // don't infer a 1.type for the type of x!
> x += 1

Yes, but that doesn't preclude having 1 match { case 2 => } statically
fail. You have to widen the types of values which are mutable or which
can be overridden (at least if you want to be useful) but neither is
true of literals.

Stefan Wagner
Joined: 2011-04-08,
User offline. Last seen 42 years 45 weeks ago.
Re: val 1 = 2 compiles

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 23.08.2011 17:05, schrieb Aleksey Nikiforov:
> Surprisingly, the following compiles. However it does not produce a
> val `1` but generates strange bytecode.
>
> scala> object Foo { val 1 = 100 }

I guess it is related:

object Foo { val _ = 100 }

but I have no idea what to do with it.

Jim Powers
Joined: 2011-01-24,
User offline. Last seen 36 weeks 2 days ago.
Re: Re: Re: val 1 = 2 compiles
On Thu, Aug 25, 2011 at 5:50 AM, Tony Morris <tonymorris [at] gmail [dot] com> wrote:
It's also a phase that all haskell newbies come to, freak out, and some of us just kick back smoking a pipe and watch the fun begin.

let 1 = 2 in 7
7

Wouldn't the more surprising (and puff-worthy) case be:
let 1 = 2 in 11
;-)
--  Jim Powers
Jim Powers
Joined: 2011-01-24,
User offline. Last seen 36 weeks 2 days ago.
Re: Re: Re: val 1 = 2 compiles
On Fri, Aug 26, 2011 at 3:49 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
For non-binding value definitions, they can be used as a kind ofassertion, checking the shape of a value.  List(List(_)) = xssI'm not arguing this is the best style :)

Shouldn't the shape of something already be captured in its type?

--
Jim Powers
Seth Tisue
Joined: 2008-12-16,
User offline. Last seen 34 weeks 3 days ago.
Re: Re: Re: val 1 = 2 compiles

On Thu, Sep 1, 2011 at 11:47 AM, Jim Powers wrote:
> On Fri, Aug 26, 2011 at 3:49 AM, Lukas Rytz wrote:
>>
>> For non-binding value definitions, they can be used as a kind of
>> assertion, checking the shape of a value.
>>   List(List(_)) = xss
>> I'm not arguing this is the best style :)
>
> Shouldn't the shape of something already be captured in its type?

This "assertion" checks not only the type (List[List[T]]), but also
that the outer and the inner list each contain exactly one element.

Or maybe you realize that and you're making a more philosophical
point. I can't tell. If so, feel free to expand on it :-)

Jim Powers
Joined: 2011-01-24,
User offline. Last seen 36 weeks 2 days ago.
Re: Re: Re: val 1 = 2 compiles
On Tue, Sep 6, 2011 at 5:36 PM, Seth Tisue <seth [at] tisue [dot] net> wrote:
On Thu, Sep 1, 2011 at 11:47 AM, Jim Powers <jim [at] casapowers [dot] com> wrote:
> On Fri, Aug 26, 2011 at 3:49 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
>>
>> For non-binding value definitions, they can be used as a kind of
>> assertion, checking the shape of a value.
>>   List(List(_)) = xss
>> I'm not arguing this is the best style :)
>
> Shouldn't the shape of something already be captured in its type?

This "assertion" checks not only the type (List[List[T]]), but also
that the outer and the inner list each contain exactly one element.

Or maybe you realize that and you're making a more philosophical
point. I can't tell. If so, feel free to expand on it :-)

I would guess that the more philosophical point would be closer to the target.  It doesn't seem like a good way to test the condition of a list containing a list of one element.  The input type allows for a large space of nested lists and the code surrounding the example line ought to be correctly dealing with the variations in a clear manner (as Lukas points out: clearly this is not a "best style" ;-) ).  If such an example existed in an actual body of "production" code it would appear that the author would need education in the use of Option (more specifically Option[Option[T]]) as opposed to relying on the exception mechanism to direct program flow :-).
-- Jim Powers

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