Search code examples
scalanamed-parametersdefault-parameters

Keeping named and default parameters when assigning a function


When assigning a function using an unapplied method, it appears that named and default parameters are lost. Is there any way to avoid this?

def foo(namedParam: String = "defaultValue") = namedParam*2
// scala> foo()
// res8: String = defaultValuedefaultValue

def bar = foo _
// scala> bar()
// <console>:28: error: not enough arguments for method 
//               apply: (v1: String)String in trait Function1. 
//               Unspecified value parameter v1.

The reason I want to do this is to bundle my imports in a single file, i.e.

myproject/imports.scala

object imports {
  def externalAPIFunction = myproject.somepackage.internalFunction _
}

scala shell

import myproject.imports._

externalAPIFunction() // no named or default arguments :(

Any way to do this or do I have to put my default arguments in the external function definition?


Solution

  • Functions (i.e. values of type Function<N>[...]) simply can't have default or implicit parameters in Scala, only methods can. And method _ returns a function: that's what it's for. So yes, to achieve your purpose you'd need to write

    object imports {
      def externalAPIFunction(namedParam: String = "defaultValue") = 
        myproject.somepackage.internalFunction(namedParam)
    }
    

    You can avoid duplication using

    object imports {
      val x = myproject.somepackage
    }
    
    // elsewhere
    import myproject.imports._
    
    x.internalAPIFunction()
    
    // or
    import myproject.imports.x._
    
    internalAPIFunction()
    

    which may or may not be good enough for your purposes.