SlideShare a Scribd company logo
Tailrec Through
The Ages
Until Kotlin
1950 through to 2016
By João Esperancinha (2024/03/01)
Who am I?
Overview
Understanding the problems
Project objective
Target audience
Market trends
Cycle diagram
Introducing: Lorem ipsum
Spotlight on desktop
Spotlight on mobile
Spotlight on landscape view on mobile
Spotlight on wearables
Spotlight on tablet
Spotlight on landscape view on tablet
Spotlight on wearables
João Esperancinha
● Java
● Kotlin
● Groovy
● Scala
● Software Engineer 10+ years
● JESPROTECH owner for 1 year
● Kong Champion/Java Professional/Spring Professional
Project timeline
What is Tail
Recursivity?
Tail
What is tailrec?
● Recursivity
No, not just any
recursivity
Any Recursivity?
● Tail recursivity
● The last function call!
And then?
What defines a tail recursive function?
A recursive function is said to be tail recursive
when:
● The last function call is the call to the
recursive function
● The last function call doesn’t occur in
combination with any calculated value or
any other function call
● In other words nothing should be stored per
stack frame
Awesome!
When did Tailrec become a thing?
01 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eleifend a diam
quis suscipit. Class aptent taciti sociosqu ad litora et nec torquent per conubia
nostra.
02 Amet, consectetur adipiscing elit. Curabitur eleifend a diam quis suscipit. Class
aptent taciti The ad litora torquent per conubia nostra.fd
03 Consectetur adipiscing elit. Curabitur eleifend lorem a diam quis suscipit. Class
aptent taciti sociosqu ad litora torquent ipsum per conubia nostra.
Late 1950’s computing studies showed that tail
recursive algorithms could be easily reimplemented
with iterative alternatives, making them more
efficient
No more usage of Stack Frames
No need to hold values in memory for every iteration
Tail Recursivity
Became a thing!
Space complexity reduced to O(1)
Recursivity
through the
years
The 1950’s
1957 - IBM Mathematical Formula Translating System, or
Fortran. Created by John Backus team
1959 - COBOL by CODASYL
(Conference/Committee on Data Systems Languages)
1958 - LISP by John McCarthy
By Jooja
CC BY-SA 4.0 DEED
By PIerre.Lescanne
CC BY-SA 4.0 DEED
John Backus
By WikiPedant
CC BY-SA 2.0 DEED
John McCarthy
By Jonathan Schilling
CC BY-SA 4.0 DEED
COBOL punch cards
The 1970’s to the 90’s
● 1983-84 - Standard ML(Meta Language) by Robin Milner,
Mads Tofte, and others at the University of Edinburgh
● 1975 - Scheme by Gerald Jay Sussman and Guy L. Steele Jr
● 1990 - Haskell named after Haskell
Curry and released by committee of
researchers and academics
● 1986 - Erlang by Joe Armstrong,
Robert Virding, and Mike Williams at
Ericsson
By Magnus Manske
CC BY-SA 1.0 DEED
Gerald Jay Sussman
By George Ruban
CC BY-SA 4.0 DEED
Guy L. Steele Jr
By Flavbeli
CC BY 2.0 DEED
University of Edinburgh
The 1990’s to 2016 - JVM Evolution
● 2007 Clojure by Rich Hickey
● 1995 - Java by Sun Microsystems,
however the invention of Java is attributed to James Gosling
and colleagues Mike Sheridan, and Patrick Naughton
● 2016 by the team led by Andrey
Breslav
● 2003 Scala by Martin Odersky
James Gosling
By Peter Campbell
CC BY-SA 4.0 DEED
Rich Hickey
By Tapestry Dude - Flickr
CC BY-SA 2.0 DEED
Martin Odersky
By LindaPoengPhotography
CC BY 3.0 DEED
By Lightbend, Inc.
CC BY 4.0 DEED
What was the whole point?
● Function Simplification
● Use recursivity without impacting performance
● Make code easy to read
● Avoid the usage of global variables
● Adhere to immutability principles
Much later on…
Pseudo-code
Example
A pseudo-code example
function fibonacci(n) = {
var result = 0
var next = 1
var i = 0
while (i < n) {
val temp = next
next = result + next
result = temp
i += 1
}
return result
}
Leonardo of Pisa
By Hans-Peter Postel
CC BY 2.5 DEED
Statue of Fibonacci (1863) by
Giovanni Paganucci in the
Camposanto di Pisa
Fibonacci Sequence
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 … etc
F(n) = F(n-1) + F(n-2)
Iterations
● Efficient 👍
● Difficult to Read 👎
O(n) time / O(1) space
By Romain
CC BY-SA 4.0 DEED
Graphical
representation
A pseudo-code example
function fibonacci(n) {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
Fibonacci Sequence
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 … etc
F(n) = F(n-1) + F(n-2)
Recursivity
● Not very efficient 👎
● Easier to read 👍
O(2^n) time / O(2^n) space
function fibonacci(n) {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
function fibonacci(n) {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
function fibonacci(n) {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
function fibonacci(n) {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
function fibonacci(n) {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
function fibonacci(n) {
if (n <= 1) {
return n
} else {
return fibonacci(n - 1) + fibonacci(n - 2)
}
}
(…) (…) (…) (…)
A pseudo-code example
Fibonacci Sequence
0, 1, 1, 2, 3, 5, 8, 13, 21, 34 … etc
F(n) = F(n-1) + F(n-2)
Tail Recursivity
● Back to being efficient 👍
● Still easy to read, but less 👎
O(n) time / O(1) space
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) result
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
● Efficiency isn’t 100% guaranteed 👎
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) result
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) result
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) result
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) result
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) result
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) result
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
(…)
Applying TCO
Tail Call Optimization
function fibonacci(n) {
function fiboHelper(n, result, next) {
if (n == 0) next
else return fiboHelper(n - 1, next, result + next)
}
return fiboHelper(n, 0, 1)
}
function fibonacci(n) {
function fiboHelper(n) = {
var result = 0
var next = 1
var i = 0
while (i < n) {
val temp = next
next = result + next
result = temp
i += 1
}
return result
}
}
How we implement…
… how we would have implemented in the result
Fortran
Example
The Beginnings with Fortran - 1957
● Fortran I: 1957
● Fortran II: 1958
● Fortran III: Not released
● Fortran IV: 1962
● Fortran 66: 1966
● Fortran 77: 1977
● Fortran 90: 1991
● Fortran 95: 1997
● Fortran 2003: 2004
● Fortran 2008: 2010
● Fortran 2018: 2018
PROGRAM FIBONACCI
INTEGER N, I
REAL F1, F2, FIB
N = 100
F1 = 0
F2 = 1
DO I = 2, N
FIB = F1 + F2
F1 = F2
F2 = FIB
END DO
WRITE(*,*) FIB
END
PROGRAM RECURSIVE_FIBONACCI_REAL
INTEGER N
N = 100
DO I = 0, N - 1
CALL fibonacci_real(I, Result)
END DO
WRITE(*, *) Result
CONTAINS
RECURSIVE SUBROUTINE fibonacci_real(N, Result)
INTEGER N
REAL Result
IF (N <= 1) THEN
Result = REAL(N)
ELSE
CALL fibonacci_real(N - 1, Result1)
CALL fibonacci_real(N - 2, Result2)
Result = Result1 + Result2
END IF
END SUBROUTINE fibonacci_real
END
Recursivity
Fortran nowadays (since 1991)
program Fibonacci
implicit none
integer :: n, i
real :: fib_prev, fib_current, result
n = 100
fib_prev = 0
fib_current = 1
do i = 1, n
if (i <= 1) then
result = i
else
result = fib_prev + fib_current
fib_prev = fib_current
fib_current = result
end if
end do
print *, "The result is", result
end program Fibonacci
program FibonacciTailRecursive
implicit none
integer :: n, i
real :: result
n = 100
result = fibonacci(n)
print *, "The result is", result
contains
recursive function fibonacci(n) result(fib)
integer, intent(in) :: n
integer :: fib
if (n == 0) then
fib = 0
else if (n == 1) then
fib = 1
else
fib = fibonacci(n - 1) + fibonacci(n - 2)
end if
end function fibonacci
end program FibonacciTailRecursive
program FibonacciTailRecursive
implicit none
integer :: n
real :: result
n = 100
result = fibonacci(n)
print *, "The result is", result
contains
recursive function fibonacci(n) result(fib)
integer, intent(in) :: n
real :: fib
if (n <= 1) then
fib = n
else
fib = fibonacci_helper(n, 0.0, 1.0)
end if
end function fibonacci
recursive function fibonacci_helper(n, a, b) result(fib)
integer, intent(in) :: n
real :: fib, a, b
if (n == 0) then
fib = a
else if (n == 1) then
fib = b
else
fib = fibonacci_helper(n - 1, b, a + b)
end if
end function fibonacci_helper
end program FibonacciTailRecursive
Lisp
Example
LISP 1958
(defun fibonacci-iterative (n)
(if (<= n 1)
n
(fib-iter 0 1 n)))
(defun fib-iter (a b count)
(loop repeat (- count 1)
do (setf (values a b) (values b (+ a b)))
finally (return b)))
(defun fibonacci-recursive (n)
(if (<= n 1)
n
(+ (fibonacci-recursive (- n 1))
(fibonacci-recursive (- n 2)))))
● Lisp: 1958
● Lisp 1.5: 1962
● MacLisp: Late 1960s
● InterLisp: 1966
● Common Lisp: 1984
(defun fibonacci-tail-recursive (n)
(if (<= n 1)
n
(fib-tail-recursive 0 1 n)))
(defun fib-tail-recursive (a b count)
(if (= count 0)
a
(fib-tail-recursive b (+ a b) (- count 1))))
COBOL
Example
COBOL 1959
IDENTIFICATION DIVISION.
PROGRAM-ID. Fibonacci.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 F1 PIC 9(21)V9(1) VALUE 0.0.
01 F2 PIC 9(21)V9(1) VALUE 1.0.
01 FIB PIC 9(21)V9(1).
01 N PIC 9(5) VALUE 100.
01 I PIC 9(5) VALUE 3.
PROCEDURE DIVISION.
MAIN-LOGIC.
PERFORM VARYING I FROM 2 BY 1 UNTIL I
> N
COMPUTE FIB = F1 + F2
COMPUTE F1 = F2
COMPUTE F2 = FIB
END-PERFORM.
DISPLAY FIB.
STOP RUN.
IDENTIFICATION DIVISION.
PROGRAM-ID. FibonacciRecursive.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 F1 PIC 9(21)V9(1) VALUE 0.0.
01 F2 PIC 9(21)V9(1) VALUE 1.0.
01 FIB PIC 9(21)V9(1).
01 N PIC 9(5) VALUE 100.
01 I PIC 9(5) VALUE 0.
PROCEDURE DIVISION.
MOVE N TO I
CALL 'FIBONACCI'.
DISPLAY "Fibonacci of " I " is " F1.
STOP RUN.
ENTRY 'FIBONACCI'.
IF N = 0 THEN
EXIT PROGRAM
ELSE
COMPUTE FIB = F1 + F2
COMPUTE F1 = F2
COMPUTE F2 = FIB
SUBTRACT 1 FROM N
CALL 'FIBONACCI'
END-IF.
● COBOL 60 - 1960.
● COBOL 61 - 1961.
● COBOL 65 - 1965.
● COBOL 68 - 1968
● COBOL 74 - 1974
● COBOL 85 - 1985
● COBOL 2002 - 2002
● COBOL 2014 - 2014
Recursivity
Scheme
Example
Scheme - 1975
(define (fibonacci n)
(fibonacci-iter n 0 1))
(define (fibonacci-iter n a b)
(do ((i n (- i 1))
(x a b)
(y b (+ a b)))
((= i 0) x)
(set! a x)
(set! b y)))
(define (fibonacci n)
(if (or (= n 0) (= n 1))
n
(+ (fibonacci (- n 1)) (fibonacci (- n 2)))))
(display (fibonacci 100))
● Scheme 75: 1975
● Scheme 84: 1984
● Several follow up
releases until 2013
(define (fibonacci n)
(define (fib-helper n a b)
(if (= n 0)
a
(fib-helper (- n 1) b (+ a b))))
(fib-helper n 0 1))
(display (fibonacci 100))
SML
Example
Standard Meta Language - 1983/84
● Moby: Moby - 1980’s
● SML/NJ - 1983/1984
● MLton - 1999
● SML '90 - 1990
● SML '97 - 1997
● SML 2007 - 2007
● SML 2022 - 2022
fun fibonacci n =
if n < 2 then n
else fibonacci (n - 1) + fibonacci (n - 2);
structure IntInf = IntInf
fun fibonacci n =
let
fun fibIter n a b =
if n = 0 then
a
else
fibIter (n - 1) b (IntInf.+(a, b))
in
fibIter n 0 1
end;
Erlang
Example
Erlang - 1986
● Erlang 1986 - First
proprietary release
● Erlang/OTP R1
(1996) - First
commercial release
● Erlang/OTP 24 -
Erlang until 2021
-module(fibonacci_recursive).
-export([fib/1]).
fib(0) -> 0;
fib(1) -> 1;
fib(N) when N > 1 ->
fib(N - 1) + fib(N - 2).
-module(fibonacci_recursive_tco).
-export([fib/1]).
fib(N) when N < 2 ->
N;
fib(N) ->
fib_iter(N, 0, 1).
fib_iter(0, A, _) ->
A;
fib_iter(N, A, B) ->
fib_iter(N - 1, B, A + B).
Haskell
Example
Haskell - 1990
● First draft - 1987
● Haskell 1.0 - 1990
● Haskell 1.1 - 1991
● Haskell 1.2 - 1992
● Haskell 1.3 - 1996
● Haskell 1.4 - 1997
● Haskell 98 - 1998
● Haskell 2010 - 2010
● Haskell 2022 - 2022
fibonacci :: Integer -> Integer
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n - 1) + fibonacci (n -
2)
main :: IO ()
main = do
let result = fibonacci 1000
putStrLn $ "Fibonacci of the order of 1000:
" ++ show result
fibonacciTailRec :: Integer -> Integer
fibonacciTailRec n = fibonacciHelper n 0 1
where
fibonacciHelper 0 a _ = a
fibonacciHelper 1 _ b = b
fibonacciHelper n a b = fibonacciHelper
(n - 1) b (a + b)
main :: IO ()
main = do
let result = fibonacciTailRec 1000
putStrLn $ "Fibonacci of the order of
1000: " ++ show result
Java
Example
About Java - 1995
Java deliberately doesn’t support Tail Call Optimization because:
● Backward compatibility
● It might not go well with the JVM architecture because of overhead and potential side-effects.
● Performance and complexity
● The iterative alternative is always possible
● Not very clear if TCO is the best idea for Java
But this didn’t stop JVM alternative
languages to explore TCO possibilities...
Scala
Example
Scala - 2003
● Scala 1.0 - 2003
● Scala 2.0 - 2006
● Scala 2.7 - 2009
● Scala 2.8 - 2010
● Scala 2.9 - 2011
● Scala 2.10 - 2012
● Scala 2.11 - 2014
● Scala 2.12 - 2016
● Scala 2.13 - 2019
● Scala 3 (previously
known as Dotty) -
2020
def fibonacciIterative(n: Double): Double = {
var a = 0f
var b = 1f
var i = 0f
while (i < n) {
val temp = b
b = a + b
a = temp
i += 1
}
a
}
def fibonacciRecursive(n: Double): Double = {
if (n <= 1f) {
n
} else {
fibonacciRecursive(n - 1f) + fibonacciRecursive(n - 2f)
}
}
def fibonacciTailRec(n: Double): Double = {
def fibHelper(n: Double, a: Double, b:
Double): Double = {
if (n == 0.0) a
else fibHelper(n - 1.0, b, a + b)
}
fibHelper(n, 0.0, 1.0)
}
Scala - 2003
● Scala 1.0 - 2003
● Scala 2.0 - 2006
● Scala 2.7 - 2009
● Scala 2.8 - 2010
● Scala 2.9 - 2011
● Scala 2.10 - 2012
● Scala 2.11 - 2014
● Scala 2.12 - 2016
● Scala 2.13 - 2019
● Scala 3 (previously
known as Dotty) -
2020
def fibonacciTailRecTCO(n: Double): Double
= {
@annotation.tailrec
def fibHelper(n: Double, a: Double, b:
Double): Double = {
if (n == 0f) a
else fibHelper(n - 1f, b, a + b)
}
fibHelper(n, 0f, 1f)
}
def fibonacciTailRecManualTCO(n: Double):
Double = {
def fibHelper(n: Double, a: Double, b:
Double): Double = {
var a = 0f
var b = 1f
var i = 0f
while (i < n) {
val temp = b
b = a + b
a = temp
i += 1
}
a
if (n == 0.0) a
else fibHelper(n - 1.0, b, a + b)
}
fibHelper(n, 0.0, 1.0)
}
Scala - 2003
def fibonacciTailRecTCO(n: Double): Double = {
@annotation.tailrec
def fibHelper(n: Double, a: Double, b: Double): Double =
{
if (n == 0f) a
else fibHelper(n - 1f, b, a + b)
}
fibHelper(n, 0f, 1f)
}
def factorialUnMarked(n: Double): Double = {
def factorialHelper(n: Double): Double = {
if (n <= 1f) 1f
else n * factorialHelper(n - 1f)
}
factorialHelper(n)
}
public static double factorialUnMarked(double var0) {
return Fibonacci$.MODULE$.factorialUnMarked(var0);
}
public double factorialUnMarked(final double n) {
return this.factorialHelper$1(n);
}
private final double factorialHelper$1(final double n) {
return n <= 1.0 ? 1.0 : n * this.factorialHelper$1(n - 1.0);
}
public static double fibonacciTailRecTCO(double var0) {
return Fibonacci$.MODULE$.fibonacciTailRecTCO(var0);
}
public double fibonacciTailRecTCO(final double n) {
return this.fibHelper$3(n, 0.0, 1.0);
}
private final double fibHelper$3(final double n, final double a, final
double b) {
while(n != 0.0) {
double var7 = n - 1.0;
double var11 = a + b;
n = var7;
a = b;
b = var11;
}
return a;
}
Clojure
Example
Clojure - 2007
(defn fibonacci-iterative [n]
(if (<= n 1)
n
(loop [a 0
b 1
i 1]
(if (= i n)
(+ a b)
(recur b (+ a b) (inc i))))))
(defn fibonacci-recursive [n]
(let [n (if (instance? String n)
(Double/parseDouble n)
n)]
(if (<= n 1.0)
n
(+ (fibonacci-recursive (- n 1.0)) (fibonacci-recursive (- n 2.0))))))
(defn fibonacci-tail-rec [n]
(let [n (if (instance? String n)
(Double/parseDouble n)
n)]
(letfn [(fib-tail [n a b]
(if (zero? n)
a
(fib-tail (dec n) b (+ a b))))]
(fib-tail n 0.0 1.0))))
● First version - 2007
● Clojure 1.0 - 2009
● Clojure until 1.11.1 in
2022
Clojure - 2007
● First version - 2007
● Clojure 1.0 - 2009
● Clojure until 1.11.1 in
2022
(defn fibonacci-tail-rec-tco [n]
(let [n (if (instance? String n)
(Double/parseDouble n)
n)]
(letfn [(fib [n a b]
(if (zero? n)
a
(recur (dec n) b (+ a b))))]
(fib n 0.0 1.0))))
Kotlin
Example
Kotlin - 2016
● Kotlin 1.0 - 2016
● Kotlin 1.1 - 2017
● Kotlin 1.2 - 2017
● Kotlin 1.3 - 2018
● Kotlin 1.4 - 2020
● Kotlin 1.5 - 2021
● Kotlin 1.6 - 2021
● Kotlin 1.7 - 2022
● Kotlin 1.8 - 2023
● Kotlin 1.9 - 2023
private fun fibonacciIterative(n: Int): Double
{
if (n <= 1) {
return n.toDouble()
}
var a = 0.0
var b = 1.0
for (i in 2..n) {
val temp = a + b
a = b
b = temp
}
return b
}
fun fibonacciRecursive(n: Int): Double =
if (n <= 1) n.toDouble()
else
fibonacciRecursive(n - 1) +
fibonacciRecursive(n - 2)
private fun fibonacciTailRecursive(
n: Int,
a: Double = 0.0,
b: Double = 1.0
): Double = if (n == 0) a
else fibonacciTailRecursive(n - 1, b, a + b)
Kotlin - 2016
private tailrec fun fibonacciTailRecursiveTCO(
n: Int,
a: Double = 0.0,
b: Double = 1.0
): Double = if (n == 0) a
else fibonacciTailRecursiveTCO(n - 1, b, a + b)
● Kotlin 1.0 - 2016
● Kotlin 1.1 - 2017
● Kotlin 1.2 - 2017
● Kotlin 1.3 - 2018
● Kotlin 1.4 - 2020
● Kotlin 1.5 - 2021
● Kotlin 1.6 - 2021
● Kotlin 1.7 - 2022
● Kotlin 1.8 - 2023
● Kotlin 1.9 - 2023
Kotlin - 2016
private tailrec fun fibonacciTailRecursiveTCO(
n: Int,
a: Double = 0.0,
b: Double = 1.0
): Double = if (n == 0) a
else fibonacciTailRecursiveTCO(n - 1, b, a + b)
private fun fibonacciTailRecursive(
n: Int,
a: Double = 0.0,
b: Double = 1.0
): Double = if (n == 0) a
else fibonacciTailRecursive(n - 1, b, a + b)
private final double fibonacciTailRecursive(int n, double a, double b) {
return n == 0 ? a : ((Companion)this).fibonacciTailRecursive(n - 1, b, a + b);
}
// $FF: synthetic method
static double fibonacciTailRecursive$default(Companion var0, int var1,
double var2, double var4, int var6, Object var7) {
if ((var6 & 2) != 0) {
var2 = 0.0;
}
if ((var6 & 4) != 0) {
var4 = 1.0;
}
return var0.fibonacciTailRecursive(var1, var2, var4);
}
private final double fibonacciTailRecursiveTCO(int n, double a, double b) {
while(n != 0) {
Companion var10000 = (Companion)this;
int var10001 = n - 1;
double var10002 = b;
b += a;
a = var10002;
n = var10001;
}
return a;
}
// $FF: synthetic method
static double fibonacciTailRecursiveTCO$default(Companion var0, int var1,
double var2, double var4, int var6, Object var7) {
if ((var6 & 2) != 0) {
var2 = 0.0;
}
if ((var6 & 4) != 0) {
var4 = 1.0;
}
return var0.fibonacciTailRecursiveTCO(var1, var2, var4);
}
Conclusion
Conclusions
● Which direction is this all taking?
● Is programming still a challenge?
● Why do we do software development?
● Are we being forced into thinking recursively?
● Is Mutability something to be completely removed from a programming language?
● Productivity vs The Joy of Coding
● What happens when we keep thinking only recursively when implementing algorithms?
● Can we blindly rely on the TCO algorithms in the way that we already trust Garbage Collection?
● Do we trust Garbage Collection?
● Can we manually implement a better algorithm with better performance than TCO?
● Would we still be able to do it, if we don’t practice?
● Can we still produce without challenges in the long run?
Questions?
Resources for this presentation
Image sources
● https://commons.wikimedia.org/wiki/File:John_McCarthy_Stanford.jpg
● https://commons.wikimedia.org/wiki/File:John_Backus_2.jpg
● https://commons.wikimedia.org/wiki/File:Guy_Steele.jpg
● https://commons.wikimedia.org/wiki/File:Jerry_Sussman.jpg
● https://nl.wikipedia.org/wiki/Rij_van_Fibonacci#/media/Bestand:Fibonacci_Spiral.svg
● https://en.wikipedia.org/wiki/File:Fortran_logo.svg
● https://en.m.wikipedia.org/wiki/File:Lisp_logo.svg
● https://commons.wikimedia.org/wiki/File:IBM_keypunch_deck_for_Cobol_student_program_at_New_York_Universi
ty_1979.jpg
● https://commons.wikimedia.org/wiki/File:Lambda_lc.svg
● https://commons.wikimedia.org/wiki/File:Informatics_Forum_Atrium_turned.jpg
● https://commons.wikimedia.org/wiki/File:Ericsson_logo.svg
● https://commons.wikimedia.org/wiki/File:Erlang_logo.png
● https://en.wikipedia.org/wiki/File:Haskell-Logo.svg
● https://commons.wikimedia.org/wiki/File:James_Gosling_2008.jpg
● https://commons.wikimedia.org/wiki/File:Mark_Odersky_photo_by_Linda_Poeng.jpg
● https://commons.wikimedia.org/wiki/File:Scala-full-color.svg
● https://en.m.wikipedia.org/wiki/File:Clojure_logo.svg
● https://commons.wikimedia.org/wiki/File:Kotlin_logo_2021.svg
Resources for this presentation
● https://www.smlnj.org/sml.html
● https://en.wikibooks.org/wiki/Standard_ML_Programming/Types
● https://en.wikipedia.org/wiki/Standard_ML
● https://www.smlnj.org/
● https://www.scala-lang.org/
● https://kotlinlang.org/
● https://en.wikipedia.org/wiki/COBOL
● https://fortran-lang.org/
● https://www.java.com/en/
● https://developer.ibm.com/languages/cobol/
● https://www.haskell.org/
● https://www.erlang.org/
● https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gfortran/Code-Gen-Options.html
Data sources
Thank you!

More Related Content

Similar to Exploring Tailrec Through Time Until Kotlin.pptx

Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and Effects
Dylan Forciea
 
lecture4-recursion.pptx
lecture4-recursion.pptxlecture4-recursion.pptx
lecture4-recursion.pptx
Lizhen Shi
 
Sync considered unethical
Sync considered unethicalSync considered unethical
Sync considered unethical
💡 Tomasz Kogut
 
Class 18: Measuring Cost
Class 18: Measuring CostClass 18: Measuring Cost
Class 18: Measuring Cost
David Evans
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Codemotion
 
Recursion
RecursionRecursion
Recursion
James Wong
 
Functional go
Functional goFunctional go
Functional go
Geison Goes
 
Line Search Techniques by Fibonacci Search
Line Search Techniques by Fibonacci SearchLine Search Techniques by Fibonacci Search
Line Search Techniques by Fibonacci Search
inventionjournals
 
6-Python-Recursion.pdf
6-Python-Recursion.pdf6-Python-Recursion.pdf
6-Python-Recursion.pdf
AshishPalandurkar2
 
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
it-people
 
Chapter 02 functions -class xii
Chapter 02   functions -class xiiChapter 02   functions -class xii
Chapter 02 functions -class xii
Praveen M Jigajinni
 
Introduction to Python Programming | InsideAIML
Introduction to Python Programming | InsideAIMLIntroduction to Python Programming | InsideAIML
Introduction to Python Programming | InsideAIML
VijaySharma802
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
David Hoyt
 
Functional Programming You Already Know
Functional Programming You Already KnowFunctional Programming You Already Know
Functional Programming You Already Know
Kevlin Henney
 
Concept of scoping in programming languages
Concept of scoping in programming languagesConcept of scoping in programming languages
Concept of scoping in programming languages
Md. Jafar Sadik
 
orders of_growth
orders of_growthorders of_growth
orders of_growth
Rajendran
 
Introduction to Python Programming
Introduction to Python ProgrammingIntroduction to Python Programming
Introduction to Python Programming
VijaySharma802
 
02 functions, variables, basic input and output of c++
02   functions, variables, basic input and output of c++02   functions, variables, basic input and output of c++
02 functions, variables, basic input and output of c++
Manzoor ALam
 
Efficient Hill Climber for Multi-Objective Pseudo-Boolean Optimization
Efficient Hill Climber for Multi-Objective Pseudo-Boolean OptimizationEfficient Hill Climber for Multi-Objective Pseudo-Boolean Optimization
Efficient Hill Climber for Multi-Objective Pseudo-Boolean Optimization
jfrchicanog
 
functions
functionsfunctions
functions
Makwana Bhavesh
 

Similar to Exploring Tailrec Through Time Until Kotlin.pptx (20)

Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and Effects
 
lecture4-recursion.pptx
lecture4-recursion.pptxlecture4-recursion.pptx
lecture4-recursion.pptx
 
Sync considered unethical
Sync considered unethicalSync considered unethical
Sync considered unethical
 
Class 18: Measuring Cost
Class 18: Measuring CostClass 18: Measuring Cost
Class 18: Measuring Cost
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
 
Recursion
RecursionRecursion
Recursion
 
Functional go
Functional goFunctional go
Functional go
 
Line Search Techniques by Fibonacci Search
Line Search Techniques by Fibonacci SearchLine Search Techniques by Fibonacci Search
Line Search Techniques by Fibonacci Search
 
6-Python-Recursion.pdf
6-Python-Recursion.pdf6-Python-Recursion.pdf
6-Python-Recursion.pdf
 
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
 
Chapter 02 functions -class xii
Chapter 02   functions -class xiiChapter 02   functions -class xii
Chapter 02 functions -class xii
 
Introduction to Python Programming | InsideAIML
Introduction to Python Programming | InsideAIMLIntroduction to Python Programming | InsideAIML
Introduction to Python Programming | InsideAIML
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
 
Functional Programming You Already Know
Functional Programming You Already KnowFunctional Programming You Already Know
Functional Programming You Already Know
 
Concept of scoping in programming languages
Concept of scoping in programming languagesConcept of scoping in programming languages
Concept of scoping in programming languages
 
orders of_growth
orders of_growthorders of_growth
orders of_growth
 
Introduction to Python Programming
Introduction to Python ProgrammingIntroduction to Python Programming
Introduction to Python Programming
 
02 functions, variables, basic input and output of c++
02   functions, variables, basic input and output of c++02   functions, variables, basic input and output of c++
02 functions, variables, basic input and output of c++
 
Efficient Hill Climber for Multi-Objective Pseudo-Boolean Optimization
Efficient Hill Climber for Multi-Objective Pseudo-Boolean OptimizationEfficient Hill Climber for Multi-Objective Pseudo-Boolean Optimization
Efficient Hill Climber for Multi-Objective Pseudo-Boolean Optimization
 
functions
functionsfunctions
functions
 

More from João Esperancinha

Managing gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API GatewayManaging gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API Gateway
João Esperancinha
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
João Esperancinha
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
João Esperancinha
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
João Esperancinha
 
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptxDemystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
João Esperancinha
 
Unlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptxUnlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptx
João Esperancinha
 
Reactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptxReactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptx
João Esperancinha
 
KONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applicationsKONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applications
João Esperancinha
 

More from João Esperancinha (8)

Managing gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API GatewayManaging gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API Gateway
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
 
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptxDemystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
 
Unlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptxUnlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptx
 
Reactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptxReactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptx
 
KONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applicationsKONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applications
 

Recently uploaded

dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
Edge AI and Vision Alliance
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Tatiana Kojar
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
Dinusha Kumarasiri
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
Javier Junquera
 
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
Data Hops
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
Intelisync
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
Alex Pruden
 
SAP S/4 HANA sourcing and procurement to Public cloud
SAP S/4 HANA sourcing and procurement to Public cloudSAP S/4 HANA sourcing and procurement to Public cloud
SAP S/4 HANA sourcing and procurement to Public cloud
maazsz111
 

Recently uploaded (20)

dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
 
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3FREE A4 Cyber Security Awareness  Posters-Social Engineering part 3
FREE A4 Cyber Security Awareness Posters-Social Engineering part 3
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024A Comprehensive Guide to DeFi Development Services in 2024
A Comprehensive Guide to DeFi Development Services in 2024
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
 
SAP S/4 HANA sourcing and procurement to Public cloud
SAP S/4 HANA sourcing and procurement to Public cloudSAP S/4 HANA sourcing and procurement to Public cloud
SAP S/4 HANA sourcing and procurement to Public cloud
 

Exploring Tailrec Through Time Until Kotlin.pptx

  • 1. Tailrec Through The Ages Until Kotlin 1950 through to 2016 By João Esperancinha (2024/03/01)
  • 2. Who am I? Overview Understanding the problems Project objective Target audience Market trends Cycle diagram Introducing: Lorem ipsum Spotlight on desktop Spotlight on mobile Spotlight on landscape view on mobile Spotlight on wearables Spotlight on tablet Spotlight on landscape view on tablet Spotlight on wearables João Esperancinha ● Java ● Kotlin ● Groovy ● Scala ● Software Engineer 10+ years ● JESPROTECH owner for 1 year ● Kong Champion/Java Professional/Spring Professional Project timeline
  • 4. What is tailrec? ● Recursivity No, not just any recursivity Any Recursivity? ● Tail recursivity ● The last function call! And then?
  • 5. What defines a tail recursive function? A recursive function is said to be tail recursive when: ● The last function call is the call to the recursive function ● The last function call doesn’t occur in combination with any calculated value or any other function call ● In other words nothing should be stored per stack frame Awesome!
  • 6. When did Tailrec become a thing? 01 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eleifend a diam quis suscipit. Class aptent taciti sociosqu ad litora et nec torquent per conubia nostra. 02 Amet, consectetur adipiscing elit. Curabitur eleifend a diam quis suscipit. Class aptent taciti The ad litora torquent per conubia nostra.fd 03 Consectetur adipiscing elit. Curabitur eleifend lorem a diam quis suscipit. Class aptent taciti sociosqu ad litora torquent ipsum per conubia nostra. Late 1950’s computing studies showed that tail recursive algorithms could be easily reimplemented with iterative alternatives, making them more efficient No more usage of Stack Frames No need to hold values in memory for every iteration Tail Recursivity Became a thing! Space complexity reduced to O(1)
  • 8. The 1950’s 1957 - IBM Mathematical Formula Translating System, or Fortran. Created by John Backus team 1959 - COBOL by CODASYL (Conference/Committee on Data Systems Languages) 1958 - LISP by John McCarthy By Jooja CC BY-SA 4.0 DEED By PIerre.Lescanne CC BY-SA 4.0 DEED John Backus By WikiPedant CC BY-SA 2.0 DEED John McCarthy By Jonathan Schilling CC BY-SA 4.0 DEED COBOL punch cards
  • 9. The 1970’s to the 90’s ● 1983-84 - Standard ML(Meta Language) by Robin Milner, Mads Tofte, and others at the University of Edinburgh ● 1975 - Scheme by Gerald Jay Sussman and Guy L. Steele Jr ● 1990 - Haskell named after Haskell Curry and released by committee of researchers and academics ● 1986 - Erlang by Joe Armstrong, Robert Virding, and Mike Williams at Ericsson By Magnus Manske CC BY-SA 1.0 DEED Gerald Jay Sussman By George Ruban CC BY-SA 4.0 DEED Guy L. Steele Jr By Flavbeli CC BY 2.0 DEED University of Edinburgh
  • 10. The 1990’s to 2016 - JVM Evolution ● 2007 Clojure by Rich Hickey ● 1995 - Java by Sun Microsystems, however the invention of Java is attributed to James Gosling and colleagues Mike Sheridan, and Patrick Naughton ● 2016 by the team led by Andrey Breslav ● 2003 Scala by Martin Odersky James Gosling By Peter Campbell CC BY-SA 4.0 DEED Rich Hickey By Tapestry Dude - Flickr CC BY-SA 2.0 DEED Martin Odersky By LindaPoengPhotography CC BY 3.0 DEED By Lightbend, Inc. CC BY 4.0 DEED
  • 11. What was the whole point? ● Function Simplification ● Use recursivity without impacting performance ● Make code easy to read ● Avoid the usage of global variables ● Adhere to immutability principles Much later on…
  • 13. A pseudo-code example function fibonacci(n) = { var result = 0 var next = 1 var i = 0 while (i < n) { val temp = next next = result + next result = temp i += 1 } return result } Leonardo of Pisa By Hans-Peter Postel CC BY 2.5 DEED Statue of Fibonacci (1863) by Giovanni Paganucci in the Camposanto di Pisa Fibonacci Sequence 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 … etc F(n) = F(n-1) + F(n-2) Iterations ● Efficient 👍 ● Difficult to Read 👎 O(n) time / O(1) space By Romain CC BY-SA 4.0 DEED Graphical representation
  • 14. A pseudo-code example function fibonacci(n) { if (n <= 1) { return n } else { return fibonacci(n - 1) + fibonacci(n - 2) } } Fibonacci Sequence 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 … etc F(n) = F(n-1) + F(n-2) Recursivity ● Not very efficient 👎 ● Easier to read 👍 O(2^n) time / O(2^n) space function fibonacci(n) { if (n <= 1) { return n } else { return fibonacci(n - 1) + fibonacci(n - 2) } } function fibonacci(n) { if (n <= 1) { return n } else { return fibonacci(n - 1) + fibonacci(n - 2) } } function fibonacci(n) { if (n <= 1) { return n } else { return fibonacci(n - 1) + fibonacci(n - 2) } } function fibonacci(n) { if (n <= 1) { return n } else { return fibonacci(n - 1) + fibonacci(n - 2) } } function fibonacci(n) { if (n <= 1) { return n } else { return fibonacci(n - 1) + fibonacci(n - 2) } } function fibonacci(n) { if (n <= 1) { return n } else { return fibonacci(n - 1) + fibonacci(n - 2) } } (…) (…) (…) (…)
  • 15. A pseudo-code example Fibonacci Sequence 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 … etc F(n) = F(n-1) + F(n-2) Tail Recursivity ● Back to being efficient 👍 ● Still easy to read, but less 👎 O(n) time / O(1) space function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) result else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } ● Efficiency isn’t 100% guaranteed 👎 function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) result else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) result else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) result else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) result else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) result else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) result else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } (…)
  • 16. Applying TCO Tail Call Optimization function fibonacci(n) { function fiboHelper(n, result, next) { if (n == 0) next else return fiboHelper(n - 1, next, result + next) } return fiboHelper(n, 0, 1) } function fibonacci(n) { function fiboHelper(n) = { var result = 0 var next = 1 var i = 0 while (i < n) { val temp = next next = result + next result = temp i += 1 } return result } } How we implement… … how we would have implemented in the result
  • 18. The Beginnings with Fortran - 1957 ● Fortran I: 1957 ● Fortran II: 1958 ● Fortran III: Not released ● Fortran IV: 1962 ● Fortran 66: 1966 ● Fortran 77: 1977 ● Fortran 90: 1991 ● Fortran 95: 1997 ● Fortran 2003: 2004 ● Fortran 2008: 2010 ● Fortran 2018: 2018 PROGRAM FIBONACCI INTEGER N, I REAL F1, F2, FIB N = 100 F1 = 0 F2 = 1 DO I = 2, N FIB = F1 + F2 F1 = F2 F2 = FIB END DO WRITE(*,*) FIB END PROGRAM RECURSIVE_FIBONACCI_REAL INTEGER N N = 100 DO I = 0, N - 1 CALL fibonacci_real(I, Result) END DO WRITE(*, *) Result CONTAINS RECURSIVE SUBROUTINE fibonacci_real(N, Result) INTEGER N REAL Result IF (N <= 1) THEN Result = REAL(N) ELSE CALL fibonacci_real(N - 1, Result1) CALL fibonacci_real(N - 2, Result2) Result = Result1 + Result2 END IF END SUBROUTINE fibonacci_real END Recursivity
  • 19. Fortran nowadays (since 1991) program Fibonacci implicit none integer :: n, i real :: fib_prev, fib_current, result n = 100 fib_prev = 0 fib_current = 1 do i = 1, n if (i <= 1) then result = i else result = fib_prev + fib_current fib_prev = fib_current fib_current = result end if end do print *, "The result is", result end program Fibonacci program FibonacciTailRecursive implicit none integer :: n, i real :: result n = 100 result = fibonacci(n) print *, "The result is", result contains recursive function fibonacci(n) result(fib) integer, intent(in) :: n integer :: fib if (n == 0) then fib = 0 else if (n == 1) then fib = 1 else fib = fibonacci(n - 1) + fibonacci(n - 2) end if end function fibonacci end program FibonacciTailRecursive program FibonacciTailRecursive implicit none integer :: n real :: result n = 100 result = fibonacci(n) print *, "The result is", result contains recursive function fibonacci(n) result(fib) integer, intent(in) :: n real :: fib if (n <= 1) then fib = n else fib = fibonacci_helper(n, 0.0, 1.0) end if end function fibonacci recursive function fibonacci_helper(n, a, b) result(fib) integer, intent(in) :: n real :: fib, a, b if (n == 0) then fib = a else if (n == 1) then fib = b else fib = fibonacci_helper(n - 1, b, a + b) end if end function fibonacci_helper end program FibonacciTailRecursive
  • 21. LISP 1958 (defun fibonacci-iterative (n) (if (<= n 1) n (fib-iter 0 1 n))) (defun fib-iter (a b count) (loop repeat (- count 1) do (setf (values a b) (values b (+ a b))) finally (return b))) (defun fibonacci-recursive (n) (if (<= n 1) n (+ (fibonacci-recursive (- n 1)) (fibonacci-recursive (- n 2))))) ● Lisp: 1958 ● Lisp 1.5: 1962 ● MacLisp: Late 1960s ● InterLisp: 1966 ● Common Lisp: 1984 (defun fibonacci-tail-recursive (n) (if (<= n 1) n (fib-tail-recursive 0 1 n))) (defun fib-tail-recursive (a b count) (if (= count 0) a (fib-tail-recursive b (+ a b) (- count 1))))
  • 23. COBOL 1959 IDENTIFICATION DIVISION. PROGRAM-ID. Fibonacci. DATA DIVISION. WORKING-STORAGE SECTION. 01 F1 PIC 9(21)V9(1) VALUE 0.0. 01 F2 PIC 9(21)V9(1) VALUE 1.0. 01 FIB PIC 9(21)V9(1). 01 N PIC 9(5) VALUE 100. 01 I PIC 9(5) VALUE 3. PROCEDURE DIVISION. MAIN-LOGIC. PERFORM VARYING I FROM 2 BY 1 UNTIL I > N COMPUTE FIB = F1 + F2 COMPUTE F1 = F2 COMPUTE F2 = FIB END-PERFORM. DISPLAY FIB. STOP RUN. IDENTIFICATION DIVISION. PROGRAM-ID. FibonacciRecursive. DATA DIVISION. WORKING-STORAGE SECTION. 01 F1 PIC 9(21)V9(1) VALUE 0.0. 01 F2 PIC 9(21)V9(1) VALUE 1.0. 01 FIB PIC 9(21)V9(1). 01 N PIC 9(5) VALUE 100. 01 I PIC 9(5) VALUE 0. PROCEDURE DIVISION. MOVE N TO I CALL 'FIBONACCI'. DISPLAY "Fibonacci of " I " is " F1. STOP RUN. ENTRY 'FIBONACCI'. IF N = 0 THEN EXIT PROGRAM ELSE COMPUTE FIB = F1 + F2 COMPUTE F1 = F2 COMPUTE F2 = FIB SUBTRACT 1 FROM N CALL 'FIBONACCI' END-IF. ● COBOL 60 - 1960. ● COBOL 61 - 1961. ● COBOL 65 - 1965. ● COBOL 68 - 1968 ● COBOL 74 - 1974 ● COBOL 85 - 1985 ● COBOL 2002 - 2002 ● COBOL 2014 - 2014 Recursivity
  • 25. Scheme - 1975 (define (fibonacci n) (fibonacci-iter n 0 1)) (define (fibonacci-iter n a b) (do ((i n (- i 1)) (x a b) (y b (+ a b))) ((= i 0) x) (set! a x) (set! b y))) (define (fibonacci n) (if (or (= n 0) (= n 1)) n (+ (fibonacci (- n 1)) (fibonacci (- n 2))))) (display (fibonacci 100)) ● Scheme 75: 1975 ● Scheme 84: 1984 ● Several follow up releases until 2013 (define (fibonacci n) (define (fib-helper n a b) (if (= n 0) a (fib-helper (- n 1) b (+ a b)))) (fib-helper n 0 1)) (display (fibonacci 100))
  • 27. Standard Meta Language - 1983/84 ● Moby: Moby - 1980’s ● SML/NJ - 1983/1984 ● MLton - 1999 ● SML '90 - 1990 ● SML '97 - 1997 ● SML 2007 - 2007 ● SML 2022 - 2022 fun fibonacci n = if n < 2 then n else fibonacci (n - 1) + fibonacci (n - 2); structure IntInf = IntInf fun fibonacci n = let fun fibIter n a b = if n = 0 then a else fibIter (n - 1) b (IntInf.+(a, b)) in fibIter n 0 1 end;
  • 29. Erlang - 1986 ● Erlang 1986 - First proprietary release ● Erlang/OTP R1 (1996) - First commercial release ● Erlang/OTP 24 - Erlang until 2021 -module(fibonacci_recursive). -export([fib/1]). fib(0) -> 0; fib(1) -> 1; fib(N) when N > 1 -> fib(N - 1) + fib(N - 2). -module(fibonacci_recursive_tco). -export([fib/1]). fib(N) when N < 2 -> N; fib(N) -> fib_iter(N, 0, 1). fib_iter(0, A, _) -> A; fib_iter(N, A, B) -> fib_iter(N - 1, B, A + B).
  • 31. Haskell - 1990 ● First draft - 1987 ● Haskell 1.0 - 1990 ● Haskell 1.1 - 1991 ● Haskell 1.2 - 1992 ● Haskell 1.3 - 1996 ● Haskell 1.4 - 1997 ● Haskell 98 - 1998 ● Haskell 2010 - 2010 ● Haskell 2022 - 2022 fibonacci :: Integer -> Integer fibonacci 0 = 0 fibonacci 1 = 1 fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) main :: IO () main = do let result = fibonacci 1000 putStrLn $ "Fibonacci of the order of 1000: " ++ show result fibonacciTailRec :: Integer -> Integer fibonacciTailRec n = fibonacciHelper n 0 1 where fibonacciHelper 0 a _ = a fibonacciHelper 1 _ b = b fibonacciHelper n a b = fibonacciHelper (n - 1) b (a + b) main :: IO () main = do let result = fibonacciTailRec 1000 putStrLn $ "Fibonacci of the order of 1000: " ++ show result
  • 33. About Java - 1995 Java deliberately doesn’t support Tail Call Optimization because: ● Backward compatibility ● It might not go well with the JVM architecture because of overhead and potential side-effects. ● Performance and complexity ● The iterative alternative is always possible ● Not very clear if TCO is the best idea for Java But this didn’t stop JVM alternative languages to explore TCO possibilities...
  • 35. Scala - 2003 ● Scala 1.0 - 2003 ● Scala 2.0 - 2006 ● Scala 2.7 - 2009 ● Scala 2.8 - 2010 ● Scala 2.9 - 2011 ● Scala 2.10 - 2012 ● Scala 2.11 - 2014 ● Scala 2.12 - 2016 ● Scala 2.13 - 2019 ● Scala 3 (previously known as Dotty) - 2020 def fibonacciIterative(n: Double): Double = { var a = 0f var b = 1f var i = 0f while (i < n) { val temp = b b = a + b a = temp i += 1 } a } def fibonacciRecursive(n: Double): Double = { if (n <= 1f) { n } else { fibonacciRecursive(n - 1f) + fibonacciRecursive(n - 2f) } } def fibonacciTailRec(n: Double): Double = { def fibHelper(n: Double, a: Double, b: Double): Double = { if (n == 0.0) a else fibHelper(n - 1.0, b, a + b) } fibHelper(n, 0.0, 1.0) }
  • 36. Scala - 2003 ● Scala 1.0 - 2003 ● Scala 2.0 - 2006 ● Scala 2.7 - 2009 ● Scala 2.8 - 2010 ● Scala 2.9 - 2011 ● Scala 2.10 - 2012 ● Scala 2.11 - 2014 ● Scala 2.12 - 2016 ● Scala 2.13 - 2019 ● Scala 3 (previously known as Dotty) - 2020 def fibonacciTailRecTCO(n: Double): Double = { @annotation.tailrec def fibHelper(n: Double, a: Double, b: Double): Double = { if (n == 0f) a else fibHelper(n - 1f, b, a + b) } fibHelper(n, 0f, 1f) } def fibonacciTailRecManualTCO(n: Double): Double = { def fibHelper(n: Double, a: Double, b: Double): Double = { var a = 0f var b = 1f var i = 0f while (i < n) { val temp = b b = a + b a = temp i += 1 } a if (n == 0.0) a else fibHelper(n - 1.0, b, a + b) } fibHelper(n, 0.0, 1.0) }
  • 37. Scala - 2003 def fibonacciTailRecTCO(n: Double): Double = { @annotation.tailrec def fibHelper(n: Double, a: Double, b: Double): Double = { if (n == 0f) a else fibHelper(n - 1f, b, a + b) } fibHelper(n, 0f, 1f) } def factorialUnMarked(n: Double): Double = { def factorialHelper(n: Double): Double = { if (n <= 1f) 1f else n * factorialHelper(n - 1f) } factorialHelper(n) } public static double factorialUnMarked(double var0) { return Fibonacci$.MODULE$.factorialUnMarked(var0); } public double factorialUnMarked(final double n) { return this.factorialHelper$1(n); } private final double factorialHelper$1(final double n) { return n <= 1.0 ? 1.0 : n * this.factorialHelper$1(n - 1.0); } public static double fibonacciTailRecTCO(double var0) { return Fibonacci$.MODULE$.fibonacciTailRecTCO(var0); } public double fibonacciTailRecTCO(final double n) { return this.fibHelper$3(n, 0.0, 1.0); } private final double fibHelper$3(final double n, final double a, final double b) { while(n != 0.0) { double var7 = n - 1.0; double var11 = a + b; n = var7; a = b; b = var11; } return a; }
  • 39. Clojure - 2007 (defn fibonacci-iterative [n] (if (<= n 1) n (loop [a 0 b 1 i 1] (if (= i n) (+ a b) (recur b (+ a b) (inc i)))))) (defn fibonacci-recursive [n] (let [n (if (instance? String n) (Double/parseDouble n) n)] (if (<= n 1.0) n (+ (fibonacci-recursive (- n 1.0)) (fibonacci-recursive (- n 2.0)))))) (defn fibonacci-tail-rec [n] (let [n (if (instance? String n) (Double/parseDouble n) n)] (letfn [(fib-tail [n a b] (if (zero? n) a (fib-tail (dec n) b (+ a b))))] (fib-tail n 0.0 1.0)))) ● First version - 2007 ● Clojure 1.0 - 2009 ● Clojure until 1.11.1 in 2022
  • 40. Clojure - 2007 ● First version - 2007 ● Clojure 1.0 - 2009 ● Clojure until 1.11.1 in 2022 (defn fibonacci-tail-rec-tco [n] (let [n (if (instance? String n) (Double/parseDouble n) n)] (letfn [(fib [n a b] (if (zero? n) a (recur (dec n) b (+ a b))))] (fib n 0.0 1.0))))
  • 42. Kotlin - 2016 ● Kotlin 1.0 - 2016 ● Kotlin 1.1 - 2017 ● Kotlin 1.2 - 2017 ● Kotlin 1.3 - 2018 ● Kotlin 1.4 - 2020 ● Kotlin 1.5 - 2021 ● Kotlin 1.6 - 2021 ● Kotlin 1.7 - 2022 ● Kotlin 1.8 - 2023 ● Kotlin 1.9 - 2023 private fun fibonacciIterative(n: Int): Double { if (n <= 1) { return n.toDouble() } var a = 0.0 var b = 1.0 for (i in 2..n) { val temp = a + b a = b b = temp } return b } fun fibonacciRecursive(n: Int): Double = if (n <= 1) n.toDouble() else fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2) private fun fibonacciTailRecursive( n: Int, a: Double = 0.0, b: Double = 1.0 ): Double = if (n == 0) a else fibonacciTailRecursive(n - 1, b, a + b)
  • 43. Kotlin - 2016 private tailrec fun fibonacciTailRecursiveTCO( n: Int, a: Double = 0.0, b: Double = 1.0 ): Double = if (n == 0) a else fibonacciTailRecursiveTCO(n - 1, b, a + b) ● Kotlin 1.0 - 2016 ● Kotlin 1.1 - 2017 ● Kotlin 1.2 - 2017 ● Kotlin 1.3 - 2018 ● Kotlin 1.4 - 2020 ● Kotlin 1.5 - 2021 ● Kotlin 1.6 - 2021 ● Kotlin 1.7 - 2022 ● Kotlin 1.8 - 2023 ● Kotlin 1.9 - 2023
  • 44. Kotlin - 2016 private tailrec fun fibonacciTailRecursiveTCO( n: Int, a: Double = 0.0, b: Double = 1.0 ): Double = if (n == 0) a else fibonacciTailRecursiveTCO(n - 1, b, a + b) private fun fibonacciTailRecursive( n: Int, a: Double = 0.0, b: Double = 1.0 ): Double = if (n == 0) a else fibonacciTailRecursive(n - 1, b, a + b) private final double fibonacciTailRecursive(int n, double a, double b) { return n == 0 ? a : ((Companion)this).fibonacciTailRecursive(n - 1, b, a + b); } // $FF: synthetic method static double fibonacciTailRecursive$default(Companion var0, int var1, double var2, double var4, int var6, Object var7) { if ((var6 & 2) != 0) { var2 = 0.0; } if ((var6 & 4) != 0) { var4 = 1.0; } return var0.fibonacciTailRecursive(var1, var2, var4); } private final double fibonacciTailRecursiveTCO(int n, double a, double b) { while(n != 0) { Companion var10000 = (Companion)this; int var10001 = n - 1; double var10002 = b; b += a; a = var10002; n = var10001; } return a; } // $FF: synthetic method static double fibonacciTailRecursiveTCO$default(Companion var0, int var1, double var2, double var4, int var6, Object var7) { if ((var6 & 2) != 0) { var2 = 0.0; } if ((var6 & 4) != 0) { var4 = 1.0; } return var0.fibonacciTailRecursiveTCO(var1, var2, var4); }
  • 46. Conclusions ● Which direction is this all taking? ● Is programming still a challenge? ● Why do we do software development? ● Are we being forced into thinking recursively? ● Is Mutability something to be completely removed from a programming language? ● Productivity vs The Joy of Coding ● What happens when we keep thinking only recursively when implementing algorithms? ● Can we blindly rely on the TCO algorithms in the way that we already trust Garbage Collection? ● Do we trust Garbage Collection? ● Can we manually implement a better algorithm with better performance than TCO? ● Would we still be able to do it, if we don’t practice? ● Can we still produce without challenges in the long run?
  • 48. Resources for this presentation Image sources ● https://commons.wikimedia.org/wiki/File:John_McCarthy_Stanford.jpg ● https://commons.wikimedia.org/wiki/File:John_Backus_2.jpg ● https://commons.wikimedia.org/wiki/File:Guy_Steele.jpg ● https://commons.wikimedia.org/wiki/File:Jerry_Sussman.jpg ● https://nl.wikipedia.org/wiki/Rij_van_Fibonacci#/media/Bestand:Fibonacci_Spiral.svg ● https://en.wikipedia.org/wiki/File:Fortran_logo.svg ● https://en.m.wikipedia.org/wiki/File:Lisp_logo.svg ● https://commons.wikimedia.org/wiki/File:IBM_keypunch_deck_for_Cobol_student_program_at_New_York_Universi ty_1979.jpg ● https://commons.wikimedia.org/wiki/File:Lambda_lc.svg ● https://commons.wikimedia.org/wiki/File:Informatics_Forum_Atrium_turned.jpg ● https://commons.wikimedia.org/wiki/File:Ericsson_logo.svg ● https://commons.wikimedia.org/wiki/File:Erlang_logo.png ● https://en.wikipedia.org/wiki/File:Haskell-Logo.svg ● https://commons.wikimedia.org/wiki/File:James_Gosling_2008.jpg ● https://commons.wikimedia.org/wiki/File:Mark_Odersky_photo_by_Linda_Poeng.jpg ● https://commons.wikimedia.org/wiki/File:Scala-full-color.svg ● https://en.m.wikipedia.org/wiki/File:Clojure_logo.svg ● https://commons.wikimedia.org/wiki/File:Kotlin_logo_2021.svg
  • 49. Resources for this presentation ● https://www.smlnj.org/sml.html ● https://en.wikibooks.org/wiki/Standard_ML_Programming/Types ● https://en.wikipedia.org/wiki/Standard_ML ● https://www.smlnj.org/ ● https://www.scala-lang.org/ ● https://kotlinlang.org/ ● https://en.wikipedia.org/wiki/COBOL ● https://fortran-lang.org/ ● https://www.java.com/en/ ● https://developer.ibm.com/languages/cobol/ ● https://www.haskell.org/ ● https://www.erlang.org/ ● https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gfortran/Code-Gen-Options.html Data sources