252 lines
6.8 KiB
Markdown
252 lines
6.8 KiB
Markdown
# ƿit Language — AI Context
|
|
|
|
ƿit (pronounced "pit") is a safe, actor-based programming language. Its syntax resembles JavaScript but with significant differences. Scripts use `.ce` (actors) and `.cm` (modules) file extensions.
|
|
|
|
## Key Differences from JavaScript
|
|
|
|
- **`var` / `def`** — `var` is mutable, `def` is constant. No `let` or `const`.
|
|
- **`==` is strict** — No `===` or `!==`. `==` and `!=` are always strict comparison.
|
|
- **No `undefined`** — Only `null`. Division by zero produces `null`, not `Infinity`.
|
|
- **No classes** — Use `meme()`, `proto()`, `isa()` for prototype chains.
|
|
- **No `for...in`, `for...of`, spread, rest, or default params.**
|
|
- **Variables declared at function body level only** — Not inside `if`/`while`/`for` blocks.
|
|
- **All variables must be initialized** — `var x` alone is an error; use `var x = null`.
|
|
- **`disrupt` / `disruption`** — No `try`/`catch`/`throw`. Error handling uses:
|
|
```javascript
|
|
var fn = function() {
|
|
disrupt // raise an error (bare keyword, no value)
|
|
} disruption {
|
|
// handle the error
|
|
}
|
|
```
|
|
- **No arraybuffers** — Use `blob` (works with bits; `stone(blob)` before reading).
|
|
- **Identifiers can contain `?` and `!`** — e.g., `nil?`, `set!`, `is?valid`.
|
|
- **4-parameter limit** — Functions take at most 4 named parameters.
|
|
- **Everything lowercase** — Convention is all-lowercase identifiers with underscores.
|
|
|
|
## Variable Declaration
|
|
|
|
```javascript
|
|
var count = 0 // mutable
|
|
def MAX = 100 // constant (cannot be reassigned)
|
|
var x = null // must initialize (var x alone is an error)
|
|
```
|
|
|
|
## Functions
|
|
|
|
```javascript
|
|
var greet = function(name) {
|
|
print(`hello ${name}`)
|
|
}
|
|
|
|
// Arrow functions
|
|
var double = x => x * 2
|
|
var add = (a, b) => a + b
|
|
```
|
|
|
|
## Push / Pop Syntax
|
|
|
|
```javascript
|
|
var a = [1, 2]
|
|
a[] = 3 // push: a is now [1, 2, 3]
|
|
var v = a[] // pop: v is 3, a is [1, 2]
|
|
```
|
|
|
|
## Control Flow
|
|
|
|
```javascript
|
|
if (x > 0) {
|
|
print("positive")
|
|
} else {
|
|
print("non-positive")
|
|
}
|
|
|
|
while (i < 10) {
|
|
i = i + 1
|
|
}
|
|
|
|
for (var i = 0; i < 10; i = i + 1) {
|
|
print(i)
|
|
}
|
|
|
|
// do-while
|
|
do {
|
|
i = i + 1
|
|
} while (i < 10)
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```javascript
|
|
var safe_divide = function(a, b) {
|
|
if (b == 0) {
|
|
disrupt
|
|
}
|
|
return a / b
|
|
} disruption {
|
|
return null
|
|
}
|
|
```
|
|
|
|
## Creator Functions (Polymorphic)
|
|
|
|
These examine argument types to decide behavior:
|
|
|
|
### array()
|
|
- `array(5)` — `[null, null, null, null, null]`
|
|
- `array(3, 0)` — `[0, 0, 0]`
|
|
- `array(5, i => i * 2)` — `[0, 2, 4, 6, 8]`
|
|
- `array([1,2])` — copy
|
|
- `array([1,2,3], x => x * 10)` — map: `[10, 20, 30]`
|
|
- `array([1,2], [3,4])` — concat: `[1, 2, 3, 4]`
|
|
- `array([1,2,3,4,5], 1, 4)` — slice: `[2, 3, 4]`
|
|
- `array({a: 1, b: 2})` — keys: `["a", "b"]`
|
|
- `array("hello")` — characters: `["h", "e", "l", "l", "o"]`
|
|
- `array("a,b,c", ",")` — split: `["a", "b", "c"]`
|
|
|
|
### text()
|
|
- `text([1, 2, 3], ", ")` — join: `"1, 2, 3"`
|
|
- `text(255, 16)` — radix: `"ff"`
|
|
- `text("hello", 0, 3)` — substring: `"hel"`
|
|
|
|
### number()
|
|
- `number("42")` — parse: `42`
|
|
- `number("ff", 16)` — radix: `255`
|
|
- `number(true)` — `1`
|
|
|
|
### record()
|
|
- `record({a: 1})` — copy
|
|
- `record({a: 1}, {b: 2})` — merge: `{a: 1, b: 2}`
|
|
- `record(["x", "y"])` — from keys: `{x: true, y: true}`
|
|
|
|
## All Intrinsic Functions
|
|
|
|
**Constants:** `false`, `true`, `null`, `pi`
|
|
|
|
**Type checks:** `is_array`, `is_blob`, `is_character`, `is_data`, `is_digit`, `is_false`, `is_fit`, `is_function`, `is_integer`, `is_letter`, `is_logical`, `is_lower`, `is_null`, `is_number`, `is_object`, `is_pattern`, `is_stone`, `is_text`, `is_true`, `is_upper`, `is_whitespace`
|
|
|
|
**Creators:** `array`, `logical`, `number`, `record`, `text`
|
|
|
|
**Math:** `abs`, `ceiling`, `floor`, `fraction`, `max`, `min`, `modulo`, `neg`, `remainder`, `round`, `sign`, `trunc`, `whole`
|
|
|
|
**Text:** `character`, `codepoint`, `ends_with`, `extract`, `format`, `lower`, `normalize`, `replace`, `search`, `starts_with`, `trim`, `upper`
|
|
|
|
**Array:** `every`, `filter`, `find`, `for`, `length`, `reduce`, `reverse`, `some`, `sort`
|
|
|
|
**Objects:** `meme`, `proto`, `isa`, `stone`
|
|
|
|
**Functions:** `apply`, `splat`
|
|
|
|
**I/O:** `print`
|
|
|
|
**Async:** `fallback`, `parallel`, `race`, `sequence`
|
|
|
|
**Misc:** `logical`, `not`, `use`
|
|
|
|
## Variable Scoping
|
|
|
|
Variables are scoped to the function body in which they are declared. There is no block scoping. All declarations must be at the top level of a function body (not nested inside `if`/`while`/`for`).
|
|
|
|
```javascript
|
|
var outer = function() {
|
|
var x = 10
|
|
var inner = function() {
|
|
// x is visible here via closure
|
|
print(x)
|
|
}
|
|
inner()
|
|
}
|
|
```
|
|
|
|
## Modules (.cm files)
|
|
|
|
Modules return a value (typically a record of exports). They are loaded with `use()`, cached, and frozen.
|
|
|
|
```javascript
|
|
// math_utils.cm
|
|
var square = x => x * x
|
|
var cube = x => x * x * x
|
|
return {square: square, cube: cube}
|
|
|
|
// main.ce
|
|
var utils = use('math_utils')
|
|
print(utils.square(5)) // 25
|
|
```
|
|
|
|
## Standard Library (loaded with use())
|
|
|
|
- `blob` — binary data (works with bits, not bytes)
|
|
- `time` — time constants and conversions
|
|
- `math` — trig, logarithms, roots (sub-modules: `math/radians`, `math/turns`)
|
|
- `json` — JSON encoding/decoding (`json.encode`, `json.decode`)
|
|
- `random` — random number generation
|
|
- `fd` — file descriptor operations (`fd.read`, `fd.write`, `fd.slurp`, `fd.stat`)
|
|
|
|
## Actor Model (.ce files)
|
|
|
|
Actors are independent execution units that never share memory. They communicate via message passing.
|
|
|
|
```javascript
|
|
// greeter.ce
|
|
$receiver(function(msg) {
|
|
$send(msg.from, {greeting: `hello ${msg.name}`})
|
|
})
|
|
```
|
|
|
|
### Actor Intrinsics ($ prefix)
|
|
|
|
- `$me` — this actor's address
|
|
- `$send(address, message)` — send a message
|
|
- `$start(script, env)` — start a new actor
|
|
- `$stop()` — stop this actor
|
|
- `$delay(ms)` — delay processing
|
|
- `$receiver(fn)` — set message handler
|
|
- `$clock(interval, message)` — periodic self-message
|
|
- `$portal(name)` — create named portal
|
|
- `$contact(name)` — connect to portal
|
|
- `$couple(address)` — lifecycle coupling
|
|
- `$unneeded(fn)` — cleanup callback
|
|
- `$connection(address)` — establish connection
|
|
- `$time_limit(ms)` — execution time limit
|
|
|
|
## Common Patterns
|
|
|
|
### Iteration
|
|
```javascript
|
|
// Preferred: use for() intrinsic
|
|
for([1, 2, 3], function(item, index) {
|
|
print(`${text(index)}: ${text(item)}`)
|
|
})
|
|
|
|
// C-style for loop
|
|
for (var i = 0; i < length(items); i = i + 1) {
|
|
print(items[i])
|
|
}
|
|
```
|
|
|
|
### String Building
|
|
```javascript
|
|
// Use backtick interpolation
|
|
var msg = `hello ${name}, you are ${text(age)} years old`
|
|
|
|
// Join array
|
|
var csv = text(values, ",")
|
|
```
|
|
|
|
### Record Manipulation
|
|
```javascript
|
|
var obj = {name: "alice", age: 30}
|
|
var keys = array(obj) // ["name", "age"]
|
|
var copy = record(obj) // mutable copy
|
|
var merged = record(obj, {role: "admin"})
|
|
```
|
|
|
|
### Error-Safe Operations
|
|
```javascript
|
|
var safe_parse = function(input) {
|
|
return number(input)
|
|
} disruption {
|
|
return null
|
|
}
|
|
```
|