1
0
Fork 0
forked from fun/fun
fun/spec/v0.3.md

484 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Fun Language Specification v0.3
This document describes Fun (Fun Uses Nothing) as of version 0.3. It supersedes v0.2 by formalizing classes/objects, inheritance, namespaced includes, richer collections and builtins, concurrency primitives, networking and OS integration, as reflected by the examples.
---
## 1) Overview and Goals
- Readable: strict, indentation-based syntax (2 spaces), no semicolons.
- Safe: explicit types, no implicit numeric coercions, bounds-checked operations, controlled side effects.
- Hackable: pragmatic stdlib, process I/O, sockets, threads.
Whats new in v0.3 (high level):
- Classes and objects with methods, constructors, and inheritance (`extends`).
- Dot-call sugar for method calls, and explicit `this` in method definitions.
- Namespaced `#include ... as alias` for module imports.
- Maps (dictionaries) with literals and helpers.
- Control-flow additions: `break` and `continue`.
- Threads: `thread_spawn`, `thread_join` and `sleep`.
- Expanded system and network APIs (TCP/Unix sockets, serial, env, timers).
- Bitwise helpers (`band`, `bor`, `bxor`, `bnot`, `shl`).
- Exception syntax (`try/catch/finally`) is defined; runtime throwing/handling may be partial.
---
## 2) Lexical Structure
- Case-sensitive identifiers: letters, digits, `_`; must not start with a digit.
- Comments:
- Single-line: `// comment`
- Multi-line: `/* ... */`
- Whitespace and newlines:
- Indentation is exactly 2 spaces; tabs are forbidden.
- Newline terminates statements; no semicolons.
Reserved keywords (cannot be redefined):
- `if`, `else`, `for`, `while`, `break`, `continue`
- `fun`, `return`
- `class`, `extends`
- `global`, `private`
- `true`, `false`
- `try`, `catch`, `finally`
Notes:
- `#include` is a directive, not an expression; `as` is part of the include alias syntax (see Modules & Includes).
---
## 3) Types
Scalar types:
- `number`: 64-bit signed integer.
- `float`: 64-bit IEEE-754 floating point.
- `string`
- `boolean`: `true` / `false` (in conditionals `0` and `1` are accepted where noted).
- `byte`: 8-bit value (see conversions and overflow rules).
Fixed-width integers (signed/unsigned):
- `int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `int64`, `uint64`
Aggregate types:
- `array` and typed arrays: `array<T>`
- `map<K, V>` (dictionary / associative array)
- `object` (instances of `class`)
Examples:
```fun
number n = 42
float pi = 3.14159
string s = 'He said: "Fun!"'
boolean ok = true
byte b = 0x41
array<number> nums = [1, 2, 3]
array mixed = [1, "two", true, [3, 4]]
m = { "a": 1, "b": 2 } // map<string, number>
```
Dynamic typing escape hatch (discouraged; use when interacting with unknown data):
```fun
dynamic string x = 42 // allowed by spec; runtime performs dynamic checks
x = "Now I'm a string"
```
---
## 4) Variables and Scope
- `global` variables are visible program-wide.
- `private` variables are file-local (module private).
- Rebinding a global or shadowing a name is a compile-time error.
```fun
global string message = "Hello"
private number count = 42
number local = 23
```
---
## 5) Operators and Builtins
Arithmetic: `+`, `-`, `*`, `/`, `%`
Comparison: `==`, `!=`, `>`, `<`, `>=`, `<=`
Boolean: `&&`, `||`, `!`
Assignment: `=`
Bitwise helpers (functions):
- `band(a, b)`, `bor(a, b)`, `bxor(a, b)`, `bnot(a)`, `shl(a, n)`
```fun
print(bxor(0x80000000, 0x00000001)) // 2147483649
print(shl(0x80, 24)) // 2147483648
```
Collection helpers (selected):
- Arrays: `push(arr, v)`, `join(arr, sep)`, `map(arr, f)`, `filter(arr, pred)`, `reduce(arr, init, f)`
- Maps: `has(m, key)`, `keys(m)`, `values(m)`
Type/convert helpers (selected):
- `typeof(x) -> string`
- `to_string(x)` and numeric casts (see examples for `cast_demo.fun` and `conversions_showcase.fun`)
---
## 6) Control Flow
If/Else:
```fun
if (x != y)
print(x)
else if (a == b || h != i)
print(a + b)
else
if (k < 1 && l > 1)
print("Buh!")
```
While:
```fun
number i = 0
while i < 10
if i % 2 == 0
i = i + 1
continue
if i > 5
break
i = i + 1
```
For:
- Range iteration: `for i in range(start, end)`
- Array iteration: `for x in arr`
- Map iteration: `for k in keys(m)` then `m[k]`
```fun
for i in range(0, 5)
print(i)
for x in [1, 2, 3]
print(x)
```
Loop control:
- `break` exits the innermost loop.
- `continue` skips to next iteration of the current loop.
Try/Catch/Finally (syntax defined; runtime throwing may be incomplete):
```fun
try
// protected section
risky()
catch err
print("caught error:")
print(err)
finally
print("cleanup")
```
---
## 7) Functions
Built-in/runtime functions (selected):
- Basic: `print(x)`, `range(a, b)`, `sleep(ms)`
- Processes: `exec(cmd) -> string`, `system(cmd) -> number`
- Async processes: `nexec(cmd) -> pid/object`, `nsystem(cmd) -> number`, `nspawn(cmd) -> pid`, `wait(pid)`, `read(pid)`, `kill(pid)`
- Threads: `thread_spawn(fn, argOrArgs) -> thread_id`, `thread_join(thread_id) -> any`
User-defined functions:
```fun
fun add(a, b)
return a + b
fun divide(a, b)
if b == 0
return 0, "division by zero"
return a / b, ""
```
Higher-order helper (example pattern):
```fun
fun call(f, arg)
return f(arg)
```
Multiple return values are supported syntactically; use tuple-like unpacking via arrays as needed in user code patterns.
---
## 8) Classes and Objects
Definition:
```fun
class Name(/* optional ctor params with types */)
// field defaults
field1 = 0
field2 = ""
// method: first parameter must be `this`
fun method(this, arg1, arg2)
// ...
return 0
```
Constructors:
- Default constructor maps the class header parameters to fields of the same names.
- Optional explicit constructor hook: define `fun _construct(this, ...params...)` to customize initialization. It is invoked automatically on instantiation.
Fields and methods:
- Fields are created/initialized with simple assignments in the class body.
- Methods are functions declared inside the class; the first parameter must be `this`.
- Private members: any field or method whose name starts with `_` is considered private to the class. Accessing them from outside should raise an access error.
Instantiation and method calls:
```fun
p = Point(10, -2)
print(p.x) // field access via `.` or indexing
print(p["x"]) // map-like field access is supported
// Dot-call sugar: p.method(a, b) is equivalent to method(p, a, b)
print(p.toString())
```
Method references:
```fun
move_fn = p["move"]
move_fn(p, 3, 5) // call with explicit `this`
```
Inheritance:
```fun
class Parent(number start)
value = 0
fun _construct(this, s)
this.value = s
fun describe(this)
return "Parent(value=" + to_string(this.value) + ")"
class Child(number start) extends Parent
bonus = 5
fun _construct(this, s)
// runs after parent fields merged
this.value = this.value + this.bonus
fun describe(this)
return "Child(value=" + to_string(this.value) + ", bonus=" + to_string(this.bonus) + ")"
```
`typeof` on classes and instances:
- `typeof(Point) == "Class"`
- `typeof(p) == "Point(10, -2)"` (implementation-specific descriptive form)
---
## 9) Modules and Includes
Include sources:
- System/stdlib: angle brackets search the Fun library path (e.g., `FUN_LIB_DIR`).
```fun
#include <utils/math.fun>
```
- Local file: quoted, relative to the current working directory or file.
```fun
#include "./utils/file.fun"
```
- Absolute path is supported.
Namespaced includes:
- Use `as` to bind a module into a namespace alias.
```fun
#include <utils/math.fun> as m
#include "examples/namespaced_mod.fun" as mod
print(m.add(2, 3))
g = mod.Greeter("Hi")
g.say("World")
```
Aliased access uses `alias.symbol` or `alias.ClassName`.
Global/private at file scope control symbol exports from a module.
---
## 10) Collections
Arrays:
- Literals with `[ ... ]`; may be heterogeneous unless `array<T>` is declared.
- Helpers: `push`, `join`, `map`, `filter`, `reduce`, iteration via `for x in arr`.
Maps:
- Literal: `{ key: value, ... }`
- Indexing: `m["a"]`, assignment `m["c"] = 5`
- Introspection: `has(m, key)`, `keys(m)`, `values(m)`
- Iterate keys/values using arrays returned by `keys`/`values`.
---
## 11) Concurrency (Threads)
- `thread_spawn(fn, args)` starts `fn` in a new thread. `args` may be a single value or an array for multiple arguments.
- `thread_join(id)` waits for the thread and returns its result.
- `sleep(ms)` suspends current thread.
Example:
```fun
fun square(n)
sleep(100)
return n * n
ids = []
for x in [1, 2, 3]
push(ids, thread_spawn(square, x))
results = []
for id in ids
push(results, thread_join(id))
print(results)
```
---
## 12) System, Files, Environment, and Networking
Processes:
- Blocking: `exec(cmd) -> string` (stdout), `system(cmd) -> number` (exit code)
- Non-blocking: `nexec`, `nspawn`, `nsystem`, with `wait(pid)`, `read(pid)`, `kill(pid)` helpers
Environment and CLI:
- `env(NAME) -> string` to read env variables (see `os_env.fun`)
- `argv() -> array<string>` from `<cli.fun>`; also `FUN_ARGC`/`FUN_ARGS` environment interoperability in examples
Files:
- Basic file I/O helpers exist in the stdlib; see `file_io.fun`, `file_print_for_file_line_by_line.fun`
Time:
- Date/time and timers (see `datetime_basic.fun`, `datetime_extended.fun`, `datetime_timer.fun`)
Random:
- `random` helpers (see `random_demo.fun`, `random_number_example.fun`)
Regex:
- Regex operations via stdlib (see `regex_demo.fun`, `regex_procedural.fun`)
Networking:
- TCP client helpers: `tcp_connect(host, port) -> fd`, `sock_send(fd, data)`, `sock_recv(fd, nbytes)`, `sock_close(fd)`
- Unix domain sockets (see `unix_socket_echo.fun`)
Serial:
- Serial port helpers (see `serial_demo.fun`)
Progress/UI:
- Helper functions to render CLI progress (see `progress.fun`, `progress_inline.fun`)
Note: function names may live in stdlib modules; import accordingly (system-dependent availability).
---
## 13) Error Handling and Type Safety
- No implicit type coercion between numeric types; explicit casts or constructors are required.
- Overflow/underflow on fixed-width types is an error.
- Accessing undefined variables or re-defining globals is a compile-time error.
- Shadowing internal/runtime functions is forbidden.
- Exception syntax `try/catch/finally` is standardized in v0.3; throwing and catching at runtime may be partially implemented depending on the feature (see examples like `byte_overflow_try_catch.fun` and notes within).
---
## 14) Examples (from the repository)
Hello:
```fun
print("Hello, World!")
```
Namespaced includes:
```fun
#include <utils/math.fun> as m
print(m.add(2, 3))
```
Classes:
```fun
class Counter
value = 0
fun inc(this)
this.value = this.value + 1
return this.value
c = Counter()
print(c.inc())
```
Inheritance:
```fun
class Parent(number start)
value = 0
fun _construct(this, s)
this.value = s
class Child(number start) extends Parent
bonus = 5
fun _construct(this, s)
this.value = this.value + this.bonus
```
Threads:
```fun
tid = thread_spawn(add3, [10, 20, 30])
print(thread_join(tid)) // 60
```
TCP GET:
```fun
fd = tcp_connect("example.org", 80)
req = "GET / HTTP/1.0\r\nHost: example.org\r\n\r\n"
sent = sock_send(fd, req)
print(sock_recv(fd, 8192))
sock_close(fd)
```
---
## 15) Versioning and Compatibility
- v0.3 keeps v0.2 syntax intact and adds new features. Where runtime support is evolving (exceptions, some stdlib facets), the syntax is stable and forward-compatible.
- Examples are authoritative for idioms and available helpers; consult `examples/` and `lib/` modules.
---
## 16) Appendix: Notation and Conventions
- Use backticks for code identifiers in prose (`fun`, `class`, `extends`, etc.).
- All code blocks are in `fun` pseudolanguage.
- Indentation is always 2 spaces; tabs will cause errors.
---
## Changelog (from v0.2 to v0.3)
- Added: `class`, methods with explicit `this`, default and custom constructors via `_construct`.
- Added: inheritance with `extends`.
- Added: private members by leading underscore naming convention.
- Added: dot-call sugar `obj.method(a, b)` ≡ `method(obj, a, b)`.
- Added: namespaced includes: `#include <path> as alias`, `#include "path" as alias`.
- Added: `map` type with literals `{ key: value }` and helpers.
- Added: loop control `break`, `continue`.
- Added: threads (`thread_spawn`, `thread_join`), sleep.
- Added: socket helpers (TCP/Unix), serial devices, CLI argv, env helpers, timers.
- Added: bitwise helper functions: `band`, `bor`, `bxor`, `bnot`, `shl`.
- Added: exception syntax `try/catch/finally` (runtime handling is evolving).
---
## How to use this file
- Save this content as `./spec/v0.3.md` in the repository.
- Keep `examples/` in sync with this spec. When adding a new feature, provide an example and update the spec accordingly.