lyng/docs/whats_new.md

3.2 KiB

What's New in Lyng

This document highlights the latest additions and improvements to the Lyng language and its ecosystem.

Language Features

Class Properties with Accessors

Classes now support properties with custom get() and set() accessors. Properties in Lyng do not have automatic backing fields; they are pure accessors.

class Person(private var _age: Int) {
    // Read-only property
    val ageCategory get() = if (_age < 18) "Minor" else "Adult"

    // Read-write property
    var age: Int
        get() = _age
        set(v) {
            if (v >= 0) _age = v
        }
}

Private and Protected Setters

You can now restrict the visibility of a property's or field's setter using private set or protected set. This allows members to be publicly readable but only writable from within the declaring class or its subclasses.

class Counter {
    var count = 0
        private set  // Field with private setter
        
    fun increment() { count++ }
}

class AdvancedCounter : Counter {
    var totalOperations = 0
        protected set // Settable here and in further subclasses
}

let c = Counter()
c.increment() // OK
// c.count = 10 // Error: setter is private

Late-initialized val Fields

val fields in classes can be declared without an immediate initializer, provided they are assigned exactly once. If accessed before initialization, they hold the special Unset singleton.

class Service {
    val logger
    
    fun check() {
        if (logger == Unset) println("Not initialized yet")
    }

    init {
        logger = Logger("Service")
    }
}

Named Arguments and Named Splats

Function calls now support named arguments using the name: value syntax. If the variable name matches the parameter name, you can use the name: shorthand.

fun greet(name, greeting = "Hello") {
    println("$greeting, $name!")
}

val name = "Alice"
greet(name:)                  // Shorthand for greet(name: name)
greet(greeting: "Hi", name: "Bob")

let params = { name: "Charlie", greeting: "Hey")
greet(...params)              // Named splat expansion

Multiple Inheritance (MI)

Lyng now supports multiple inheritance using the C3 Method Resolution Order (MRO). Use this@Type or casts for disambiguation.

class A { fun foo() = "A" }
class B { fun foo() = "B" }

class Derived : A, B {
    fun test() {
        println(foo())              // Resolves to A.foo (leftmost)
        println(this@B.foo())       // Qualified dispatch to B.foo
    }
}

let d = Derived()
println((d as B).foo())             // Disambiguation via cast

Tooling and Infrastructure

CLI: Formatting Command

A new fmt subcommand has been added to the Lyng CLI.

lyng fmt MyFile.lyng             # Print formatted code to stdout
lyng fmt --in-place MyFile.lyng  # Format file in-place
lyng fmt --check MyFile.lyng     # Check if file needs formatting

IDEA Plugin: Autocompletion

Experimental lightweight autocompletion is now available in the IntelliJ plugin. It features type-aware member suggestions and inheritance-aware completion.

You can enable it in Settings | Lyng Formatter | Enable Lyng autocompletion.