From 516603a9484b2e0d98d9bfd20f404a4ecb338c22 Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Sat, 18 Aug 2018 09:25:02 -0400 Subject: [PATCH] Convert tail calls to kotlin --- src/main/kotlin/recursion/TailCall.java | 25 -------------------- src/main/kotlin/recursion/TailCall.kt | 13 +++++++++++ src/main/kotlin/recursion/TailCalls.java | 28 ----------------------- src/main/kotlin/recursion/TailCalls.kt | 16 +++++++++++++ src/test/kotlin/recursion/TailCallTest.kt | 4 ++-- 5 files changed, 31 insertions(+), 55 deletions(-) delete mode 100644 src/main/kotlin/recursion/TailCall.java create mode 100644 src/main/kotlin/recursion/TailCall.kt delete mode 100644 src/main/kotlin/recursion/TailCalls.java create mode 100644 src/main/kotlin/recursion/TailCalls.kt diff --git a/src/main/kotlin/recursion/TailCall.java b/src/main/kotlin/recursion/TailCall.java deleted file mode 100644 index 0facd50..0000000 --- a/src/main/kotlin/recursion/TailCall.java +++ /dev/null @@ -1,25 +0,0 @@ -package recursion; - -import java.util.stream.Stream; - -@FunctionalInterface -public interface TailCall { - - TailCall apply(); - - default boolean isComplete() { - return false; - } - - default T result() { - throw new UnsupportedOperationException(); - } - - default T invoke() { - return Stream.iterate(this, TailCall::apply) - .filter(TailCall::isComplete) - .findFirst() - .get() - .result(); - } -} diff --git a/src/main/kotlin/recursion/TailCall.kt b/src/main/kotlin/recursion/TailCall.kt new file mode 100644 index 0000000..97bde28 --- /dev/null +++ b/src/main/kotlin/recursion/TailCall.kt @@ -0,0 +1,13 @@ +package recursion + +@FunctionalInterface +interface TailCall { + + fun isComplete() = false + fun apply(): TailCall + fun result(): T = throw UnsupportedOperationException() + + operator fun invoke() = generateSequence(this) { it.apply() } + .first { it.isComplete() } + .result() +} diff --git a/src/main/kotlin/recursion/TailCalls.java b/src/main/kotlin/recursion/TailCalls.java deleted file mode 100644 index 3950b2f..0000000 --- a/src/main/kotlin/recursion/TailCalls.java +++ /dev/null @@ -1,28 +0,0 @@ -package recursion; - -public class TailCalls { - - public static TailCall tailCall(TailCall nextCall) { - return nextCall; - } - - public static TailCall done(T value) { - return new TailCall() { - - @Override - public boolean isComplete() { - return true; - } - - @Override - public T result() { - return value; - } - - @Override - public TailCall apply() { - throw new UnsupportedOperationException(); - } - }; - } -} \ No newline at end of file diff --git a/src/main/kotlin/recursion/TailCalls.kt b/src/main/kotlin/recursion/TailCalls.kt new file mode 100644 index 0000000..1c9d7f7 --- /dev/null +++ b/src/main/kotlin/recursion/TailCalls.kt @@ -0,0 +1,16 @@ +package recursion + +object TailCalls { + + @JvmStatic + fun tailCall(nextCall: () -> TailCall) = object : TailCall { + override fun apply() = nextCall() + } + + @JvmStatic + fun done(value: T) = object : TailCall { + override fun isComplete() = true + override fun result() = value + override fun apply() = throw UnsupportedOperationException() + } +} \ No newline at end of file diff --git a/src/test/kotlin/recursion/TailCallTest.kt b/src/test/kotlin/recursion/TailCallTest.kt index 9e0ef74..82471a3 100644 --- a/src/test/kotlin/recursion/TailCallTest.kt +++ b/src/test/kotlin/recursion/TailCallTest.kt @@ -8,13 +8,13 @@ class TailCallTest { @Test fun `tailCall does not support result`() { - val tailCall = TailCall { null } + val tailCall = object : TailCall { override fun apply() = done(null) } assertThrows(UnsupportedOperationException::class.java) { tailCall.result() } } @Test fun `done does not support apply`() { - assertThrows(UnsupportedOperationException::class.java) { done(null).apply() } + assertThrows(UnsupportedOperationException::class.java) { done(null).apply() } } }