Skip to content

Commit 89ecb4b

Browse files
committed
extended docs
1 parent ddf8178 commit 89ecb4b

File tree

2 files changed

+78
-9
lines changed

2 files changed

+78
-9
lines changed

README.md

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ Using annotations instead of comment directives to configure scripts is cleaner
301301
// declare application entry point (applies on for kt-files)
302302
@file:EntryPoint("Foo.bar")
303303

304+
import kscript.annotations.*
305+
304306
print("1+1")
305307
```
306308

@@ -311,27 +313,79 @@ com.github.holgerbrandl:kscript-annotations:1.1
311313

312314
`kscript` will automatically detect an annotation-driven script, and if so will declare a dependency on this artifact internally.
313315

314-
Support API
315-
-----------
316+
Text Processing Mode
317+
--------------------
318+
319+
`kscript` can be used as a speedier and more flexible substitute for built-in terminal tools such as `awk` or `sed`
316320

317321

318-
`kscript` is complemented by a [support library](https://github.com/holgerbrandl/kscript-support-api) to ease the writing of Kotlin scriptlets for text-processing. The latter includes solutions to common use-cases like argument parsing, data streaming, IO utilities, and various iterators to streamline the development of kscript applications.
322+
`kscript` is complemented by
319323

320324
The text processing mode can be enabled with `-t` or `--text`. If so, `kscript` will
321-
* declare `com.github.holgerbrandl:kscript-support:1.2.4` as dependency for the script
322-
* import the `kscript.*` namespace
325+
326+
* Declare `com.github.holgerbrandl:kscript-support:1.2.4` as dependency for the script. This [support library](https://github.com/holgerbrandl/kscript-support-api) eases the writing of Kotlin scriptlets for text-processing. It includes solutions to common use-cases like argument parsing, data streaming, IO utilities, and various iterators to streamline the writing of scriptlets for text processing.
327+
* Import the `kscript.*` namespace
323328
* Define variable `val lines = kscript.text.StreamUtilKt.resolveArgFile(args)` which returns an iterator over the lines in the first input argument of the script, or the standard input if no file arguments are provided to the script
324329

325-
This allows for `sed`/`awk`/`perl`-like constructs such as
330+
331+
This allows to to replace `awk`ward constructs (or `sed` or`perl`) with _kotlinesque_ solutions such as
326332

327333
```bash
328-
cat some_file | kscript -t 'lines.filter { "^de0[-0]*".toRegex().matches(it) }.map { it + "foo:" }.print()'
334+
cat some_file | kscript -t 'lines
335+
.filter { "^de0[-0]*".toRegex().matches(it) }
336+
.map { it + "foo:" }
337+
.print()
338+
'
329339
```
330340

331341
In this example, the extension method [`Iterable<String>.print()`](https://github.com/holgerbrandl/kscript-support-api/blob/master/src/main/kotlin/kscript/text/StreamUtil.kt#L34) to print the lines to stdout comes from the support API. The rest is stdlib Kotlin.
332342

333343
For more examples using the support library see this [blog post](http://holgerbrandl.github.io/kotlin/2017/05/08/kscript_as_awk_substitute.html).
334344

345+
Treat yourself a REPL with `--interactive`
346+
------------------------------------------
347+
348+
To create an interactive kotlin shell (aka [REPL](https://kotlinlang.org/docs/tutorials/command-line.html#running-the-repl)) with all script dependencies added to the classpath you can use `--interactive`.
349+
350+
For example, let's assume the following short script, named `count_records.kts`
351+
```kotlin
352+
#!/usr/bin/env kscript
353+
@file:DependsOn("de.mpicbg.scicomp:kutils:0.4")
354+
355+
import de.mpicbg.scicomp.bioinfo.openFasta
356+
357+
if (args.size != 1) {
358+
System.err.println("Usage: CountRecords <fasta>")
359+
kotlin.system.exitProcess(-1)
360+
}
361+
362+
val records = openFasta(java.io.File(args[0]))
363+
println(records.count())
364+
```
365+
366+
To build a REPL that has the declared artifact in its classpath, we can just do
367+
368+
```bash
369+
kscript --interactive count_records.kts
370+
```
371+
which will bring up the classpath-enhanced REPL:
372+
```
373+
Creating REPL from count_records.kts
374+
Welcome to Kotlin version 1.1.51 (JRE 1.8.0_151-b12)
375+
>>> import de.mpicbg.scicomp.bioinfo.openFasta
376+
>>>
377+
```
378+
379+
Boostrap IDEA from a `kscript`let
380+
-----------------------------------
381+
382+
Artifacts and versions will differ between scripts, so it is hard to maintain them all in a single project. To nevertheless provide optimal tooling when scripting with Kotlin `kscript` allows to create temporary projects for `<script>` arguments. .
383+
384+
```bash
385+
kscript --idea CountRecords.kts
386+
```
387+
This will open [IntelliJ IDEA](https://www.jetbrains.com/idea/) with a minimalistic project containing just your (1) `<script>` and (2) a generated `gradle.build` file:
388+
![](misc/readme_images/minus_idea.png)
335389

336390

337391
FAQ
@@ -346,11 +400,11 @@ print("hello kotlin!")
346400
is a valid Kotlin `kts` script. Plain and simple, no `main`, no `companion`, just a few bits of code.
347401

348402

349-
### Ok, but does `kscript` also work for regular kotlin `.kt` source files with a `main` as entry point?
403+
### Does `kscript` also work for regular kotlin `.kt` source files with a `main` as entry point?
350404

351405
Yes, (since v1.6) you can run kotlin source files through `kscript`. By default it will assume a top-level `main` method as entry-point.
352406

353-
However in case you're using a companion object to declare the entry point, you need to indicate this via the `//ENTRY` directive:
407+
However in case you're using a companion object to declare the entry point, you need to indicate this via the `//ENTRY`/`@file:Entry` directive:
354408

355409

356410
### Why does it fail to read my script file when using cygwin?
@@ -360,6 +414,21 @@ In order to use cygwin you need to use windows paths to provide your scripts. Yo
360414
kscript $(cygpath -w /cygdrive/z/some/path/my_script.kts)
361415
```
362416

417+
## What are performance and resource usage difference between scripting with kotlin and python?
418+
419+
Kotlin is a compiled language, so there is a compilation overhead when you run a script/application written in Kotlin for the first time.
420+
421+
Kotlin runs (mainly) on the JVM which needs some time (~200ms) to start up. In contrast, the python interpreter has close to zero warmup time.
422+
423+
I think there is a consensus that JVM programs execute much faster than python equivalents. Still, python might be faster depending on your specific usecase. Also, with kotlin-native becoming more mature, you could compile into native binaries directly, which should bring it close to C/C++ performance.
424+
425+
Main motivations for using Kotlin over Python for scripting and development are
426+
* Kotlin is the better designed, more fluent language with much better tooling around it
427+
* The JVM dependency ecosystem allows for strict versioning. No more messing around with virtualenv, e.g. to run a short 10liner against a specific version of numpy.
428+
429+
430+
431+
363432

364433
### Can I use custom artifact repositories?
365434

misc/readme_images/minus_idea.png

342 KB
Loading

0 commit comments

Comments
 (0)