2025-05-18 00:52:19 +04:00
2025-08-13 23:22:04 +03:00
2025-08-13 23:22:04 +03:00
2025-08-14 14:31:51 +03:00
2025-08-13 23:22:04 +03:00
2025-05-18 00:52:19 +04:00
2025-08-13 23:24:51 +03:00
2025-08-14 14:31:51 +03:00
2025-08-13 23:22:04 +03:00
2025-08-13 23:22:04 +03:00
2025-08-13 23:22:04 +03:00
2025-05-18 00:52:19 +04:00
2025-05-18 00:52:19 +04:00
2025-08-13 23:22:04 +03:00
2025-05-18 00:52:19 +04:00
2025-08-13 23:22:04 +03:00

Lyng: modern scripting for kotlin multiplatform

A KMP library and a standalone interpreter

  • simple, compact, intuitive and elegant modern code:
class Point(x,y) {
   fun dist() { sqrt(x*x + y*y) } 
}
Point(3,4).dist() //< 5

fun swapEnds(first, args..., last, f) {
    f( last, ...args, first)
} 
  • extremely simple Kotlin integration on any platform (JVM, JS, WasmJS, Lunux, MacOS, iOS, Windows)
  • 100% secure: no access to any API you didn't explicitly provide
  • 100% coroutines! Every function/script is a coroutine, it does not block the thread, no async/await/suspend keyword garbage, see parallelism
  val deferred = launch {
    delay(1.5) // coroutine is delayed for 1.5s, thread is not blocked!
    "done"
  }
  // ...
  // suspend current coroutine, no thread is blocked again,
  // and wait for deferred to return something:
  assertEquals("donw", deferred.await())

and it is multithreaded on platforms supporting it (automatically, no code changes required, just launch more coroutines and they will be executed concurrently if possible). See parallelism

  • functional style and OOP together, multiple inheritance, implementing interfaces for existing classes, writing extensions.
  • Any Unicode letters can be used as identifiers: assert( sin(π/2) == 1 ).

Resources:

Integration in Kotlin multiplatform

Add dependency to your project

// update to current please:
val lyngVersion = "0.6.1-SNAPSHOT"

repositories {
    // ...
    maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
}

And add dependency to the proper place in your project, it could look like:

comminMain by getting {
    dependencies {
        // ...
        implementation("net.sergeych:lynglib:$lyngVersion")
    }
}

Now you can import lyng and use it:

Execute script:

import net.sergeyh.lyng.*

// we need a coroutine to start, as Lyng
// is a coroutine based language, async topdown
runBlocking {
    assert(5 == eval(""" 3*3 - 4 """).toInt())
    eval(""" println("Hello, Lyng!") """)
}

Exchanging information

Script is executed over some Scope. Create instance, add your specific vars and functions to it, and call:


import com.sun.source.tree.Scope
import new.sergeych.lyng.*

// simple function
val scope = Script.newScope().apply {
    addFn("sumOf") {
        var sum = 0.0
        for (a in args) sum += a.toDouble()
        ObjReal(sum)
    }
    addConst("LIGHT_SPEED", ObjReal(299_792_458.0))

    // callback back to kotlin to some suspend fn, for example::
    // suspend fun doSomeWork(text: String): Int
    addFn("doSomeWork") {
        // this _is_ a suspend lambda, we can call suspend function,
        // and it won't consume the thread.
        // note that in kotlin handler, `args` is a list of `Obj` arguments
        // and return value from this lambda should be Obj too:
        doSomeWork(args[0]).toObj()
    }
}
// adding constant:
scope.eval("sumOf(1,2,3)") // <- 6

Note that the scope stores all changes in it so you can make calls on a single scope to preserve state between calls.

Why?

Designed to add scripting to kotlin multiplatform application in easy and efficient way. This is attempt to achieve what Lua is for C/++.

  • fast start (times and times faster than initializing v8/wasm)
  • fast and simple kotlin interoperability
  • coroutine-based, truly async. On platforms with multithreading, run multithreaded. No python/ruby/javascript threads hell.
  • small footprint
  • absolutely safe: no access to any dangerous or sensitive functions until you specifically provide it.

Language

  • Javascript, WasmJS, native, JVM, android - batteries included.
  • dynamic types in most elegant and concise way
  • async, 100% coroutines, supports multiple cores where platform supports thread
  • good for functional an object-oriented style

Language Roadmap

v1.0.0

Planned autumn 2025. Complete dynamic language with sufficient standard library:

Ready features:

  • Language platform and independent command-line launcher
  • Integral types and user classes, variables and constants, functions
  • lambdas and closures, coroutines for all callables
  • while-else, do-while-else, for-else loops with break-continue returning values and labels support
  • ranges, lists, strings, interfaces: Iterable, Iterator, Collection, Array
  • when(value), if-then-else
  • exception handling: throw, try-catch-finally, exception classes.
  • multiplatform maven publication
  • documentation for the current state
  • maps, sets and sequences (flows?)
  • modules
  • string formatting and tools
  • launch, deferred, CompletableDeferred, Mutex, etc.
  • multiline strings
  • typesafe bit-effective serialization
  • compression/decompression (integrated in serialization)
  • dynamic fields
  • function annotations

Under way:

  • regular exceptions
  • multiple inheritance for user classes
  • site with integrated interpreter to give a try
  • kotlin part public API good docs, integration focused
  • better stack reporting

v1.1+

Planned features.

  • type specifications
  • source docs and maybe lyng.md to a standard
  • metadata first class access from lyng

Further

  • client with GUI support based on compose multiplatform somehow
  • notebook - style workbooks with graphs, formulae, etc.
  • language server or compose-based lyng-aware editor
Description
No description provided
Readme 5.1 MiB
Languages
Kotlin 99.7%
Shell 0.3%