Skip to content

Instantly share code, notes, and snippets.

@tpolecat
Last active December 26, 2015 06:19
Show Gist options
  • Save tpolecat/7107143 to your computer and use it in GitHub Desktop.
Save tpolecat/7107143 to your computer and use it in GitHub Desktop.
Due to an oversight in the implementation it's possible for function values to have a vararg signature, leading to various kinds of hilarity. Retronym confirms that this is a bug (see tweeties at https://twitter.com/tpolecat/status/392747549733306368)
// Eta-expansion turns A* to Seq[A]
scala> def foo(ns:Int*) = ns.sum
foo: (ns: Int*)Int
scala> foo(1,2,3)
res0: Int = 6
scala> val foov = foo _
foov: Seq[Int] => Int = <function1>
scala> foov(1,3,3)
<console>:10: error: too many arguments for method apply: (v1: Seq[Int])Int in trait Function1
foov(1,3,3)
^
scala> foov(Seq(1,2,3))
res2: Int = 6
// REPL can't cope with vararg functions
scala> val bar: (Int*) => Int = _.sum
<console>:5: error: type mismatch;
found : Int* => Int
required: Seq[Int] => Int
lazy val $result = `bar`
^
// Works if not at top level, but REPL reports the wrong type
scala> object Baz { val qux: (Int*) => Int = _.sum }
defined module Baz
scala> Baz.qux
res0: Seq[Int] => Int = <function1>
scala> Baz.qux(Seq(1,2,3))
<console>:9: error: type mismatch;
found : Seq[Int]
required: Int
Baz.qux(Seq(1,2,3))
^
scala> Baz.qux(1,2,3)
res2: Int = 6
scala> :t Baz.qux
Seq[Int] => Int
scala> Baz.qux : (Seq[Int] => Int)
<console>:9: error: type mismatch;
found : Int* => Int
required: Seq[Int] => Int
Baz.qux : (Seq[Int] => Int)
^
// Reassigning a vararg value loses the varargness
scala> val quux = Baz.qux
quux: Seq[Int] => Int = <function1>
scala> quux(1,2,3)
<console>:10: error: too many arguments for method apply: (v1: Seq[Int])Int in trait Function1
quux(1,2,3)
^
scala> quux(Seq(1,2,3))
res5: Int = 6
scala> quux eq Baz.qux
res6: Boolean = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment