What Clojure Taught Us About Kotlin
We tried to capture lightning in a bottle
- The Journey so far...
- Kotlin vs. Clojure
- Functional, the good bits
- FP vs. OO
- OOP done poorly
- Clojure big wins
- How to Kotlin better
- Clojure, caveats
What did we do?
-
Wrote NetApp E-Series
- In Kotlin
-
Talked about Kotlin at GRJUG's "Alternative Languages on the JVM"
- Enticed by the Clojure talk
- Read Clojure for the Brave and True
-
Went to Clojure/Conj
-
Ate Vegan Junkfood
- http://hotdogscoldbeer.com/
- Learned more about Clojure
- Wrote some Clojure - liked it
-
Ate Vegan Junkfood
- Rewrote NetApp E-Series in Clojure - liked it
What is Clojure?
;; (A LISP)
;; (On the JVM)
;; (Functional Programming Language)
(defn -main
"This is the main"
[& args]
(println "Hello Blue Medora"))
;; (Immutable Data Structures)
;; (Released in 2007, most recent version is 1.8.0 )
;; ((January 2016) 1.9 coming soon!)
((((((Parenthesis))))))
Functional Programming
- Immutability
- Make a new copy instead of mutating old copy
- Pure Functions
- No side Effects
- Higher Order Functions
- Functions that act on functions
- Recursion
Object Oriented
- Mutability AND Immutability
- Functions may have side effects
- Some support for HOFs
- Lambdas
- Iteration preferred
- Recursion possible
// functions
var things = listOf(1, 2, 3, 4)
for (thing in things) {
things[things.indexOf(thing)] = thing + 1
}
// assoc
var things = listOf("id", "name", "cpu")
var newStuff = MutableMapOf<String, JSONObject>
for (thing in things) {
newStuff.put(thing, json.get(thing))
}
// let
fun crazyPills() {
whatever = listOf("a", "b", "c")
stuff = listOf(1, 2, 3, 4)
things = listOf("Perl", "JavaScript", "OCAML")
for (thing in things){
for (item in stuff) {
for (what in whatever) {
newValue = thing + item + what
}
}
}
}
// lambdas
// TODO Use Lambdas if the language offers them
;; Clojure
;; functions
(map inc [0 1 2 3])
;; assoc
(assoc result-set (keyword sys-id) (build-result-set host port jsessionID sys-id))
;; let
(defn create-metric-from-metric-definition
[mdefinition drive-json]
(let [json-name (split (.getMetadata mdefinition "json_name") #" ")]
(.toMetric mdefinition (get-value mdefinition (get-in drive-json json-name)))))
;; fn (considered fn-amazing)
(map (fn [drive] (create-drive drive arrayID)) drives)
// Kotlin
// functions
fun increment(numbers: List<Number>) = numbers.map { it + 1 }
increment(listOf(1, 2, 3, 4))
// assoc
val valueMap = listOf("id", "name", "cpu").associate { it, json.get(it) }
// let
for (thing in functionThatGetsThings()) {
println(thing)
}
with is possible, but only for one level deep
// lambdas
val driveList = drives.map { drive -> create-drive(drive, arrayId) }
Clojure it is!

Caveats
Exception in thread "main" java.lang.ClassCastException: com.bluemedora.exuno.result.ExUnoCollectionResult cannot be cast to clojure.lang.IFn, compiling:(/private/var/folders/jb/vdyx1v7n5f1b2djmf16vw71h0000gn/T/form-init9017850513260832378.clj:1:125)
at clojure.lang.Compiler.load(Compiler.java:7391)
at clojure.lang.Compiler.loadFile(Compiler.java:7317)
at clojure.main$load_script.invokeStatic(main.clj:275)
at clojure.main$init_opt.invokeStatic(main.clj:277)
at clojure.main$init_opt.invoke(main.clj:277)
at clojure.main$initialize.invokeStatic(main.clj:308)
at clojure.main$null_opt.invokeStatic(main.clj:342)
at clojure.main$null_opt.invoke(main.clj:339)
at clojure.main$main.invokeStatic(main.clj:421)
at clojure.main$main.doInvoke(main.clj:384)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassCastException: com.bluemedora.exuno.result.ExUnoCollectionResult cannot be cast to clojure.lang.IFn
at sirani.core$_main.invokeStatic(core.clj:84)
at sirani.core$_main.invoke(core.clj:75)
at clojure.lang.Var.invoke(Var.java:383)
at user$eval5.invokeStatic(form-init9017850513260832378.clj:1)
at user$eval5.invoke(form-init9017850513260832378.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6917)
at clojure.lang.Compiler.load(Compiler.java:7379)
... 14 more
Caveats (cont'd)
- Using ExUno ensures a blend of OO and FP
- Unfamiliarity
- (thing(whatever(do(stuff ))))
(.asProperty
(.asString
(.withMetadata
(.withUnits
(com.bluemedora.exuno.definition.MetricDefinition. "name" "Name")
com.bluemedora.exuno.common.ExUnoUnit/UNITLESS)
(java.util.HashMap. {"json_name" "name"}))))
Is the lightning bottled?
- Reinvigorated enthusiasm about Kotlin
- Functional Programming
- Schooled by a Sophomore
- Tooling and Community is great
- Emacs/REPL-Driven Development
- Leiningen
- Caveat
- Too many "Idempotent"s
- "But if you use Kotlin without embracing any of the functional programming concepts, you aren't going to get much more than just Java" - Kevin Greene
(thanks)
What Clojure taught us about Kotlin
By dlindema
What Clojure taught us about Kotlin
- 702