Partially applied function error - OK in foldLeft

View: New views
7 Messages — Rating Filter:   Alert me  

Partially applied function error - OK in foldLeft

by Jeremy Mawson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi. I'm not clear on why these two scenarios are different. Can someone explain why the foldLeft code works, but the map(i)=z operation fails?


scala> def z(s: String) = s
z: (String)String

scala> val seed = Map.empty[Int, (String)=>String]    
seed: scala.collection.immutable.Map[Int,(String) => String] = Map()

scala> List(1,2,3).foldLeft(seed) {(acc, next) => acc(next) = z}                            
res23: scala.collection.immutable.Map[Int,(String) => String] = Map(1 -> <function>, 2 -> <function>, 3 -> <function>)


scala> seed(1) = z
<console>:7: error: missing arguments for method z in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
       seed(1) = z
                 ^


I know z _ will work, as per the message, but I don't understand how the latter operation differs from the foldLeft scenario. In both cases I invoke map(int)=<function>. What is the difference?

Thanks
Jeremy

Parent Message unknown Re: Partially applied function error - OK in foldLeft

by Mario Camou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Jem,

seed(1)=z means "call function z and assign the return value". The principle of uniform access means that Scala doesn't require parentheses on method calls with no arguments. To get around this you use the underscore to indicate you want to rederence the function object itself.

Hope this helps,
-Mario.

- Sent from my Android G1

On Jul 7, 2009 9:31 AM, "Jem" <jem.mawson@...> wrote:

Hi. I'm not clear on why these two scenarios are different. Can someone explain why the foldLeft code works, but the map(i)=z operation fails?


scala> def z(s: String) = s
z: (String)String

scala> val seed = Map.empty[Int, (String)=>String]    
seed: scala.collection.immutable.Map[Int,(String) => String] = Map()

scala> List(1,2,3).foldLeft(seed) {(acc, next) => acc(next) = z}                            
res23: scala.collection.immutable.Map[Int,(String) => String] = Map(1 -> <function>, 2 -> <function>, 3 -> <function>)


scala> seed(1) = z
<console>:7: error: missing arguments for method z in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
       seed(1) = z
                 ^


I know z _ will work, as per the message, but I don't understand how the latter operation differs from the foldLeft scenario. In both cases I invoke map(int)=<function>. What is the difference?

Thanks
Jeremy


Parent Message unknown Re: Partially applied function error - OK in foldLeft

by Jeremy Mawson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

So how is acc(next) = z  different to seed(1) = z ?

The only difference is that one is within the block parameter of List.foldLeft and the other is stand-alone.

In my observation what triggers treatment as call-by-name is the typing of the method or container that is receiving the reference. 

The snippet seed(1) = z is assigning z: String=>String as a value in a map that takes values of type String=>String. There's no ambiguity as far as I can tell.




2009/7/7 Jem <jem.mawson@...>
Thanks Mario,

So how is acc(next) = z  different to seed(1) = z ?

The only difference is that one is within the block parameter of List.foldLeft and the other is stand-alone.




2009/7/7 Mario Camou <mcamou@...>

Hi Jem,

seed(1)=z means "call function z and assign the return value". The principle of uniform access means that Scala doesn't require parentheses on method calls with no arguments. To get around this you use the underscore to indicate you want to rederence the function object itself.

Hope this helps,
-Mario.

- Sent from my Android G1

On Jul 7, 2009 9:31 AM, "Jem" <jem.mawson@...> wrote:

Hi. I'm not clear on why these two scenarios are different. Can someone explain why the foldLeft code works, but the map(i)=z operation fails?


scala> def z(s: String) = s
z: (String)String

scala> val seed = Map.empty[Int, (String)=>String]    
seed: scala.collection.immutable.Map[Int,(String) => String] = Map()

scala> List(1,2,3).foldLeft(seed) {(acc, next) => acc(next) = z}                            
res23: scala.collection.immutable.Map[Int,(String) => String] = Map(1 -> <function>, 2 -> <function>, 3 -> <function>)


scala> seed(1) = z
<console>:7: error: missing arguments for method z in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
       seed(1) = z
                 ^


I know z _ will work, as per the message, but I don't understand how the latter operation differs from the foldLeft scenario. In both cases I invoke map(int)=<function>. What is the difference?

Thanks
Jeremy




Re: Partially applied function error - OK in foldLeft

by Johannes Rudolph-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

While that is no real reason, just the difference: The use in foldLeft
expects a return type of Map[Int,String => String], while the  second
use doesn't expect any (specific) return type. I would guess the first
use helps the type inferer to guess what you meant to say. Still, the
syntax Scala requires in the second case is the general one: 'seed(1)
= z _', i.e. treat the method z as (unapplied) function object.

On Tue, Jul 7, 2009 at 12:39 PM, Jem<jem.mawson@...> wrote:

> So how is acc(next) = z  different to seed(1) = z ?
> The only difference
> is that one is within the block parameter of List.foldLeft and the other is
> stand-alone.
> In my observation what triggers treatment as call-by-name is the typing of
> the method or container that is receiving the reference.
> The snippet seed(1) = z is assigning z: String=>String as a value in a map
> that takes values of type String=>String. There's no ambiguity as far as I
> can tell.
>
>
>
> 2009/7/7 Jem <jem.mawson@...>
>>
>> Thanks Mario,
>> So how is acc(next) = z  different to seed(1) = z ?
>> The only difference
>> is that one is within the block parameter of List.foldLeft and the other is
>> stand-alone.
>>
>>
>>
>> 2009/7/7 Mario Camou <mcamou@...>
>>>
>>> Hi Jem,
>>>
>>> seed(1)=z means "call function z and assign the return value". The
>>> principle of uniform access means that Scala doesn't require parentheses on
>>> method calls with no arguments. To get around this you use the underscore to
>>> indicate you want to rederence the function object itself.
>>>
>>> Hope this helps,
>>> -Mario.
>>>
>>> - Sent from my Android G1
>>>
>>> On Jul 7, 2009 9:31 AM, "Jem" <jem.mawson@...> wrote:
>>>
>>> Hi. I'm not clear on why these two scenarios are different. Can someone
>>> explain why the foldLeft code works, but the map(i)=z operation fails?
>>>
>>> scala> def z(s: String) = s
>>> z: (String)String
>>> scala> val seed = Map.empty[Int, (String)=>String]
>>> seed: scala.collection.immutable.Map[Int,(String) => String] = Map()
>>> scala> List(1,2,3).foldLeft(seed) {(acc, next) => acc(next) = z}
>>>
>>> res23: scala.collection.immutable.Map[Int,(String) => String] = Map(1 ->
>>> <function>, 2 -> <function>, 3 -> <function>)
>>>
>>> scala> seed(1) = z
>>> <console>:7: error: missing arguments for method z in object $iw;
>>> follow this method with `_' if you want to treat it as a partially
>>> applied function
>>>        seed(1) = z
>>>                  ^
>>>
>>> I know z _ will work, as per the message, but I don't understand how the
>>> latter operation differs from the foldLeft scenario. In both cases I invoke
>>> map(int)=<function>. What is the difference?
>>> Thanks
>>> Jeremy
>
>



--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Re: Partially applied function error - OK in foldLeft

by Jeremy Mawson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks Johannes.

Surely both cases are typed. seed is a typed map: 

> val seed = Map.empty[Int, (String)=>String]

To require a trailing underscore on the function reference in this case still seems odd.




2009/7/7 Johannes Rudolph <johannes.rudolph@...>
While that is no real reason, just the difference: The use in foldLeft
expects a return type of Map[Int,String => String], while the  second
use doesn't expect any (specific) return type. I would guess the first
use helps the type inferer to guess what you meant to say. Still, the
syntax Scala requires in the second case is the general one: 'seed(1)
= z _', i.e. treat the method z as (unapplied) function object.

On Tue, Jul 7, 2009 at 12:39 PM, Jem<jem.mawson@...> wrote:
> So how is acc(next) = z  different to seed(1) = z ?
> The only difference
> is that one is within the block parameter of List.foldLeft and the other is
> stand-alone.
> In my observation what triggers treatment as call-by-name is the typing of
> the method or container that is receiving the reference.
> The snippet seed(1) = z is assigning z: String=>String as a value in a map
> that takes values of type String=>String. There's no ambiguity as far as I
> can tell.
>
>
>
> 2009/7/7 Jem <jem.mawson@...>
>>
>> Thanks Mario,
>> So how is acc(next) = z  different to seed(1) = z ?
>> The only difference
>> is that one is within the block parameter of List.foldLeft and the other is
>> stand-alone.
>>
>>
>>
>> 2009/7/7 Mario Camou <mcamou@...>
>>>
>>> Hi Jem,
>>>
>>> seed(1)=z means "call function z and assign the return value". The
>>> principle of uniform access means that Scala doesn't require parentheses on
>>> method calls with no arguments. To get around this you use the underscore to
>>> indicate you want to rederence the function object itself.
>>>
>>> Hope this helps,
>>> -Mario.
>>>
>>> - Sent from my Android G1
>>>
>>> On Jul 7, 2009 9:31 AM, "Jem" <jem.mawson@...> wrote:
>>>
>>> Hi. I'm not clear on why these two scenarios are different. Can someone
>>> explain why the foldLeft code works, but the map(i)=z operation fails?
>>>
>>> scala> def z(s: String) = s
>>> z: (String)String
>>> scala> val seed = Map.empty[Int, (String)=>String]
>>> seed: scala.collection.immutable.Map[Int,(String) => String] = Map()
>>> scala> List(1,2,3).foldLeft(seed) {(acc, next) => acc(next) = z}
>>>
>>> res23: scala.collection.immutable.Map[Int,(String) => String] = Map(1 ->
>>> <function>, 2 -> <function>, 3 -> <function>)
>>>
>>> scala> seed(1) = z
>>> <console>:7: error: missing arguments for method z in object $iw;
>>> follow this method with `_' if you want to treat it as a partially
>>> applied function
>>>        seed(1) = z
>>>                  ^
>>>
>>> I know z _ will work, as per the message, but I don't understand how the
>>> latter operation differs from the foldLeft scenario. In both cases I invoke
>>> map(int)=<function>. What is the difference?
>>> Thanks
>>> Jeremy
>
>



--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net


Re: Partially applied function error - OK in foldLeft

by Johannes Rudolph-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Jul 7, 2009 at 2:37 PM, Jem<jem.mawson@...> wrote:
> Thanks Johannes.
> Surely both cases are typed. seed is a typed map:
>> val seed = Map.empty[Int, (String)=>String]
Right, but there is no expected return type in the second case. To
make it work you can change the second case to

scala> (seed(1) = z):Map[Int,String=>String]
res2: Map[Int,(String) => String] = Map(1 -> <function>)

which, of course, is ridicously verbose but shows the difference the
context can make. This is still only an observation not an
explanation.

Trying an explanation:
seed(1) = z is syntactic sugar for seed.update(1,z). And Map.update is
defined as

def update  [B1 >: B](key : A, value : B1) : Map[A, B1]

So the type of the value may change the type of the result. This may
explain the dependence on the presence of a fixed return type. Perhaps
the syntax without the underscore is only valid, if the type can be
fully infered?!?

--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Parent Message unknown Re: Partially applied function error - OK in foldLeft

by Naftoli Gugenheim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

But z is for value: B1, and B1 in this case is an unapplied function from String to String.


-------------------------------------
Johannes Rudolph<johannes.rudolph@...> wrote:

On Tue, Jul 7, 2009 at 2:37 PM, Jem<jem.mawson@...> wrote:
> Thanks Johannes.
> Surely both cases are typed. seed is a typed map:
>> val seed = Map.empty[Int, (String)=>String]
Right, but there is no expected return type in the second case. To
make it work you can change the second case to

scala> (seed(1) = z):Map[Int,String=>String]
res2: Map[Int,(String) => String] = Map(1 -> <function>)

which, of course, is ridicously verbose but shows the difference the
context can make. This is still only an observation not an
explanation.

Trying an explanation:
seed(1) = z is syntactic sugar for seed.update(1,z). And Map.update is
defined as

def update  [B1 >: B](key : A, value : B1) : Map[A, B1]

So the type of the value may change the type of the result. This may
explain the dependence on the presence of a fixed return type. Perhaps
the syntax without the underscore is only valid, if the type can be
fully infered?!?

--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net