Extension Function/Property with two receivers


#1

I think it would be a nice addition if we could write Extensions Properties (and Functions) with two Receivers.
It would allow us to define extension Functions which are only valid in a specific content, for example in an Android Activity / Context.

Example:

val Context.Int.dip: Int 
    get() = (value * this@Context.resources.displayMetrics.density).toInt()

instead of

fun Context.dip(value: Int): Int = (value * resources.displayMetrics.density).toInt()

So the usage would be:

width = 8.dip

instead of

width = dip(8)

Of course in this scenario it is only a small improvement, but in my opinion this addition could be useful in many situations.
What do you think?


#2

Totally agreed !


#3

We’ve seen several usecases where such properties could be needed, but so far we’re trying to avoid adding them to the language. Single-receiver extension properties can be hard enough to explain, and this becomes even less obvious.

Note that your scenario can be partially solved with a member extension property defined in a base class that all of your activities extend.


#4

Is it possible to define member-extension with multiple receivers outside of the class, like this:

/* File 1: */
class A {
}

class B {
}


/* File 2: */
reopen class A {
     fun B.extension() {
     }
}

fun something() {
    /* here I want to use an extension on A, B */
}

/*or*/
fun A.extension1() {
    val x = fun B.extension2() {
    }
}

#5

No, member extension functions can’t be defined outside of a class.


#6

Thank you for your response!

I know that my scenario could be resolved with a member extension property defined in a base class, but there are many scenarios where this approach doesn’t work.
Also such methods would be very useful for creating DSLs for existing frameworks (see Anko’s _LinearLayout.lparams() method).

While I understand the argument, that such methods could be sometimes hard to understand, I still hope that you will change your point of view regarding this topic some day :slight_smile: