Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Kotlin for Non-Functional JVM

Functional Kotlin for Non-Functional JVM

This presentation is presented at BlrKotlin's meetup on 1st Dec, 2018. In this presentation, I explained how Kotlin supports functional style of programming even though JVM doesn't understand it. We have understood, how Kotlin compiler tweaks the code to let the JVm understand the generated bytecode and execute it.

Chandra Sekhar Nayak

December 01, 2018
Tweet

More Decks by Chandra Sekhar Nayak

Other Decks in Programming

Transcript

  1. Functional Programming •First class citizenship to functions •Better abstraction •Immutability

    •“What To Do” instead of “How To Do” @iChanSek www.chansek.com
  2. @iChanSek www.chansek.com val fruits = listOf("banana", "avocado", "apple", "kiwifruit") for

    (fruit in fruits) { if (fruit.startsWith('a')) { println(fruit.toUpperCase()) } } Imperative Style
  3. Functional Style fruits .filter { it.startsWith("a") } .map { it.toUpperCase()

    } .forEach { println(it) } @iChanSek www.chansek.com for (fruit in fruits) { if (fruit.startsWith('a')) { println(fruit.toUpperCase()) } } Imperative Style val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
  4. first-class functions •functions are not mandated to be declared as

    methods. •functions can accept functions as arguments. •functions can return other functions. •functions can be assigned to variables. •functions can be stored in data structures. •… @iChanSek www.chansek.com
  5. // File - TestKt.class public final class TestKt { public

    static final void main(String[] args) { System.out.println("Hello Kotlin"); } } @iChanSek www.chansek.com // File - Test.kt fun main(args: Array<String>) { println("Hello Kotlin") }
  6. @iChanSek www.chansek.com // File - Test.kt fun add(x: Int, y:

    Int) = x + y // File - TestKt.class public final class TestKt { public static final int add(int x, int y) { return x + y; } }
  7. @iChanSek www.chansek.com // File - Print.kt val printKotlin = fun

    (): Unit { print("Hello Kotlin") } // File - Print.kt fun main(args: Array<String>) { }
  8. @iChanSek www.chansek.com // File - Print.kt val printKotlin = fun

    (): Unit { print("Hello Kotlin") } // File - Print.kt fun main(args: Array<String>) { printKotlin() }
  9. @iChanSek www.chansek.com // File - PrintKt.class val printKotlin = fun

    (): Unit { print("Hello Kotlin") } // File - Print.kt fun main(args: Array<String>) { printKotlin() }
  10. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { val printKotlin = fun (): Unit { print("Hello Kotlin") } } // File - Print.kt fun main(args: Array<String>) { printKotlin() }
  11. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final XXX printKotlin; = fun (): Unit { print("Hello Kotlin") } } // File - Print.kt fun main(args: Array<String>) { printKotlin() }
  12. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final XXX printKotlin; public void invoke() { print(“Hello Kotlin”) } } // File - Print.kt fun main(args: Array<String>) { printKotlin()
  13. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final XXX printKotlin; public void invoke() { System.out.println("Hello Kotlin") } } // File - Print.kt fun main(args: Array<String>) { printKotlin()
  14. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final XXX printKotlin; static { printKotlin = new XXX() { @Override public void invoke() { System.out.println("Hello Kotlin"); } } } }
  15. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = new Function0<Unit>() { @Override public Unit invoke() { System.out.println("Hello Kotlin”); return Unit.INSTANCE; } } } }
  16. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } } // File - Print.kt
  17. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } }
  18. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } } // File - Print.kt fun main(args: Array<String>) { printKotlin() } public interface Function0<out R> : Function<R> { public operator fun invoke(): R }
  19. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } } // File - Print.kt fun main(args: Array<String>) { printKotlin() } public interface Function0<out R> : Function<R> { public operator fun invoke(): R } public interface Function<out R>
  20. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } } // File - Print.kt fun main(args: Array<String>) { printKotlin() } public interface Function0<out R> : Function<R> { public operator fun invoke(): R }
  21. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } } // File - Print.kt fun main(args: Array<String>) { printKotlin() } public interface Function0 extends Function { Object invoke(); }
  22. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } } // File - PrintKt.class public static void main(String[] args) { printKotlin.invoke(); } public interface Function0 extends Function { Object invoke(); }
  23. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = () -> { System.out.println("Hello Kotlin"); return Unit.INSTANCE; }; } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } } // File - Another.class public static void main(String[] args) { getPrintKotlin().invoke(); } public interface Function0 extends Function { Object invoke(); }
  24. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = new Function0<Unit>() { @Override public Unit invoke() { System.out.println("Hello Kotlin”); return Unit.INSTANCE; } } } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } }
  25. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printKotlin; static { printKotlin = new Function0<Unit>() { @Override public Unit invoke() { System.out.println("Hello Kotlin”); return Unit.INSTANCE; } } } public static final Function0<Unit> getPrintKotlin() { return printKotlin; } }
  26. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printMessage; static { printMessage = new Function0<Unit>() { @Override public Unit invoke() { System.out.println("Hello Kotlin”); return Unit.INSTANCE; } } } public static final Function0<Unit> getPrintMessage() { return printMessage; } }
  27. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function0<Unit> printMessage; static { printMessage = new Function0<Unit>() { @Override public Unit invoke() { System.out.println("Hello Kotlin”); return Unit.INSTANCE; } } } public static final Function0<Unit> getPrintMessage() { return printMessage; } }
  28. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = new Function1<String, Unit>() { @Override public Unit invoke(String msg) { System.out.println("Hello Kotlin”); return Unit.INSTANCE; } } } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } }
  29. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = new Function1<String, Unit>() { @Override public Unit invoke(String msg) { System.out.println(“Hello” + msg); return Unit.INSTANCE; } } } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } }
  30. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = msg -> { System.out.println(“Hello” + msg); return Unit.INSTANCE; }; } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } }
  31. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = msg -> { System.out.println(“Hello” + msg); return Unit.INSTANCE; }; } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } } // File - Print.kt fun main(args: Array<String>) { printMessage("Java") }
  32. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = msg -> { System.out.println(“Hello” + msg); return Unit.INSTANCE; }; } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } } // File - Print.kt fun main(args: Array<String>) { printMessage("Java") } public interface Function1<in P1, out R> : Function<R> { public operator fun invoke(p1: P1): R }
  33. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = msg -> { System.out.println(“Hello” + msg); return Unit.INSTANCE; }; } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } } // File - Print.kt fun main(args: Array<String>) { printMessage("Java") } public interface Function1 extends Function { Object invoke(Object p1); }
  34. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = msg -> { System.out.println(“Hello” + msg); return Unit.INSTANCE; }; } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } } public interface Function1 extends Function { Object invoke(Object p1); } // File - PrintKt.class public static void main(String[] args) { printMessage.invoke(“Java”); }
  35. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = msg -> { System.out.println(“Hello” + msg); return Unit.INSTANCE; }; } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } } public interface Function1 extends Function { Object invoke(Object p1); } // File - Another.class public static void main(String[] args) { getPrintMessage().invoke(“Java”); }
  36. @iChanSek www.chansek.com // File - PrintKt.class public final class PrintKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = new Function1<String, Unit>() { @Override public Unit invoke(String msg) { System.out.println(“Hello” + msg); return Unit.INSTANCE; } } } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } }
  37. @iChanSek www.chansek.com // File - CalculatorKt.class public final class CalculatorKt

    { private static final Function1<String, Unit> printMessage; static { printMessage = new Function1<String, Unit>() { @Override public Unit invoke(String msg) { System.out.println(“Hello” + msg); return Unit.INSTANCE; } } } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } }
  38. @iChanSek www.chansek.com // File - CalculatorKt.class public final class CalculatorKt

    { private static final Function2<Integer, Integer, Integer> add; static { printMessage = new Function1<String, Unit>() { @Override public Unit invoke(String msg) { System.out.println(“Hello” + msg); return Unit.INSTANCE; } } } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } }
  39. @iChanSek www.chansek.com // File - CalculatorKt.class public final class CalculatorKt

    { private static final Function2<Integer, Integer, Integer> add; static { add = new Function2<Integer, Integer, Integer>() { @Override public Integer invoke(Integer p1, Integer p2) { return p1 + p2; } } } public static final Function1<String, Unit> getPrintMessage() { return printMessage; } }
  40. @iChanSek www.chansek.com // File - CalculatorKt.class public final class CalculatorKt

    { private static final Function2<Integer, Integer, Integer> add; static { add = new Function2<Integer, Integer, Integer>() { @Override public Integer invoke(Integer p1, Integer p2) { return p1 + p2; } } } public static final Function2<Integer, Integer, Integer> getAdd() { return add; } }
  41. @iChanSek www.chansek.com // File - CalculatorKt.class public final class CalculatorKt

    { private static final Function2<Integer, Integer, Integer> add; static { add = (p1, p2) -> p1 + p2; } public static final Function1<Integer, Integer, Integer> getAdd() { return add; } }
  42. kotlin.jvm.functions •A package from kotlin-stdlib •All functional interfaces that powers

    functional programming resides here •Function0..Function22 •FunctionN @iChanSek www.chansek.com
  43. public interface Function0<out R> : Function<R> { public operator fun

    invoke(): R } Return Type No Parameter @iChanSek www.chansek.com
  44. Return Type One Parameter public interface Function1<in P1, out R>

    : Function<R> { public operator fun invoke(p1: P1): R } @iChanSek www.chansek.com
  45. Return Type Two Parameters public interface Function2<in P1, in P2,

    out R> : Function<R> { public operator fun invoke(p1: P1, p2: P2): R } @iChanSek www.chansek.com
  46. Return Type Three Parameters @iChanSek www.chansek.com public interface Function3<in P1,

    in P2, in P3, out R> : Function<R> { public operator fun invoke(p1: P1, p2: P2, p3: P3): R }
  47. Overriden from FunctionBase @iChanSek www.chansek.com interface FunctionN<out R> : Function<R>,

    FunctionBase<R> { operator fun invoke(vararg args: Any?): R override val arity: Int }
  48. Usecases •You are jelous of someone •You have not got

    any PR comments •You want to experience the tension of being fired •Many more… @iChanSek www.chansek.com
  49. @iChanSek www.chansek.com fun onCreate() { button.setOnClickListener { view -> print("Clicked

    $view") } } final class <Class Name>$<Method Name>$1 implements OnClickListener { public static final 1 INSTANCE = new 1(); public final void onClick(View view) { System.out.print("Clicked" + view); } }
  50. @iChanSek www.chansek.com fun onCreate() { button.setOnClickListener { view -> print("Clicked

    $view") } } final class <Class Name>$<Method Name>$1 implements OnClickListener { public static final 1 INSTANCE = new 1(); public final void onClick(View view) { System.out.print("Clicked" + view); } } public final void onCreate() { button.setOnClickListener( (OnClickListener) <Class>.1.INSTANCE ); }
  51. @iChanSek www.chansek.com public interface OnClickListener { void onClick(View view); }

    interface OnClickListener { fun onClick(view: View) } button.setOnClickListener { view -> println("Clicked $view") }
  52. @iChanSek www.chansek.com public interface OnClickListener { void onClick(View view); }

    interface OnClickListener { fun onClick(view: View) } button.setOnClickListener { view -> println("Clicked $view") }
  53. @iChanSek www.chansek.com lateinit var success: (Response) -> Unit lateinit var

    error: (Error) -> Unit fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code }
  54. @iChanSek www.chansek.com lateinit var success: (Response) -> Unit lateinit var

    error: (Error) -> Unit fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code } fun main(args: Array<String>) { success = ::onSuccess error = ::onError }
  55. @iChanSek www.chansek.com lateinit var success: (Response) -> Unit lateinit var

    error: (Error) -> Unit fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code } fun main(args: Array<String>) { success = ::onSuccess error = ::onError onSuccess(Response) onError(Error) }
  56. @iChanSek www.chansek.com lateinit var success: (Response) -> Unit lateinit var

    error: (Error) -> Unit fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code } fun main(args: Array<String>) { success = ::onSuccess error = ::onError success(Response) error(Error) }
  57. @iChanSek www.chansek.com public static Function1 success; public static Function1 error;

    fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code } fun main(args: Array<String>) { success = ::onSuccess error = ::onError success(Response) error(Error) }
  58. @iChanSek www.chansek.com public static Function1 success; public static Function1 error;

    fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code } fun main(args: Array<String>) { success = (Function1)...1.INSTANCE; error = (Function1)...2.INSTANCE; success(Response) error(Error) }
  59. @iChanSek www.chansek.com public static Function1 success; public static Function1 error;

    fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code } fun main(args: Array<String>) { success = (Function1)…1.INSTANCE; error = (Function1)…2.INSTANCE; success.invoke(new Response()) error.invoke(new Error()) }
  60. @iChanSek www.chansek.com public static Function1 success; public static Function1 error;

    fun onSuccess(resp: Response) { // Some code } fun onError(error: Error) { // Some code } fun main(args: Array<String>) { success = (Function1)…1.INSTANCE; error = (Function1)…2.INSTANCE; success.invoke(new Response()) error.invoke(new Error()) }
  61. @iChanSek www.chansek.com fun main(args: Array<String>) { val fruits = listOf("Apple",

    "Banana", "Coconut", "Grape") fruits.filter { it.length > 4 } }
  62. @iChanSek www.chansek.com fun main(args: Array<String>) { val fruits = listOf("Apple",

    "Banana", "Coconut", "Grape") fruits.filter { it.length > 4 } } public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> { return filterTo(ArrayList<T>(), predicate) } Result Function