update version, site and docs
This commit is contained in:
parent
c5b8871c3a
commit
afa4b20070
39
CHANGELOG.md
39
CHANGELOG.md
@ -1,6 +1,31 @@
|
||||
## Changelog
|
||||
## 1.5.0-SNAPSHOT
|
||||
|
||||
### Unreleased
|
||||
### Language Features
|
||||
- Added `return` statement with local and non-local exit support (`return@label`).
|
||||
- Support for `abstract` classes, methods, and variables.
|
||||
- Introduced `interface` as a synonym for `abstract class`.
|
||||
- Multiple Inheritance (MI) completed and enabled by default (C3 MRO).
|
||||
- Class properties with custom accessors (`get`, `set`).
|
||||
- Restricted setter visibility (`private set`, `protected set`).
|
||||
- Late-initialized `val` fields in classes with `Unset` protection.
|
||||
- Named arguments (`name: value`) and named splats (`...Map`).
|
||||
- Assign-if-null operator `?=`.
|
||||
- Refined `protected` visibility rules and `closed` modifier.
|
||||
- Transient attribute `@Transient` for serialization and equality.
|
||||
- Unified Delegation model for `val`, `var`, and `fun`.
|
||||
- Singleton objects (`object`) and object expressions.
|
||||
|
||||
### Standard Library
|
||||
- Added `with(self, block)` for scoped execution.
|
||||
- Added `clamp()` function and extension.
|
||||
- Improved `Exception` and `StackTraceEntry` reporting.
|
||||
|
||||
### Tooling and IDE
|
||||
- **CLI**: Added `fmt` as a first-class subcommand for code formatting.
|
||||
- **IDEA Plugin**: Lightweight autocompletion (experimental), improved docs, and Grazie integration.
|
||||
- **Highlighters**: Updated TextMate bundle and website highlighters for new syntax.
|
||||
|
||||
### Detailed Changes:
|
||||
|
||||
- Language: Refined `protected` visibility rules
|
||||
- Ancestor classes can now access `protected` members of their descendants, provided the ancestor also defines or inherits a member with the same name (indicating an override of a member known to the ancestor).
|
||||
@ -109,16 +134,6 @@
|
||||
|
||||
- Documentation updated (docs/OOP.md and tutorial quick-start) to reflect MI with active C3 MRO.
|
||||
|
||||
Notes:
|
||||
- Existing single-inheritance code continues to work; resolution reduces to the single base.
|
||||
- If code previously relied on non-deterministic parent set iteration, C3 MRO provides a predictable order; disambiguate explicitly if needed using `this@Type`/casts.
|
||||
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased
|
||||
|
||||
- CLI: Added `fmt` as a first-class Clikt subcommand.
|
||||
- Default behavior: formats files to stdout (no in-place edits by default).
|
||||
- Options:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Lyng Language AI Specification (V1.3)
|
||||
# Lyng Language AI Specification (V1.5.0-SNAPSHOT)
|
||||
|
||||
High-density specification for LLMs. Reference this for all Lyng code generation.
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ assertEquals(A.One, A.E.One)
|
||||
|
||||
- [Language home](https://lynglang.com)
|
||||
- [introduction and tutorial](docs/tutorial.md) - start here please
|
||||
- [What's New in 1.3](docs/whats_new_1_3.md)
|
||||
- [What's New in 1.5](docs/whats_new_1_5.md)
|
||||
- [Testing and Assertions](docs/Testing.md)
|
||||
- [Filesystem and Processes (lyngio)](docs/lyngio.md)
|
||||
- [Return Statement](docs/return_statement.md)
|
||||
@ -64,7 +64,7 @@ assertEquals(A.One, A.E.One)
|
||||
|
||||
```kotlin
|
||||
// update to current please:
|
||||
val lyngVersion = "0.6.1-SNAPSHOT"
|
||||
val lyngVersion = "1.5.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
// ...
|
||||
@ -177,7 +177,7 @@ Designed to add scripting to kotlin multiplatform application in easy and effici
|
||||
|
||||
# Language Roadmap
|
||||
|
||||
We are now at **v1.0**: basic optimization performed, battery included: standard library is 90% here, initial
|
||||
We are now at **v1.5.0-SNAPSHOT** (stable development cycle): basic optimization performed, battery included: standard library is 90% here, initial
|
||||
support in HTML, popular editors, and IDEA; tools to syntax highlight and format code are ready. It was released closed to schedule.
|
||||
|
||||
Ready features:
|
||||
@ -217,7 +217,7 @@ Ready features:
|
||||
|
||||
All of this is documented in the [language site](https://lynglang.com) and locally [docs/language.md](docs/tutorial.md). the current nightly builds published on the site and in the private maven repository.
|
||||
|
||||
## plan: towards v1.5 Enhancing
|
||||
## plan: towards v2.0 Next Generation
|
||||
|
||||
- [x] site with integrated interpreter to give a try
|
||||
- [x] kotlin part public API good docs, integration focused
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# What's New in Lyng
|
||||
|
||||
This document highlights the latest additions and improvements to the Lyng language and its ecosystem.
|
||||
For a programmer-focused migration summary, see `docs/whats_new_1_3.md`.
|
||||
For a programmer-focused migration summary, see `docs/whats_new_1_5.md`.
|
||||
|
||||
## Language Features
|
||||
|
||||
@ -102,7 +102,7 @@ Singleton objects are declared using the `object` keyword. They provide a conven
|
||||
|
||||
```lyng
|
||||
object Config {
|
||||
val version = "1.2.3"
|
||||
val version = "1.5.0-SNAPSHOT"
|
||||
fun show() = println("Config version: " + version)
|
||||
}
|
||||
|
||||
|
||||
93
docs/whats_new_1_5.md
Normal file
93
docs/whats_new_1_5.md
Normal file
@ -0,0 +1,93 @@
|
||||
# What's New in Lyng 1.5 (vs 1.3.* / master)
|
||||
|
||||
This document summarizes the significant changes and new features introduced in the 1.5.0-SNAPSHOT development cycle.
|
||||
|
||||
## Highlights
|
||||
|
||||
- **The `return` Statement**: Added support for local and non-local returns using labels.
|
||||
- **Abstract Classes and Interfaces**: Full support for `abstract` members and the `interface` keyword.
|
||||
- **Class Properties with Accessors**: Define `val` and `var` properties with custom `get()` and `set()`.
|
||||
- **Restricted Setter Visibility**: Use `private set` and `protected set` on fields and properties.
|
||||
- **Late-initialized `val`**: Support for `val` fields that are initialized in `init` blocks or class bodies.
|
||||
- **Named Arguments and Splats**: Improved call-site readability with `name: value` and map-based splats.
|
||||
- **Refined Visibility**: Improved `protected` access and `closed` modifier for better encapsulation.
|
||||
|
||||
## Language Features
|
||||
|
||||
### The `return` Statement
|
||||
You can now exit from the innermost enclosing callable (function or lambda) using `return`. Lyng also supports non-local returns to outer scopes using labels.
|
||||
|
||||
```lyng
|
||||
fun findFirst<T>(list: Iterable<T>, predicate: (T)->Bool): T? {
|
||||
list.forEach {
|
||||
if (predicate(it)) return@findFirst it
|
||||
}
|
||||
null
|
||||
}
|
||||
```
|
||||
|
||||
### Abstract Classes and Interfaces
|
||||
Lyng now supports the `abstract` modifier for classes and their members. `interface` is introduced as a synonym for `abstract class`, allowing for rich multi-inheritance patterns.
|
||||
|
||||
```lyng
|
||||
interface Shape {
|
||||
abstract val area: Real
|
||||
fun describe() = "Area: %g"(area)
|
||||
}
|
||||
|
||||
class Circle(val radius: Real) : Shape {
|
||||
override val area get = Math.PI * radius * radius
|
||||
}
|
||||
```
|
||||
|
||||
### Class Properties with Accessors
|
||||
Properties can now have custom getters and setters. They do not have automatic backing fields, making them perfect for computed values or delegation.
|
||||
|
||||
```lyng
|
||||
class Rectangle(var width: Real, var height: Real) {
|
||||
val area: Real get() = width * height
|
||||
|
||||
var squareSize: Real
|
||||
get() = area
|
||||
set(v) {
|
||||
width = sqrt(v)
|
||||
height = width
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Named Arguments and Named Splats
|
||||
Improve call-site clarity by specifying argument names. You can also expand a Map into named arguments using the splat operator.
|
||||
|
||||
```lyng
|
||||
fun configure(timeout: Int, retry: Int = 3) { ... }
|
||||
|
||||
configure(timeout: 5000, retry: 5)
|
||||
val options = { timeout: 1000, retry: 1 }
|
||||
configure(...options)
|
||||
```
|
||||
|
||||
### Modern Operators
|
||||
The `?=` operator allows for concise "assign if null" logic.
|
||||
|
||||
```lyng
|
||||
var cache: Map? = null
|
||||
cache ?= { "status": "ok" } // Only assigns if cache is null
|
||||
```
|
||||
|
||||
## Tooling and IDE
|
||||
|
||||
- **IDEA Plugin**: Significant improvements to autocompletion, documentation tooltips, and natural language support (Grazie integration).
|
||||
- **CLI**: The `lyng fmt` command is now a first-class tool for formatting code with various options like `--check` and `--in-place`.
|
||||
- **Performance**: Ongoing optimizations in the bytecode VM and compiler for faster execution and smaller footprint.
|
||||
|
||||
## Migration Guide (from 1.3.*)
|
||||
|
||||
1. **Check Visibility**: Refined `protected` and `private` rules may catch previously undetected invalid accesses.
|
||||
2. **Override Keyword**: Ensure all members that override ancestor declarations are marked with the `override` keyword (now mandatory).
|
||||
3. **Return in Shorthand**: Remember that `return` is forbidden in `=` shorthand functions; use block syntax if you need early exit.
|
||||
|
||||
## References
|
||||
- `docs/OOP.md`
|
||||
- `docs/return_statement.md`
|
||||
- `docs/tutorial.md`
|
||||
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "1.4.0-SNAPSHOT"
|
||||
version = "1.5.0-SNAPSHOT"
|
||||
|
||||
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
||||
|
||||
|
||||
@ -29,8 +29,8 @@ fun HomePage() {
|
||||
listOf(
|
||||
"""
|
||||
// Everything is an expression
|
||||
val x = 10
|
||||
val status = if (x > 0) "Positive" else "Zero or Negative"
|
||||
val x: Int = 10
|
||||
val status: String = if (x > 0) "Positive" else "Zero or Negative"
|
||||
|
||||
// Even loops return values!
|
||||
val result = for (i in 1..5) {
|
||||
@ -40,8 +40,8 @@ fun HomePage() {
|
||||
println("Result: " + result)
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Functional power with ranges and collections
|
||||
val squares = (1..10)
|
||||
// Functional power with generics and collections
|
||||
val squares: List<Int> = (1..10)
|
||||
.filter { it % 2 == 0 }
|
||||
.map { it * it }
|
||||
|
||||
@ -49,20 +49,43 @@ fun HomePage() {
|
||||
// Output: [4, 16, 36, 64, 100]
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Generics and type aliases
|
||||
typealias Num = Int | Real
|
||||
|
||||
class Box<out T: Num>(val value: T) {
|
||||
fun get(): T = value
|
||||
}
|
||||
|
||||
val intBox = Box(42)
|
||||
val realBox = Box(3.14)
|
||||
println("Boxes: " + intBox.get() + ", " + realBox.get())
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Strict compile-time types and symbol resolution
|
||||
fun greet(name: String, count: Int) {
|
||||
for (i in 1..count) {
|
||||
println("Hello, " + name + "!")
|
||||
}
|
||||
}
|
||||
|
||||
greet("Lyng", 3)
|
||||
// greet(10, "error") // This would be a compile-time error!
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Flexible map literals and shorthands
|
||||
val id = 101
|
||||
val name = "Lyng"
|
||||
val base = { id:, name: } // Shorthand for id: id, name: name
|
||||
|
||||
val full = { ...base, version: "1.0", status: "active" }
|
||||
val full = { ...base, version: "1.5.0-SNAPSHOT", status: "active" }
|
||||
println(full)
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Modern null safety
|
||||
var config = null
|
||||
var config: Map<String, Int>? = null
|
||||
config ?= { timeout: 30 } // Assign only if null
|
||||
|
||||
val timeout = config?.timeout ?: 60
|
||||
val timeout = config?["timeout"] ?: 60
|
||||
println("Timeout is: " + timeout)
|
||||
""".trimIndent(),
|
||||
"""
|
||||
@ -76,10 +99,10 @@ fun HomePage() {
|
||||
"""
|
||||
// Diamond-safe Multiple Inheritance (C3 MRO)
|
||||
interface Logger {
|
||||
fun log(m) = println("[LOG] " + m)
|
||||
fun log(m: String) = println("[LOG] " + m)
|
||||
}
|
||||
interface Auth {
|
||||
fun login(u) = println("Login: " + u)
|
||||
fun login(u: String) = println("Login: " + u)
|
||||
}
|
||||
|
||||
class App() : Logger, Auth {
|
||||
@ -92,30 +115,30 @@ fun HomePage() {
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Extension functions and properties
|
||||
fun String.shout() = this.toUpperCase() + "!!!"
|
||||
fun String.shout(): String = this.uppercase() + "!!!"
|
||||
|
||||
println("hello".shout())
|
||||
|
||||
val List.second get = this[1]
|
||||
val List<T>.second: T get() = this[1]
|
||||
println([10, 20, 30].second)
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Non-local returns from closures
|
||||
fun findFirst(list, predicate) {
|
||||
fun findFirst<T>(list: Iterable<T>, predicate: (T)->Bool): T? {
|
||||
list.forEach {
|
||||
if (predicate(it)) return@findFirst it
|
||||
}
|
||||
null
|
||||
}
|
||||
|
||||
val found = findFirst([1, 5, 8, 12]) { it > 10 }
|
||||
val found: Int? = findFirst([1, 5, 8, 12]) { it > 10 }
|
||||
println("Found: " + found)
|
||||
""".trimIndent(),
|
||||
"""
|
||||
// Easy operator overloading
|
||||
class Vector(val x, val y) {
|
||||
override fun plus(other) = Vector(x + other.x, y + other.y)
|
||||
override fun toString() = "Vector(%g, %g)"(x, y)
|
||||
class Vector(val x: Real, val y: Real) {
|
||||
override fun plus(other: Vector): Vector = Vector(x + other.x, y + other.y)
|
||||
override fun toString(): String = "Vector(%g, %g)"(x, y)
|
||||
}
|
||||
|
||||
val v1 = Vector(1, 2)
|
||||
@ -125,7 +148,7 @@ fun HomePage() {
|
||||
"""
|
||||
// Property delegation to Map
|
||||
class User() {
|
||||
var name by Map()
|
||||
var name: String by Map()
|
||||
}
|
||||
|
||||
val u = User()
|
||||
@ -165,17 +188,18 @@ fun HomePage() {
|
||||
Div({ classes("text-center") }) {
|
||||
H1({ classes("display-5", "fw-bold", "mb-3") }) { Text("Welcome to Lyng") }
|
||||
P({ classes("lead", "text-muted", "mb-4") }) {
|
||||
Text("A lightweight, expressive scripting language designed for clarity, composability, and fun. ")
|
||||
Text("A lightweight, expressive scripting language with strict static typing and functional power. ")
|
||||
Br()
|
||||
Text("Run it anywhere Kotlin runs — share logic across JS, JVM, and more.")
|
||||
}
|
||||
Div({ classes("d-flex", "justify-content-center", "gap-2", "flex-wrap", "mb-4") }) {
|
||||
// Benefits pills
|
||||
listOf(
|
||||
"Clean, familiar syntax",
|
||||
"Strict static typing",
|
||||
"Generics & Type Aliases",
|
||||
"Implicit coroutines",
|
||||
"both FP and OOP",
|
||||
"Batteries-included standard library",
|
||||
"Embeddable and testable"
|
||||
"Batteries-included standard library"
|
||||
).forEach { b ->
|
||||
Span({ classes("badge", "text-bg-secondary", "rounded-pill") }) { Text(b) }
|
||||
}
|
||||
@ -233,7 +257,7 @@ fun HomePage() {
|
||||
// Short features list
|
||||
Div({ classes("row", "g-4", "mt-1") }) {
|
||||
listOf(
|
||||
Triple("Fast to learn", "Familiar constructs and readable patterns — be productive in minutes.", "lightning"),
|
||||
Triple("Safe and Robust", "Strict compile-time resolution, generics, and null safety catch errors early.", "shield-check"),
|
||||
Triple("Portable", "Runs wherever Kotlin runs: reuse logic across platforms.", "globe2"),
|
||||
Triple("Pragmatic", "A standard library that solves real problems without ceremony.", "gear-fill")
|
||||
).forEach { (title, text, icon) ->
|
||||
|
||||
@ -22,6 +22,7 @@ import net.sergeych.lyng.Script
|
||||
import net.sergeych.lyng.ScriptError
|
||||
import net.sergeych.lyng.highlight.TextRange
|
||||
import net.sergeych.lyng.miniast.CompletionItem
|
||||
import net.sergeych.lyng.requireScope
|
||||
import net.sergeych.lyng.tools.LyngDiagnostic
|
||||
import net.sergeych.lyng.tools.LyngDiagnosticSeverity
|
||||
import net.sergeych.lyng.tools.LyngSymbolInfo
|
||||
@ -48,11 +49,18 @@ fun TryLyngPage(route: String) {
|
||||
var code by remember(initialCode) {
|
||||
mutableStateOf(
|
||||
initialCode ?: """
|
||||
// Welcome to Lyng! Edit and run.
|
||||
// Try changing the data and press Ctrl+Enter or click Run.
|
||||
|
||||
val data = 1..5 // or [1, 2, 3, 4, 5]
|
||||
data.filter { it % 2 == 0 }.map { it * it }
|
||||
// Welcome to Lyng! Modern scripting with strict types and generics.
|
||||
|
||||
typealias Numeric = Int | Real
|
||||
|
||||
fun process<T: Numeric>(items: List<T>): List<T> {
|
||||
items.filter { it > 0 }.map { it * it }
|
||||
}
|
||||
|
||||
val data: List<Int> = [-2, -1, 0, 1, 2]
|
||||
println("Processed: " + process(data))
|
||||
|
||||
// Try changing data or adding Real numbers!
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
@ -94,13 +102,13 @@ fun TryLyngPage(route: String) {
|
||||
s.addVoidFn("print") {
|
||||
for ((i, a) in this.args.withIndex()) {
|
||||
if (i > 0) printed.append(' ')
|
||||
printed.append(a.toString(this).value)
|
||||
printed.append(a.toString(this.requireScope()).value)
|
||||
}
|
||||
}
|
||||
s.addVoidFn("println") {
|
||||
for ((i, a) in this.args.withIndex()) {
|
||||
if (i > 0) printed.append(' ')
|
||||
printed.append(a.toString(this).value)
|
||||
printed.append(a.toString(this.requireScope()).value)
|
||||
}
|
||||
printed.append('\n')
|
||||
}
|
||||
@ -154,8 +162,8 @@ fun TryLyngPage(route: String) {
|
||||
|
||||
fun resetCode() {
|
||||
code = initialCode ?: """
|
||||
// Welcome to Lyng! Edit and run.
|
||||
[1,2,3].map { it * 10 }
|
||||
// Welcome to Lyng! Modern scripting with strict types and generics.
|
||||
[1, 2, 3].map { it * 10 }
|
||||
""".trimIndent()
|
||||
output = null
|
||||
error = null
|
||||
|
||||
@ -329,7 +329,7 @@
|
||||
<!-- Top-left version ribbon -->
|
||||
<div class="corner-ribbon bg-danger text-white">
|
||||
<span style="margin-left: -5em">
|
||||
v1.2.0!
|
||||
v1.5.0-SNAPSHOT!
|
||||
</span>
|
||||
</div>
|
||||
<!-- Fixed top navbar for the whole site -->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user