Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function delegation proposition #89

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

MarcinMoskala
Copy link

This is just an idea now, but I would like to know what do you think about it

Without buffering it is very unefficient. Using function delegation we might add buffering this way:

```
fun <V, T> memorise(f: (V) -> T): (V) -> T {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean "memoize"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, memoize is a better name for this function

```
class Delegate {
operator fun functionDelegate(thisRef: Any?, function: KFunction<*>, val property: Int): Int // Designed for this function
operator fun functionDelegate(thisRef: Any?, function: KFunction<*>, vararg arguments: Any?): Int // Desifned for any functio
Copy link

@damianw damianw Oct 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a better and more general solution -- there's no reason that the rest of the above proposal couldn't be implemented using such operator functions on KFunction[X]. I feel like the proposal can just be reduced to support of something like operator fun functionDelegate(thisRef: Any?, function: KFunction<*>, vararg arguments: Any?). I'd like to see this idea expanded upon... especially the arguments part.

Copy link
Author

@MarcinMoskala MarcinMoskala Oct 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fact is that would be more coherent with property delegation, and I can also make extension functions that would allow previous use-cases:

fun (()->Unit).functionDelegate(thisRef: Any?, function: KFunction<*>) = this()

fun <T1> ((T1)->Unit).functionDelegate(thisRef: Any?, function: KFunction<*>, arg1: T1) = this(arg1)

fun <T1, T2> ((T1, T2)->Unit).functionDelegate(thisRef: Any?, function: KFunction<*>, arg1: T1, arg2: T2) = this(arg1, arg2)

But I would l would like to hear whar others are thinking about it.

class MainActivity : MainView {
val adapter = ListAdapter()

override fun deleteListElementAt(position: Int) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make comparison fair I'd convert that to expression body:

override fun deleteListElementAt(position: Int) = adapter.deleteAt(position)

Copy link
Author

@MarcinMoskala MarcinMoskala Oct 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It changes nothing, and I am not using single expression functions for expressions that are returning Unit because this is misleading for a person who is reading it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It changes nothing

Current example takes 3 lines of code without delegate, with delegate it takes 1. But in simple cases delegate only omits function arguments in compare to expression body =.

and I am not using single expression functions for expressions that are returning Unit because this is misleading for a person who is reading it.

  • In your own examples delegate hides return type Unit as well: override fun deleteListElementAt(position: Int) by adapter::deleteAt
  • You can always specify return type explicitly if you want override fun deleteListElementAt(position: Int): Unit = adapter.deleteAt(position)

Just want to remove bias from the syntax comparison, so far I'm positive about this proposal :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sound fair. I will change it then


class MainActivity: MainView {

override fun setTitle(text: String) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

override fun setTitle(text: String) = titleView.setText(text)

Copy link
Author

@MarcinMoskala MarcinMoskala Oct 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It changes nothing, and I am not using single expression functions for expressions that are returning Unit, because this is misleading for a person who is reading it.

@artem-zinnatullin
Copy link

Would be great to explicitly cover contructor delegation in the proposal!

Could be super helpful for boilerplate reduction in DI/factory functions:

@Module
class DeviceModule {
  
  @Provides
  fun motherboard(cpu: Cpu, ram: Ram, gpu: Gpu): Motherboard by ::RealMotherboard
}

The reason is to eliminate bias from the syntax comparison
@d3xter
Copy link

d3xter commented Oct 23, 2017

Will it be possible to use an arbitrary expression to delegate to, or just an existing function?

If arbitrary expressions are allowed, that proposal would make the "Pointfree" style (Haskell Pointfree) possible:

infix fun <T, R, S> ((T) -> R).compose(f: (R) -> S) : (T) -> S = { f(this(it)) }

fun add5(i: Int) = i + 5

fun add10(i: Int) = i + 10

fun stringToInt(s: String) = s.toInt()

fun convertAndAdd15 by ::stringToInt compose ::add5 compose ::add10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants