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

_ vs. Any

6 replies
manojo
Joined: 2008-12-22,
User offline. Last seen 3 years 3 weeks ago.
Hello,

I am trying to populate a list of Function1s of any type to any type. I know that the return type of the first function is the input type of the second, etc. etc. Once the list is populated, I want to create an actor out of each function, in which each Actor computes the local value (for the sake of the example.) Here is the code :


val functionSet : ListBuffer[Function1[_,_]] = new ListBuffer
 
  functionSet += ((a : Int) => 2 * a)
  functionSet += ((a : Int) => a * a == 16)
  functionSet += ((a : Boolean) => if(a) "Hello" else "Bye")

 case object Done
   
 val actorList : List[Actor] = functionSet.foldRight(List[Actor]()){
  //some bad type matching here
  (func : Function1[_,_] , acc: List[Actor]) => {
     actor{
        while(true){
          receive {
            case Done => if(acc.isEmpty)println("DONE"); exit()
-->        case a: Any =>
              val res = f(a)
              if(!acc.isEmpty) acc.head ! res else println("hey "+res)
            case _ => println("must have done something wrong"); exit()
          }
        }
      } :: acc
   }
 }


The problem is that, on the given line, giving type Any to a doesn't work, and giving type _ neither. Is there any way to match the fact that this can be any type ?

Thanks,
Manohar
ewilligers
Joined: 2008-08-20,
User offline. Last seen 3 years 17 weeks ago.
Re: _ vs. Any

Manohar Jonnalagedda wrote:
> Hello,
>
> I am trying to populate a list of Function1s of any type to any type. I
> know that the return type of the first function is the input type of the
> second, etc. etc. Once the list is populated, I want to create an actor
> out of each function, in which each Actor computes the local value (for
> the sake of the example.) Here is the code :
>
>
> val functionSet : ListBuffer[Function1[_,_]] = new ListBuffer
>
> functionSet += ((a : Int) => 2 * a)
> functionSet += ((a : Int) => a * a == 16)
> functionSet += ((a : Boolean) => if(a) "Hello" else "Bye")
>
> case object Done
>
> val actorList : List[Actor] = functionSet.foldRight(List[Actor]()){
> //some bad type matching here
> (func : Function1[_,_] , acc: List[Actor]) => {
> actor{
> while(true){
> receive {
> case Done => if(acc.isEmpty)println("DONE"); exit()
> --> case a: Any =>
> val res = f(a)
> if(!acc.isEmpty) acc.head ! res else println("hey "+res)
> case _ => println("must have done something wrong"); exit()
> }
> }
> } :: acc
> }
> }
>
>
> The problem is that, on the given line, giving type Any to a doesn't
> work, and giving type _ neither. Is there any way to match the fact that
> this can be any type ?
>
> Thanks,
> Manohar

Think of _ as meaning some specific unknown type, for example either Int
or Boolean or String.

Think of Any as being non-specific, accepting various arbitrary types,
used like "void *" in C or C++, or "Object" in Java or C#.

In this example, I think it makes more sense to use Any everywhere:

import scala.collection.mutable.ListBuffer
import scala.actors.Actor
import scala.actors.Actor.{actor, receive}

val functionSet : ListBuffer[Function1[Any,Any]] = new ListBuffer

functionSet += { case (a : Int) => 2 * a }
functionSet += { case (a : Int) => a * a == 16 }
functionSet += { case (a : Boolean) => if(a) "Hello" else "Bye" }

case object Done

val actorList : List[Actor] = functionSet.foldRight(List[Actor]()){
//some bad type matching here
(func : Function1[Any,Any] , acc: List[Actor]) => {
actor{
while(true){
receive {
case Done => if(acc.isEmpty)println("DONE"); exit()
case a: Any =>
val res = func(a)
if(!acc.isEmpty) acc.head ! res else println("hey "+res)
}
}
} :: acc
}
}

manojo
Joined: 2008-12-22,
User offline. Last seen 3 years 3 weeks ago.
Re: Re: _ vs. Any
Thanks for the response.

So, if I understand well, my example functions are now converted into partial functions ?

I would like to provide syntax for chaining these functions, much like the andThen method in Function1 :

functionSet += {case (a : Int) => 2 * a} andThen {case (b : Int) => b * b == 16}

The option I have seems to be :
val newFun = {(a: Int) => 2 * a} andThen {(b : Int) => b*b == 16}
functionSet += {case (a:Int) => newFun(a)}

Is there something more elegant ?

Actually, what I would really like to have is a method like andThen which does the queuing in the functionSet. But probably one question at a time is the right way to go.

Thanks,
Manohar

On Tue, Mar 31, 2009 at 1:55 PM, Eric Willigers <ewilligers [at] gmail [dot] com> wrote:
Manohar Jonnalagedda wrote:
Hello,

I am trying to populate a list of Function1s of any type to any type. I know that the return type of the first function is the input type of the second, etc. etc. Once the list is populated, I want to create an actor out of each function, in which each Actor computes the local value (for the sake of the example.) Here is the code :


val functionSet : ListBuffer[Function1[_,_]] = new ListBuffer
   functionSet += ((a : Int) => 2 * a)
 functionSet += ((a : Int) => a * a == 16)
 functionSet += ((a : Boolean) => if(a) "Hello" else "Bye")

 case object Done
   val actorList : List[Actor] = functionSet.foldRight(List[Actor]()){
 //some bad type matching here
 (func : Function1[_,_] , acc: List[Actor]) => {
    actor{
       while(true){
         receive {
           case Done => if(acc.isEmpty)println("DONE"); exit()
-->        case a: Any =>
             val res = f(a)
             if(!acc.isEmpty) acc.head ! res else println("hey "+res)
           case _ => println("must have done something wrong"); exit()
         }
       }
     } :: acc
  }
 }


The problem is that, on the given line, giving type Any to a doesn't work, and giving type _ neither. Is there any way to match the fact that this can be any type ?

Thanks,
Manohar

Think of _ as meaning some specific unknown type, for example either Int or Boolean or String.

Think of Any as being non-specific, accepting various arbitrary types, used like "void *" in C or C++, or "Object" in Java or C#.


In this example, I think it makes more sense to use Any everywhere:


import scala.collection.mutable.ListBuffer
import scala.actors.Actor
import scala.actors.Actor.{actor, receive}

val functionSet : ListBuffer[Function1[Any,Any]] = new ListBuffer

 functionSet += { case (a : Int) => 2 * a }
 functionSet += { case (a : Int) => a * a == 16 }
 functionSet += { case (a : Boolean) => if(a) "Hello" else "Bye" }

 case object Done

 val actorList : List[Actor] = functionSet.foldRight(List[Actor]()){
 //some bad type matching here
 (func : Function1[Any,Any] , acc: List[Actor]) => {
    actor{
       while(true){
         receive {
           case Done => if(acc.isEmpty)println("DONE"); exit()
           case a: Any =>
             val res = func(a)
             if(!acc.isEmpty) acc.head ! res else println("hey "+res)
         }
       }
     } :: acc
  }
 }


extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: _ vs. Any

On Tue, Mar 31, 2009 at 12:12:39AM -0700, Manohar Jonnalagedda wrote:
> I am trying to populate a list of Function1s of any type to any type.
> I know that the return type of the first function is the input type of
> the second, etc. etc.

In that case, don't squander the types:

scala> case class FunctionSet[T, R](f: (T) => R) {
| def +[U](g: (R) => U) = FunctionSet((x: T) => g(f(x)))
| }
defined class FunctionSet

scala> FunctionSet((a : Int) => { 2 * a })
res0: FunctionSet[Int,Int] = FunctionSet()

scala> res0 + ((a : Int) => a * a == 16)
res1: FunctionSet[Int,Boolean] = FunctionSet()

scala> res1 + ((a : Boolean) => if(a) "Hello" else "Bye")
res2: FunctionSet[Int,java.lang.String] = FunctionSet()

scala> res2.f(2)
res5: java.lang.String = Hello

scala> res2.f(5)
res6: java.lang.String = Bye

manojo
Joined: 2008-12-22,
User offline. Last seen 3 years 3 weeks ago.
Re: _ vs. Any
Hi,


On Tue, Mar 31, 2009 at 2:38 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:
In that case, don't squander the types:

scala> case class FunctionSet[T, R](f: (T) => R) {
    |   def +[U](g: (R) => U) = FunctionSet((x: T) => g(f(x)))
    | }
defined class FunctionSet

it seems to me here that you are simply wrapping Function1 in a FunctionSet superclass. You could define + in terms of andThen :

case class FunctionSet[T, R](f: (T) => R) {
    |   def +[U](g: (R) => U) = FunctionSet(f andThen g)
    | }

What I want is to be able to run each function on a separate actor (that is why I am first storing them separately).

Thanks,
Manohar

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: _ vs. Any

On Tue, Mar 31, 2009 at 03:55:50PM -0700, Manohar Jonnalagedda wrote:
> What I want is to be able to run each function on a separate actor
> (that is why I am first storing them separately).

Sorry, what I was getting at was that you shouldn't have to abandon the
type relationships, which is what you're doing by whipping out Any. You
might want to look at Channel to see typed messages between actors.

ewilligers
Joined: 2008-08-20,
User offline. Last seen 3 years 17 weeks ago.
Re: _ vs. Any

Paul Phillips wrote:
> On Tue, Mar 31, 2009 at 03:55:50PM -0700, Manohar Jonnalagedda wrote:
>> What I want is to be able to run each function on a separate actor
>> (that is why I am first storing them separately).

Here's an implementation with andThen_: that keeps the typing
relationships between the actors.

There's no type safety at the beginning of the chain - e.g. head ! 2 -
or inside the implementation - i.e. t.asInstanceOf[T] - but Paul's
Channel suggestion addresses that.

import scala.collection.mutable.ListBuffer
import scala.actors.Actor
import scala.actors.Actor.{actor, receive}

trait AndThenActor[-R] extends Actor {

def andThen_: [T](f: T => R): AndThenActor[T] =
new ComputingActor[T, R](f, this)
}

case object PrintingActor extends AndThenActor[Any] {

def act() {
while(true) {
receive {
case a: Any => println(a)
}
}
}

start()
}

final class ComputingActor[T, R](f: T => R, tail: AndThenActor[R])
extends AndThenActor[T] {

def act() {
while(true) {
receive {
case t => tail ! f(t.asInstanceOf[T])
}
}
}

start()
}

val head =
{ (a : Int) => 2 * a } andThen_:
{ (a : Int) => a * a == 16 } andThen_:
{ (a : Boolean) => if(a) "Hello" else "Bye" } andThen_:
PrintingActor

head ! 2
head ! 5

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