Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala ActionListener / anonymous function type mismatch

Attempting to implement code similar to that found in the higher-order-function example from http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6

val button = new JButton("test")
button.addActionListener{ e:ActionEvent => println("test") }
add(button)

leads to the following

error: type mismatch;
found   : (java.awt.event.ActionEvent) => Unit 
required: java.awt.event.ActionListener
   button.addActionListener{ e:ActionEvent => println("test") }
                                           ^

This is true at least with Scala compiler version 2.7.6.final on my system. I am able to achieve what I want in the Java-style way of explicitly implementing an anonymous ActionListener.

button.addActionListener( new ActionListener() {
  def actionPerformed(e:ActionEvent) { println("test") }
})

As far as I understand, Scala should be able to use duck-typing to render this explicit implementation of ActionListener unnecessary; so why isn't it working here? I have next to no practical experience of duck-typing at this point.

like image 593
PeterT Avatar asked Jul 13 '10 16:07

PeterT


2 Answers

Duck-typing has nothing to do with the reason that your code doesn't work. It is because Scala's type system doesn't provide implicit conversion between interface type and function type by default. However, if the following implicit conversion is defined, your code works correctly.

implicit def toActionListener(f: ActionEvent => Unit) = new ActionListener {
  def actionPerformed(e: ActionEvent) { f(e) }
}

This implicit conversion provides conversions from (ActionEvent => Unit) to ActionListner.

like image 122
kmizu Avatar answered Oct 27 '22 01:10

kmizu


Scala isn't duck-typed. It has optional, explicit structural-typing, but that doesn't have anything to do with why your code does not work.

Your code does not work, because JButton.addActionListener expects an ActionListener as its argument, not a function. Even if scala were ducktyped, you couldn't just pass a function because the same methods available on an ActionListener are not available on a function.

Note that the article says "Let’s assume for one blissful moment that we could rewrite Swing to take full advantage of Scala’s syntax", i.e. the article does not claim to show you actual code that works.

However scala does have it's own swing package (scala.swing) which contains classes which are more "scalaish" to use than their java equivalents.

like image 22
sepp2k Avatar answered Oct 26 '22 23:10

sepp2k