Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

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 array a contains the value key

          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 that true is returned if an element is found that equals key.

      The loop invariant ensures that the first i elements of the array, a.take i, all are unequeal to key expressed using the infix quantor ∀ !=key.

      The loop invariant is trivially true on the first iteration where i is 0 and hence the a.take i is empty.

      After each iteration, the invariant stays true since the invariant from the previous iteration a.take i-1 ∀ !=key combined with the negated until condition !(a[i] = key) implies the invariant of the current iteration a.take i ∀ !=key.

      Finally, the negated while condition !(i != a.length) combined with the invariant ensures that a.take a.length ∀ !=key, i.e., that no element equals key, so we return false.

      In summary, true is returned only in case an element equals key and false is returned only in case all elements are not equal to key, 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 follows

          say (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 and time.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 repeated realloc in expanding_array.concat (#5526)

      • base: remove constraint T : numeric for option.infix >>? since the type does not need to be constrained (#5606)

      • base/String: rename fields_func as split_if (#5567)

      • lib: fix substring_codepoint that mixed base and codepoint indices (#5513)

      • lib: fix tuple1 that returned the tuple element's Type 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)

    • crash fix #5353, require condition in Call (#5616)

    • 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 in Universe.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 to f_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)

    • cleanup AbstractType.asValue/asRef/asThis (#5615, #5478)

    • 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)

  • Monomorphization / DFA
    • 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)

  • JVM back end
    • be/jvm: add error message for missing library (#5476)

  • Windows
    • add workaround for windows encoding issue (#5628)

    • check_simple_example, windows: fix stdout/stderr to UTF-8 (#5577)

    • fix windows sockets test (#5589)

    • action, windows: run test in parallel (#5584)

    • revert cfe45d7, since this does not work on windows (#5601)

  • Documentation
    • docs: change module list to match style of API docs (#5464)

    • docs: limit annotation [Contains abstract features] to current module and its dependencies (#5465)

    • docs: use relative paths in API docs when full HTML is generated (#5492)

    • ebnf: raise error on grammar error (#5448)

  • Tests
    • tests: add source dir option to generics_negative tests (#5545)

    • tests: fix sed-expression in negative.mk (#5547)

    • tests: in negative.fz use $(FILE) instead of $(NAME) (#4322)

    • tests: make tests/free_types_negative _simple_and_negative_ (#5559)

  • Build tools
    • lsp.mk: do not rebuild lsp completely every time (#5512)

    • port check_simple_example to fuzion (#5339)

    • record_simple_example: remove usage of _cur_dir.sh (#5534)

    • tests: remove FUZION_JAVA_STACK_SIZE from some Makefiles (#5532)

    • tests: remove_old_shell_scripts (#5527)

    • enable javac lint (#5608)

Cheers,

--The Fuzion Team.

last changed: 2025-08-18