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,
--
Francois ARMAND
http://fanf42.blogspot.com
http://www.normation.com
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-----
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,
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
It's also a phase that all haskell newbies come to, freak out, and some
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
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-----
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
<pattern> = <expression> 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) = <expr> would work to match a tuple (ie. unchanging syntax of the most
common case), and one would have to write val (List(_, t, _*)) = <expr> to make it work.
But it looks a bit inconsistent with regard to tuples...
And given Martin's answer, I doubt this will change...
--
Philippe Lhoste
-- (near) Paris -- France
-- http://Phi.Lho.free.fr
-- -- -- -- -- -- -- -- -- -- -- -- -- --
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
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.
--
Daniel C. Sobral
I travel to the future all the time.
+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?
Thanks,
Razvan
Thanks,
Razvan
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.
May I suggest something more expressive for that?
assertMatch(xss, { case List(List(_)) => })
You certainly have a point here. I agree that such a function (maybe on
`Predef`) incurs a significant amount of noise. But as already written
somewhere in the thread, the `val` syntax does not allow `|`. Also, a
`MatchError` is misleading for an assertion -- just because an assertion
happens to be a match does not mean we should not use an
`AssertionError` or something along those lines.
Or:
val x @ List(List(_)) = xss
Well, sorry for derailing the discussion, but I'd like to argue that
this is actually quite similar to `Predef.assert` with the minor
difference that the usual assertion methods take a `Boolean`. I see no
reason why stating that "this value should match that pattern" is not a
valid use case for assertions.
Of course, one might still say that
value match {
case pattern => doStuff
case _ => sys.error("match failed!")
}
is sufficiently concise, so I'll leave this for discussion here.
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/
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 :(
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.
It's also a phase that all haskell newbies come to, freak out, and someof us just kick back smoking a pipe and watch the fun begin.
let 1 = 2 in 7
7
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 :)
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 :-)
This "assertion" checks not only the type (List[List[T]]), but alsoOn Thu, Sep 1, 2011 at 11:47 AM, Jim Powers <j...@casapowers.com> wrote:
> On Fri, Aug 26, 2011 at 3:49 AM, Lukas Rytz <lukas...@epfl.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?
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 :-)