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

2.8 nesting _ behaviour: bug or not?

15 replies
Alexey Romanov
Joined: 2010-06-04,
User offline. Last seen 42 years 45 weeks ago.

There is a significant change in the behaviour of _ in nested
functions which I don't understand.

Scala 2.7.7:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: ((Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: ((Boolean) => Unit)Unit

scala> foo(conv(i = _))

scala> i
res4: Int = 1

Scala 2.8.0RC3:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: (f: (Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: (g: (Boolean) => Unit)Unit

scala> foo(conv(i = _))
:9: error: type mismatch;
found : Boolean
required: Int
foo(conv(i = _))
^

scala> foo(conv(j => i = j))

scala> i
res3: Int = 1

foo(conv(println _)) works as expected:

scala> foo(conv(println _))
1

It doesn't seem like i = _ is being understood as assigning the
default value to i; I'd expect a different type mismatch message in
this case (found: Unit; required: Int => Unit).

Yours, Alexey Romanov

rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: 2.8 nesting _ behaviour: bug or not?
Hi Alexey,
there has been a change in semantics when we introduced named arguments.An expression
  foo(a = _)
used to be parsed as follows:   foo(x => a = x)
In 2.8, "a" is treated as a named argument, i.e. the expression is parsed as:  x => foo(a = x)
I will add a migration warning for this change. Could you please open a ticket reminding me of this?
Thanks: Lukas


On Mon, Jun 7, 2010 at 08:38, Alexey Romanov <alexey [dot] v [dot] romanov [at] gmail [dot] com> wrote:
There is a significant change in the behaviour of _ in nested
functions which I don't understand.

Scala 2.7.7:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: ((Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: ((Boolean) => Unit)Unit

scala> foo(conv(i = _))

scala> i
res4: Int = 1

Scala 2.8.0RC3:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: (f: (Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: (g: (Boolean) => Unit)Unit

scala> foo(conv(i = _))
<console>:9: error: type mismatch;
 found   : Boolean
 required: Int
      foo(conv(i = _))
                 ^

scala> foo(conv(j => i = j))

scala> i
res3: Int = 1

foo(conv(println _)) works as expected:

scala> foo(conv(println _))
1

It doesn't seem like i = _ is being understood as assigning the
default value to i; I'd expect a different type mismatch message in
this case (found: Unit; required: Int => Unit).

Yours, Alexey Romanov

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?
Was that change necessary?It doesn't seem to agree with the general rule that, if I'm not mistaken,x + (y + _)is interpreted asx + (z => y + z)since it's surrounded by parenthesis.

On Tue, Jun 8, 2010 at 9:03 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Hi Alexey,
there has been a change in semantics when we introduced named arguments.An expression
  foo(a = _)
used to be parsed as follows:   foo(x => a = x)
In 2.8, "a" is treated as a named argument, i.e. the expression is parsed as:  x => foo(a = x)
I will add a migration warning for this change. Could you please open a ticket reminding me of this?
Thanks: Lukas


On Mon, Jun 7, 2010 at 08:38, Alexey Romanov <alexey [dot] v [dot] romanov [at] gmail [dot] com> wrote:
There is a significant change in the behaviour of _ in nested
functions which I don't understand.

Scala 2.7.7:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: ((Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: ((Boolean) => Unit)Unit

scala> foo(conv(i = _))

scala> i
res4: Int = 1

Scala 2.8.0RC3:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: (f: (Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: (g: (Boolean) => Unit)Unit

scala> foo(conv(i = _))
<console>:9: error: type mismatch;
 found   : Boolean
 required: Int
      foo(conv(i = _))
                 ^

scala> foo(conv(j => i = j))

scala> i
res3: Int = 1

foo(conv(println _)) works as expected:

scala> foo(conv(println _))
1

It doesn't seem like i = _ is being understood as assigning the
default value to i; I'd expect a different type mismatch message in
this case (found: Unit; required: Int => Unit).

Yours, Alexey Romanov


rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: 2.8 nesting _ behaviour: bug or not?
the example you give parses as before, the change just affectsmethod calls with named arguments.
The change was not necessary, but it can be useful:
def f(x: Int = 0, y: Int = 1, z: Int = 2) val fun: Int => Int = f(z = _)
Lukas



On Thu, Jun 10, 2010 at 01:00, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Was that change necessary?It doesn't seem to agree with the general rule that, if I'm not mistaken, x + (y + _)is interpreted asx + (z => y + z)since it's surrounded by parenthesis.

On Tue, Jun 8, 2010 at 9:03 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Hi Alexey,
there has been a change in semantics when we introduced named arguments.An expression
  foo(a = _)
used to be parsed as follows:   foo(x => a = x)
In 2.8, "a" is treated as a named argument, i.e. the expression is parsed as:  x => foo(a = x)
I will add a migration warning for this change. Could you please open a ticket reminding me of this?
Thanks: Lukas


On Mon, Jun 7, 2010 at 08:38, Alexey Romanov <alexey [dot] v [dot] romanov [at] gmail [dot] com> wrote:
There is a significant change in the behaviour of _ in nested
functions which I don't understand.

Scala 2.7.7:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: ((Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: ((Boolean) => Unit)Unit

scala> foo(conv(i = _))

scala> i
res4: Int = 1

Scala 2.8.0RC3:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: (f: (Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: (g: (Boolean) => Unit)Unit

scala> foo(conv(i = _))
<console>:9: error: type mismatch;
 found   : Boolean
 required: Int
      foo(conv(i = _))
                 ^

scala> foo(conv(j => i = j))

scala> i
res3: Int = 1

foo(conv(println _)) works as expected:

scala> foo(conv(println _))
1

It doesn't seem like i = _ is being understood as assigning the
default value to i; I'd expect a different type mismatch message in
this case (found: Unit; required: Int => Unit).

Yours, Alexey Romanov



Alexey Romanov
Joined: 2010-06-04,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?

Shoudn't braces prevent parsing as named argument?

scala> foo(conv( {i = _} ))
:9: error: type mismatch;
found : Boolean
required: Int
foo(conv( {i = _} ))

However,

scala> foo(conv{i = _})

does work. Unfortunately, it won't help in my use case...

Yours, Alexey Romanov

On Thu, Jun 10, 2010 at 10:01 AM, Lukas Rytz wrote:
> the example you give parses as before, the change just affects
> method calls with named arguments.
> The change was not necessary, but it can be useful:
> def f(x: Int = 0, y: Int = 1, z: Int = 2)
> val fun: Int => Int = f(z = _)
> Lukas
>
>
>
> On Thu, Jun 10, 2010 at 01:00, Naftoli Gugenheim
> wrote:
>>
>> Was that change necessary?
>> It doesn't seem to agree with the general rule that, if I'm not mistaken,
>> x + (y + _)
>> is interpreted as
>> x + (z => y + z)
>> since it's surrounded by parenthesis.
>>
>> On Tue, Jun 8, 2010 at 9:03 AM, Lukas Rytz wrote:
>>>
>>> Hi Alexey,
>>> there has been a change in semantics when we introduced named arguments.
>>> An expression
>>>   foo(a = _)
>>> used to be parsed as follows:
>>>   foo(x => a = x)
>>> In 2.8, "a" is treated as a named argument, i.e. the expression is parsed
>>> as:
>>>   x => foo(a = x)
>>> I will add a migration warning for this change. Could you please open a
>>> ticket
>>> reminding me of this?
>>> Thanks: Lukas
>>>
>>>
>>> On Mon, Jun 7, 2010 at 08:38, Alexey Romanov
>>> wrote:
>>>>
>>>> There is a significant change in the behaviour of _ in nested
>>>> functions which I don't understand.
>>>>
>>>> Scala 2.7.7:
>>>>
>>>> scala> var i = 0
>>>> i: Int = 0
>>>>
>>>> scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
>>>> conv: ((Int) => Unit)(Boolean) => Unit
>>>>
>>>> scala> def foo(g: Boolean => Unit) { g(true) }
>>>> foo: ((Boolean) => Unit)Unit
>>>>
>>>> scala> foo(conv(i = _))
>>>>
>>>> scala> i
>>>> res4: Int = 1
>>>>
>>>> Scala 2.8.0RC3:
>>>>
>>>> scala> var i = 0
>>>> i: Int = 0
>>>>
>>>> scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
>>>> conv: (f: (Int) => Unit)(Boolean) => Unit
>>>>
>>>> scala> def foo(g: Boolean => Unit) { g(true) }
>>>> foo: (g: (Boolean) => Unit)Unit
>>>>
>>>> scala> foo(conv(i = _))
>>>> :9: error: type mismatch;
>>>>  found   : Boolean
>>>>  required: Int
>>>>       foo(conv(i = _))
>>>>                  ^
>>>>
>>>> scala> foo(conv(j => i = j))
>>>>
>>>> scala> i
>>>> res3: Int = 1
>>>>
>>>> foo(conv(println _)) works as expected:
>>>>
>>>> scala> foo(conv(println _))
>>>> 1
>>>>
>>>> It doesn't seem like i = _ is being understood as assigning the
>>>> default value to i; I'd expect a different type mismatch message in
>>>> this case (found: Unit; required: Int => Unit).
>>>>
>>>> Yours, Alexey Romanov
>>>
>>
>
>

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?
I know it parses. That's why I think this "useful" change is inconsistent with the general rule that the compile doesn't look outside parenthesis to create an anonymous function.This change breaks a very common idiom in Lift:
var textFieldValue = "default"SHtml.text(textFieldValue,  textFieldValue = _ )
I (and others) would really prefer that the above would continue to parse asSHtml.text(textFieldValue, x => textFieldValue = x) like it used to.



On Thu, Jun 10, 2010 at 2:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
the example you give parses as before, the change just affectsmethod calls with named arguments.
The change was not necessary, but it can be useful:
def f(x: Int = 0, y: Int = 1, z: Int = 2) val fun: Int => Int = f(z = _)
Lukas



On Thu, Jun 10, 2010 at 01:00, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Was that change necessary?It doesn't seem to agree with the general rule that, if I'm not mistaken, x + (y + _)is interpreted asx + (z => y + z)since it's surrounded by parenthesis.

On Tue, Jun 8, 2010 at 9:03 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Hi Alexey,
there has been a change in semantics when we introduced named arguments.An expression
  foo(a = _)
used to be parsed as follows:   foo(x => a = x)
In 2.8, "a" is treated as a named argument, i.e. the expression is parsed as:  x => foo(a = x)
I will add a migration warning for this change. Could you please open a ticket reminding me of this?
Thanks: Lukas


On Mon, Jun 7, 2010 at 08:38, Alexey Romanov <alexey [dot] v [dot] romanov [at] gmail [dot] com> wrote:
There is a significant change in the behaviour of _ in nested
functions which I don't understand.

Scala 2.7.7:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: ((Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: ((Boolean) => Unit)Unit

scala> foo(conv(i = _))

scala> i
res4: Int = 1

Scala 2.8.0RC3:

scala> var i = 0
i: Int = 0

scala> def conv(f: Int => Unit) = if (_:Boolean) f(1) else f(0)
conv: (f: (Int) => Unit)(Boolean) => Unit

scala> def foo(g: Boolean => Unit) { g(true) }
foo: (g: (Boolean) => Unit)Unit

scala> foo(conv(i = _))
<console>:9: error: type mismatch;
 found   : Boolean
 required: Int
      foo(conv(i = _))
                 ^

scala> foo(conv(j => i = j))

scala> i
res3: Int = 1

foo(conv(println _)) works as expected:

scala> foo(conv(println _))
1

It doesn't seem like i = _ is being understood as assigning the
default value to i; I'd expect a different type mismatch message in
this case (found: Unit; required: Int => Unit).

Yours, Alexey Romanov




odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: 2.8 nesting _ behaviour: bug or not?


On Tue, Jun 15, 2010 at 1:50 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I know it parses. That's why I think this "useful" change is inconsistent with the general rule that the compile doesn't look outside parenthesis to create an anonymous function.This change breaks a very common idiom in Lift:
var textFieldValue = "default"SHtml.text(textFieldValue,  textFieldValue = _ )
I (and others) would really prefer that the above would continue to parse asSHtml.text(textFieldValue, x => textFieldValue = x) like it used to.
Note, however, that the following works if textFieldValue is a field.

SHtml.text(textFieldValue, textFieldValue_= )

Is that enough to solve your problem, or do you also use setters for local variables in this way?

Cheers

 -- Martin

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?
The widespread Lift idiom usually involves local variables.The idea is that when you create a form you pass it function closures that handle the form. So a simple form (skipping template binding) could look like this (SHtml functions return scala.xml.NodeSeq's):
def myFormSnippet(templateXml: NodeSeq): NodeSeq = {
    var textFieldContents = ""
    SHtml.text(textFieldContents,  textFieldContents = _)     ++
      SHtml.submit("Save",  () => {          println("Saving value: " + textFieldContents)      } )}

This creates an <input type="text" /> Elem whose name attribute on the server is mapped to the function x => textFieldContents = x, and an <input type="submit" /> Elem whose name attribute is mapped to the println closure. When the form is submitted Lift goes through each query parameter and passes its value to the function it names, if any.
Thus, {x => /* local var */ y = x} functions are very commonplace, and it would be nice to keep the old shorthand. Why break code when there's no need to?



On Tue, Jun 15, 2010 at 5:51 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Tue, Jun 15, 2010 at 1:50 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I know it parses. That's why I think this "useful" change is inconsistent with the general rule that the compile doesn't look outside parenthesis to create an anonymous function.This change breaks a very common idiom in Lift:
var textFieldValue = "default"SHtml.text(textFieldValue,  textFieldValue = _ )
I (and others) would really prefer that the above would continue to parse asSHtml.text(textFieldValue, x => textFieldValue = x) like it used to.
Note, however, that the following works if textFieldValue is a field.

SHtml.text(textFieldValue, textFieldValue_= )

Is that enough to solve your problem, or do you also use setters for local variables in this way?

Cheers

 -- Martin


Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?
Note that fields are not always an option because the same class instance and method can be used to create two forms with separate state.

On Tue, Jun 15, 2010 at 5:49 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
The widespread Lift idiom usually involves local variables.The idea is that when you create a form you pass it function closures that handle the form. So a simple form (skipping template binding) could look like this (SHtml functions return scala.xml.NodeSeq's):
def myFormSnippet(templateXml: NodeSeq): NodeSeq = {
    var textFieldContents = ""
    SHtml.text(textFieldContents,  textFieldContents = _)     ++
      SHtml.submit("Save",  () => {          println("Saving value: " + textFieldContents)      } )}

This creates an <input type="text" /> Elem whose name attribute on the server is mapped to the function x => textFieldContents = x, and an <input type="submit" /> Elem whose name attribute is mapped to the println closure. When the form is submitted Lift goes through each query parameter and passes its value to the function it names, if any.
Thus, {x => /* local var */ y = x} functions are very commonplace, and it would be nice to keep the old shorthand. Why break code when there's no need to?



On Tue, Jun 15, 2010 at 5:51 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Tue, Jun 15, 2010 at 1:50 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I know it parses. That's why I think this "useful" change is inconsistent with the general rule that the compile doesn't look outside parenthesis to create an anonymous function.This change breaks a very common idiom in Lift:
var textFieldValue = "default"SHtml.text(textFieldValue,  textFieldValue = _ )
I (and others) would really prefer that the above would continue to parse asSHtml.text(textFieldValue, x => textFieldValue = x) like it used to.
Note, however, that the following works if textFieldValue is a field.

SHtml.text(textFieldValue, textFieldValue_= )

Is that enough to solve your problem, or do you also use setters for local variables in this way?

Cheers

 -- Martin



rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: 2.8 nesting _ behaviour: bug or not?
Hi Naftoli,
the syntax was reverted to the previous behavior in 2.8.0.RC6.Defining a function
    x => f(a = x)
has to be written out now; f(a = _) is parsed as f(x => a = x) again.
Lukas

On Tue, Jun 15, 2010 at 23:49, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
The widespread Lift idiom usually involves local variables.The idea is that when you create a form you pass it function closures that handle the form. So a simple form (skipping template binding) could look like this (SHtml functions return scala.xml.NodeSeq's):
def myFormSnippet(templateXml: NodeSeq): NodeSeq = {
    var textFieldContents = ""
    SHtml.text(textFieldContents,  textFieldContents = _)     ++
      SHtml.submit("Save",  () => {          println("Saving value: " + textFieldContents)      } )}

This creates an <input type="text" /> Elem whose name attribute on the server is mapped to the function x => textFieldContents = x, and an <input type="submit" /> Elem whose name attribute is mapped to the println closure. When the form is submitted Lift goes through each query parameter and passes its value to the function it names, if any.
Thus, {x => /* local var */ y = x} functions are very commonplace, and it would be nice to keep the old shorthand. Why break code when there's no need to?



On Tue, Jun 15, 2010 at 5:51 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Tue, Jun 15, 2010 at 1:50 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I know it parses. That's why I think this "useful" change is inconsistent with the general rule that the compile doesn't look outside parenthesis to create an anonymous function.This change breaks a very common idiom in Lift:
var textFieldValue = "default"SHtml.text(textFieldValue,  textFieldValue = _ )
I (and others) would really prefer that the above would continue to parse asSHtml.text(textFieldValue, x => textFieldValue = x) like it used to.
Note, however, that the following works if textFieldValue is a field.

SHtml.text(textFieldValue, textFieldValue_= )

Is that enough to solve your problem, or do you also use setters for local variables in this way?

Cheers

 -- Martin



David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?


On Fri, Jun 18, 2010 at 7:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Hi Naftoli,
the syntax was reverted to the previous behavior in 2.8.0.RC6.Defining a function
    x => f(a = x)
has to be written out now; f(a = _) is parsed as f(x => a = x) again.

Wow!  Thanks!

I noticed that from the very first Lift -> 2.8 ports, but I didn't ask for it... but am super-happy that the Scala team made the change... who do I send the beer to?
 

Lukas

On Tue, Jun 15, 2010 at 23:49, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
The widespread Lift idiom usually involves local variables.The idea is that when you create a form you pass it function closures that handle the form. So a simple form (skipping template binding) could look like this (SHtml functions return scala.xml.NodeSeq's):
def myFormSnippet(templateXml: NodeSeq): NodeSeq = {
    var textFieldContents = ""
    SHtml.text(textFieldContents,  textFieldContents = _)     ++
      SHtml.submit("Save",  () => {          println("Saving value: " + textFieldContents)      } )}

This creates an <input type="text" /> Elem whose name attribute on the server is mapped to the function x => textFieldContents = x, and an <input type="submit" /> Elem whose name attribute is mapped to the println closure. When the form is submitted Lift goes through each query parameter and passes its value to the function it names, if any.
Thus, {x => /* local var */ y = x} functions are very commonplace, and it would be nice to keep the old shorthand. Why break code when there's no need to?



On Tue, Jun 15, 2010 at 5:51 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Tue, Jun 15, 2010 at 1:50 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I know it parses. That's why I think this "useful" change is inconsistent with the general rule that the compile doesn't look outside parenthesis to create an anonymous function.This change breaks a very common idiom in Lift:
var textFieldValue = "default"SHtml.text(textFieldValue,  textFieldValue = _ )
I (and others) would really prefer that the above would continue to parse asSHtml.text(textFieldValue, x => textFieldValue = x) like it used to.
Note, however, that the following works if textFieldValue is a field.

SHtml.text(textFieldValue, textFieldValue_= )

Is that enough to solve your problem, or do you also use setters for local variables in this way?

Cheers

 -- Martin






--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics
Antonio Cunei
Joined: 2008-12-16,
User offline. Last seen 3 years 22 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?

David Pollak wrote:
> Wow! Thanks!
>
> I noticed that from the very first Lift -> 2.8 ports, but I didn't ask for
> it... but am super-happy that the Scala team made the change... who do I
> send the beer to?
>

http://search.epfl.ch/directory.do?sciper=154104

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?


On Fri, Jun 18, 2010 at 7:14 AM, Antonio Cunei <antonio [dot] cunei [at] epfl [dot] ch> wrote:
David Pollak wrote:
Wow!  Thanks!

I noticed that from the very first Lift -> 2.8 ports, but I didn't ask for
it... but am super-happy that the Scala team made the change... who do I
send the beer to?


http://search.epfl.ch/directory.do?sciper=154104


Done.  Beer via PayPal.


--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics
David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?


On Fri, Jun 18, 2010 at 7:32 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
wow, that's cool! i had already trashed the confirmation e-mail forthat beer transfer because i thought it was some spam, but i couldrecover it :) 

e-Dumpster Diving ? http://en.wikipedia.org/wiki/Dumpster_diving
 

thanks!

On Fri, Jun 18, 2010 at 16:19, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:


On Fri, Jun 18, 2010 at 7:14 AM, Antonio Cunei <antonio [dot] cunei [at] epfl [dot] ch> wrote:
David Pollak wrote:
Wow!  Thanks!

I noticed that from the very first Lift -> 2.8 ports, but I didn't ask for
it... but am super-happy that the Scala team made the change... who do I
send the beer to?


http://search.epfl.ch/directory.do?sciper=154104


Done.  Beer via PayPal.


--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics




--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics
rytz
Joined: 2008-07-01,
User offline. Last seen 45 weeks 5 days ago.
Re: 2.8 nesting _ behaviour: bug or not?
wow, that's cool! i had already trashed the confirmation e-mail forthat beer transfer because i thought it was some spam, but i couldrecover it :) 
thanks!

On Fri, Jun 18, 2010 at 16:19, David Pollak <feeder [dot] of [dot] the [dot] bears [at] gmail [dot] com> wrote:


On Fri, Jun 18, 2010 at 7:14 AM, Antonio Cunei <antonio [dot] cunei [at] epfl [dot] ch> wrote:
David Pollak wrote:
Wow!  Thanks!

I noticed that from the very first Lift -> 2.8 ports, but I didn't ask for
it... but am super-happy that the Scala team made the change... who do I
send the beer to?


http://search.epfl.ch/directory.do?sciper=154104


Done.  Beer via PayPal.


--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: 2.8 nesting _ behaviour: bug or not?
Thanks tons!

On Fri, Jun 18, 2010 at 10:01 AM, Lukas Rytz <lukas [dot] rytz [at] epfl [dot] ch> wrote:
Hi Naftoli,
the syntax was reverted to the previous behavior in 2.8.0.RC6.Defining a function
    x => f(a = x)
has to be written out now; f(a = _) is parsed as f(x => a = x) again.
Lukas

On Tue, Jun 15, 2010 at 23:49, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
The widespread Lift idiom usually involves local variables.The idea is that when you create a form you pass it function closures that handle the form. So a simple form (skipping template binding) could look like this (SHtml functions return scala.xml.NodeSeq's):
def myFormSnippet(templateXml: NodeSeq): NodeSeq = {
    var textFieldContents = ""
    SHtml.text(textFieldContents,  textFieldContents = _)     ++
      SHtml.submit("Save",  () => {          println("Saving value: " + textFieldContents)      } )}

This creates an <input type="text" /> Elem whose name attribute on the server is mapped to the function x => textFieldContents = x, and an <input type="submit" /> Elem whose name attribute is mapped to the println closure. When the form is submitted Lift goes through each query parameter and passes its value to the function it names, if any.
Thus, {x => /* local var */ y = x} functions are very commonplace, and it would be nice to keep the old shorthand. Why break code when there's no need to?



On Tue, Jun 15, 2010 at 5:51 AM, martin odersky <martin [dot] odersky [at] epfl [dot] ch> wrote:


On Tue, Jun 15, 2010 at 1:50 AM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I know it parses. That's why I think this "useful" change is inconsistent with the general rule that the compile doesn't look outside parenthesis to create an anonymous function.This change breaks a very common idiom in Lift:
var textFieldValue = "default"SHtml.text(textFieldValue,  textFieldValue = _ )
I (and others) would really prefer that the above would continue to parse asSHtml.text(textFieldValue, x => textFieldValue = x) like it used to.
Note, however, that the following works if textFieldValue is a field.

SHtml.text(textFieldValue, textFieldValue_= )

Is that enough to solve your problem, or do you also use setters for local variables in this way?

Cheers

 -- Martin




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