Changelog
All notable changes to @prism-lang/core will be documented in this file.
[Unreleased]
Added
Module System Runtime Support - Complete runtime implementation for the module system introduced in v1.0.26
- Import statements: default, named, namespace, and renamed imports
- Export statements: default, named, re-exports, and direct exports
- Module loading infrastructure with caching and circular dependency detection
- Path resolution for relative imports
- Import hoisting for proper execution order
- Module isolation with separate environments
- Full confidence preservation through module boundaries
- Partial circular dependency support (functions can reference each other)
- Comprehensive test coverage for all import/export patterns
Confident Ternary Operator (~?
) - Propagates confidence through conditional expressions
- Syntax:
condition ~? trueBranch : falseBranch
- Combines confidence from both condition and selected branch
- Multiplies confidences for full propagation
- Example:
(true ~> 0.8) ~? ("yes" ~> 0.9) : "no"
returns "yes" ~> 0.72
- Differentiates from regular ternary which ignores confidence
Confident Assignment Operators - Syntactic sugar for confident arithmetic with assignment
~+=
- Confident addition assignment: x ~+= y
same as x = x ~+ y
~-=
- Confident subtraction assignment: x ~-= y
same as x = x ~- y
~*=
- Confident multiplication assignment: x ~*= y
same as x = x ~* y
~/=
- Confident division assignment: x ~/= y
same as x = x ~/ y
- Preserves and combines confidence values during assignment
- Useful for accumulating values with confidence tracking
Multi-Parameter Arrow Functions - Already supported, now with comprehensive tests
- Support for 0 to N parameters:
(a, b, c) => a + b + c
- Works with array methods:
reduce((acc, val) => acc + val, 0)
- Nested multi-param lambdas:
op => (a, b) => op == "+" ? a + b : a * b
- Full documentation and test coverage
Improved
- Documentation - Added comprehensive examples for lambda functions and confident operators
- Test Coverage - Added extensive tests for multi-parameter lambdas, confident ternary, and confident assignment operators
- Validator Updates - Added support for confident ternary expression in linter
Example
import {sum, PI} from "./math.prism"
export result = sum(10, 20) * PI
message = condition ~? "Welcome!" : "Please verify"
total ~+= reading
sum = reduce(numbers, (acc, val) => acc + val, 0)
[1.2.1] - 2025-01-07
Added
Improved
- Validator Enhancements
- Fixed unknown node type warnings for ExportStatement, ImportStatement, VariableDeclaration
- Added async/await validation with proper error messages
- Fixed duplicate FunctionExpression case in validator
- Improved import/export validation to match AST structure
Example
async function analyzeData(input) ~> 0.9 {
data = await fetchFromAPI(input)
analysis = await llm("Analyze: " + data)
results = await Promise.all([
processA(data),
processB(data),
processC(data)
])
return results
}
"5" == 5
"5" === 5
null == undefined
null === undefined
[1, 2, 3] === [1, 2, 3]
[1.0.26] - 2025-07-22
Added
- Module import/export system - ES-module style imports and exports for code organization
- Import statements - Full support for all import patterns
- Default imports:
import defaultName from "module"
- Named imports:
import {name1, name2} from "module"
- Renamed imports:
import {original as renamed} from "module"
- Namespace imports:
import * as name from "module"
- Mixed imports:
import defaultName, {named1, named2} from "module"
- Empty imports:
import {} from "side-effects-only"
- Export statements - Comprehensive export functionality
- Default exports:
export default expression
- Named exports:
export {name1, name2}
- Renamed exports:
export {local as exported}
- Re-exports:
export {names} from "other-module"
- Namespace re-exports:
export * from "utilities"
- Direct exports:
export result = calculate()
- New keywords -
import
, export
, from
, as
for module syntax
- AST support - New AST node types:
ImportStatement
, ExportStatement
, ImportSpecifier
, ExportSpecifier
- Comprehensive test suite - 31 tests covering all import/export patterns and error cases
- Trailing comma support - Allows trailing commas in import/export specifier lists
- Proper error handling - Clear error messages for malformed module syntax
Example
export sum = (a, b) => a + b
export multiply = (a, b) => a * b
export const PI = 3.14159
import {sum, PI} from "./math.prism"
import * as math from "./math.prism"
import defaultCalculator, {advanced} from "./calculator.prism"
result = sum(10, 20) * PI
product = math.multiply(5, 6)
export processedData = data.map(x => sum(x, 1))
export default finalResult = processedData.reduce(sum, 0)
export {helper1, helper2} from "./helpers.prism"
export * from "./shared-utilities.prism"
Breaking Changes
- None - this is a pure addition to the language
Implementation Notes
- Module loading and resolution will be implemented in future versions
- Import/export statements are parsed and represented in the AST
- Runtime module system will follow ES module semantics
- Supports relative paths, absolute paths, and package imports
[1.0.20] - 2025-07-08
Added
- Function argument spread operator - Expand arrays as individual arguments in function calls
- Use
...array
syntax to spread array elements: max(...[1, 2, 3])
- Combine multiple arrays:
concat(...arr1, ...arr2)
- Mix regular and spread arguments:
fn(a, ...rest, b)
- Rest parameters in function definitions - Collect variable arguments as an array
- Use
...name
in lambda parameters: (...args) => args.length
- Regular params with rest:
(first, ...rest) => first + rest.join(",")
- Rest parameters preserve confidence values
- Works seamlessly with array methods
- Array.join() method - Convert array elements to string
- Default separator is comma:
[1, 2, 3].join()
// "1,2,3"
- Custom separator:
["a", "b", "c"].join(" ")
// "a b c"
- Handles null/undefined as empty strings
Example
numbers = [1, 2, 3, 4, 5]
maxValue = max(...numbers)
sum = (...nums) => nums.reduce((a, b) => a + b, 0)
total = sum(1, 2, 3, 4, 5)
greet = (greeting, ...names) => greeting + " " + names.join(" and ")
message = greet("Hello", "Alice", "Bob")
[1.0.19] - 2025-07-08
Added
- JavaScript-style logical operators - The
||
and &&
operators now behave like JavaScript
||
returns the first truthy value or the last value
&&
returns the first falsy value or the last value
- Enables common patterns like
name = userInput || "default"
- Full short-circuit evaluation for better performance
- Enhanced error messages - Runtime errors now include location information
- Shows line and column numbers where errors occur
- Example:
Error at line 5, column 23: Cannot apply - to string and number
- AST nodes now carry optional location information
- Improved developer experience for debugging
Changed
- Logical operators
||
and &&
now return actual values instead of booleans
- Runtime error handling enhanced with location tracking
[1.0.18] - 2025-07-08
Added
- Uncertainty-aware loops - Revolutionary loop constructs that adapt behavior based on confidence levels
- Uncertain for loops - Execute different branches based on loop confidence
uncertain for i = 0; condition ~> confidence; i++
- High, medium, and low confidence branches
- Dynamic confidence evaluation at each iteration
- Uncertain while loops - Conditional execution with confidence-based branching
uncertain while condition ~> confidence
- Automatic branch selection based on confidence thresholds
- Perfect for sensor monitoring and AI model inference
- Confidence thresholds:
- HIGH: confidence >= 0.7
- MEDIUM: 0.5 <= confidence < 0.7
- LOW: confidence < 0.5
- Full support for break and continue within uncertainty branches
- Seamless integration with existing confidence system
Example
uncertain for i = 0; (i < readings.length) ~> confidence; i++ {
high {
processAutomatically(readings[i])
}
medium {
flagForReview(readings[i])
}
low {
sendAlert(readings[i])
break
}
}
uncertain while (systemActive() ~> getSystemHealth()) {
high {
runNormalOperations()
}
medium {
runDegradedMode()
}
low {
enterSafeMode()
break
}
}
uncertain for attempt = 0; attempt < 3; attempt++ {
high {
return model.predict(input)
}
medium {
return ensemblePredict(input)
}
low {
return requestHumanInput(input)
}
}
[1.0.17] - 2025-07-08
Added
- Complete loop support - Standard JavaScript-style loops with Prism's unique features
- C-style for loops - Traditional loops with init, condition, and update expressions
- Optional parts:
for ; i < 10; i++
or for i = 0; ; i++
- Variables use outer scope (not block-scoped)
- For-in loops - Iterate over array elements with optional index
for item in array { ... }
for item, index in array { ... }
- Creates new scope for loop variables
- While loops - Execute while condition is true
- Do-while loops - Execute at least once, then check condition
- Break and continue - Control flow within loops
- Break exits the current loop
- Continue skips to next iteration
- Nested loops - Full support for loops within loops
- Confidence preservation - Loops work seamlessly with confident values
- Comprehensive test suite with 31 loop tests
Example
sum = 0
for i = 0; i < 5; i = i + 1 {
sum = sum + i
}
arr = ["a", "b", "c"]
result = ""
for item, idx in arr {
result = result + item + idx
}
i = 0
while i < 3 {
i = i + 1
}
count = 0
do {
count = count + 1
} while false
for i = 0; i < 10; i = i + 1 {
if (i == 5) break
if (i % 2 == 0) continue
}
data = [1, 2, 3] ~> 0.8
sum = 0
for item in data {
sum = sum + item
}
for i = 0; i < 3; i = i + 1 {
for j = 0; j < 2; j = j + 1 {
}
}
[1.0.16] - 2025-07-08
Added
- Array methods as properties - All array methods now available as properties for better ergonomics
array.map(fn)
- Transform array elements with a function
array.filter(fn)
- Filter elements based on a predicate
array.reduce(fn, init?)
- Reduce array to a single value with optional initial value
array.forEach(fn)
- Iterate over elements (returns undefined)
array.push(...items)
- Add elements to array (returns new array, immutable)
- All methods preserve confidence values when used on confident arrays
- Methods intelligently handle optional parameters (e.g., index in reduce)
- Both method syntax (
arr.map(fn)
) and function syntax (map(arr, fn)
) are supported
Fixed
- Lambda functions now properly track their arity for correct parameter handling
- Array method callbacks receive the correct number of arguments based on their parameter count
Example
numbers = [1, 2, 3, 4, 5]
doubled = numbers.map(x => x * 2)
squares = numbers.map(x => x ** 2)
evens = numbers.filter(x => x % 2 == 0)
large = numbers.filter(x => x > 3)
sum = numbers.reduce((a, b) => a + b)
product = numbers.reduce((a, b) => a * b, 1)
indexed = numbers.reduce((acc, val, idx) => acc + val * idx, 0)
result = numbers.forEach(x => x * 2)
original = [1, 2, 3]
expanded = original.push(4, 5)
result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
.filter(x => x % 2 == 0)
.map(x => x ** 2)
.reduce((a, b) => a + b)
confident = [1, 2, 3] ~> 0.8
doubled = confident.map(x => x * 2)
methodResult = arr.map(x => x * 2)
functionResult = map(arr, x => x * 2) // Same result
[1.0.15] - 2025-07-08
Added
- Spread operator (
...
) - Essential for modern data manipulation
- Array spreading:
[...arr1, ...arr2]
combines arrays immutably
- Object spreading:
{...obj1, ...obj2}
merges objects with property overriding
- Works seamlessly with confidence values by unwrapping before spreading
- Enables clean, functional programming patterns
Example
arr1 = [1, 2, 3]
arr2 = [4, 5, 6]
combined = [...arr1, ...arr2]
newArray = [0, ...arr1, 4]
defaults = {theme: "dark", lang: "en"}
userPrefs = {lang: "es", debug: true}
settings = {...defaults, ...userPrefs}
user = {name: "Alice", age: 30}
updated = {...user, age: 31}
a = [1, 2]
b = [3, 4]
c = [5, 6]
all = [...a, ...b, ...c]
data = [1, 2, 3] ~> 0.8
extended = [...data, 4, 5]
config = {
server: {host: "localhost", port: 3000},
debug: true
}
production = {...config, debug: false}
[1.0.14] - 2024-06-27
Added
- Exponentiation operator (``)** - Mathematical power operations with right associativity
- Nullish coalescing operator (
??
) - Returns right operand only for null/undefined values
- Exponentiation has higher precedence than multiplication/division
- Nullish coalescing differs from
||
by preserving falsy values like 0
, false
, and ""
- Both operators work seamlessly with confidence values
Example
squared = 3 ** 2
cubed = 2 ** 3
rightAssoc = 2 ** 3 ** 2
base = 4
result = base ** 0.5
complex = (base + 1) ** 2
port = process.env.PORT ?? 3000
enabled = config.enabled ?? true
retries = options.retries ?? 0
value = cache ?? database ?? defaultValue
user = { profile: null }
name = user?.profile?.name ?? "Anonymous"
uncertain = getData() ~> 0.7
result = (uncertain ?? fallback) ** 2
[1.0.13] - 2024-06-27
Added
- Optional chaining operator (
?.
) - Safe property access that returns null instead of throwing errors
- Undefined support -
undefined
is now a proper value type, distinct from null
- Undefined works with all operators including optional chaining
- Both null and undefined are falsy but remain distinct values
- Optional chaining works with arrays, objects, and nested properties
Example
user = { profile: null }
name = user?.profile?.name
value = undefined
isEmpty = value == null
isUndefined = value == undefined
data = { info: undefined }
result = data?.info?.details
missing = undefined
empty = null
if (!missing && !empty) {
}
config = {
server: {
host: "localhost",
port: undefined
}
}
port = config?.server?.port ?? 3000
[1.0.12] - 2024-06-27
Added
- Compound assignment operators -
+=
, -=
, *=
, /=
, %=
- Compound assignments work with numbers, strings, and confidence values
- String concatenation with
+=
operator
- All compound operators properly propagate confidence values
Example
score = 100
score += 25
score -= 10
score *= 2
score /= 5
score %= 10
greeting = "Hello"
greeting += ", "
greeting += "World!"
measurement = 50 ~> 0.9
adjustment = 10 ~> 0.7
measurement += adjustment
[1.0.11] - 2024-06-27
Added
- Null literal support -
null
is now a proper value type
- Null can be used in variables, arrays, objects, and comparisons
- Null works with all operators including ternary and logical operators
- Null integrates with confidence system
- Array methods handle null values properly
Example
value = null
isEmpty = value == null
user = { name: "Alice", email: null }
data = [1, null, 3, null, 5]
validData = filter(data, x => x != null)
mapped = map(data, x => x != null ? x * 2 : 0)
uncertain = null ~> 0.5
fallback = uncertain ~?? "default"
[1.0.9] - 2024-06-26
Added
- Lambda expressions with arrow syntax (
=>
)
- Support for single parameter without parentheses:
x => x * 2
- Support for multiple parameters:
(x, y) => x + y
- Support for zero parameters:
() => 42
- Closures - lambdas can capture variables from outer scope
- Modulo operator (
%
) for remainder operations
- Integration of lambdas with array methods for functional programming
Example
double = x => x * 2
add = (x, y) => x + y
getRandom = () => 42
numbers = [1, 2, 3, 4, 5]
squared = map(numbers, x => x * x)
evens = filter(numbers, x => x % 2 == 0)
sum = reduce(numbers, (a, b) => a + b, 0)
multiplier = 10
scale = x => x * multiplier
scaled = scale(5)
makeAdder = x => (y => x + y)
add10 = makeAdder(10)
result = add10(32)
[1.0.8] - 2024-06-25
Added
- Array methods as built-in global functions
map(array, fn)
- transform each element
filter(array, predicate)
- keep elements matching predicate
reduce(array, reducer, initialValue?)
- combine elements into single value
- Confidence preservation through array transformations
- Support for index parameter in reduce function
Example
data = [10, 20, 30] ~> 0.8
doubled = map(data, x => x * 2)
filtered = filter(data, x => x > 15)
sum = reduce(data, (acc, val) => acc + val, 0)
indexed = reduce(data, (acc, val, idx) => acc + (val * idx), 0)
[1.0.7] - 2024-06-22
Added
- String interpolation with
${}
syntax inside strings
- Support for complex expressions in interpolations
- Nested interpolations with proper quote handling
- Interpolation in multiline strings
- Confidence value formatting in interpolations
Example
name = "Alice"
greeting = "Hello, ${name}!"
user = { name: "Bob", age: 30 }
info = "${user.name} is ${user.age} years old"
score = 85
grade = "Your grade: ${score >= 90 ? "A" : "B"}"
report =
User: ${name}
Score: ${score}
Grade: ${grade}
[1.0.6] - 2024-06-22
Added
- Arrays and lists with literal syntax
[1, 2, 3]
- Objects/dictionaries with literal syntax
{ key: value }
- Array methods: length property, index access
array[0]
- Object property access with dot notation
object.property
- Built-in array functions:
map()
, filter()
, reduce()
- Support for nested data structures and confidence propagation
Example
// Arrays and objects
scores = [85 ~> 0.9, 92 ~> 0.8, 78 ~> 0.7]
firstScore = scores[0]
count = scores.length
person = {
name: "Alice",
scores: scores,
metadata: { verified: true }
}
name = person.name
verified = person.metadata.verified
[1.0.5] - 2024-06-22
Added
- Ternary operator support (
condition ? true : false
)
- Support for nested ternary expressions
- Reduces need for verbose if-else statements
Example
status = age >= 18 ? "adult" : "minor"
grade = score >= 90 ? "A" : (score >= 80 ? "B" : "C")
action = confidence > 0.8 ? "auto-approve" : "manual-review"
[1.0.4] - 2024-06-22
Added
- Multiline string support with triple backticks (
`
) - enables passing code snippets to LLMs
- Standard escape sequences in strings (\n, \t, ", \, etc.)
- Enhanced error messages showing line content and error position
Fixed
- String literals now properly handle escape sequences instead of throwing errors
- Parse errors now show helpful context including the problematic line and column marker
Example
// New multiline strings for code analysis
code =
function getUserData(userId) {
const query = "SELECT * FROM users WHERE id = " + userId;
return db.execute(query);
}
analysis = llm("Find security issues in: " + code)
query = "SELECT * FROM users WHERE name = \"John\""
[1.0.3] - 2024-06-22
Fixed
- LLM providers now properly initialize when API keys are provided
- Fixed "No LLM provider configured" error when using geminiApiKey or anthropicApiKey options
- Providers are automatically registered and set as default when API keys are available
[1.0.2] - 2024-06-22
Fixed
- Updated GitHub repository URL in documentation to correct address
[1.0.1] - 2024-06-06
Added
- Semicolon support for statement separation
- Better handling of multiple statements per line
- Backwards compatibility maintained (semicolons are optional)
Fixed
- Parser now properly consumes semicolons after statements
- Improved statement boundary detection
Known Issues
- Multiple assignments on one line (e.g.,
x = 10; y = 20
) still require workaround
- Recommended: Use one statement per line for best results
[1.0.0] - 2024-06-06
Initial Release
- 18 confidence-aware operators for uncertainty handling
- Native LLM integration support
- Uncertainty-aware control flow (uncertain if statements)
- Automatic confidence propagation
- Full TypeScript implementation
- Interactive REPL
- CLI tools (prism run, prism eval, prism repl)
- npm package: @prism-lang/core