100 Languages Speedrun (102 Part Series)
1 100 Languages Speedrun: Episode 01: Python
2 100 Languages Speedrun: Episode 02: Emojicode
… 98 more parts…
3 100 Languages Speedrun: Episode 03: CSS
4 100 Languages Speedrun: Episode 04: Lua
5 100 Languages Speedrun: Episode 05: Kotlin
6 100 Languages Speedrun: Episode 06: Tcl/Tk
7 100 Languages Speedrun: Episode 07: Sed and Regular Expression FizzBuzz
8 100 Languages Speedrun: Episode 08: Reverse Polish Notation Calculator
9 100 Languages Speedrun: Episode 09: Ada
10 100 Languages Speedrun: Episode 10: Befunge
11 100 Languages Speedrun: Episode 11: Tcsh
12 100 Languages Speedrun: Episode 12: D
13 100 Languages Speedrun: Episode 13: Arc
14 100 Languages Speedrun: Episode 14: Recursive Descent Parser
15 100 Languages Speedrun: Episode 15: Awk
16 100 Languages Speedrun: Episode 16: Octave
17 100 Languages Speedrun: Episode 17: Rake
18 100 Languages Speedrun: Episode 18: PLY Python Lex-Yacc
19 100 Languages Speedrun: Episode 19: Julia
20 100 Languages Speedrun: Episode 20: Forth
21 100 Languages Speedrun: Episode 21: Clojure
22 100 Languages Speedrun: Episode 22: XSLT
23 100 Languages Speedrun: Episode 23: Ruby Z3
24 100 Languages Speedrun: Episode 24: Postscript
25 100 Languages Speedrun: Episode 25: JQ
26 100 Languages Speedrun: Episode 26: Raku (Perl 6)
27 100 Languages Speedrun: Episode 27: Whenever
28 100 Languages Speedrun: Episode 28: TeX
29 100 Languages Speedrun: Episode 29: Verilog
30 100 Languages Speedrun: Episode 30: SageMath
31 100 Languages Speedrun: Episode 31: Fortran
32 100 Languages Speedrun: Episode 32: Gherkin
33 100 Languages Speedrun: Episode 33: Logo
34 100 Languages Speedrun: Episode 34: Racket Scheme
35 100 Languages Speedrun: Episode 35: Groovy
36 100 Languages Speedrun: Episode 36: AppleScript
37 100 Languages Speedrun: Episode 37: OCaml
38 100 Languages Speedrun: Episode 38: BC
39 100 Languages Speedrun: Episode 39: SQLite
40 100 Languages Speedrun: Episode 40: x86-64 Assembly
41 100 Languages Speedrun: Episode 41: WebGL Shader Language
42 100 Languages Speedrun: Episode 42: Prolog
43 100 Languages Speedrun: Episode 43: Thue
44 100 Languages Speedrun: Episode 44: RISC-V Assembly
45 100 Languages Speedrun: Episode 45: M4
46 100 Languages Speedrun: Episode 46: ARM64 Assembly
47 100 Languages Speedrun: Episode 47: Raku (Perl 6) Regular Expressions
48 100 Languages Speedrun: Episode 48: Elvish
49 100 Languages Speedrun: Episode 49: Crystal
50 100 Languages Speedrun: Episode 50: COBOL
51 100 Languages Speedrun: Episode 51: R
52 100 Languages Speedrun: Episode 52: Perl
53 100 Languages Speedrun: Episode 53: QBasic
54 100 Languages Speedrun: Episode 54: Haskell
55 100 Languages Speedrun: Episode 55: Better Thue Interpreter in Crystal
56 100 Languages Speedrun: Episode 56: PHP
57 100 Languages Speedrun: Episode 57: Scala
58 100 Languages Speedrun: Episode 58: XQuery
59 100 Languages Speedrun: Episode 59: Smalltalk
60 100 Languages Speedrun: Episode 60: Asciidots
61 100 Languages Speedrun: Episode 61: POV-Ray
62 100 Languages Speedrun: Episode 62: LLVM Intermediate Representation
63 100 Languages Speedrun: Episode 63: CSVQ
64 100 Languages Speedrun: Episode 64: ChucK
65 100 Languages Speedrun: Episode 65: Randomized Finite Automaton for Fast Thue Interpreter in Crystal
66 100 Languages Speedrun: Episode 66: Xonsh
67 100 Languages Speedrun: Episode 67: Io
68 100 Languages Speedrun: Episode 68: Raku (Perl 6) Grammars
69 100 Languages Speedrun: Episode 69: Ioke
70 100 Languages Speedrun: Episode 70: Wren
71 100 Languages Speedrun: Episode 71: Factor
72 100 Languages Speedrun: Episode 72: Windows Batch Files
73 100 Languages Speedrun: Episode 73: Free Pascal
74 100 Languages Speedrun: Episode 74: Python ANTLR 4
75 100 Languages Speedrun: Episode 75: Abstract Syntax Trees with Python ANTLR 4
76 100 Languages Speedrun: Episode 76: Python SLY
77 100 Languages Speedrun: Episode 77: JVM Assembly with Jasmin
78 100 Languages Speedrun: Episode 78: Better Whenever Interpreter with Python and SLY
79 100 Languages Speedrun: Episode 79: Designing New Esoteric Language Tuples
80 100 Languages Speedrun: Episode 80: Minimalistic Version of Esoteric Language Tuples
81 100 Languages Speedrun: Episode 81: Elixir
82 100 Languages Speedrun: Episode 82: Pyret
83 100 Languages Speedrun: Episode 83: PowerShell
84 100 Languages Speedrun: Episode 84: Lingua Romana Perligata
85 100 Languages Speedrun: Episode 85: Linguagem Potigol
86 100 Languages Speedrun: Episode 86: Emacs Lisp
87 100 Languages Speedrun: Episode 87: Sidef
88 100 Languages Speedrun: Episode 88: Brat
89 100 Languages Speedrun: Episode 89: MoonScript
90 100 Languages Speedrun: Episode 90: YueScript
91 100 Languages Speedrun: Episode 91: Arturo
92 100 Languages Speedrun: Episode 92: newLISP
93 100 Languages Speedrun: Episode 93: Coconut
94 100 Languages Speedrun: Episode 94: Ezhil
95 100 Languages Speedrun: Episode 95: Janet
96 100 Languages Speedrun: Episode 96: Langage Linotte
97 100 Languages Speedrun: Episode 97: Quackery
98 100 Languages Speedrun: Episode 98: Rexx
99 100 Languages Speedrun: Episode 99: Extending Esoteric Language Tuples
100 100 Languages Speedrun: Episode 100: Ruby
101 100 Languages Speedrun: Bonus Episode 101: Programming Languages Tier List
102 100 Languages Speedrun: Bonus Episode 102: Series Retrospective
Kotlin is to Java what ES6 is to old style JavaScript. A lot of people are stuck with JavaScript engine (like browser) or a JVM (like Android). Their native languages are atrocious, but using a completely non-native language leads to huge complexity interfacing with native APIs. And so compromise solutions were created, like ES6 for JavaScript, and Kotlin for Java. Kotlin is especially popular among Android developers, but you can use it anywhere where you can use JVM, and really it’s hard to come up with a legitimate reason to use “plain Java” these days.
Hello, World
We can start with the usual program! It’s nothing unusual, unless you remember just how bad it was in plain Java:
fun main() {
println("Hello, World!")
}
Enter fullscreen mode Exit fullscreen mode
Unfortunately to run this we need to do this silly line, and the whole thing takes way too long for a reasonable hello world, 7s on my laptop:
$ kotlinc hello.kt -include-runtime -d hello.jar && java -jar hello.jar
Enter fullscreen mode Exit fullscreen mode
Well, the Java world has very different expectations of what’s a reasonable startup time than me. Kotlin has some sort of “scripting mode”, and REPL, and it can be integrated with your IDE, so maybe it’s not such a problem for people who code it on a daily basis.
I included a short script that allows ./run file.kt
in the code repository.
Fibonacci
It’s not too bad. We need some type annotations which feel like they should be inferable, but it’s all perfectly reasonable code. If you think I’m asking for too much, just wait until we get to Crystal; but a lot of languages could figure out that fib
is Int
into Int
.
Range loop syntax is perfectly readable, overall it’s shockingly readable and concise code considering it’s basically Java under the hood.
fun fib(n: Int): Int {
if (n < 3) {
return 1
} else {
return fib(n - 1) + fib(n - 2)
}
}
fun main() {
for (i in 1..30) {
println(fib(i))
}
}
Enter fullscreen mode Exit fullscreen mode
FizzBuzz
Kotlin threw away C style switch
and instead introduced when
syntax, which vaguely resembles Haskell style pattern matching.
fun fizzbuzz(n: Int): String {
return when {
n % 15 == 0 -> "FizzBuzz"
n % 3 == 0 -> "Fizz"
n % 5 == 0 -> "Buzz"
else -> n.toString()
}
}
fun main() {
for (i in 1..100) {
println(fizzbuzz(i))
}
}
Enter fullscreen mode Exit fullscreen mode
Unicode
As Kotlin is basically Java under the hood, it still doesn’t handle Unicode correctly outside the base plane, so the last answer is wrong:
fun main() {
println("Hello".length)
println("Źółw".length)
println("".length)
}
Enter fullscreen mode Exit fullscreen mode
It prints:
5
4
2
Enter fullscreen mode Exit fullscreen mode
Data classes
Java makes it really tedious to work with just about any kind of data. Every simple data class needs explicit constructor, getters, setters, hashcode, and equals. You cannot even use ==
, you need to run .equals()
, but that would literally crash if one of the sides was null, so you need to null check both sides first, then .equals()
. It’s ridiculous amount of boilerplate for basic data manipulation.
Kotlin avoids almost all of this bullshit:
data class Point(val x: Double, val y: Double) {
fun length() = Math.sqrt(x * x + y * y)
}
fun main() {
val a = listOf(1, 2, 3)
val b = listOf(1, 2, 3)
val c = Point(30.0, 40.0)
val d = Point(30.0, 40.0)
println(a == b)
println(c == d)
println(null == d)
println("len of ${c} is ${c.length()}")
}
Enter fullscreen mode Exit fullscreen mode
Which prints:
true
true
false
len of Point(x=30.0, y=40.0) is 50.0
Enter fullscreen mode Exit fullscreen mode
Well, we still needed to do listOf(1, 2, 3)
instead of [1, 2, 3]
, and it would complain if we tried Point(30, 40)
, but it’s not too bad.
Functional programming
And how would we do map
, filter
, and reduce
in Kotlin? It looks almost like Ruby with { arguments -> ... }
blocks. Interestingly if you pass a block without any arguments, it treats as if it had default { it -> ... }
. That’s a rare feature, most notably seen in Perl where it’s called somewhat more cryptic $_
.
fun main() {
val alist = listOf(1, 2, 3, 4, 5)
println(alist.map{ x -> x * 2 })
println(alist.map{ it * 2 })
println(alist.filter{ it % 2 == 1 })
println(alist.reduce{ a, b -> a + b })
}
Enter fullscreen mode Exit fullscreen mode
It produces the expected:
[2, 4, 6, 8, 10]
[2, 4, 6, 8, 10]
[1, 3, 5]
15
Enter fullscreen mode Exit fullscreen mode
Should you use Java?
Normally I’d ask “should you use Kotlin”, but that’s looking at things backwards. The real question is “should you use Java” and the answer is clear and unambiguous NO! If you need to run something on JVM and interact with the “Java” ecosystem, you can do this without ever touching that miserable excuse for a language. Kotlin is to Java what ES6 was to old style JavaScript, but the improvement is much greater here. Old style JavaScript is dead, completely replaced by ES6+ JavaScript, and that’s the fate that should befall Java as well.
There are other JVM languages like JRuby, Clojure, Scala, and so on, but they are essentially different languages, with different semantics, and with varied interoperability story. Kotlin is just Fixed Java, nothing more, nothing less.
So please don’t use Java, ever.
Code
All code examples for the series will be in this repository.
Code for the Kotlin episode is available here.
100 Languages Speedrun (102 Part Series)
1 100 Languages Speedrun: Episode 01: Python
2 100 Languages Speedrun: Episode 02: Emojicode
… 98 more parts…
3 100 Languages Speedrun: Episode 03: CSS
4 100 Languages Speedrun: Episode 04: Lua
5 100 Languages Speedrun: Episode 05: Kotlin
6 100 Languages Speedrun: Episode 06: Tcl/Tk
7 100 Languages Speedrun: Episode 07: Sed and Regular Expression FizzBuzz
8 100 Languages Speedrun: Episode 08: Reverse Polish Notation Calculator
9 100 Languages Speedrun: Episode 09: Ada
10 100 Languages Speedrun: Episode 10: Befunge
11 100 Languages Speedrun: Episode 11: Tcsh
12 100 Languages Speedrun: Episode 12: D
13 100 Languages Speedrun: Episode 13: Arc
14 100 Languages Speedrun: Episode 14: Recursive Descent Parser
15 100 Languages Speedrun: Episode 15: Awk
16 100 Languages Speedrun: Episode 16: Octave
17 100 Languages Speedrun: Episode 17: Rake
18 100 Languages Speedrun: Episode 18: PLY Python Lex-Yacc
19 100 Languages Speedrun: Episode 19: Julia
20 100 Languages Speedrun: Episode 20: Forth
21 100 Languages Speedrun: Episode 21: Clojure
22 100 Languages Speedrun: Episode 22: XSLT
23 100 Languages Speedrun: Episode 23: Ruby Z3
24 100 Languages Speedrun: Episode 24: Postscript
25 100 Languages Speedrun: Episode 25: JQ
26 100 Languages Speedrun: Episode 26: Raku (Perl 6)
27 100 Languages Speedrun: Episode 27: Whenever
28 100 Languages Speedrun: Episode 28: TeX
29 100 Languages Speedrun: Episode 29: Verilog
30 100 Languages Speedrun: Episode 30: SageMath
31 100 Languages Speedrun: Episode 31: Fortran
32 100 Languages Speedrun: Episode 32: Gherkin
33 100 Languages Speedrun: Episode 33: Logo
34 100 Languages Speedrun: Episode 34: Racket Scheme
35 100 Languages Speedrun: Episode 35: Groovy
36 100 Languages Speedrun: Episode 36: AppleScript
37 100 Languages Speedrun: Episode 37: OCaml
38 100 Languages Speedrun: Episode 38: BC
39 100 Languages Speedrun: Episode 39: SQLite
40 100 Languages Speedrun: Episode 40: x86-64 Assembly
41 100 Languages Speedrun: Episode 41: WebGL Shader Language
42 100 Languages Speedrun: Episode 42: Prolog
43 100 Languages Speedrun: Episode 43: Thue
44 100 Languages Speedrun: Episode 44: RISC-V Assembly
45 100 Languages Speedrun: Episode 45: M4
46 100 Languages Speedrun: Episode 46: ARM64 Assembly
47 100 Languages Speedrun: Episode 47: Raku (Perl 6) Regular Expressions
48 100 Languages Speedrun: Episode 48: Elvish
49 100 Languages Speedrun: Episode 49: Crystal
50 100 Languages Speedrun: Episode 50: COBOL
51 100 Languages Speedrun: Episode 51: R
52 100 Languages Speedrun: Episode 52: Perl
53 100 Languages Speedrun: Episode 53: QBasic
54 100 Languages Speedrun: Episode 54: Haskell
55 100 Languages Speedrun: Episode 55: Better Thue Interpreter in Crystal
56 100 Languages Speedrun: Episode 56: PHP
57 100 Languages Speedrun: Episode 57: Scala
58 100 Languages Speedrun: Episode 58: XQuery
59 100 Languages Speedrun: Episode 59: Smalltalk
60 100 Languages Speedrun: Episode 60: Asciidots
61 100 Languages Speedrun: Episode 61: POV-Ray
62 100 Languages Speedrun: Episode 62: LLVM Intermediate Representation
63 100 Languages Speedrun: Episode 63: CSVQ
64 100 Languages Speedrun: Episode 64: ChucK
65 100 Languages Speedrun: Episode 65: Randomized Finite Automaton for Fast Thue Interpreter in Crystal
66 100 Languages Speedrun: Episode 66: Xonsh
67 100 Languages Speedrun: Episode 67: Io
68 100 Languages Speedrun: Episode 68: Raku (Perl 6) Grammars
69 100 Languages Speedrun: Episode 69: Ioke
70 100 Languages Speedrun: Episode 70: Wren
71 100 Languages Speedrun: Episode 71: Factor
72 100 Languages Speedrun: Episode 72: Windows Batch Files
73 100 Languages Speedrun: Episode 73: Free Pascal
74 100 Languages Speedrun: Episode 74: Python ANTLR 4
75 100 Languages Speedrun: Episode 75: Abstract Syntax Trees with Python ANTLR 4
76 100 Languages Speedrun: Episode 76: Python SLY
77 100 Languages Speedrun: Episode 77: JVM Assembly with Jasmin
78 100 Languages Speedrun: Episode 78: Better Whenever Interpreter with Python and SLY
79 100 Languages Speedrun: Episode 79: Designing New Esoteric Language Tuples
80 100 Languages Speedrun: Episode 80: Minimalistic Version of Esoteric Language Tuples
81 100 Languages Speedrun: Episode 81: Elixir
82 100 Languages Speedrun: Episode 82: Pyret
83 100 Languages Speedrun: Episode 83: PowerShell
84 100 Languages Speedrun: Episode 84: Lingua Romana Perligata
85 100 Languages Speedrun: Episode 85: Linguagem Potigol
86 100 Languages Speedrun: Episode 86: Emacs Lisp
87 100 Languages Speedrun: Episode 87: Sidef
88 100 Languages Speedrun: Episode 88: Brat
89 100 Languages Speedrun: Episode 89: MoonScript
90 100 Languages Speedrun: Episode 90: YueScript
91 100 Languages Speedrun: Episode 91: Arturo
92 100 Languages Speedrun: Episode 92: newLISP
93 100 Languages Speedrun: Episode 93: Coconut
94 100 Languages Speedrun: Episode 94: Ezhil
95 100 Languages Speedrun: Episode 95: Janet
96 100 Languages Speedrun: Episode 96: Langage Linotte
97 100 Languages Speedrun: Episode 97: Quackery
98 100 Languages Speedrun: Episode 98: Rexx
99 100 Languages Speedrun: Episode 99: Extending Esoteric Language Tuples
100 100 Languages Speedrun: Episode 100: Ruby
101 100 Languages Speedrun: Bonus Episode 101: Programming Languages Tier List
102 100 Languages Speedrun: Bonus Episode 102: Series Retrospective
暂无评论内容