Jason Kinzer | 1 Mar 2006 04:46
Picon

Re: weirdness in typechecking call on overloaded java method

Lex,

It was indeed an older version of the compiler.

Thanks for the reply & also thanks to Martin Sandin for passing on Sean's workaround (simply assign a dummy result to obtain the correct overload) and Martin Odersky for mentioning that the bug had already been fixed locally. I greatly appreciate the responses.

Jason

On 27 Feb 2006 11:10:30 +0100, Lex Spoon <lex <at> cc.gatech.edu> wrote:
"Jason Kinzer" <jmkinzer <at> gmail.com> writes:
> I've stumbled upon a typing issue I'm at a loss to explain. Following is a
> minimal test case:
>
> ---------------------------------------------
> // ScalaMenuTest.scala
> object ScalaMenuTest {
>   def main(args: Array[String]): Unit = {
>     val v = new javax.swing.JMenu()
>     v.add (new javax.swing.JMenuItem())
>     //v.add(new java.awt.PopupMenu());
>   }
> }
>
> //==> compiling with scalac2 results in
> //
> // found   : javax.swing.JMenuItem
> // required: java.awt.PopupMenu
> //    v.add(new javax.swing.JMenuItem())
> //          ^
> //one error found
> ---------------------------------------------

There have been problems like this, but your example compiles for
me using version 2.0.5843 and 2.0.5774 .  Can you check your
version (scalac -version), and upgrade if it is older than these?

Otherwise, maybe it is environmental.  I am using a 1.5 Sun SDK.

-Lex


Lex Spoon | 2 Mar 2006 15:10
Picon
Favicon

[ANN] sbaz server moved

Hey guys, I have moved the main sbaz server ("scala-dev") from a
linode.com virtual host onto a server maintained by LAMP.  Thus, if
you have a sbaz directory around, you need to point it towards the new
server.  If you do not, everything will continue to work, but you will
not see any updates.

To repoint the server, create a file named scala-dev.univ with the
following contents:

<simpleuniverse>
  <name>scala-dev</name>
  <description>
    development universe of Scala
  </description>
  <location>http://scala-webapps.epfl.ch/sbaz/scala-dev</location>
</simpleuniverse>

Then, run the command, "sbaz setuniverse scala-dev.univ" .

Let me know if there are any problems!

-Lex

Sean McDirmid | 3 Mar 2006 18:44
Picon
Picon
Favicon

Scala Eclipse plug-in 2.1.9

I'm pleased to annouce a new version of the plug-in (2.1.9) is available 
on the BETA update site (lamp.epfl.ch/~mcdirmid/scala-plugin).  This 
release fixes a bunch of bugs (including a pretty bad one in the 
resident compiler) and is recommended for everyone actively using the 
plug-in.

Thanks,

Sean

John Williams | 6 Mar 2006 23:31
Picon
Favicon

implicit conversions and pattern matching

I just started using Scala, and overall I'm very happy with it--I 
imagine before too long I'll be trying to talk my coworkers into using it.

One feature I'm missing is the ability to use an implicit function for 
pattern matching, like this example representing complex numbers in 
either polar or rectangular form:

   case class Rect(re: double, im: double)
   case class Polar(r: double, theta: double)

   object Test {
     import Math._

     implicit def p2r(z: Polar) = z match {
       case Polar(r, theta) =>
         Rect(r * cos(theta), r * sin(theta))
     }

     def main(args: Array[String]) = {
       Polar(1, PI/2) match { // <------------ call p2r here
         case Rect(re, im) =>
           Console.println(re + " + " + im + "i")
       }
     }
   }

Being able to use implicit conversions this way seems to accomplish much 
the same thing as the "views" proposed for Haskell 
(http://www.haskell.org/development/views.html) with nothing more than a 
slight liberalization of the existing rules in Scala.

--jw

Burak Emir | 7 Mar 2006 02:20
Picon
Picon
Favicon

Re: implicit conversions and pattern matching

Dear John,

Thanks for your interest in Scala and pattern matching. The behavior you 
are talking about was indeed discussed, however we were reluctant to go 
for it. Especially in the presence of deep patterns, it may become quite 
a hairy thing to specify. Let me try to explain why.

1) Type checking patterns relies on static information (like everywhere 
else in the compiler). In the case of patterns, an "expected type" is 
propagated down, in order to type variable binding patterns and more 
generally verify that the pattern is something that makes sense. The 
expected type starts, of course, with the scrutinee (aka the selector 
expression aka what is matched upon).

2) The translation of pattern matching uses (almost) every means 
possible to avoid redundant type tests. This means, that the cases 
present in the source code get "compressed" into a sort of decision tree 
diagram. This later gets translated to code.

Enter implicit conversions. Having the scrutinee be of a different type 
then the patterns means we cannot make use of expected type in patterns. 
Consequently, we would have to type check patterns independently of the 
type of the scrutinee.

This alone might still be feasible (careful here, who can foresee hairy 
interactions with sequence patterns etc). We could say, patterns have a 
type independent of the expected type, and type checking will see 
whether the type of the scrutinee complies with the pattern types 
(possibly after applying some implicit conversion).

But this turns out to be a non-specification.

implicit def fbTypeToFoo ...
implicit def fbTypeToBar ...

fb match {
case Foo(...) =>
case Bar(...) =>
}

What seems to really be needed is to apply the views "by need", meaning 
"inside" the pattern match.

This clashes with the present algorithm doing task 2). In presence of 
implicit conversions, the task of pattern matching is in fact pushed one 
level deeper, as the outermost pattern will always match (there's a 
conversion after all). This is quite annoying to implement and to 
specify, because patterns with and patterns without implicit conversion 
from the scrutinee type might be mixed, like in

implicit def FooToBar...
myFoo match {
 case Foo(...)
 case Bar(... )
 case Foo( ...)
}

The assumption that a top-level "Foo" would never enter the "Bar" case 
is now invalid (there's a conversion after all). One basically loses all 
hope of optimizing for the outermost level. While the current matcher 
would join the remainder of patterns 1 and 3, a hypothetical matcher 
with implicit calls could not be designed to do so, as it would violate 
the first match policy.

Now it still seems possible to implement and specify this whole thing, 
but the cost is considerable.

Luckily, the pattern matcher is anyway being rewritten at the moment, 
but I am just not sure about the performance penalty associated and 
whether the benefit justifies the effort. IMHO we shall discuss about 
this at a Scala meeting and wait for the rewrite to be completed before 
assessing what to do. The trend was going towards (even) more  
optimization and more reliance on types (making better use of "sealed", 
use switches, check exhaustivity).

In any case thanks for your suggestion, this feature is for sure going 
to be considered soon.
Burak

John Williams wrote:

> I just started using Scala, and overall I'm very happy with it--I 
> imagine before too long I'll be trying to talk my coworkers into using 
> it.
>
> One feature I'm missing is the ability to use an implicit function for 
> pattern matching, like this example representing complex numbers in 
> either polar or rectangular form:
>
>   case class Rect(re: double, im: double)
>   case class Polar(r: double, theta: double)
>
>   object Test {
>     import Math._
>
>     implicit def p2r(z: Polar) = z match {
>       case Polar(r, theta) =>
>         Rect(r * cos(theta), r * sin(theta))
>     }
>
>     def main(args: Array[String]) = {
>       Polar(1, PI/2) match { // <------------ call p2r here
>         case Rect(re, im) =>
>           Console.println(re + " + " + im + "i")
>       }
>     }
>   }
>
> Being able to use implicit conversions this way seems to accomplish 
> much the same thing as the "views" proposed for Haskell 
> (http://www.haskell.org/development/views.html) with nothing more than 
> a slight liberalization of the existing rules in Scala.
>
> --jw

Judson, Ross | 7 Mar 2006 23:25
Favicon

Functions, Tuples, Sequences

Scala unifies functions and objects via definitions for apply(), and the
FunctionN types.  Consider this small extension of the basic Function2
type:

package scala;

/**
 * Function with 2 parameters
 */
mixin class Function2[-T0, -T1, +R] extends AnyRef {
  def apply(v0: T0, v1: T1): R;
  final def apply(tuple: Tuple2[T0,T1]): R = apply(tuple._1, tuple._2);
  final def apply(s1: Seq[T0], s2: Seq[T1]): Seq[R] = new Seq[R] {
    def apply(n: int) = Function2.this.apply(s1(n), s2(n));
    def length = s1.length;
    def elements = Function2.this.apply(s1.elements, s2.elements);
  }
  final def apply(i1: Iterator[T0], i2: Iterator[T1]): Iterator[R] = new
Iterator[R] {
    def hasNext = i1.hasNext;
    def next = apply(i1.next, i2.next);
  }
  def apply[X](f1: X => T0, f2: X => T1): X => R = (x: X) =>
apply(f1(x),f2(x));
  def apply[X,Y](f1: X => T0, f2: Y => T1): (X,Y) => R = (x: X, y: Y) =>
apply(f1(x),f2(y));  
  override def toString() = "<function>";
}

We've gained several things.  First, we can apply the function with a
full argument list OR a tuple containing precisely the same types.  This
is a convenient shorthand.  Second, I have inserted additional apply
methods that recognize sequences and iterators, then perform reasonable
(?) actions.  This allows me to write:

object tt extends Application {

  val adder = (x: String, y: int) => Integer.parseInt(x) + y;
  val times = (a: int, b: int) => a * b;

  val t = Tuple2("43", 43);
  Console.println(t(adder));

  val listA = List("10", "11", "12");
  val listB = List(1,2,3);
  val listC = List(4,5,6);

  for (val z <- listA.zip(listB))
    Console.println(adder(z));

  for (val a <- adder(listA, listB))
    Console.println(a);

  val mult = times(listB, listC);
  Console.println(mult);    

  def * = (a: int, b: int) => a * b;

  val m = listB * listC;   <-- will not compile (and shouldn't yet)

  type Time = int;

  val oddSeconds = (t: Time) => (t % 2) == 1; 
  val square = (t: Time) => t * t;

  val gate = (b: Boolean, t: Time) => if (b) t else 0;
  val gateOdd = gate(oddSeconds,square);
  for (val i <- Stream.range(0, 100))
    Console.println(gateOdd(i));  
}

Being able to shift fluidly from tuples to arguments is useful.  The
sequence and iterator-based extensions allow defined functions to be
"lifted" up to sequences and iterators automatically.  In other words,
for the example I've given here any binary function automatically "does
the right thing" when used with sequences.

Except that last case; deep inside the Typers nsc is checking to see if
* is a member of List, which it is not, so compilation fails.  I don't
think it's possible use implicit to instruct the compiler that if:

Val Oa = Outer[InnerA] and
Val Ob = Outer[InnerB] and
Val Result: R = Outer[InnerA] op Outer[InnerB], and
InnerA op InnerB: T     is defined

Then

Result = ((left: Inner, right: Outer) => left op right)(Oa, Ob)

With this we've extended the unary member function "op" into a binary
function.  If extended with the additional apply() methods outlined
above, we now have a very concise way of extending arbitrary functions
to work on sequences. This is a kind of "meta-implicit" operation, where
we want to be able to specify an implicit type context in additional to
implicit typed _values_.  With such a facility I might redefine List:

class List[implicit A] { ... }

When we look for a name inside List, if it is not found we search A.  If
found there, the symbol may have enough meaning to be valid, or may be
refined through another implicit conversion into what is needed.

The law of unintended consequences applies of course, but somewhere in
this is a way to cleanly fold vector programming into Scala's domain.

Keeping FunctionN light is very important if any replication is
performed.  But...since Scala is unifying functions and objects, doesn't
it make sense that Scala's function/objects be a little smarter than
normal "dumb" functions?  

I modified FunctionN to have the extra "apply" functions.  Implicit
types are obviously a deeper issue, but interesting, nonetheless.  You
can also see a pair of higher-order composers above, as well...I am
still thinking through the implications of them.  Composing higher order
functions is fraught with twistiness, so I thought it might be useful to
have a few common cases easily accessible.

RJ

Ted Neward | 8 Mar 2006 08:49

Introduction, and general request for assistance

Greetings, all; I'm a regular speaker on the No Fluff Just Stuff software
symposium tour in the States, and I happened across Scala while looking for
alternative languages that run on the JVM. (To put it bluntly, I'm not
convinced--as Dave Thomas and Bruce Tate are--that you have to jump to the
Ruby platform to get some of that dynamic language goodness.) Having found
Scala and liking it's functional/object hybrid nature, I'm preparing to give
talks on it this year as a practical language for use on the Java platform.
I've been working through Scala and posting elements on my blog (below) as I
go.

Here's the rub: I'm not entirely certain I've intuited the basic
fundamentals of the Scala language, and I know I'm probably going to
approach particular problems from a more traditional O-O approach instead of
taking advantage of some of Scala's functional goodness. So what I'm asking
is (a) for people who "get" Scala to keep an eye on my blog and correct me
where I'm wrong about how to approach things, and (b) help me understand
elements of the Scala language so I can spread the good word. :-)

Question #1: How in the hell does the Application trait work, and how would
I create one like it (say, for a servlet)? I can't figure out how to
replicate that behavior in a different trait, such that the body of the
class defined would be called when something in the trait is called (the way
main() in the trait somehow executes the body of the "<<thing>> with
Application" does).

Ted Neward
Author, Presenter, Consultant
Java, .NET, XML services
http://blogs.tedneward.com

Nikolay Mihaylov | 8 Mar 2006 09:33
Picon
Picon
Favicon

Re: Introduction, and general request for assistance

Hi Ted,

On Tue, 2006-03-07 at 23:49 -0800, Ted Neward wrote:

> Question #1: How in the hell does the Application trait work, and how would
> I create one like it (say, for a servlet)? 

The Application trait expolits a Java compatibility feature of the Scala
compiler. Although a Scala object does not define a Scala class the
compiler creates one which is instantiated as a singleton. You are not
supposed to access this class directly (but for the record it has the
name of the object plus a trailing '$'). In addition, for a top-level
object (that is, not nested in other class/object) the compiler creates
a so called "mirror" class with the name of the object (caveat - it
cannot do it if we define a Scala class with the same name as the
object). This mirror class has a static method for each method of the
mirrored object that simply forwards the call to the corresponding
method on the singleton instance of the object. You can see where this
is leading - if the object defines a main method with the proper
signature its static forwarder method in the mirror class will be a
proper JVM main method.

> I can't figure out how to
> replicate that behavior in a different trait, such that the body of the
> class defined would be called when something in the trait is called (the way
> main() in the trait somehow executes the body of the "<<thing>> with
> Application" does).

Class-level (or object-level) statements are executed as part of the
constructor of the class/object. I don't see a way to achieve what you
describe as "the body of the class defined would be called when
something in the trait is called." In fact, I have argued against the
use of the Application mixin class in

http://article.gmane.org/gmane.comp.lang.scala/1757/

Cheers

Nikolay

Jamie Webb | 9 Mar 2006 03:24

Re: Introduction, and general request for assistance

On Tue, Mar 07, 2006 at 11:49:35PM -0800, Ted Neward wrote:
> Here's the rub: I'm not entirely certain I've intuited the basic
> fundamentals of the Scala language, and I know I'm probably going to
> approach particular problems from a more traditional O-O approach instead of
> taking advantage of some of Scala's functional goodness. So what I'm asking
> is (a) for people who "get" Scala to keep an eye on my blog and correct me
> where I'm wrong about how to approach things, and (b) help me understand
> elements of the Scala language so I can spread the good word. :-)

Ok, I just read through your posts and I see nothing glaringly wrong.
There are numerous minor issues, but none particularly noteworthy. A
random sample from your most recent post:

- The functional and imperative style quicksorts are not equivalent:
  the imperative one works in-place and is therefore more efficent,
  both in terms of space and time once memory management overhead is
  counted. Having said that, the meme that 'programmer time is more
  expensive than CPU time' is common to both Scala and Java. Scala is
  just better at applying it.

- You might want to investigate the 'Ordered' trait and the way
  arbitrary types can be 'viewed' as Ordered, rather than explicitly
  passing about comparison functions. Admittedly that's quite
  advanced. Maybe a reason to revisit quicksort in a few articles'
  time.

- What's with the 'if(rhs < lhs) true else false'? You realise that
  the comparison operators already return booleans, right?

Keep up the good work.

-- Jamie Webb

Ted Neward | 9 Mar 2006 04:17

RE: Introduction, and general request for assistance

> - The functional and imperative style quicksorts are not equivalent:
>   the imperative one works in-place and is therefore more efficent,
>   both in terms of space and time once memory management overhead is
>   counted. Having said that, the meme that 'programmer time is more
>   expensive than CPU time' is common to both Scala and Java. Scala is
>   just better at applying it.
> 
Fair enough--don't suppose you want to point this out in a comment on the
blog....?

> - You might want to investigate the 'Ordered' trait and the way
>   arbitrary types can be 'viewed' as Ordered, rather than explicitly
>   passing about comparison functions. Admittedly that's quite
>   advanced. Maybe a reason to revisit quicksort in a few articles'
>   time.
> 
Was planning to, maybe actually in the next one--traits seemed a natural
next thing to point out.

> - What's with the 'if(rhs < lhs) true else false'? You realise that
>   the comparison operators already return booleans, right?
>
Now THAT's what I'm talkin' 'bout. Didn't know that. Makes sense once you
point it out, mind you, but didn't think of it. :-)

Ted Neward
Author, Presenter, Consultant
Java, .NET, XML services
http://blogs.tedneward.com

> -----Original Message-----
> From: Jamie Webb [mailto:j <at> jmawebb.cjb.net]
> Sent: Wednesday, March 08, 2006 6:25 PM
> To: scala <at> listes.epfl.ch
> Subject: Re: Introduction, and general request for assistance
> 
> On Tue, Mar 07, 2006 at 11:49:35PM -0800, Ted Neward wrote:
> > Here's the rub: I'm not entirely certain I've intuited the basic
> > fundamentals of the Scala language, and I know I'm probably going to
> > approach particular problems from a more traditional O-O approach
> instead of
> > taking advantage of some of Scala's functional goodness. So what I'm
> asking
> > is (a) for people who "get" Scala to keep an eye on my blog and correct
> me
> > where I'm wrong about how to approach things, and (b) help me understand
> > elements of the Scala language so I can spread the good word. :-)
> 
> Ok, I just read through your posts and I see nothing glaringly wrong.
> There are numerous minor issues, but none particularly noteworthy. A
> random sample from your most recent post:
> 
> - The functional and imperative style quicksorts are not equivalent:
>   the imperative one works in-place and is therefore more efficent,
>   both in terms of space and time once memory management overhead is
>   counted. Having said that, the meme that 'programmer time is more
>   expensive than CPU time' is common to both Scala and Java. Scala is
>   just better at applying it.
> 
> - You might want to investigate the 'Ordered' trait and the way
>   arbitrary types can be 'viewed' as Ordered, rather than explicitly
>   passing about comparison functions. Admittedly that's quite
>   advanced. Maybe a reason to revisit quicksort in a few articles'
>   time.
> 
> - What's with the 'if(rhs < lhs) true else false'? You realise that
>   the comparison operators already return booleans, right?
> 
> Keep up the good work.
> 
> -- Jamie Webb


Gmane