# Changelog ## 4.0.0-alpha.33 (5/20/2022) ### New ### Changes * All types are now allowed in block weights. Non-numeric types are converted to integers based on their truthiness. ### Fixes * Fixed build failure on installation due to missing files ## 4.0.0-alpha.32 (2/17/2022) ### New * Added stdlib functions: * `[char]` * `[ord]` * `[ord-all]` ### Changes * Changed `@and` operator to a symbol: `&` * Changed `@or` operator to a symbol: `|` (must use within parentheses in block element context) * Changed `@xor` operator to a symbol: `^` * Compound assignment operator symbols are now monomorphic -- meaning you can't insert whitespace before the `=` anymore. * Allow hints/sinks in more places ### Fixes * Fixed parser bug caused by `/=` operator * Fixed trailing newline on REPL input ### Removed * Removed `@nand` and `@nor` ## 4.0.0-alpha.31 (2/12/2022) ### New * Added stdlib functions: * `[fill-self]` * `[fill-thru]` * `[pickn]` * `[sel-skip]` * `[sel-freeze]` * `[sel-frozen]` * `[trim]` * CLI: Added `[credits]` function * CLI: Program-global variables now persist between lines in the REPL * CLI: Added functions to display copyright notice & credits * Closures can now be used to create Rant functions * Added compound assignment support for all arithmetic and logic operators ### Changes * Renamed type `special` to `selector` because it's only used for selectors * Renamed type `empty` to `nothing` to make its meaning clearer and avoid API confusion * Renamed stdlib functions: * `[is-empty]` → `[is-nothing]` * Changed behavior of `[sel]` so that it now prints the current selector when no arguments are passed * Updated the Rust API to reflect the selector type changes: * Renamed `Selector` to `RantSelector` for consistency. * `RantSelector` has its own handle type, `RantSelectorHandle`. * `RantSelectorHandle` can be directly accepted by native functions. * Exposed some read-only fields on `RantSelector` through public methods ### Fixes * CLI: Fixed accidental REPL activation when launched with redirected stdin ## 4.0.0-alpha.30 (2/5/2022) ### New * Added three new Unicode escape formats * 16-bit: `\uXXXX` * 32-bit: `\UXXXXXXXX` * Unsized (max 1-8 digits): `\U(XXXXXXXX)` * Added stdlib functions * `[ds-query-sources]` ### Changes * The escape sequence parser is now more strict, and will create a compiler error if you escape non-reserved characters * Renamed stdlib functions: * `[data]` → `[ds-request]` ### Fixes * Fixed `RantValue::concat()` not supporting maps * Fixed field visibility on `ModuleResolveError` ## 4.0.0-alpha.29 (1/31/2022) ### New * Module resolver has been externalized into a separate `ModuleResolver` trait, which you can use to write your own custom resolution logic. * 2 impls included: `DefaultModuleResolver` (default), `NoModuleResolver` (to disable modules completely) ### Changes * `[sum]` now accepts any ordered collection type * Changed behavior of `RantValue::is_empty()` to match that of `Vec` * Changed slice bound separator from `:` to `..` * Removed need for `!` in anonymous accessors and function calls; just use an access path! * Renamed `CompilerErrorKind` to `CompilerError` * Moved `RantOptions::enable_global_modules` and `RantOptions::local_modules_path` to `DefaultModuleResolver` * `VarArgs` and `RequiredVarArgs` are now public. Use them to add variadic parameters to your native functions! * Renamed stdlib functions: * `[nop]` → `[tap]` ### Removed * Removed ability to specify dynamic variable names in accessors - expressions in the first path component now act as anonymous value sources * `RantOptions::enable_require` ### Fixes * Fixed parsing bug in function call accessors where a dynamic child component followed by arg list start (`:`) was incorrectly parsed as a slice * Fixed incorrect behavior in `[shuffle-thru]` * Fixed incorrect infix operator associativity ## 4.0.0-alpha.28 (1/29/2022) ### New * Added complex spread; add a parametric spread to each iteration of a temporal argument with `***` or `*a**` * Added assignment pipe; assign pipeval to a new or existing variable at the end of a piped call * Added infallible `IntoRant` and `FromRant` traits * Added stdlib functions: * `[pick-sparse]` * `[string-replace]` * `[tuple]` ### Changes * Dynamic keys are now wrapped in `()` instead of `{}` * Renamed stdlib functions: * `[collect]` → `[list]` * Upgraded library dependencies: * `quickscope` → 0.2.0 ### Removed * Removed depth operator ### Fixes * Fixed runtime error when attempting to use pipeval in a pipecall path * Fixed improper tokenization of labeled temporal spread operators * Fixed typo in `[to-tuple]` registration ## 4.0.0-alpha.27 (1/26/2022) ### New * Added the `tuple` type, along with tuple initialization syntax: * `()`, `(A;)`, `(A; B)`, `(A; B; C)`, ... * Added stdlib functions: * `[squish-thru]` * `[to-tuple]` * Added several Rust API functions to support conversion to and from tuples and other collection types ### Changes * Renamed `FromRant` to `TryFromRant` (and adjusted member names) * Renamed `IntoRant` to `TryIntoRant` (and adjusted member names) * Renamed `lang::Rst` to `lang::Expression` to better reflect its purpose * Parametric spread is now enabled for all indexable collection types; not just lists * Changed the reference handle types for all collection types from type aliases to structs (and much refactoring was had) * Completely changed all collection initializer syntax: * List: `(:)`, `(: A)`, `(: A; B)`, ... * Map: `(::)`, `(:: A=1)`, `(:: A=1; B=2)`, ... * Renamed stdlib functions: * `[whitespace-fmt]` → `[ws-fmt]` * `[squish]` → `[squish-self]` * `[squished]` → `[squish]` ### Fixes * Fixed `[augment]` accidentally mutating the original instance of the destination map * Fixed `[to-list]` not working on tuples ## 4.0.0-alpha.26 (1/25/2022) ### New * Added map initializer shorthands; specify both a key and value with a single variable getter * Added stdlib functions: * `[augment]` * `[augment-self]` * `[augment-thru]` * `[sort-thru]` * `[sift-thru]` * `[shuffle-thru]` ### Changes * Hints/sinks on string literals are allowed * Renamed stdlib functions: * `[sort]` → `[sort-self]` * `[sorted]` → `[sort]` * `[sift]` → `[sift-self]` * `[sifted]` → `[sift]` * `[shuffle]` → `[shuffle-self]` * `[shuffled]` → `[shuffle]` ### Removed * Removed inner-protected blocks * Removed stdlib functions: * `[push-attrs]` * `[pop-attrs]` * `[count-attrs]` ### Fixes * Fixed hints/sinks being rejected on accessors * Fixed key setters accidentally tripping constant reassignment error ## 4.0.0-alpha.25 (1/23/2022) ### New * Added compiler errors when int/float literals are out of range * Added `@edit`: apply recursive functions to your output, iteratively! * Pipeval (`[]`) is now supported in access paths without needing to nest it in a dynamic key * Added protected blocks ### Changes * Renamed stdlib functions: * `[pipe]` → `[mut]` ### Fixes * Fixed pipeval being unhintable * Fixed fallible optional parameters not generating warnings when unused * Fixed minimum int value not being parsed correctly * Fixed conditional bodies not working like standard blocks ## 4.0.0-alpha.24 (1/17/2022) ### New * Added `@require` statements. These take *static* module paths. You can still use `[require]` if you need to import modules dynamically. * Added conditional branching with `@if`, `@elseif`, `@else` * Added ability to auto-hint variables, params, and function calls using the `@text` keyword * Added a ton of arithmetic, logic, and comparison operators, including many C-style infix operators with precedence support * Addition: `+` * Subtraction: `-` * Multiplication: `*` * Division: `/` * Modulo: `%` * Exponentiation: `**` * Negation: `@neg` (`-` is still valid for negating constants, e.g. `-123`) * Logical AND: `@and` * Logical OR: `@or` * Logical NOT: `@not` * Logical NAND: `@nand` * Logical NOR: `@nor` * Logical XOR: `@xor` * Equality: `@eq` * Inequality: `@neq` * Less than: `@lt` * Less than or equal: `@le` * Greater than: `@gt` * Greater than or equal to: `@ge` - Added stdlib functions: - `[assert-not]` ### Changes * Anonymous accessor values now must be surrounded by a block. * Rant is now relicensed under MIT and Apache 2.0! * Update `FromRant` impl for `bool` to coerce from any RantValue type according to truthiness rules * Renamed stdlib functions: * `[shred]` → `[rand-list-sum]` ### Removed * Removed inline lambda bodies. All lambda bodies now require braces. ### Fixes * Fixed broken `[chunks]` behavior ## 4.0.0-alpha.23 (1/11/2022) ### New * Added stdlib functions: * `[print]` * `[chunks]` * `[to-bool]` * `[values]` * Added stdlib constants: * `MIN_INT`, `MAX_INT` * `MIN_FLOAT`, `MAX_FLOAT` * `EPSILON` * Added API items: * `RantValue::MIN_INT`, `RantValue::MAX_INT` * `RantValue::MIN_FLOAT`, `RantValue::MAX_FLOAT` * `RantValue::NAN` * `RantValue::EPSILON` ### Changes * Changed hint operator: `'` → ` * Changed sink operator: `_` → `~` * Changed emptyval literal: `~` → `<>` * Added old behavior back to `[cat]`; previous `[cat]` behavior migrated to `[print]` function * Changed behavior of sinks * Instead of suppressing output, sinking an element does the opposite of hinting: it informs the compiler that the sinked element should be treated as _not text_, causing surrounding whitespace to be ignored during compilation. * Upgraded library dependencies: * `cast` → 0.3.0 * Upgraded CLI dependencies: * `ctrlc` → 3.1.9 * Renamed stdlib functions: * `[string]` → `[to-string]` * `[int]` → `[to-int]` * `[float]` → `[to-float]` * `[list]` → `[to-list]` * Move R1005 (fallible optional param access) to R0028 and upgrade it from a warning to an error ### Removed * Removed the `block` type * Removed the defer operator (formerly `<>`) * Removed stdlib functions: * `[resolve]` * Removed `RantValue::nan()` (superceded by constant `RantValue::NAN`) ### Fixes * Fixed bench stats in CLI printing to stdout instead of stderr * Fixed anonymous calls always expecting a pipeval even when not in a piped context * Fixed pipeval not getting captured in closures * Fixed panic in `[pick]` when input list is empty; now prints nothing in this case * Fixed several panics in number formatter when handling `` ## 4.0.0-alpha.22 (4/27/2021) ### New * Added data sources (access through the `rant::data::DataSource` trait) * Added inline lambdas (you no longer need braces for lambdas with a single expression in them!) * Optional function parameters can now have user-specified default values * Exposed `Rant.options` through the `Rant.options()` method ### Changes * Boolean literals are now keywords; this means that `true` and `false` are now `@true` and `@false`. The original reserved fragments are now treated like strings. * In addition, boolean keywords now ignore surrounding whitespace. * Optional parameters without default arguments now no longer define variables in the function body when the user doesn't pass a value to them; as a result, access to these arguments is now fallible. * Made runtime error messages more consistent ### Removed * Removed `Rant.debug_mode` in favor of using `Rant.options()` to get the value instead * Removed `Rant.run_into_string()` and `Rant.run_into_string_with()` because they're kind of pointless ### Fixes * Fixed panic that occurred with some variadic function calls ## 4.0.0-alpha.21 (4/13/2021) ### New * Added new number format system: `alpha` * Added "depth operator" to determine originating scope of a variable * Trailing semicolons are now allowed in list initializers ### Changes * `[seg]` now operates internally on grapheme boundaries instead of `char` boundaries * Renamed `[is-any]` to `[is-some]` * CLI now uses `clap` instead of `argh` to parse cmdline options ### Fixes * Fixed `[cat]` printing to the wrong scope level * Fixed panic when setting number format with no output * Fixed bug where `@return`-ing from a module scope would unwind the call stack too far * Fixed `[require]` not assigning module constants when retrieving from cache ## 4.0.0-alpha.20 (4/10/2021) ### New * Added number formatter * Currently supports these numeral systems: * Arabic (Western + Eastern) * Persian * Babylonian cuneiform (base 60) * Roman (upper/lower) * Hexadecimal (upper/lower) * Octal * Binary * Added stdlib functions: * `[num-fmt: options?; depth?]` * `[num-fmt-system: system?; depth?]` * `[num-fmt-padding: padding?; depth]` * `[num-fmt-precision: precision?; depth?]` * `[num-fmt-sign: sign-mode?; depth?]` * `[num-fmt-alt: enable?; depth?]` * `[num-fmt-upper: enable?; depth?]` * `[num-fmt-infinity: infinity?; depth?]` * `[num-fmt-endian: endianness?; depth?]` * Added stdlib constants: * Float constants: `INFINITY`, `NEG_INFINITY`, `NAN` ### Changes * Renamed `[else-if]` to `[elseif]` * Removed unnecessary `unsafe` usage from string formatter for `function` type * Renamed module `rant::random` to `rant::rng` * E notation is now accepted on float literals ## 4.0.0-alpha.19 (4/3/2021) ### New * Add `[rev]` support to the `block` type * Add slice support to `block` type ### Changes * Encapsulate `RantRange` fields to prevent unwanted mutation * Rename `ToRant` trait to `IntoRant` in order to better reflect its behavior ### Fixes * (internal) Fix `flag` parameter on `rant::runtime::VM::pre_push_block()` not being used * Fixed nested function lookups accidentally considering their container as a function * Fixed incorrect const redef error on nested function definitions against a constant collection * Fixed panic when block with no elements is resolved * Fixed bad slicing behavior on ranges ## 4.0.0-alpha.18 (2/16/2021) ### New * Added "charms": right-associative operators for control flow * Added block weights using the `@weight` charm * `return`, `continue`, and `break` are now reimplemented as charms ### Removed * Removed from stdlib: `[return]`, `[continue]`, `[break]` ## 4.0.0-alpha.17 (2/7/2021) ### New * Added `range` type * Standard Library items: * `[irange]`: Create a new inclusive range * `[range]`: Create a new exclusive range * `[rev]`: Create a reversed copy of an ordered collection (list, string, range) ### Changes * Renamed old `[list]` function to `[collect]` * Renamed `[concat]` to `[cat]` * Added new `[list]` function which converts a single argument to a Rant list * Temporal spreading now works on any indexable type (`list`, `string`, `range`) * String representations of collections actually show the contents now (up to 4 layers deep) * Upgraded library dependencies: * `logos` → 0.12.0 * `rand` → 0.8.3 * Upgraded dev dependencies: * `assert_matches` → 1.5.0 ### Fixes * Fixed stdlib functions `[frac]`, `[floor]`, `[ceil]` not being registered (oops.) * Fixed temporal spreads not handling non-list collections properly ## 4.0.0-alpha.16 (1/26/2021) ### New * Added temporal argument spreading * Standard Library items: * `[concat]`: Print a series of arguments * `[list]`: Create a list from a set of arguments * `[nlist]`: Create a list from a set of arguments and nest it inside another list ### Changes * Changed pipe operator from `&` to `|>` * Changed spread operator from `+` to `*` * Changed defer operator from `*` to `<>` * Adjusted whitespace behavior around blocks to avoid ambiguities * Made separator parameter on `[join]` optional ### Fixes * Fixed incorrect whitespace print behavior around unflagged function calls ## 4.0.0-alpha.15 (1/15/2021) ### New * Added support for constants * Added "pipe" attribute to allow custom block element handling * Print semantics for collection auto-concatenation * Compiler now emits warnings for unused variables * Attribute frame stack now has a max size of 255 * `[sel]` can now additionally accept selector mode strings directly to create + apply a transient selector * API features: * `Rant::set_global_const()` * `Rant::set_global_force()` * `lang::AccessPath::is_variable()` * `lang::Rst::ConstDef` * `compiler::message::CompilerMessage.is_warning()` * CLI: added `-W` switch to disable warnings * Standard Library: * `[pipe]`: Sets the pipe attribute. ### Changes * Updated some AST structures to support constants * The following items are now made constant: * Standard library items * Program arguments * Function arguments * Imported modules * API changes: * Renamed `lang::AccessPath::capture_var_name()` to `var_name()` * Upgraded library dependencies: * `once_cell` → 0.5.2 * `quickscope` → 0.1.6 * `rand` → 0.8.2 * `rand-xoshiro` → 0.6.0 * `smallvec` → 1.6.1 * `smartstring` → 0.2.6 * `unicode-segmentation` → 1.7.1 * Stamdard library: * Swapped the positions of the two parameters in `[join]` so the separator comes last * Upgraded CLI dependencies: * `argh` → 0.1.4 ### Fixes * Fixed globals created within program scope not being tracked by compiler * Fixed `[whitespace-fmt]` modifying the wrong stack frame ## 4.0.0-alpha.14 (1/9/2021) ### New * Add support for spread notation in function calls * Add support for slice notation in getters and setters * Added `BUILD_VERSION` constant to stdlib * Added new stdlib functions: * `[try]`: execute a protected call on a function or block with optional error handling callback ### Changes * Make some unnecessarily public runtime/compiler APIs crate-visible * Strings are now measured by grapheme clusters instead of bytes; this affects indexing + slicing behavior ### Fixes * Fixed some unintended module re-exports * Fixed modules imported with `[require]` not living long enough * Fixed panic when trying to return from main program scope ## 4.0.0-alpha.13 (10/19/2020) ### Changes * Renamed `ErrorKind` to `CompilerErrorKind` in `rant::compiler` * Exposed the `rant::runtime` module and several types inside * More runtime types will be exposed over time as they are documented. ### Fixes * Fixed several stdlib functions not being registered ## 4.0.0-alpha.12 (yanked) (10/19/2020) ### New * Added `RuntimeErrorType::AssertError` * Added `ValueError::Overflow` * Added new stdlib functions: * `[abs]`: calculate the absolute value of a number * `[acos]`: calculate the arccosine of a number * `[asin]`: calculate the arcsine of a number * `[assert-eq]`: raise an error if two values are not equal * `[assert-neq]`: raise an error if two values are equal * `[assert]`: raise an error if a condition is false * `[atan]`: calculate the arctangent of a number * `[atan2]`: calculate the four-quadrant arctangent of a number * `[cos]`: calculate the cosine of an angle * `[has]`: check if a collection contains a specific value * `[index-of]`: return the index of the first occurrence of a value in a list, or `~` if it's not found * `[is]`: check if a value is a specific type * `[last-index-of]`: return the index of the last occurrence of a value in a list, or `~` if it's not found * `[pow]`: raise x to y power * `[sin]`: calculate the sine of an angle * `[sqrt]`: calculate the square root of a number * `[tan]`: calculate the tangent of an angle ### Changes * Renamed Rant's `integer` type to `int` * Renamed stdlib functions: * `[is-integer]` → `[is-int]` * Changed `[min]` and `[max]` to accept varargs+; lists are replaced with their min/max values respectively ### Removed * Removed `[has-key]` from stdlib ## 4.0.0-alpha.11 (10/14/2020) ### New * Getters can now accept an optional fallback value * Added function call piping * Added new stdlib functions: * `[clamp]`: clamp a value between two others * `[is-any]`: check if a value is not empty * `[is-between]`: check if a value is between two others (inclusive) * `[zip]`: combine two lists into a new list using a function ### Changes * Empty value token `<>` changed to `~` * CLI now trims trailing whitespace from REPL input ## 4.0.0-alpha.10 (10/11/2020) ### New * Added inverse indices in accessors * Added anonymous getters/setters * Added "function percolation": function calls will now descope until the requested variable provides a function or other callable value ### Changes * Compiler now consolidates adjacent fragments/escape sequences into single AST node * Updated `quickscope` to 0.1.5 ### Fixes * Fixed dynamically-keyed setters pushing values to stack in wrong order ### Removed * Removed `[get]` from stdlib ## 4.0.0-alpha.9 (10/10/2020) ### New * Added `RuntimeErrorType::TypeError` * Added `Rant.run_with()`, `Rant.run_into_string_with()` * Added new stdlib functions: * `[filter]`: make a copy of a list containing only items that pass a predicate * `[map]`: apply a function to items in a list and return another list with the results * `[oxford-join]`: print a list with custom separators for applying series commas and conjunctions * `[rand-list]`: generate a list of random integers * `[randf-list]`: generate a list of random floats * `[translate]`: map a list's values to the values in a map ### Fixes * Fixed `[sifted]` and `[squished]` returning `<>` when input list meets target size * Fixed sinks not being honored on native function calls ## 4.0.0-alpha.8 (10/7/2020) ### New * Added `RantProgramInfo` struct * Added `[require]` now searches the containing directory of the running program before the local modules path * Added new stdlib functions: * `[alpha]`: print a string of random alphanumeric characters * `[assoc]`: create a map from a list of keys and a list of values * `[ceil]`: get the smallest integer greater than or equal to a number * `[floor]`: get the largest integer less than or equal to a number * `[frac]`: get the fractional part of a float value * `[sift]`: remove random items from a list down to a target size * `[sifted]`: create a random, ordered subset of a list * `[squish]`: merge random adjacent elements in-place in a list using addition until a target size is reached * `[squished]`: make a copy of a list with random adjacent elements merged down to a target size ### Changes * `[require]` now accepts a relative path, as long as it is contained in the modules directory * `RantProgram.name()` now returns `Option<&str>` instead of `&str` * Renamed `RantOptions.local_module_path` to `RantOptions.local_modules_path` * Renamed stdlib functions `[num]` and `[numf]` to `[rand]` and `[randf]`, respectively ### Fixes * Fixed function calls not triggering variable capture pass * Fixed def + get/set of same variable in chained accessor causing erroneous variable capture inside functions ## 4.0.0-alpha.7 (10/1/2020) ### New * Added new stdlib functions: * `[break]` * `[continue]` * `[fork]` * `[max]` * `[min]` * `[return]` * `[shred]` * `[shuffled]` * `[sort]` * `[sum]` * `[unfork]` ### Changes * Main program body can now be returned from with `[return]` * Upgraded `smartstring` to 0.2.5 ## 4.0.0-alpha.6 (9/22/2020) ### New * Modules are now cached by the executing context in a global map * Added support for variable capturing in closures * Added `.delete_global()`, `.has_global()`, `.delete_global()`, `.global_names()` methods to `Rant` ### Removed * Removed `.globals()` method from `Rant` ### Changes * Upgraded `quickscope` to 0.1.3 ## 4.0.0-alpha.5 (9/21/2020) ### New * Added `Rant::with_random_seed()` constructor * Added `.compile_named()` and `.compile_quiet_named()` methods to `Rant` * Added support for multi-part accessors * Added support for modules * Added new stdlib functions: * `[require]` * `[error]` ### Removed * Removed `RantProgram::with_name()` method ### Changes * Replaced `RuntimeErrorType::GeneralError` with `RuntimeErrorType::UserError` * Upgraded `quickscope` to 0.1.2 * `[sep]` now supports `block` values and will auto-resolve them for each separator * Improved stack trace formatting * Error messages are categorized and have improved readability * Consecutive duplicate stack frames are now combined ## 4.0.0-alpha.4 (9/12/2020) ### New * Added descope and explicit global modifiers to accessors * Added implicit local variable scope to program root * Added support for whitespace normalization via `[whitespace-fmt]`. * Added new stdlib functions: * `[insert]` * `[remove]` * `[take]` * `[whitespace-fmt]` ### Changes * Runtime now uses `quickscope` crate for variable access * Changed `Rant::run()` to return a `RantValue` and added `Rant::run_into_string()` to explicitly return a `String` output * `[dignz]` * Renamed stdlib functions: * `[dec]` -> `[dig]` * `[hex]` -> `[digh]` * Upgraded `smartstring` to version 0.2.4 ### Removed * Removed `_GLOBALS` from stdlib ## 4.0.0-alpha.3 (8/29/2020) ### New * Added initial support for optional debug symbols. Enable them via `debug_mode` option in `RantOptions`. * Added (very basic) stack traces. They may be buggy still. * Added the `block` type. * Added new stdlib functions: * `[and]`, `[or]`, `[not]`, `[xor]` * `[clear]` * `[copy]` * `[either]` * `[eq]`, `[neq]`, `[gt]`, `[lt]`, `[ge]`, `[le]` * `[has-key]` * `[if]`, `[else-if]`, `[else]` * `[indent]` * `[is-odd]`, `[is-even]`, `[is-factor]` * `[is-string]`, `[is-number]`, `[is-integer]`, `[is-float]`, `[is-bool]`, `[is-empty]`, `[is-nan]` * `[keys]` * `[lines]` * `[nop]` * `[push]`, `[pop]` * `[reset-attrs]` * `[resolve]` * `[shuffle]` * `[sorted]` * CLI benchmarks are now hidden by default; enable with `--bench-mode` / `-b`. ### Changes * Renamed `[n]` to `[num]` * Renamed `[nf]` to `[numf]` ### Fixes * Fixed compiler bug where non-printing whitespace was sometimes printed. * Fixed bug where printing empties with a non-empty would cause output to be coerced incorrectly to a string. * Fixed bug where sinked blocks print when they're not supposed to. ## 4.0.0-alpha.2 (8/26/2020) ### New * Added support for some block attributes: conditional value, repetitions, separator * Added a lot of new stdlib functions * Added `special` Rant type to represent opaque internal runtime data. * Added `get_global()` and `set_global()` to `Rant`. * Added new `Rant::with_options` constructor that lets you customize the context using new `RantOptions` struct. * Added `RantValueType` to represent the type of a value. ### Changes * Replaced empty `Err` variant on `Rant::compile*` methods with new `compiler::ErrorKind` enum. * Changed `IndexError` and `KeyError` to use `RantValueType` instead of `&'static str` to represent types. * Renamed `get_by_index`, `set_by_index`, `get_by_key`, and `set_by_key` methods in `RantValue` to `index_get`, `index_set`, `key_get`, and `key_set` respectively. * Expanded type aliases on `Rant::compile*` method return types to make them less confusing. * Hid some modules that don't need to be user-facing. ## 4.0.0-alpha.1 (8/24/2020) * Initial alpha release.