kscript
class: center, middle, inverse, title-slide #
kscript
## Scripting Enhancements for Kotlin ### Holger Brandl ### 3.11.2017 - KotlinConf2017 --- background-image: url(images/official_cover.jpg) background-position: center background-repeat: no-repeat background-size: 100% ??? welcome -> holger --> dresden, germany--> data consultant in academic= life science research center first, thanks cool to meet people from the kotlin community in person. honored to be here, humble contribution to kotlin ecosystem topic -> little but handy tool called kscript --- class: middle, inverse <!-- ## Outline --> ## What are language requirements for data-driven science? ## Why Kotlin may be the right choice. ## How `kscript` provides enhanced scripting support for Kotlin. ??? part 1: my background, data scientiest/analyst working with various kinds of data. lessons I've learned. * Software examples from academia * Shortcomings of existing languages * What works and what did not part 2: argue that Kotlin might . short because assumed that audience knowns Kotlin. what's missing yet part 3: main part. obviously. how `kscript`, feature walkthroguh and examples. --- # Language requirements for data-driven science ### 1. Reproducible: Can we reproduce results at a later date? ### 2. Rapid Prototyping: Can we quickly setup an analysis? ### 3. Scalable: Can we upscale scripts into systems and tools? ### 4. Community: Can we enable colleagues to analyze data? ??? not complete listing, but most important ingredients start with script, but long run model cell, tiusse, pyhcucal system, some aspect universe community: analysts / scientist not engineers, . curious about data. want to bring them onboard. usable without having a phd in computer science with those requirmentwalk through most common candidates when bash, java, python, R --- # Use just the linux shell for data-driven science? > But it's faster and way shorter to do it bash! (unknown colleague) Do _magical_ things in the terminal without dependencies -- ```bash removeMultiMappers(){ perl -ne 'unless((!($_=~/^@.*/)&&!(m/AS:i:/))||(m/AS:i:(\S+).+XS:i:(\S+)/ && $1-$2<1)){print;}' } bowtie2 $fastqFile | samtools view -SF 4 - | removeMultiMappers | samtools sort - result.bam ``` -- > Marta Florio, Mareike Albert, Elena Taverna, Takashi Namba, **Holger Brandl**, Eric Lewitus, Christiane Haffner, Alex Sykes, Fong Kuan Wong, Jula Peters, E. Guhr, Sylvia Klemroth, Kay Prüfer, Janet Kelso, Ronald Naumann, Ina Nüsslein, Andreas Dahl, Robert Lachmann, Svante Pääbo, Wieland B. Huttner **Human-specific gene ARHGAP11B promotes basal progenitor amplification and neocortex expansion.** *Science* , 347(6229) 1465-1470 (2015) -- Get published and forget. ### Fast to write. Impossible to maintain or to evolve. Does not scale. Unteachable black art. ??? Is possibe to get away with it hellfire A: fire & forget Lesson learned: Don't stop when it *just* works. Don't use awkward methods to avoid an actual implementation. just fast Don't get me wrong: the linux shell is great. often see bloated apis, why? it's faster and way shorter to do it bash Great frameworks like csv but --- background-image: url(images/0d638038_whiteend.jpg) background-position: center background-repeat: no-repeat background-size: 100% # Java for Data Science? 2001 - First contact: > #### Evolving image processing for 2d gel electrophoresis analysis <!-- .image-50[![](images/0d638038.png)] --> -- Likes * Static typing provides guidance and context * Type- and compile-time checking of code * Ease of deployment * Java dependency trees rock! -- Dislikes * Prototyping in the debugger * Rerun apps again and again * Lack of interactivity -- ### Java allows to write complex software but fails for explorative analysis and prototyping. ??? * Did not know about REPL (python R, but experience felt flawed already --- # Java for Data Science? ### 1. Reproducible: Can we reproduce results at a later date? ![](check.png) ### 2. Rapid Prototyping: Can we quickly setup an analysis? ![](fail.png) ### 3. Scalable: Can we upscale scripts into systems and tools? ![](check.png) ### 4. Community: Can we enable colleagues to analyze data? ![](fail.png) ??? Great because 1. Rock-solid dependency model 2. standardized deployment path 3. Scalabilty to build complex systems They don't scale because of static typing. Not so great * Language complexity and readability * Missing REPL & scriptability repl started in j9. but overal languge evolution very slow. --- # Most popular choices for data science? R stronger for statistics and explorative data-analysis (dplyr, tidyr, rstudio). Python more popular for machine learning (kaggle, keras, scikit) Both are fun to teach and great for prototyping. .left-column40[ .center[![](images/r_logo.jpeg)] ] .right[ ![](images/python_logo.png) ] ??? for sure other options but none of them really appealing --- # Python Dependencies: The _best_ practice ```bash virtualenv my_scikit source my_scikit/bin/activate pip install -U scikit-learn ## actual logic goes in here! /sw/bin/python -c ' from sklearn import datasets ... the cool stuff! ' deactivate ``` * Per project index only via `virtualenv`, which is tedious for small scale tasks * No binaries, always (slowly) compiles from scratch ### No sound way to manage dependencies in python ??? Shed light on most crticial feature: Reproducitbilitgy. Often just scriplet are just about 10 lines, more overhead than usercode. [Why I hate virtualenv and pip](https://pythonrants.wordpress.com/2013/12/06/why-i-hate-virtualenv-and-pip/) " --- # R dependencies * No built-in way to indicate a specific dependency version for a project * Also declaration of package-dependencies is sloppy by design ``` Imports: assertthat, bindrcpp (>= 0.2), glue (>= 1.1.1), magrittr, methods, pkgconfig, rlang (>= 0.1.2), R6, Rcpp (>= 0.12.7), tibble (>= 1.3.1), utils ``` * Existing approaches like [packrat](https://github.com/rstudio/packrat) are no yet ready for prime time: build package index from scratch per project -- .image-200[![](images/me_in_hell.jpg)] ??? from http://127.0.0.1:30576/library/dplyr/DESCRIPTION ??? --- # Python and R fail to be _the_ solution for data science ### 1. Reproducible: Can we reproduce results at a later date? ![](fail.png) ### 2. Rapid Prototyping: Can we quickly do setup an analysis? ![](check.png) ### 3. Scalable: Can we upscale scripts into systems and tools? ![](fail.png) ### 4. Learning curve: Can we enable colleagues to analyze data? ![](check.png) ??? How are `R` and `python` fail in the data science process? 1. fail to provide a robust dependency tooling 2. No standardized deployment path 3. Missing scalabilty to build complex systems due to dynamic typing that prevents scaling up systems Don't get me wrong, they are * Great for protoyping * easy to get started with * Amazing level of interactivity --- # How to deploy software for data-driven science? Webservices don't scale with data. Bring tools to users. Example: > Raphael Etournay, Marko Popović, Matthias Merkel, Amitabha Nandi, Corinna Blasse, Benoit Aigouy, Holger Brandl, Gene Myers, Guillaume Salbreux, Frank Jülicher, Suzanne Eaton **Interplay of cell dynamics and epithelial tension during morphogenesis of the Drosophila pupal wing.** *Elife* , 4 Art. No. e07090 (2015) <section data-markdown> <video controls> <source src="9b__blue_square_tracking_rec.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </section> ![play movie](./9b__blue_square_tracking.mp4) ??? Understand how tissue shape changes emerge -> timelapse imaging --> trck cell, divivde, die, squeezed, --> build phycical model --> visualize & statistics Great projct. one of my all-time favorites. --- class: inverse, center, middle background-image: url(images/wing_cropped.jpg) background-position: center background-repeat: no-repeat background-size: 120% # How to ship it to the community? -- # Dockerize it! ??? C++, python, java, R, --> scared to give it away --> hard to setup --- background-image: url(images/wing_cropped_white.jpg) background-position: center background-size: 120% ## Tried it! ![](check.png) -- ## Sucessfully published! ![](check.png) Raphael Etournay, Matthias Merkel, Marko Popović, **Holger Brandl**, Natalie Dye, Benoit Aigouy, Guillaume Salbreux, Suzanne Eaton, Frank Jülicher **TissueMiner: a multiscale analysis toolkit to quantify how cellular processes create tissue dynamics.** *Elife* , 5 Art. No. e14334 (2016) https://github.com/mpicbg-scicomp/tissue_miner -- ```bash alias tm='docker run --rm -ti -v $(dirname $PWD):/movies etournay/tissue_miner' tm analyze_sheer <image_data> tm track_cell_divisions <image_data> ``` -- ## Doing _just_ docker-support since then. ![](fail.png) ??? docker is great. use it almost daily. not much feedback with respect to science just technical support since then Take home message > Bundling tools as containers not yet the way to go. More lightweight solution seem better. data science context --> users might be experts in a specific domain, but less technically skilled -> docker not the right tool yet --- # A better way to do data science? .left-column40[ * Reproducibility, Dependencies & Scalability: **Java** * Prototyping & Community: **R & Python** Fusion would be great: #### Java with the ease of a scripting language ] -- .right-column60[ _eierlegende Wollmilchsau_ .image[![](images/7d17d6d4.png)] ] ??? r&python mostly, java few, Prototype today using something convenient such as python * python * R Reimplement later in a more production-ready language like * java * c++ * god why is it all so complicated would provide magic 4: Reproducible, Rapid Prototyping, Scalable, Community Egg-laying wool-milk-sow? --- background-image: url(images/kotlin_logo.jpg) background-position: center background-repeat: no-repeat background-size: 80% # February 2016 .left-column40[ Kotlin v1.0 released #### Type Inference #### Extension Functions #### Data Classes #### DSLs in Mind #### Default Parameters #### Lives in JVM #### Scripting Support ] -- .right-column60[ .right[ Data Science Requirements ## Proper Dependency Model ![](check.png) ## Scales from idea to product ![](check.png) ## Teachable ![](check.png) ## Rapid Prototyping ?? ] ] ??? somewhen in early 2016 god seemed to have heard our prays, and gave us kotlin. release day 15.2. what a beayty! teachable: less than python or r, but better tooling --- # Let's write a script! ```bash kotlinc -script pipeline_prototype.kts ``` which is equivalent to ```kotlin #!/usr/bin/env kotlinc -script println("do stuff") val data = readData() // not quite yet! ``` Issues with existing out-of-the-box `kotlinc` tooling * How to pull in dependencies? `kotlinc -cp ...` seems too tedious. A separate gradle/maven file even more. * `kotlinc` means recompile, so little scriptlets run slow * How to keep track of required JVM/runtime options? * More flexible way to provide scripts ??? shebang did not work out --- class: inverse ![](images/kscript_repo.png) Since March 2016 Enhanced scripting support for [Kotlin](https://kotlinlang.org/) on *nix-based systems. > `kscript` provides an easy-to-use, very flexible, and almost zero-overhead solution to write self-contained mini-applications with Kotlin. ??? Kotlin had some built-in support for scripting already but it is not yet feature-rich enough to be a viable alternative for writing small termial tools, scripts, data-workflows. so shortly after .... has techically changed since, started off as a bash script, but is now writter in kotlin itself. what is a mini-application? fuzzy concept that does not really exist. can be Prototype, quick analysis, commanmd utility, anything small enough to live in a single file without the gradle/pom infracstructure --- # Core features of `kscript` Wraps `kotlinc` and adds ### Compiled script caching (using md5 checksums) ### Dependency declarations using gradle-style resource locators ### More options to provide scripts ### Embedded runtime options ### Support library to ease the writing of Kotlin scriptlets ??? Taken all these features together, `kscript` provides an easy-to-use, very flexible, and almost zero-overhead solution to write self-contained mini-applications with Kotlin. --- ```bash # sdk install kscript ## for details see http://sdkman.io/ kscript --help ``` ``` kscript - Enhanced scripting support for Kotlin on *nix-based systems. Usage: *kscript [options] <script> [<script_args>]... kscript --clear-cache kscript --self-update The <script> can be a script file (*kts), a script URL, - for stdin, a *.kt source file with a main method, or some Kotlin code. Use '--clear-cache' to wipe cached script jars and urls Use '--self-update' to wipe cached script jars and urls Options: -i --interactive Create interactive shell with dependencies as declared in script -t --text Enable stdin support API for more streamlined text processing --idea Open script in temporary Intellij session Copyright : 2017 Holger Brandl License : MIT Version : v2.1.0 Website : https://github.com/holgerbrandl/kscript ``` ??? lighweight interface -> essentially takes a script as an argument along with some argument that are **forwarded** to the script as input --- # Input Modes There's a multitude of ways to serve a script to `kscript` The `<script>` argument can be a - script file (*kts), - a script URL, - `-` for stdin, - some kotlin code - a `*.kt` source file with a main method, ??? ...let me give you some examples so that we can develop a better feeling about it works --- # Interpreter Usage To use `kscript` as interpreter for a script `Example.kts` just point to it in the shebang line ```kotlin #!/usr/bin/env kscript println("hello world") ``` We can still run it directly with ```bash kscript Example.kts ``` Or make executable and run directly ```bash chmod +x Example.kts ./Example.kts ``` ??? create a file --> indicate kscript in the shebang --> user logic --> could be small command line utility, workflow, anything which can/should work as a self-contained script actual funs starts when making it executable --> run a any other tool --- # Inlined Usage Use `kscript` in a workflow without creating an additional script file. * Directly provide a Kotlin scriptlet as argument ```bash kscript 'println("hello world")' ``` * Pipe a Kotlin snippet into `kscript` and instruct it to read from `stdin` by using `-` as script argument ```bash echo ' println("Hello Kotlin.") ' | kscript - ``` * Use `heredoc` (preferred solution for inlining) which gives more flexibility. E.g. use single quotes in script ```bash kscript - <<"EOF" println("It's a beautiful day!") EOF ``` ??? ...throw in a few bits of kotlin here and there... also process substitution is also supported --- # `kscript` can launch apps right from the internet Example: ```bash kscript 'https://git.io/v9R73' arg u ments ``` To streamline the usage, the first part could be even aliased: ```bash alias hello_kscript="kscript https://git.io/v1cG6" hello_kscript my argu ments ``` * Support remote tool repositories * Allows for easy integration of remotely hosted (mini) programs into data pipelines * Installation-free * URLs are assumed to be static and will be cached via checksum. --- # Write command line tools with _just_ the standard library ```kotlin #!/usr/bin/env kscript val stdin: Sequence<String> = generateSequence { readLine() } stdin // retain only lines starting with digits 0 to 5 .filter{ it.contains("^[0-5]{5}".toRegex()) } // add prefix .map { "id" + it } // print to stdout .forEach { println(it) } ``` Would work using `kotlinc -script` as interpreter as well, but would be painfully slow --- # Be snappy by caching compiled scripts `kscript` execution model 1. Calculate md5 of input script 2. Look up cached jar by md5; if not yet present create it 3. Use process substitution to replace `kscript` with `kotlin` process All _kscripts_ are cached based on `md5` checksum, so running the same snippet again will be much faster The cache directory is `~/.kscript` and can be cleared with `kscript --clear-cache` --- # Directives > Script sources are (often) not enough to _... write self-contained mini-applications with Kotlin._ (from kscript README) Directives supported by `kscript`: ### `//DEPS` Declare dependencies with gradle-style locators ### `//KOTLIN_OPTS` Configure the kotlin/java runtime environment ### `//INCLUDE` Source kotlin files into the script ### `//ENTRY` Declare application entrypoint for kotlin `*.kt` applications ??? think of them as annotation, first examples, comeback to that --- # Declare dependencies with `//DEPS` ```kotlin #!/usr/bin/env kscript *//DEPS com.beust:klaxon:0.24, com.github.kittinunf.fuel:fuel:1.3.1 import com.beust.klaxon.* import com.github.kittinunf.fuel.httpGet require(args.isNotEmpty()) { println("Usage: id_converter <some_id>+") kotlin.system.exitProcess(-1) } val queryURL = "http://foo.com/bar?convert=${args.joinToString(",")}" val json = String(queryURL.httpGet().response().second.data) val jsonArray = Parser() .parse(json.byteInputStream())!! as JsonArray<*> // use klaxon library to parse the json result val conversionTable = jsonArray.map { (it as JsonObject) }.map { it.int("id") to it.string("converted") }.forEach { println(it) } ``` Run as tool with just `id_converter.kts 232 42323 23` ??? ksript resolves depedency declarations into actual classpath using maven enables us to implement a sel-contained application with dependencies on a single slide Personally think, that this is pretty cool. --- # Configure the runtime with `//KOTLIN_OPTS` Just passed on to `kotlin`. Example: Filter dna-sequences by length ```kotlin #!/usr/bin/env kscript //DEPS de.mpicbg.scicomp:kutils:0.4 *//KOTLIN_OPTS -J-Xmx5g -J-server import de.mpicbg.scicomp.bioinfo.openFasta if (args.size != 2) { System.err.println("Usage: fasta_filter <fasta> <max_length>") kotlin.system.exitProcess(-1) } val fastaFile = java.io.File(args[0]) val lengthCutoff = args[1].toInt() openFasta(fastaFile). filter { it.sequence.length <= lengthCutoff }. forEach { print(it.toEntryString()) } ``` ??? next example of how we can manipulare runtime environment actual example filter for genes up to a certain length this is what's needed most of the time --- # Ease prototyping with `//INCLUDE` Many other languages allow to directly include source files. Can we do the same in Kotlin? Yes, with `kscript`! ```kotlin //utils.kt fun Array<Double>.median(): Double { val (lower, upper) = sorted().let { take(size / 2) to takeLast(size / 2) } return if (size % 2 == 0) (lower.last() + upper.first()) / 2.0 else upper.first() } ``` Artifacts are the proper way! `kscript` allows to skip artifact deployment by using `//INCLUDE` ```kotlin #!/usr/bin/env kscript *//INCLUDE utils.kt *//INCLUDE https://github.com/krangl/blob/src/MathHelpers.kt val robustMean = listOf(1.3, 42.3, 7.).median() println(robustMean) ``` ??? The **median** is the value separating the higher half of a data [sample](https://en.wikipedia.org/wiki/Sample_(statistics) "Sample (statistics)"), outlier-tolerant version of arithmetic mean. include allows to inject the content of a resource directly into the script no need to declare a dependcy here Scope: Prototyping and devlopment. Make users from R and python to feel at home! .footnote[ https://stackoverflow.com/questions/36959031/how-to-source-file-into-python-script https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/average.html ] --- # Use `//ENTRY` to run applications with `main` method `kscript` also supports running regular Kotlin `kt` files. Example: `./examples/Foo.kt`: ```kotlin package examples //ENTRY examples.Bar class Bar{ companion object { @JvmStatic fun main(args: Array<String>) { println("Foo was called") } } } fun main(args: Array<String>) = println("main was called") ``` To run top-level main instead we would use `//ENTRY examples.FooKt` The latter is the default for `kt` files and could be omitted ??? nice infrastructure, why not run kotlin applications via kscript? bit tricky, because of the flexibility Kotlin gives you to define entrypoints single file-> multiple entrypoints --- # Replace `awk`ward terminal programming with Kotlin `kscript` can be used as a speedier and more flexible substitute for built-in terminal tools such as `awk` or `sed` Use `-t`/`--text` to enable a support API for line-based text processing * Delete a column ```bash awk '!($3="")' some_flights.tsv kscript -t 'lines.split().selectByName(-3).print()' some_flights.tsv ``` * Delete trailing white space (spaces, tabs) ```bash awk '{sub(/[ \t]*$/, "");print}' file.txt kscript -t 'lines.map { it.trim() }.print()' file.txt ``` See https://github.com/holgerbrandl/kscript-support-api and [kscript as substitute for awk](https://holgerbrandl.github.io/kotlin/2017/05/08/kscript_as_awk_substitute.html) ??? reoccuring use-case was ... so streamline that --- # Pimp your REPL with `--interactive` ```kotlin #!/usr/bin/env kscript *//DEPS de.mpicbg.scicomp:kutils:0.4 import de.mpicbg.scicomp.bioinfo.openFasta if (args.size != 1) { System.err.println("Usage: CountRecords <fasta>") kotlin.system.exitProcess(-1) } val records = openFasta(java.io.File(args[0])) println(records.count()) ``` -- Bootstrap interactive shell from your script. ```bash kscript --interactive CountRecords.kts ``` ``` Creating REPL from /Users/brandl/Dropbox/kscript_kotlinconf_2017/code_examples/count_records.kts Welcome to Kotlin version 1.1.51 (JRE 1.8.0_151-b12) >>> import de.mpicbg.scicomp.bioinfo.openFasta >>> ``` ??? toggle between coding and interactive development evolve a workflow bing up an environment that matches the script to give you an example --- # Bootstrap projects from scripts with `--idea` * Artifacts and versions will differ between scripts * `kscript` allows to create temporary project from script using Gradle ```bash kscript --idea CountRecords.kts ``` ![](images/minus_idea.png) Requires command-line launcher `idea` to be setup via `Tools->Command Line Launcher` ??? final feature is about why? having multiple differening depedencies, hard to create intellij project to accomodate difference version --- class: inverse, center, middle # What's next? ??? walked through all the main features use the remaining minutes to * outline future directions of kscript * discuss the use of kotlin as a language for data science --- ## Replace comment `//` directives with annotations Using proper file annotations would be better design and also allow for better tooling ```kotlin // DEPS log4j:log4j:1.2.14 //vs @file:DependsOn("log4j:log4j:1.2.14") ``` -- No such thing as `DependsOn` in kotlin stdlib. To enable correct code parsing add ` com.github.holgerbrandl:kscript-annotations:1.0` as dependency to the Intellij project .center[.image-75[![](images/annotations_example.png)]] ??? why comments to configure deps and runtime, why not using annotations? You're right about it! It is better to use annotations over custom syntax! don't reinvent the wheel, follow the communiy ... support the moment it goes live. Why not default? --- # Getting serious about scripting with KEEP [#75 ](https://github.com/Kotlin/KEEP/issues/75) Great proposal that aims to unify various aspects of scripting in a common API * Define Kotlin scripting and it's applications * Describe intended use cases for the Kotlin scripting * Provide sufficient control of interpretation and execution of scripts * Provide usable default components and configurations for the typical use cases -- Some core aspects are implemented by `kscript`! * IDE/tooling support via `--idea` * Project-level REPL `--interactive` * Directives/annotations to declare dependencies and modulate the runtime environment -- .left-column50[ #### Will it kill `kscript`? Maybe. #### Looking forward to tool convergence! ] .left-column50[ ![](images/kscript_grave.png) ] ??? Kotlin Evolution and Enhancement Process Ilya Chernikov Will make `kscript` superfluous? Not any time soon given previous speed don't care, all I want is rock-solid scriptinh support that is fun to use. --- # Next steps? * Go `kotlin-native` to remove ~200ms JVM launch overhead ```bash exec $(kotlin -classpath ${jarPath} kscript.app.KscriptKt "$@") ``` * Support for custom artifact repositories * Pray for [KT-16802](https://youtrack.jetbrains.com/issue/KT-16802) _Good code is always red when editing kts-script files under Kotlin v1.1_ to become fixed .center[.image-50[.images[![](images/ide_bug.png)]]] #### Not much left to do. :-) Don't get infected by _featureritis_! #### `kscript` is unit- and battle-tested, and ready production! --- # Dream, dream, dream... * Revise annotation-driven script configuration once [KEEP75](https://github.com/Kotlin/KEEP/issues/75) Scripting API supports it * Use [kohesive/keplin-maven-resolver](https://github.com/kohesive/keplin) for dependency resolution instead of `mvn` * DSL-support: Derive new interpreters from `kscript` ```kotlin #!/usr/bin/env tornando-fx-script class HelloWorld : View() { override val root = hbox { label("Hello world") } } ``` * _<your ideas here!>_ just go to https://github.com/holgerbrandl/kscript ??? native requires at least some 'java.io.File'-like native API many features presented were actually suggested by community --> so if you have an idea .footnote[ DSL talk: Frederico Tomasetti https://github.com/Kotlin/KEEP/issues/75 https://github.com/Kotlin/KEEP/blob/scripting/proposals/scripting-support.md ] --- ## What's still missing in Kotlin to rule data-science? 1. **Interactivity**: Improve jupyter-kernel support (interactive usage, idea notebook editor support) 2. **More Kotlin DataScience APIs** for modeling ([pandas](http://pandas.pydata.org/), [dplyr](http://dplyr.tidyverse.org/)) and visualization ([ggplot2](http://ggplot2.org/), [seaborn](https://community.modeanalytics.com/python/libraries/seaborn/), [d3](https://d3js.org/)) 3. **Fix the REPL** to be not just a `re` wihout `pl` 4. **Data-Science IDE** Provide a _cut down_ version of IJ for data science ??? coming back to initial motivation. is it really ready yet? -- .left-column40[ ![](images/slow_repl.png) .image-200[![](images/falling_asleep.gif)] ] -- .right-column50[ .image-85[![](images/rstudio.png)] ] ??? don't blame anyone, Kotlin is still a young products, where some parts are work in progres Read–eval–print_loop long way python and r are miles ahead with the data-sciencelibrariess. --- class: inverse # Summary ### Kotlin may be the right choice for data science. ### `kscript` provides enhanced scripting support for Kotlin. ### `kscript` allows to replace scripts written in `ruby`, `python`, `bash`, `r` etc. with Kotlin -- Questions and pull requests are welcome. For these slides, more docs, examples see https://github.com/holgerbrandl/kscript Thanks for your attention. Thanks to the contributors of `kscript` for their great feedback and help. ??? Reproducible, protoyping, scalable, flat learning curve to build community combination of simplified language & very good dependency model/tooling