Changes
2026-04-27
- Add build metadata and version information, which can be retrieved with
tomo -b. - Change interface for
List.binary_search()to be more flexible.
2026-03-16
- Added
Path.copy_to(src, dest)
2026-03-14
- Added
Path.each_child()andPath.walk()for iterating over files without the need to allocate a list of every iterated file. - Added
Text.matches_glob(glob)andPath.matches_glob(glob) - Overhaul to package system (previously: modules)
2026-02-08
- Path syntax no longer requires parentheses, any value starting with
.,/, or~is treated as a path. - Changed
Pathimplementation to use C-style strings instead of anenumwith array components. - Added
Text.distance(a,b)for calculating text distances. List.random()now returns an optional value, which isnonewhen the list is empty, instead of failing.- Improved error messages for misspelled variables and field/method names.
2025-12-31
- Added support for
123.foo()parsing the same as(123).foo() - Changed
is_between()to be bidirectional so5.is_between(10, 1) == yes
2025-12-23.2
- Fixes for OpenBSD and Mac.
2025-12-23
- Improved C preprocessing performance by eliminating expensive macro calls.
2025-12-22
- Use static linking instead of dynamic linking for the Tomo standard library as well as for user libraries. This produces binaries that do not depend on having Tomo and the library installed at runtime.
- Added
Path.writer()andPath.byte_writer()for multiple successive writes
2025-12-21.6
- Add smarter default behavior if run without any args (REPL-like script runner)
2025-12-21.5
- Various fixes for versioning and builds.
2025-12-21.4
- Version bump and deprecated
--changelogflag
2025-12-21.3
- Version bump
2025-12-21.2
- Update build process
2025-12-21
- You can now discard empty struct values.
- For an enum
Foo(A,B,C), the syntaxf!now desugars tof.A!using the first tag defined in the enum. - Error messages are more helpful for
foo.Whatever!enum field accessing. - Simplified logic for enums so there is less difference between enums that have tags with member fields and those without.
- Rename
Empty()toPresent()for set-like tables. - Paths are now an
enum Path(AbsolutePath(components:[Text]), RelativePath(components:[Text]), HomePath(components:[Text])) - Added
enum Result(Success, Failure(message:Text))type for indicating success or failure. - Some path methods now use
Resultreturn types instead of failing:Path.append()Path.append_bytes()Path.create_directory()Path.remove()Path.set_owner()Path.write()Path.write_bytes()
Path.parent()returnsnoneif path is(/)(file root)- Added check for unused variables.
2025-11-30
API changes
- Added
baseparameter to variousInt.parse()methods to allow explicitly setting the numeric base from 1-36.
Bugfixes
- Fixed various issues around parsing integers.
v2025-11-29.2
Bugfixes
- Fix for undefined behavior on enums and structs with padding.
2025-11-29
Syntax changes
- Syntax for tables has changed to use colons (
{k: v}) instead of equals ({k=v}). - Syntax for text literals and inline C code has been simplified.
- Added metadata format instead of
_HELP/_USAGE:HELP: "Help text" USAGE: "Usage text" MANPAGE_SYNOPSYS: "Synopsys..." MANPAGE_DESCRIPTION: (./description.txt) - Deprecated:
externkeyword for declaring external symbols from C.- Use
C_codeinstead.
- Use
- Deprecated: postfix
?to make values optional.- Explicitly optional values can be declared as
my_var : T? = value.
- Explicitly optional values can be declared as
- Deprecated:
>> ... = ...form of doctests. They are now called "debug logs" and you can specify multiple values:>> a, b, c - Deprecated:
extendblocks - Deprecated:
deserializeoperation and.serialized()method call- Instead, convert to and from
[Byte]
- Instead, convert to and from
Versioning and library changes
- Tomo versioning now uses dates instead of semantic versioning.
- Tomo libraries are now installed to
$TOMO_PATH/lib/tomo@TOMO_VERSION/library@LIBRARY_VERSIONinstead of$TOMO_PATH/share/tomo_TOMO_VERSION/installed/module_LIBRARY_VERSION - Core libraries are no longer shipped with the compiler, they have moved to separate repositories.
- Library installation has been cleaned up a bit.
Type Changes
- List indexing now gives an optional value.
- Added support for inline anonymous enums
- Accessing a field on an enum now gives an optional value instead of a boolean.
- Deprecated: Sets are no longer a separate type with separate methods.
- Instead of sets, use tables with a value type of
{KeyType:Empty}. - As a shorthand, you can use
{a,b,c}instead of{a:Empty(), b:Empty(), c:Empty()}and the type annotation{K}as shorthand for{K:Empty}.
- Instead of sets, use tables with a value type of
- Added
Emptyfor a built-in empty struct type andEMPTYfor an instance of the empty struct. - Struct fields that start with underscores can be accessed again and function arguments that start with underscore can be passed (but only as keyword arguments).
API changes
- Added
Path.lines(). - Added
Text.find(text, target, start=1). - Added
at_cleanup()to register cleanup functions. - Added
recursiveargument toPath.create_directory()to create parent directories if needed. setenv()now takes an optional parameter for value, which allows for unsetting environment values.- Tables now have
and,or,xor, and-(minus) metamethods. - Added
table.with(other),table.without(other),table.intersection(other), andtable.difference(other). - Changed
list.unique()to return a table withEmpty()values for each unique list item. - Added a
--formatflag to thetomobinary that autoformats your code (currently unstable, do not rely on it just yet). - Standardized text methods for Unicode encodings:
Text.from_utf8()/Text.utf8()Text.from_utf16()/Text.utf16()Text.from_utf32()/Text.utf32()
Bug fixes
Int.parse()had a memory bug.- Breaking out of a
for line in file.by_line()!loop would leak file handle resources, which could lead to exhausting the number of open file handles. When that happens, the standard library now forces a GC collection to clean up resources, which can result in file handles being freed up. &references failed to propagate when accessing fields likefoo.baz.method()whenfoois a&Fooandbaz.method()takes a&Baz.- Optional paths no longer fail to compile when you check them for
none. - Text replacement no longer infinitely loops when given an empty text to replace.
- Short CLI flag aliases now no longer use the first letter of the argument.
- Stack memory was not correctly detected in some cases, leading to potential memory errors.
Other changes
- Added automatic manpage generation.
- Major improvements to robustness of CLI argument parsing.
v0.3
- Added a versioning system based on
CHANGES.mdfiles andmodules.iniconfiguration for module aliases. - When attempting to run a program with a module that is not installed, Tomo can prompt the user to automatically install it.
- Programs can use
--versionas a CLI flag to print a Tomo program's version number and exit. - Significant improvements to type inference to allow more expressions to be
compiled into known types in a less verbose manner. For example:
enum NumberOrText(Number(n:Num), SomeText(text:Text)) func needs_number_or_text(n:NumberOrText) >> n func main() needs_number_or_text(123) needs_number_or_text(123.5) needs_number_or_text("Hello") - Added
tomo --prefixto print the Tomo install prefix. - Sets now support infix operations for
and,or,xor, and-. - Added new
jsonmodule for JSON parsing and encoding. - Added
Path.sibling(). - Added
Path.has_extension(). - Added
Table.with_fallback(). - Added
Int*.get_bit()andByte.get_bit(). - Added
Byte.parse()to parse bytes from text. - Added optional
remainderparameter toparse()methods, which (if non-none) receives the remaining text after the match. Ifnone, the match will fail unless it consumes the whole text. - Added optional
remainderparameter toText.starts_with()andText.ends_with()to allow you to get the rest of the text without two function calls. - Improved space efficiency of Text that contains non-ASCII codepoints.
- Doctests now use equality checking instead of converting to text.
- Fixed the following bugs:
- Negative integers weren't converting to text properly.
- Mutation of a collection during iteration was violating value semantics.
extendstatements weren't properly checking that the type name was valid.- Lazy recompilation wasn't happening when
use ./foo.cwas used for local C/assembly files or their#includes. - Memory offsets for enums with different member alignments were miscalculated.
- Optional types with trailing padding were not correctly being detected as
none - Tomo identifiers that happened to coincide with C keywords were not allowed.
- Compatibility issues caused compilation failure on some platforms.
v0.2
- Improved compatibility on different platforms.
- Switched to use a per-file unique ID suffix instead of renaming symbols after
compilation with
objcopy. - Installation process now sets user permissions as needed, which fixes an issue where a user not in the sudoers file couldn't install even to a local directory.
- Fixed some bugs with Table and Text hashing.
- Various other bugfixes and internal optimizations.
v0.1
First version to get a version number.