2025-08-18: Fuzion August Update
The usability of the Fuzion tools on larger applications was improved by a significant speedup of the data flow analysis. Things still need to be improved further, but we make progress one step at a time.
- General
The Fuzion team had its last month in our container in the Perfekt Futur, we will miss the create atmosphere in that great environment!
- Fuzion language
Add support for loop invariants (#5498)
Loop invariants can be used to formally proof the correctness of a loop and to perform corresponding runtime checks
Here is an example of a feature
contains
that checks if an arraya
contains the valuekey
contains(a, key) => for i := 0, i+1 inv debug: a.take i ∀ !=key while i != a.length until a[i] = key true else false say (contains [1,2,3,4] 3) say (contains [5,6,7,8] 3)
The
until
-expression ensures thattrue
is returned if an element is found that equalskey
.The loop invariant ensures that the first
i
elements of the array,a.take i
, all are unequeal tokey
expressed using the infix quantor∀ !=key
.The loop invariant is trivially
true
on the first iteration wherei
is0
and hence thea.take i
is empty.After each iteration, the invariant stays
true
since the invariant from the previous iterationa.take i-1 ∀ !=key
combined with the negated until condition!(a[i] = key)
implies the invariant of the current iterationa.take i ∀ !=key
.Finally, the negated while condition
!(i != a.length)
combined with the invariant ensures thata.take a.length ∀ !=key
, i.e., that no element equalskey
, so we returnfalse
.In summary,
true
is returned only in case an element equalskey
andfalse
is returned only in case all elements are not equal tokey
, so our function does what we want (as long as it terminates, which is another issue).parser: enable lambda expression
x,y->z
with several args in block (#5555)This permits returning a lambda as follows, before this code produced a syntax error.
f (i32,i32)->i32 => x,y -> x+y
parser: unify handling of
()
and{}
with respect to indentation, fix #4425 (#5536)Now,
{
/}
and(
/)
can be used largely interchangeably around a code block, e.g., we can create a block as followssay (if 3 = 4 then say "strange" else say "this should run" "result from code block")
which is equivalent to the same code using{
/}
:say {if 3 = 4 then say "strange" else say "this should run" "result from code block"}
- Base library
-
New library features
base: Add
time.Clock
andtime.nano.run_once
/time.nano.run_periodic
. (#5568)Add module
http
with features for serialization and deserialization of HTTP messages (#5359)http: change visibility of
canonical_header_map.map_of
(#5629)http/Message: quick fix to avoid infinite loop in reader (#5596)
http/Message: in read handler implementation, use lowest level read (#5619)
-
Changed library features
lib: add means to compose effects more easily (#5367)
Here is an example from
net.connection.with
in the Fuzion base lib that uses three effects:reader .and T _ writer .and channel_ .call fn
base: use
expand()
to avoid repeatedrealloc
inexpanding_array.concat
(#5526)base: remove constraint
T : numeric
foroption.infix >>?
since the type does not need to be constrained (#5606)base/String: rename
fields_func
assplit_if
(#5567)lib: fix
substring_codepoint
that mixed base and codepoint indices (#5513)lib: fix
tuple1
that returned the tuple element'sType
instead of its value. (#5474)lib: fix some types that were accidental `this` types needing qualification (#5509)
net/connection: treat zero read from socket as EOF unless requested (#5618)
-
- Front end
ast,
replaceGenericsAndOuter
: stricter pre condition (#5587)resultTypeIfPresentUrgent
, resolve outer on incomplete type (#5586)add switch to disable
applyTypePar
caching (#5481)change
AbstractFeature.toString
(#5557)unjustified error fix #5467 by resetting pending error when Call must be resolved again (#5470)
Fix
IndexOutOfBoundsException
in redefinition with open type parameter (#5502)Fix
NullPointerException
inUniverse.typeforInferencing
(#5607)fix
resolveFormalArg
for open generics that have to be extracted… (#5459)Fix confusing error output for redefinition of feature with type parameters (#5505)
Fix require condition failure when redefining with wrong # of type pars (#5504)
Improved error message created by
AstErrors.declarationsInLazy
(#5562)Improved grammar in error messages listing cases of a
match
(#5626)make sure free types are split off when creating cotype (#5554)
Move error checking for choice inheritance to dedicated method, fix #5539 (#5540)
Support for types that depend on outer type of type parameter constraint (#5590)
Suppress type inference errors if actual args of call had errors (#5558)
suppress
failed to infer actual type parameters
for call tof_ERROR
(#5551)Do not allow garbage expressions on left hand side of lambda, fix #5529 (#5538)
Fix the .fum file specification type for the MIR_FILE_MAGIC entry (#5463)
fix partial application for block without result expression (#5455)
call: ensure target/actuals/actualTypeParameters are not null (#5531)
remove ExpressionVisitor (#5598)
remove resolve one arg (moreThanTypes) (#5565)
make sure
ThisType
has no generics and no outer (#5445)formalgenerics, transparently use type args of feature (#5537)
ast/fe/fuir: cleanup: resolved types are not a concept for the middle end, so should not be used there (#5591)
remove second iteration in
Clazz.handDown
(#5461)dfa: performance improvement: Do not trace effect values within environments (#5518)
dfa: Two phase DFA (#5333)
fix reading uninitialized field (#5614)
fuir consider outer clazzes for
replaceThisTypeForCotype
(#5466)
be/jvm: add error message for missing library (#5476)
Cheers,
--The Fuzion Team.