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.

Reply via email to