val 1 = 2 compiles

Showing 1-31 of 31 messages
val 1 = 2 compiles Aleksey Nikiforov 8/23/11 8:05 AM
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 }
<console>:1: error: identifier expected but integer literal found.
       object Foo { def 1 = 100 }
                        ^

Is this a bug or am I missing something?

Re: [scala-user] val 1 = 2 compiles Seth Tisue 8/23/11 8:22 AM
On Tue, Aug 23, 2011 at 11:05 AM, Aleksey Nikiforov <lex...@gmail.com> 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/

Re: [scala-user] val 1 = 2 compiles Daniel Sobral 8/23/11 8:27 AM
Just tell me what's the ticket, so I can add it to my favorites. :-)

--
Daniel C. Sobral

I travel to the future all the time.

Re: [scala-user] val 1 = 2 compiles Aleksey Nikiforov 8/23/11 8:47 AM
Filed the ticket: https://issues.scala-lang.org/browse/SI-4939
Re: val 1 = 2 compiles Lars Hupel 8/23/11 10:53 AM
> 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.

Re: [scala-user] Re: val 1 = 2 compiles Aleksey Nikiforov 8/23/11 10:59 AM
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.
Re: val 1 = 2 compiles Lars Hupel 8/23/11 11:06 AM
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.

Re: [scala-user] Re: val 1 = 2 compiles HamsterofDeath 8/23/11 11:11 AM
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:

Re: val 1 = 2 compiles Lars Hupel 8/23/11 11:17 AM
> 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).

Re: [scala-user] Re: val 1 = 2 compiles Kevin Wright 8/23/11 11:31 AM
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....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: 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

Re: val 1 = 2 compiles Lars Hupel 8/23/11 11:32 AM
> 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?

Maybe with

val `G` = 1

which would be quite inconvenient I guess.

Re: [scala-user] Re: val 1 = 2 compiles Seth Tisue 8/23/11 11:37 AM
>> 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.

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

RE: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/23/11 11:46 AM
scala> object x { val 1=2 }
defined module x

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

scala> x.a


scala.MatchError: 2 (of class java.lang.Integer)
        at x$.<init>(<console>:7)
        at x$.<clinit>(<console>)
        at .<init>(<console>:9)
        at .<clinit>(<console>)
        at .<init>(<console>:11)
        at .<clinit>(<console>)
        at $export(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39
)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl
.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at
scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:592)
        at
scala.tools.nsc.interpreter.IMain$Request$$anonfun$10.apply(IMain.scala:828)
        at
scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
        at scala.tools.nsc.io.package$$anon$2.run(package.scala:31)
        at java.lang.Thread.run(Thread.java:662)

Re: val 1 = 2 compiles Lars Hupel 8/23/11 11:48 AM
> 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
<console>: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.

RE: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/23/11 11:52 AM
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...@googlegroups.com [mailto:scala...@googlegroups.com] On

Re: val 1 = 2 compiles Lars Hupel 8/23/11 11:50 AM
> scala> object x { val 1=2 }
> defined module x
>
> scala> object x { val a@1=2 }
> defined module x
>
> scala> x.a
> scala.MatchError: 2 (of class java.lang.Integer)
>         at x$.<init>(<console>:7)
>         at x$.<clinit>(<console>)
>         at .<init>(<console>:9)
>         at .<clinit>(<console>)
>         at .<init>(<console>:11)
> [snip]

So? The only difference between those two statements is that in the
second one, the name `a` is bound to `1`, which can be eliminated as no
one accesses `a`.

Re: val 1 = 2 compiles Lars Hupel 8/23/11 11:58 AM
> 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.

I'm not sure whether I'm following. In *this* example, it fails on the
first access because *objects* are lazy.

Seth's first example without {} produces a compile error in the REPL
(not expected).

Seth's second example with {} produces an immediate MatchError as you
correctly said (as I expected).

Typing `val a@1 = 2` directly in the REPL throws a MatchError (also as
expected).

RE: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/23/11 12:28 PM
What do you mean?

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

scala> x.`1`
<console>:9: error: value 1 is not a member of object x
       x.`1`
         ^

scala>

ALSO

scala> object y { val a@b=2 }
defined module y

scala> y.a
res1: Int = 2

scala> y.b
res2: Int = 2

scala>

------

It's not that simple :)
... using 1 was just a coincidence - it's not interpreted as a label...

scala> val 5=6


<console>:8: error: value x$1 is not a member of object $iw
  `x$1`
                        ^

scala>
-----

ABOUT lazy objects - indeed, mea culpa!

----


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

Re: val 1 = 2 compiles Lars Hupel 8/23/11 12:34 PM
> scala> object x { val a@1=2 }
> defined module x
>
> scala> x.`1`
> <console>:9: error: value 1 is not a member of object x
>        x.`1`

Let me proceed by analogy:

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

compiles whereas

2 match {
        case a@1 => println(`1`)
}

doesn't.

> scala> object y { val a@b=2 }
> defined module y
>
> scala> y.a
> res1: Int = 2
>
> scala> y.b
> res2: Int = 2

2 match {
        case a@b => println(a); println(b)
}

also compiles fine.

`foo@bar` binds the value matched against `bar` to the identifier `foo`.

> It's not that simple :)
> .... using 1 was just a coincidence - it's not interpreted as a label...

>
> scala> val 5=6
> <console>:8: error: value x$1 is not a member of object $iw
>   `x$1`

No idea about that one.

Re: [scala-user] Re: val 1 = 2 compiles nafg 8/23/11 4:23 PM


On Tue, Aug 23, 2011 at 3:28 PM, Razvan Cojocaru <p...@razie.com> wrote:
What do you mean?

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

scala> x.`1`
<console>:9: error: value 1 is not a member of object x
      x.`1`
        ^


Because it doesn't compile, x is never initialized.

This illustrates it:


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

scala> x                    
scala.MatchError: 2
        at x$.<init>(<console>:5)
        at x$.<clinit>(<console>)
        at .<init>(<console>:7)
        at .<clinit>(<console>)
        at RequestResult$.<init>(<console>:9)
        at RequestResult$.<clinit>(<console>)
        at RequestResult$scala_repl_result(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)
        at scala.tools.nsc.Interpreter$Request$$anonfun$loadAndRun$1$$anonfun$apply$17.apply(Interpreter.scala:988)
        at scala.util.control.Exception$Catch.ap...
scala> 

So all you need to do to get the MatchError is initialize x.

Re: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/23/11 8:31 PM
Diaconnect here... that's not what I meant :). The compiler correctly figures out that 1 is a constant and does not try to make it a label, that's what I meant. 

Also - in fact it is compiled, just never executed. The compiler would have known about x.1 if 1 became a label, that's what a@b was showing. 

Thanks,
Razvan
Re: [scala-user] Re: val 1 = 2 compiles Daniel Sobral 8/24/11 7:01 AM
On Tue, Aug 23, 2011 at 15:37, Seth Tisue <se...@tisue.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.

RE: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/24/11 7:12 AM
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...@googlegroups.com [mailto:scala...@googlegroups.com] On

Re: [scala-user] Re: val 1 = 2 compiles Daniel Sobral 8/24/11 7:25 AM
On Wed, Aug 24, 2011 at 11:12, Razvan Cojocaru <p...@razie.com> wrote:
> Why do you think val x=2 is different than case x?

scala> 2 match { X => true }
<console>: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 .<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?

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)
<console>: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.

--
Daniel C. Sobral

I travel to the future all the time.

Re: [scala-user] Re: val 1 = 2 compiles Daniel Sobral 8/24/11 7:28 AM
On Wed, Aug 24, 2011 at 11:12, Razvan Cojocaru <p...@razie.com> wrote:
> Why do you think val x=2 is different than case x?

Oops, posted incorrect code. Again:

scala> 2 match { case X => true }
<console>: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 }
<console>:8: error: not found: value an example
              2 match { case `an example` => true }
                             ^

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

RE: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/24/11 7:45 AM
WTF?

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

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

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

scala>

-----Original Message-----
From: Razvan Cojocaru [mailto:p...@razie.com]
Sent: August-24-11 10:12 AM
To: 'Daniel Sobral'; 'Seth Tisue'
Cc: scala...@googlegroups.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 .<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...@googlegroups.com [mailto:scala...@googlegroups.com] On
Behalf Of Daniel Sobral
Sent: August-24-11 10:02 AM
To: Seth Tisue
Cc: scala...@googlegroups.com
Subject: Re: [scala-user] Re: val 1 = 2 compiles

On Tue, Aug 23, 2011 at 15:37, Seth Tisue <se...@tisue.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.


Re: [scala-user] Re: val 1 = 2 compiles Vlad Patryshev 8/24/11 7:47 AM
Wow...

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

Thanks,
-Vlad
RE: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/24/11 7:54 AM
More WTF

scala> 2 match { case `razvan` => true }
<console>: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:p...@razie.com]

Re: [scala-user] Re: val 1 = 2 compiles Jason Zaugg 8/24/11 8:25 AM

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

Re: [scala-user] Re: val 1 = 2 compiles Razvan (Pub) Cojocaru 8/24/11 8:28 AM
So... That's what's wrong with the parser then!

;)

Thanks,
Razvan

Re: [scala-user] val 1 = 2 compiles Stefan Wagner 8/27/11 8:28 AM
-----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.

- --

Tsch���--->...Stefan
- ---------------------------
Don't visit my homepage at:
http://home.arcor-online.net/hirnstrom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5ZDQEACgkQQeATqGpDnRoJJACfeostKnegxI1rRD6cOmN7ZLLr
LaAAmwWCfLsPBzZbAt3eb6s3JesX1pWa
=SjJJ
-----END PGP SIGNATURE-----

More topics »