score:8

Accepted answer

huitseeker's suggestion is actually valid with the -ydependent-method-types option:

$ scala -ydependent-method-types
welcome to scala version 2.9.0.1 (java hotspot(tm) 64-bit server vm, java 1.6.0_24).

scala>   def processandreturn[a <: anyref](obj: a): obj.type = {
     |       // work with obj
     |       obj
     |   }
processandreturn: [a <: anyref](obj: a)obj.type

scala> processandreturn("hi")
res1: java.lang.string = hi

from this thread, i gather that experimental dependent method types have been around for a while, and there's even a published paper using them, but the implementation may be buggy. there has been some discussion about reworking scala's type system foundations (see adriaan moor's slides on dependent object types). if it works out, i imagine that dependent method types (among other things) will be completely kosher in future versions of scala.

score:0

the question is: if you're going to return what you passed in, why not just use void? after all, you already have the object in the calling code, don't you?

score:1

huitseeker and kipton probably have the direct answer you're looking for.

with that said, the only use case i can imagine is if you want to chain calls on the same object and ensure you're really working on the same object. are there other?

for instance:

class counter {
  var i = 0
  override def tostring = i.tostring
}

def incr(c: counter): counter = { c.i += 1; c }

val two = incr(incr((new counter)))
// two: counter = 2

if i call incr twice in a row, i expect to get two. now let's imagine i am working with an ill-behaved function like:

def incorrect_incr(c: counter): counter = { 
  c.i += 1
  new counter // should return c but does not
}

val nottwo = incorrect_incr(incorrect_incr(new counter))
// nottwo: counter = 0

i think using a wrapper to ensure we keep working on the same object would solve this problem (edited after thinking on how to make this more idiomatic):

case class id[t <: anyref](t:t) {
  def map[u](f: (t) => u): id[t] = { 
    f(t)
    this
  }
  def get: t = t
}

val reallytwo = id(new counter).map(incorrect_incr).map(incorrect_incr).get
// reallytwo: counter = 2

map basically ensures the function is called for its side effect, get unwraps the value...

score:3

i guess you would want to give the return type obj.type in your method above, but this is unfortunately prohibited as of now. as per the spec, p.47:

(...) at present singleton types of method parameters may only appear in the method body; so dependent method types are not supported.

there may be some way to achieve what you want, but not in the type specification of that method by itself.


Related Query

More Query from same tag