Return type polymorphism in Scala

156 views
Skip to first unread message

Marko Elezovic

unread,
May 24, 2013, 9:16:10 AM5/24/13
to scala...@googlegroups.com
I have created an unholy chimera by combining Scala and Jasmin:
https://blog.dsl-platform.com/hacking-in-the-jvm-return-type-polymorphism-in-scala/

Have you ever needed such functionality?
The reason why I'm asking is that I was contemplating creation of a
compiler plugin which would automate the described proxying method.

Hope you like it, would appreciate some thoughts on Reddit:
http://www.reddit.com/r/programming/comments/1eyvbm/hacking_in_the_jvm_return_type_polymorphism_in/

Regards!
Marko

Haoyi Li

unread,
May 24, 2013, 9:31:11 AM5/24/13
to Marko Elezovic, scala-user
By using return type overloading you would be able to make a tiny wrapper around the original ResultSet ...

This feels exactly like using an implicit conversion from the return type of `get` to whatever you wanted (i.e. what type was inferred at that location in the program). Is that right, or is there some deeper difference? 

-Haoyi


Marko

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Marko Elezovic

unread,
May 24, 2013, 10:05:44 AM5/24/13
to Haoyi Li, scala-user
Hey Haoyi,

there is a major difference - there is no "return type" of get to perfrom this implicit conversion on.
The return type itself is determining which method will be invoked.

Basically, consider the upper examples with the division:
  def div(x: Int, y: Int): Int = x / y
  def div(x: Int, y: Int): String = x + "/" + y

  println(div(8,2): Int) // prints 4
  println(div(8, 2): String) // prints 8/2

In implicit conversion would not help you here, because that conversion needs to be applied on the x and y arguments.
We do not wish to change the input parameters, but rather route them to the appropriate method.

I hope I understood your question correctly.

Regards
Marko
-Haoyi

To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.

Alexandru Nedelcu

unread,
May 24, 2013, 10:23:28 AM5/24/13
to scala-user
(Marko, sorry for the duplicate, forgot again to reply-all :))

On Fri, May 24, 2013 at 4:16 PM, Marko Elezovic <ma...@element.hr> wrote:
> I have created an unholy chimera by combining Scala and Jasmin:
> https://blog.dsl-platform.com/hacking-in-the-jvm-return-type-polymorphism-in-scala/

This is pretty cool dude :-)

Although I don't get how this works. It seems that the JVM itself is
handling this overloading. Which would mean that it can't work with
parametrized types.

Wouldn't it be better for the Scala compiler to generate functions
with different names under the hood and choosing the right one at the
call-site, like it currently does for specialized types?

Alexandru Nedelcu

unread,
May 24, 2013, 10:49:06 AM5/24/13
to scala-user
Personally I would be really happy if picking an implicit could be
done by also inferring the generic type from the expected return type,
like say if you have ...

def get[T : Something] = ???

Then using it as "get : String" would try to find a Something[String].
But I guess that would conflict with whatever makes CanBuildFrom to
work :-) as the found implicits themselves can establish the return
type.
--
Alexandru Nedelcu
https://bionicspirit.com

Luis Ángel Vicente Sánchez

unread,
May 24, 2013, 11:01:29 AM5/24/13
to scala-user
What would happen if I use a method without typecasting, i.e. val d = div(8, 2)? Would there be a default overload that would be called? A runtime exception would be raised?


2013/5/24 Alexandru Nedelcu <m...@alexn.org>

Haoyi Li

unread,
May 24, 2013, 12:09:54 PM5/24/13
to Luis Ángel Vicente Sánchez, scala-user
Marko,

I was thinking something like:

case class div(x: Int, y: Int)
implicit def intConv(d: div) = d.x / d.y
implicit def strConv(d: div) = d.x + "/" + d.y

println(div(8,2): Int) // prints 4
println(div(8, 2): String) // prints 8/2

This can be trivially extended to methods instead of standalone functions. What you're doing saves a class file, and probably has some performance differences, but i was wondering if there was any semantic difference from the way you're doing it? 

For example, if you don't perform the cast in the implicit-conversion scenario, you simply get the original `div()` object, and can cast it any time. What happens if you don't perform the cast using your technique? Can you pass the thing around and cast it later? 

This isn't meant to be discouraging or anything, I'm just wondering how your technique compares to existing mechanisms, especially around the edge cases =)

Thanks!
-Haoyi
Reply all
Reply to author
Forward
0 new messages