{"id":13609941,"url":"https://github.com/tokiwa-software/fuzion","last_synced_at":"2025-12-30T00:06:41.191Z","repository":{"id":37426631,"uuid":"324773491","full_name":"tokiwa-software/fuzion","owner":"tokiwa-software","description":"The Fuzion Language Implementation","archived":false,"fork":false,"pushed_at":"2025-04-10T09:29:19.000Z","size":21118,"stargazers_count":53,"open_issues_count":338,"forks_count":12,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-10T09:37:20.295Z","etag":null,"topics":["compiler","functional-programming","fuzion","object-oriented-programming","programming-language","safety-critical-systems","static-analysis"],"latest_commit_sha":null,"homepage":"https://fuzion-lang.dev","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tokiwa-software.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-27T13:58:47.000Z","updated_at":"2025-04-10T08:20:11.000Z","dependencies_parsed_at":"2022-07-14T10:21:38.401Z","dependency_job_id":"a8de2934-b663-41e7-9bf3-fe3a7949ebfb","html_url":"https://github.com/tokiwa-software/fuzion","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokiwa-software%2Ffuzion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokiwa-software%2Ffuzion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokiwa-software%2Ffuzion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokiwa-software%2Ffuzion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tokiwa-software","download_url":"https://codeload.github.com/tokiwa-software/fuzion/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248640974,"owners_count":21138120,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","functional-programming","fuzion","object-oriented-programming","programming-language","safety-critical-systems","static-analysis"],"created_at":"2024-08-01T19:01:39.523Z","updated_at":"2025-12-30T00:06:41.186Z","avatar_url":"https://github.com/tokiwa-software.png","language":"Java","funding_links":[],"categories":["Uncategorized","JVM语言"],"sub_categories":["Uncategorized"],"readme":"# \u003cimg src=\"assets/logo.svg\" alt=\"fuzion logo\" width=\"25\" /\u003e Fuzion\n\n[![OpenSSF\nScorecard](https://api.securityscorecards.dev/projects/github.com/tokiwa-software/fuzion/badge)](https://api.securityscorecards.dev/projects/github.com/tokiwa-software/fuzion)\n[![run tests on linux](https://github.com/tokiwa-software/fuzion/actions/workflows/linux.yml/badge.svg)](https://github.com/tokiwa-software/fuzion/actions/workflows/linux.yml)\n[![run tests on macOS](https://github.com/tokiwa-software/fuzion/actions/workflows/apple.yml/badge.svg)](https://github.com/tokiwa-software/fuzion/actions/workflows/apple.yml)\n[![run tests on windows](https://github.com/tokiwa-software/fuzion/actions/workflows/windows.yml/badge.svg)](https://github.com/tokiwa-software/fuzion/actions/workflows/windows.yml)\n\n\n## A language with a focus on simplicity, safety and correctness.\n\n\u003e Please note that this language is work in progress.\n\n---\n\n\u003c!--ts--\u003e\n   * [Examples](#examples)\n   * [Documentation](#documentation)\n   * [Clone](#clone)\n   * [Required packages](#required-packages)\n     * [Linux](#linux)\n     * [MacOS](#macos)\n     * [Windows](#windows)\n   * [Build](#build)\n   * [Run](#run)\n   * [Tests](#tests)\n     * [Running all tests](#running-all-tests)\n     * [Run a single test](#run-a-single-test)\n     * [Record a test](#record-a-test)\n   * [Soft dependencies](#soft-dependencies)\n   * [Install prebuilt](#install-prebuilt)\n   * [Language server](#language-server)\n     * [Install](#install)\n       * [Vim](#vim)\n       * [Emacs](#emacs)\n         * [Eglot](#eglot)\n         * [LSP-Mode](#lsp-mode)\n     * [Run standalone](#run-standalone)\n       * [socket](#transport-socket)\n       * [stdio](#transport-stdio)\n     \u003c!-- NYI: UNDER DEVELOPMENT: * [Implementation state](#implementation-state) --\u003e\n\u003c!--te--\u003e\n\n---\n\n## Examples\n\n```\nhello_world is\n\n  # first we define a custom mutate effect.\n  # we will need this for buffered reading from stdin\n  #\n  lm : mutate is\n\n  # calling `lm` creates an instance of our mutate effect,\n  # `instate_self` is then used to instate this instance and\n  # run code in the context of the instated effect.\n  #\n  lm ! ()-\u003e\n\n    # read someone's name from standard input\n    #\n    get_name =\u003e\n      (io.stdin.reader lm) ! ()-\u003e\n        (io.buffered lm).read_line ? str String =\u003e str | io.end_of_file =\u003e \"\"\n\n    # greet someone with the name given\n    #\n    greet(name String) is\n      say \"Hello, {name}!\"\n\n    # greet the user\n    #\n    x := greet get_name\n\n    # you can access any feature - even argument features of other features\n    # from outside\n    #\n    say \"How are you, {x.name}?\"\n```\n\nThis `hello_world` example demonstrates one important concept in Fuzion quite\nwell: Everything is a *feature*. *Features* are Fuzion's response to the mess\nthat is created by *classes*, *methods*, *interfaces*, and various other\nconcepts in other programming languages. Since everything is a feature, the\nprogrammer does not need to care and the compiler will do this work. As you can\nsee, it is even possible to access the argument features of some feature from\noutside.\n\n```\nex_gcd is\n\n  # return common divisors of a and b\n  #\n  common_divisors_of(a, b i32) =\u003e\n    max := max a.abs b.abs\n    (1..max).flat_map i-\u003e\n      if (a % i = 0) \u0026\u0026 (b % i = 0)\n        [-i, i]\n      else\n        []\n\n\n  # find the greatest common divisor of a and b\n  #\n  gcd(a, b i32)\n    pre\n      safety: (a != 0 || b != 0)\n    post\n      safety: a % result = 0\n      safety: b % result = 0\n      pedantic: (common_divisors_of a b).reduce bool true (acc,cur -\u003e acc \u0026\u0026 (result % cur = 0))\n  =\u003e\n    if b = 0 then a else gcd b (a % b)\n\n\n  say \u003c| gcd 8 12\n  say \u003c| gcd -8 12\n  say \u003c| gcd 28 0\n```\n\nThis example implements a simple variant of an algorithm that finds the greatest\ncommon divisor of two numbers. However, it also demonstrates one of Fuzion's\nnotable features: design by contract. By specifying pre- and postconditions for\nfeatures, correctness checks are made possible.\n\n```\ngenerator_effect is\n  # define a generator effect with a yield operation\n  #\n  gen(T type,\n      yield T-\u003eunit    # yield is called by code to yield values\n      ) : effect is\n\n  # traverse a list and yield the elements\n  #\n  list.traverse unit =\u003e\n    match list.this\n      c Cons =\u003e (generator_effect.gen A).env.yield c.head; c.tail.traverse\n      nil =\u003e\n\n  # bind the yield operation dynamically\n  #\n  (gen i32 (i -\u003e say \"yielded $i\")) ! ()-\u003e\n    [0,8,15].as_list.traverse\n```\n\nAnother major concept in Fuzion is that of the\n*[algebraic effect](https://en.wikipedia.org/wiki/Effect_system)* - a new\napproach to encapsulating code with side effects in a safe way.\n\nIn the example above, a custom *effect* has been used to implement a generator\nwith a `yield` operation. In some other languages, this requires a keyword\n`yield` to be provided by the language, but in Fuzion this can be implemented\nwithout language support.\n\nIf you want to play around with Fuzion, try the\n[interactive tutorial](https://fuzion-lang.dev/tutorial/index).\n\n## Documentation\n\nCheck [fuzion-lang.dev](https://fuzion-lang.dev) for language and implementation design.\n\n\n## Clone\n\n\u003e Note that the current directory must not contain any spaces. Make sure you have `git` installed.\n\n    git clone https://github.com/tokiwa-software/fuzion\n\n## Required packages\n\n### Linux\n\n\u003e For Debian based systems this command should install all requirements:\n\u003e\n\u003e     sudo apt-get install make clang libgc1 libgc-dev openjdk-25-jdk\n\n- OpenJDK 25[^1], (needs to include jmods)\n- clang LLVM C compiler\n- GNU make\n- libgc\n\n### MacOS\n\n\u003e This command should install all requirements:\n\u003e\n\u003e     brew install bdw-gc gnu-sed make temurin llvm\n\u003e\n\u003e Additionally you may need to update your PATH environment variable e.g.:\n\u003e\n\u003e     export PATH:\"/usr/local/opt/gnu-sed/libexec/gnubin:/usr/local/opt/gnu-make/libexec/gnubin:$PATH\"\n\n- OpenJDK 25[^1], (needs to include jmods)\n- clang LLVM C compiler\n- GNU make\n- libgc\n\n\n### Windows\n\n\u003e Note that building from powershell/cmd does not work yet.\n\n1) Install chocolatey: [chocolatey.org](https://chocolatey.org/install)\n2) In Powershell:\n    1) choco install git openjdk make msys2 diffutils\n    2) [Environment]::SetEnvironmentVariable(\"Path\",\"c:\\tools\\msys64\\ucrt64\\bin;\" + $env:Path , \"User\")\n3) In file C:\\tools\\msys64\\msys2_shell.cmd change line: 'rem set MSYS2_PATH_TYPE=inherit' to 'set MSYS2_PATH_TYPE=inherit'\n4) In msys2 shell (execute C:\\tools\\msys64\\msys2_shell.cmd):\n    1) pacman -S mingw-w64-x86_64-clang\n    2) make\n5) execute ./bin/windows_install_boehm_gc.sh\n\n## Build\n\n\u003e Make sure java/javac and clang are in your $PATH.\n\n    cd fuzion\n    make\n\nYou should have a folder called **build** now.\n\n## Run\n\n    cd build\n    export PATH=$PWD/bin:$PATH\n    cd tests/rosettacode_factors_of_an_integer\n    fz factors\n\nTo compile the same example (requires clang C compiler):\n\n    fz -c factors\n    ./factors\n\nHave fun!\n\n\n## Tests\n\n### Running all tests\n\n\u003e Since there are a lot of tests this will likely take 1h or more. See below on how to run a single test.\n\nIn the source folder, to run all tests across all backends use the following command:\n\n    make run_tests\n\nWhen testing is finished you will be presented a summary of succeeded, failed and skipped tests.\n\nTo run the tests for one specific backend only use:\n\n    # for jvm backend\n    make run_tests_jvm\n\n    # for c backend\n    make run_tests_c\n\n    # for interpreter backend\n    make run_tests_int\n\n### Run a single test\n\nIn the source folder run:\n\n    make _BACKEND_ -C _BUILD_DIR_/tests/_TEST_/\n\nwhere `_BACKEND_` may be one on the following:\n - jvm\n - c\n - int\n - effect\n - leave out to run test on all backends\n\nUnless you specified a custom build directory you need to substitute `_BUILD_DIR_` by just `build`.\n\nFinally instead of `_TEST_` specify the name of the test.\n\nFull example:\n\n    make jvm -C build/tests/hello\n\n### Record a test\n\nThis works the same as running a test but specifing a different make target.\n\n- record\n- record_jvm\n- record_c\n- record_int\n- record_effect\n\nFull example:\n\n    make record_jvm -C ./build/tests/hello\n\nThis will record stdout and stderr and save those in files in the test directory. (HelloWorld.fz.expected_out, HelloWorld.fz.expected_err)\n\n\u003e To copy the new or updated recordings from the build folder to the source folder you can use this command:\n\u003e\n\u003e     rsync -a --include='*/' --include='*.expected_*' --include='*.effect' --exclude='*' build/tests/ tests/\n\n\n## Soft dependencies\n\nThe compiler can be built and used without these dependencies.\n\nBut the following tools/dependencies are used e.g. for generating the documentation or for running the test suite:\n\n- antlr, for the ebnf grammar\n- asciidoctor, asciidoctor-pdf\n- sed, for normalizing test output\n- wget, for downloading jar dependencies\n- org.eclipse.lsp4j and others, for the language server\n\n\n## Install prebuilt\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/fuzion.svg)](https://repology.org/project/fuzion/versions)\n\n\n## Language Server\n\n### Install\n|Client|Repository|\n|---|---|\n|vscode|https://github.com/tokiwa-software/vscode-fuzion|\n|vim|see instructions below|\n|emacs|see instructions below|\n|eclipse (theia)|https://github.com/tokiwa-software/vscode-fuzion|\n\n#### Vim\n\n0) Note: fuzion_language_server (from ./bin/) needs to be in $PATH\n\n1) Example .vimrc:\n    ```vim\n    :filetype on\n\n    call plug#begin('~/.vim/plugged')\n    Plug 'neoclide/coc.nvim', {'branch': 'release'}\n    call plug#end()\n    ```\n2) in vim\n\n    1) `:PlugInstall`\n\n    2) `:CocConfig`\n\n          ```json\n          {\n            \"languageserver\": {\n              \"fuzion\": {\n                \"command\": \"fuzion_language_server\",\n                \"args\" : [\"-stdio\"],\n                \"filetypes\": [\n                  \"fz\",\n                  \"fuzion\"\n                ]\n              }\n            }\n          }\n          ```\n\n3) add filetype-detection file ~/.vim/ftdetect/fz.vim\n    ```vim\n    au BufRead,BufNewFile *.fz            set filetype=fz\n    ```\n\n#### Emacs\n\n\u003e fuzion_language_server (from ./bin/) needs to be in $PATH\n\nFor emacs there is two options eglot or lsp-mode.\n\n##### Eglot\n\n\n- M-x package-install RET eglot RET (only needed for emacs version \u003c29)\n- add the following code to ~/.emacs.d/fuzion-lsp.el to enable [eglot](https://github.com/joaotavora/eglot)\n\n\n```elisp\n(require 'package)\n(add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\") t)\n(add-to-list 'package-archives '(\"elpa\" . \"https://elpa.gnu.org/packages/\"))\n;; Comment/uncomment this line to enable MELPA Stable if desired.  See `package-archive-priorities`\n;; and `package-pinned-packages`. Most users will not need or want to do this.\n;;(add-to-list 'package-archives '(\"melpa-stable\" . \"https://stable.melpa.org/packages/\") t)\n(package-initialize)\n(custom-set-variables\n ;; custom-set-variables was added by Custom.\n ;; If you edit it by hand, you could mess it up, so be careful.\n ;; Your init file should contain only one such instance.\n ;; If there is more than one, they won't work right.\n '(inhibit-startup-screen t)\n '(package-selected-packages '(eglot ##)))\n(custom-set-faces\n ;; custom-set-faces was added by Custom.\n ;; If you edit it by hand, you could mess it up, so be careful.\n ;; Your init file should contain only one such instance.\n ;; If there is more than one, they won't work right.\n )\n\n(define-derived-mode fuzion-mode\n  fundamental-mode \"Fuzion\"\n  \"Major mode for Fuzion.\")\n\n(add-to-list 'auto-mode-alist '(\"\\\\.fz\\\\'\" . fuzion-mode))\n\n(require 'eglot)\n\n(add-to-list 'eglot-server-programs\n             '(fuzion-mode . (\"fuzion_language_server\" \"-stdio\")))\n\n(add-hook 'after-init-hook 'global-company-mode)\n(add-hook 'fuzion-mode-hook 'eglot-ensure)\n\n(provide 'init)\n;;; init.el ends here\n```\n\n- add following line to ~/.emacs.d/init.el or to ~/.emacs\n\n  (load \"~/.emacs.d/fuzion-lsp.el\")\n\n##### LSP-Mode\n\n- install lsp-mode, flycheck and company for emacs using\n    - M-x package-install RET lsp-mode\n    - M-x package-install RET flycheck\n    - M-x package-install RET company RET\n- add the following code to ~/.emacs.d/fuzion-lsp.el to enable [lsp-mode](https://github.com/emacs-lsp/lsp-mode)\n\n```elisp\n(require 'package)\n(add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\") t)\n(add-to-list 'package-archives '(\"elpa\" . \"https://elpa.gnu.org/packages/\"))\n(package-initialize)\n(custom-set-variables\n ;; custom-set-variables was added by Custom.\n ;; If you edit it by hand, you could mess it up, so be careful.\n ;; Your init file should contain only one such instance.\n ;; If there is more than one, they won't work right.\n '(inhibit-startup-screen t)\n '(package-selected-packages '(lsp-ui company flycheck lsp-mode ##)))\n(custom-set-faces\n ;; custom-set-faces was added by Custom.\n ;; If you edit it by hand, you could mess it up, so be careful.\n ;; Your init file should contain only one such instance.\n ;; If there is more than one, they won't work right.\n )\n\n(define-derived-mode fuzion-mode\n  fundamental-mode \"Fuzion\"\n  \"Major mode for Fuzion.\")\n\n(add-to-list 'auto-mode-alist '(\"\\\\.fz\\\\'\" . fuzion-mode))\n\n(require 'lsp-mode)\n(global-flycheck-mode)\n(add-to-list 'lsp-language-id-configuration '(fuzion-mode . \"fuzion\"))\n\n(defgroup lsp-fuzionlsp nil\n  \"LSP support for Fuzion, using fuzionlsp.\"\n  :group 'lsp-mode\n  :link '(url-link \"\"))\n\n(lsp-register-client\n (make-lsp-client :new-connection (lsp-stdio-connection  (lambda ()\n                                                          `(,\"fuzion_language_server\"\n                                                            \"-stdio\")))\n                  :major-modes '(fuzion-mode)\n                  :priority -1\n                  :server-id 'fuzionls))\n\n\n(lsp-consistency-check lsp-fuzion)\n\n(add-hook 'fuzion-mode-hook #'lsp)\n(add-hook 'after-init-hook 'global-company-mode)\n\n(setq lsp-enable-symbol-highlighting t)\n\n;; (setq  lsp-enable-semantic-highlighting t\n;;        lsp-semantic-tokens-enable t\n;;        lsp-semantic-tokens-warn-on-missing-face t\n;;        lsp-semantic-tokens-apply-modifiers nil\n;;        lsp-semantic-tokens-allow-delta-requests nil\n;;        lsp-semantic-tokens-allow-ranged-requests nil)\n\n;; (setq lsp-modeline-code-actions-mode t)\n\n;; (setq lsp-modeline-code-actions-segments '(name icon))\n\n;; (setq lsp-log-io t)\n\n(provide 'lsp-fuzion)\n\n(provide 'init)\n;;; init.el ends here\n```\n\n- add following line to ~/.emacs.d/init.el or to ~/.emacs\n\n  (load \"~/.emacs.d/fuzion-lsp.el\")\n\n### Run standalone\n\n#### Transport socket\n- run `./bin/fuzion_language_server -socket --port=3000`\n- connect the client to the (random) port the server prints to stdout.\n\n#### Transport stdio\n- run `./bin/fuzion_language_server -stdio`\n\n\u003c!--\n### Implementation state\n\n|Feature|Status|\n|---|---|\n|diagnostics|☑|\n|completion|☑|\n|hover|☑|\n|signatureHelp|☑|\n|declaration|☐|\n|definition|☑|\n|typeDefinition|☐|\n|implementation|☐|\n|references|☑|\n|documentHighlight|☐|\n|documentSymbol|☑|\n|codeAction|☐|\n|codeLens|☐|\n|documentLink|☐|\n|documentColor|☐|\n|colorPresentation|☐|\n|formatting|☐|\n|rangeFormatting|☐|\n|onTypeFormatting|☐|\n|rename|☑|\n|prepareRename|☑|\n|foldingRange|☐|\n|selectionRange|☐|\n|prepareCallHierarchy|☐|\n|callHierarchy incoming|☐|\n|callHierarchy outgoing|☐|\n|semantic tokens|☑|\n|linkedEditingRange|☐|\n|moniker|☐|\n|inlayHints|☐|\n|inlineValue|☐|\n|type hierarchy|☐|\n|notebook document support|☐| --\u003e\n\n\n[^1]: suggested OpenJDK distributions:\n\n    - [Adoptium](https://github.com/adoptium/temurin25-binaries/releases/) + [jmods](https://api.adoptium.net/v3/binary/latest/25/ga/linux/x64/jmods/hotspot/normal/eclipse?project=jdk), must be unpacked to a `jmods` sub-directory in the openjdk directory.\n    - [Azul](https://www.azul.com/downloads/?version=java-25\u0026package=jdk#zulu)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftokiwa-software%2Ffuzion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftokiwa-software%2Ffuzion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftokiwa-software%2Ffuzion/lists"}