On 20 May 2014, at 08:26, Mark van Gulik <[email protected]> wrote:
>
> On May 19, 2014, at 3:33 PM, Robbert van Dalen wrote:
>> is there an easy way to mimic scala’s implicits?
>
> I haven't seen these before. Here's the first example I ran into at
> scala-lang.org:
>
> abstract class SemiGroup[A] {
> def add(x: A, y: A): A
> }
> abstract class Monoid[A] extends SemiGroup[A] {
> def unit: A
> }
> object ImplicitTest extends Application {
> implicit object StringMonoid extends Monoid[String] {
> def add(x: String, y: String): String = x concat y
> def unit: String = ""
> }
> implicit object IntMonoid extends Monoid[Int] {
> def add(x: Int, y: Int): Int = x + y
> def unit: Int = 0
> }
> def sum[A](xs: List[A])(implicit m: Monoid[A]): A =
> if (xs.isEmpty) m.unit
> else m.add(xs.head, sum(xs.tail))
>
> println(sum(List(1, 2, 3)))
> println(sum(List("a", "b", "c")))
> }
> This seems like a very nice way to adapt classes. Let's try something
> similar in Avail. From the library...
>
> Public stable method "∑_" is
> [
> intTuple : <extended integer…|1..∞>
> |
> left fold intTuple through
> [i : extended integer, ri : extended integer | i + ri]
> ] : extended integer;
>
> There's also a complex semantic restriction on it that computes the most
> precise bounds possible on the result, given the specific integral types.
>
> The Scala example also adapts strings, so we can add:
>
> Public stable method "∑_" is
> [
> strTuple : <string…|>
> |
> concatenate strTuple
> ] : string;
>
> Technically that's sufficient to allow us to write:
> Print: “∑<1,2,3>”;
> Print: ∑<"a","b","c”>;
i understand the multi-method approach, but that’s different from the single
abstract implementation that sums a tuple with a monoid.
your example has two concrete implementations.
> In general it should be fairly simple to build an X --> Y adapter, but Avail
> currently has no way to invoke the conversion operation to implicitly get
> from an X to a Y. The best idea so far is to allow the "_" method for type
> conversion (its merits and pitfalls are frequently investigated in my old
> Avail notebooks). This is currently forbidden, I'm fairly certain. But if
> we open up that capability we should be able to specify any implicit
> conversion paths that we want. In a normal language technology, at some
> level of implementation we would have to synthesize actual helper objects of
> type Y, either to invoke the original X methods with reflection or to hold
> generated code that delegated to the X method. We would also not be able to
> use the resulting Y in place of X because of unwanted identity. Avail is
> still stuck in that regard, since the availability of implicit conversions
> would introduce multiple interpretations of the vast majority of expressions.
> Even something as innocuous as Print: “x”; would be ambiguous, because it
> would be unclear whether we should use x directly or convert x from an X to a
> Y (or myriad other implicit conversions).
ok, you make implicit typing sound like a tar pit: it probably is!
> I'm really not impressed by any of these possibilities. They all have the
> potential to make Avail a very messy, special-case, black-magic-filled
> language. So what aspect of Scala's implicits did you have in mind, just in
> case I didn't understand them or I didn't cover it?
in scala, i use implicit typing to effectively reduce boilerplate and other
redundant code.
and i agree with you that it is messy, black-magic even.
but if i have to choose between boilerplate or magic, i choose magic.
of course, a lot of boilerplate can also be reduced with macros - which is
another source of magic!
cheers,
Robbert.