2025-09-01
The C3 programming language has reached 0.7.5, marking another milestone in the language’s evolution. This release brings improvements to language features, developer experience, and standard library functionality.
Here’s what’s new and improved in this update.
One of the new features in 0.7.5 is the introduction of module aliasing with the syntax alias foo = module std::io
. This enhancement improves user control over code organization and readability, allowing developers to create shorter names for modules where needed.
The compile-time system has received several additions:
???
: Compile time ternary, guaranteed to resolve at compile time and will not execute the false branch.@safeinfer
: Enables the use of var
in function contexts, where it was previously disallowed.@intlog2
, @clz
, @min
, @max
and functions are now available at compile time.bitsizeof
macro builtin: Provides bit-level size information for types.C3 0.7.5 brings improvements to operator overloading:
@operator(==)
now also enables switch
statement support for the type.foo[x][y] = b
now can pass through multiple levels of overloads, and works as expected with proper overload resolution.Type.is_eq
now correctly returns true for types with equality overloads.$kindof
: Shorthand for $typeof(...).kindof
which simplifies contract checks.typeid
implicitly, streamlining contracts and compile time programming.$defined
: It now accepts declarations, like $defined(int x = y)
which removes the need for macros like @assignable_to
.The compiler now provides more helpful diagnostics:
$endif
and missing if
bodies.--max-stack-object-size
c3l
-libraries now package linked libraries in a directory specified by the "linklib-dir"
setting.The standard library has grown:
FileMmap
: Memory-mapped file managementFixedBlockPool
: Memory pool for fixed-size objectsHashSet
: Generic hash set implementation with values
method supportAsciiCharset
: Fast ASCII character matching utilitiesstd::core::log
for common logging .String manipulation gets a boost with:
String.contains_char
: Character containment checkingString.trim_charset
: Trimming based on character sets@zip
, @reduce
, @filter
, @any
, @all
, @sum
, @product
and @indices_of
.Several features have been deprecated in favor of improved alternatives:
@compact
comparison behavior (use --use-old-compact-eq
for compatibility)add_array
in favor of push_all
on lists.@assignable_to
in favor of using $define
.@typekind
in favor of using $kindof
.@typeis
in favor of $typeof(foo) == Type
.@select
in favor of $foo ??? #expr1 : #expr2
.This release addresses numerous important issues:
List.remove_at
Deprecations of many type introspection macros, such as @typekind
and @typeis
is together with the improvements in $defined
, the implicit type conversions to typeid
and $kindof
spearheading a shift to making constraint checking succinct while also being completely obvious. Relying on macros would often make the constraints less clear to a reader. On top of this we get compile time ternary using ??? :
to succinctly express compile time selection between two expressions. With the changes, the code is as short to type but without the need to remember particulars of one macro over the other.
Overall, C3 0.7.5 represents another step in maturing the language’s core features while laying the groundwork for future enhancements. The focus will continue to be aimed at improve developer experience, performance, and language consistency. Many of the standard library additions are contributions from the community around C3, which is providing essential feedback and direction to polish the language further. C3 is step-by-step establishing itself as a modern evolution of C that maintains simplicity while adding powerful abstractions.
For a deeper look at the changes, watch the demo: https://www.youtube.com/watch?v=OuZBxdM_YEI
alias foo = module std::io
module aliasing.@intlog2
macro to math.@clz
builtin. #2367bitsizeof
macro builtins. #2376@min
and @max
builtins. #2378@compact
use for comparison. Old behaviour is enabled using --use-old-compact-eq
.@operator(==)
.Type.is_eq
is now true for types with ==
overload.add_array
in favour of push_all
on lists.$endif
.foo[x][y] = b
now interpreted as (*&foo[x])[y] = b
which allows overloads to do chained [] accesses.--max-stack-object-size
).@safeinfer
to allow var
to be used locally.$defined
take declarations: $defined(int x = y)
@assignable_to
is deprecated in favour of $define
linklib-dir
to c3l-libraries to place their linked libraries in. Defaults to linked-libs
os-arch
linked library doesn’t exist, try with os
for c3l libs.@is_const
is deprecated in favour of directly using $defined
.@is_lvalue(#value)
is deprecated in favour of directly using $defined
.$kindof
compile time function.@typekind
macro in favour of $kindof
.@typeis
macro in favour of $typeof(#foo) == int
.$defined(#hash)
will not check the internal expression, just that #hash
exists. Use $defined((void)#hash)
for the old behaviour.macro foo(int x = ...)
which can be checked using $defined(x)
.$val ??? <expr> : <expr>
.if (try x = (true ? io::EOF? : 1))
, i.e. using if-try with a known Empty.if (try x = (false ? io::EOF? : 1))
, i.e. using if-try with a CT known value.@deprecated
and @pure
.$c += 1
when $c
was derived from a pointer but behind a cast.native_cpus
functionality for OpenBSD systems. #2387a5hash
in the compiler for compile-time $$str_hash
to match String.hash()
.@format
encountered *
in some cases.replace
.Socket.get_option
didn’t properly call getsockopt
, and getsockopt
had an invalid signature.@tag
was not allowed to repeat.has_tagof
on tagged lambdas returns false #2432?
after optional function name when reporting type errors.log
and exp
no-strip.@test
/@benchmark
on module would attach to interface and regular methods.@select
in favor of ???
.Foo x = $eval("A")
, now works correctly for $eval
.==
to Pair
, Triple
and TzDateTime. Add print to Pair
and Triple
.env::INET_DEVICES
and add required socket constants.FileMmap
to manage memory mapped files.vm::mmap_file
to memory map a file.FixedBlockPool
which is a memory pool for fixed size blocks.std::core::log
for logging.@zip
and @zip_into
macros. #2370env::
booleans.std::os::win32
.HashSet.values
and String.contains_char
#2386&[]
overload to HashMap.PollSubscribes
and PollEvents
in favour of PollSubscribe
and PollEvent
and made them const enums.AsciiCharset
for matching ascii characters quickly.String.trim_charset
.@reduce
, @filter
, @any
, @all
, @sum
, @product
, and @indices_of
macros.String.bformat
has reduced overhead.roundeven
has a normal implementation.Check out the documentation or download it and try it out.
Have questions? Come and chat with us on Discord.