diff --git a/language.md b/language.md index 20f0d4f..f111eba 100644 --- a/language.md +++ b/language.md @@ -387,15 +387,24 @@ This convention also includes anything that prints to the console: `print!`, `re Relatedly, just about any function that returns a boolean value is a predicate function--and has a name that ends with a question mark: `eq?` tests for equality; `ref?` tells you if something is a ref or not; `lte?` is less-than-or-equal. ## Errors: panic! in the Ludus script -A special function, `panic!`, halts script execution with any arguments output as error messages. Panics also happen in the following cases: -* a `let` binding has no match against the value of its expression +A special form, `panic!`, halts script execution with the expression that follows as an error message. + +``` +panic! :oops + +if true then :ok else panic! "It's false!" +``` + +Panics also happen in the following cases: +* a `let` binding pattern has no match against the value of its expression * a `match` or `when` form has no matching clause * a function is called with arguments that do not match any of its clauses * something that is not a function or keyword is called as a function +* a called keyword is partially applied * `div` divides by zero * certain error handling functions, like `unwrap!` or `assert!`, are invoked on values that cause them to panic -In fact, the only functions in the Prelude which can cause panics are, at current, `div`, `unwrap!`, and `assert!`. And, of course, `panic!` itself. +In fact, the only functions in the Prelude which can cause panics are, at current, `div`, `unwrap!`, and `assert!`. ### `nil`s, not errors Ludus, however, tries to return `nil` instead of panicking a lot of the time. So, for example, attempting to get access a value at a keyword off a number, while nonsensical, will return `nil` rather than panicking: @@ -403,9 +412,12 @@ Ludus, however, tries to return `nil` instead of panicking a lot of the time. So ``` let a = true a :b :c :d :e &=> nil + +let b = [1, 2, 3] +at (b, 12) &=> nil ``` ### Result tuples -Operations that could fail--especially when you want some information about why--don't always return `nil` on failures. Instead of exceptions or special error values, recoverable errors in Ludus are handled instead by result tuples: `(:ok, value)` and `(:err, msg)`. So, for example, `unwrap!` takes a result tuple and either returns the value in the `:ok` case, or panics in the `:err` case. +Operations that could fail--especially when you want some information about why--don't always return `nil` on failures. Instead of exceptions or special error values, recoverable errors in Ludus are handled instead by result tuples: `(:ok, value)` and `(:err, msg)`. So, for example, `unwrap!` takes a result tuple and either returns the value in the `:ok` case, or panics in the `:err` case. Or `assert!` will panic on a falsy value; `assert`, instead, returns a result tuple. Variants of some functions that may have undesirably inexplicit behaviour are written as `{name}/safe`. So, for example, you can get a variant of `div` that returns a result tuple in `div/safe`, which returns `(:ok, result)` when everything's good; and `(:err, "division by zero")` when the divisor is 0. Or, `get/safe` will give you a result rather than returning `nil`. (Althougn `nil` punning makes this mostly unncessary. Mostly.) diff --git a/package.json b/package.json index 3409c0b..e864249 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ludus/ludus-js-pure", - "version": "0.1.0-alpha.7.8", + "version": "0.1.0-alpha.7.9", "description": "A Ludus interpreter in a pure JS function.", "main": "target/js/ludus.js", "directories": {},