├── .cargo └── config.toml ├── .github ├── dependabot.yml ├── features.ua ├── funding.yml ├── scripts │ └── get-release-notes.js └── workflows │ ├── build_latest.yml │ ├── release.yml │ └── validate.yml ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── Cargo.lock ├── Cargo.toml ├── changelog.md ├── code_of_conduct.md ├── contributing.md ├── examples ├── audio_play.ua ├── audio_stream.ua ├── goldbach.ua ├── http_server.ua ├── life.ua ├── logo_gif.ua ├── markov.ua ├── n-body.ua ├── nqueens.ua ├── photobooth.ua ├── raw.ua ├── shuffle_music.ua ├── spiral.ua └── yahtzee.ua ├── flake.lock ├── flake.nix ├── license ├── nix ├── fonts.nix └── package.nix ├── pad └── editor │ ├── Cargo.toml │ └── src │ ├── backend.rs │ ├── lib.rs │ └── utils.rs ├── parser ├── Cargo.toml └── src │ ├── ast.rs │ ├── complex.rs │ ├── defs.rs │ ├── error.rs │ ├── inputs.rs │ ├── lex.rs │ ├── lib.rs │ ├── parse.rs │ ├── primitive.rs │ ├── signature.rs │ ├── split.rs │ └── subscript.rs ├── readme.md ├── rustfmt.toml ├── site ├── 404.html ├── CNAME ├── Cargo.toml ├── Pixua.ttf ├── assets │ ├── ooh-ee-ooh-ah.mp3 │ ├── rss.svg │ ├── sided-subscripts.png │ ├── uiua-crayon.jpg │ ├── uiua-logo-jacob.svg │ ├── uiua-logo-pride.gif │ ├── uiua-logo-pride.png │ ├── uiua-logo-scrambledine.png │ ├── uiua-logo.gif │ ├── uiua-logo.png │ ├── uiua-logo.svg │ ├── wee-wah.mp3 │ ├── wee-wuh.mp3 │ ├── weewuh-logo.png │ └── you-dont.png ├── blog │ ├── feed.rss │ ├── how-the-uiua-logo-works-text.md │ ├── its-so-over-text.md │ ├── list.txt │ ├── second-class-functions-text.md │ ├── subscripts-text.md │ ├── uiua-0.10.0-text.md │ ├── uiua-0.11.0-text.md │ ├── uiua-0.12.0-text.md │ ├── uiua-0.13.0-text.md │ ├── uiua-0.14.0-text.md │ ├── uiua-0.15.0-text.md │ ├── uiua-0.16.0-text.md │ └── what-will-1-look-like-text.md ├── blog_rss.ua ├── combinators │ ├── B.svg │ ├── B1.svg │ ├── C.svg │ ├── D.svg │ ├── D2.svg │ ├── E.svg │ ├── I.svg │ ├── K.svg │ ├── KI.svg │ ├── N.svg │ ├── R.svg │ ├── S.svg │ ├── W.svg │ ├── X.svg │ ├── Ê.svg │ ├── Δ.svg │ ├── Σ.svg │ ├── Φ.svg │ ├── Φ1.svg │ ├── Ψ.svg │ ├── ε.svg │ ├── ν.svg │ ├── ρ.svg │ └── χ.svg ├── deploy.ua ├── favicon-crayon.ico ├── favicon.ico ├── index.html ├── primitives.json ├── src │ ├── blog.rs │ ├── docs.rs │ ├── examples.rs │ ├── idioms.rs │ ├── main.rs │ ├── markdown.rs │ ├── other.rs │ ├── other_tutorial.rs │ ├── primitive.rs │ ├── tutorial.rs │ └── uiuisms.rs ├── styles.css ├── text │ ├── code_tactility.md │ ├── data_defs.md │ ├── design.md │ ├── experimental.md │ ├── files_and_streams.md │ ├── format_config.md │ ├── ga.md │ ├── idioms.ua │ ├── introduction.md │ ├── inverses.md │ ├── macros.md │ ├── more_array.md │ ├── ranges.md │ ├── strings.md │ ├── tacit_code.md │ ├── testing.md │ └── tour.md └── trunk.toml ├── src ├── algorithm │ ├── Uiua386.ttf │ ├── dyadic │ │ ├── combine.rs │ │ ├── mod.rs │ │ ├── search.rs │ │ └── structure.rs │ ├── encode.rs │ ├── ga.rs │ ├── groups.rs │ ├── loops.rs │ ├── map.rs │ ├── media.rs │ ├── mod.rs │ ├── monadic │ │ ├── mod.rs │ │ └── sort.rs │ ├── path.rs │ ├── pervade.rs │ ├── reduce.rs │ ├── stencil.rs │ ├── table.rs │ ├── tuples.rs │ └── zip.rs ├── array.rs ├── assembly.rs ├── assets │ ├── cats.webp │ ├── cats_depth.png │ ├── elevation.webp │ ├── lena.jpg │ ├── lena_depth.png │ └── uiua-logo-512.png ├── boxed.rs ├── check.rs ├── compile │ ├── algebra.rs │ ├── binding.rs │ ├── data.rs │ ├── invert │ │ ├── mod.rs │ │ ├── un.rs │ │ └── under.rs │ ├── mod.rs │ ├── modifier.rs │ ├── optimize.rs │ └── pre_eval.rs ├── complex.rs ├── constant.rs ├── cowslice.rs ├── error.rs ├── ffi.rs ├── fill.rs ├── format.rs ├── function.rs ├── grid_fmt.rs ├── impl_prim.rs ├── lib.rs ├── lsp.rs ├── main.rs ├── profile.rs ├── run.rs ├── run_prim.rs ├── shape.rs ├── stand.rs ├── sys │ ├── mod.rs │ └── native.rs ├── tree.rs ├── types.rs ├── value.rs └── window.rs ├── tests ├── box.ua ├── data_defs.ua ├── dyadic.ua ├── ga.ua ├── grid.ua ├── loops.ua ├── macros.ua ├── map.ua ├── module.ua ├── monadic.ua ├── optimized.ua ├── signature.ua ├── try.ua ├── under.ua └── units.ua ├── tests_ffi ├── Cargo.toml ├── src │ └── lib.rs └── test.ua ├── tests_special ├── error.ua └── uasm.ua └── todo.md /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = ["--cfg=web_sys_unstable_apis"] 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'cargo' 4 | directory: '/' 5 | schedule: 6 | interval: 'monthly' 7 | -------------------------------------------------------------------------------- /.github/features.ua: -------------------------------------------------------------------------------- 1 | # Test combinations of features 2 | 3 | Command ← {"cargo" "c" "--lib" "--no-default-features"} 4 | Features ← ( 5 | {"audio" "tls"} 6 | ⊂⨬( 7 | {"gif,image,terminal_image,webcam" "lsp,raw_mode"} 8 | | {"audio_encode" "gif" "image" "terminal_image" "lsp" "native_sys" "raw_mode"} 9 | ) ∈:□"all" &args 10 | ) 11 | 12 | &p "Checking with no features" 13 | ⍤⟜≍: 0 &runi Command 14 | 15 | ↘1⋯⇡ⁿ:2⧻. Features 16 | ≡(/$"_,_" ▽ 17 | &p $"Checking with features: _". 18 | ⊂ Command ⊂ □"--features" □ 19 | ⍤⟜≍: 0 &runi 20 | )⊙¤ 21 | -------------------------------------------------------------------------------- /.github/funding.yml: -------------------------------------------------------------------------------- 1 | github: uiua-lang 2 | -------------------------------------------------------------------------------- /.github/scripts/get-release-notes.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | let md = fs.readFileSync("changelog.md", "utf-8") 3 | if (md.includes(`## ${process.argv[2]}`)) { 4 | let notes = md 5 | .replaceAll(process.argv[2], "\0VER\0") 6 | .match(/(?<=^|\n)## \0VER\0 .*?(?=\n## |$)/s)[0] 7 | .replaceAll("\0VER\0", process.argv[2]) 8 | .trim() 9 | console.log(notes) 10 | } else { 11 | console.log("You can find the working changelog [here](https://www.uiua.org/docs/changelog).") 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/build_latest.yml: -------------------------------------------------------------------------------- 1 | name: Build Latest 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | paths: 7 | - "Cargo.toml" 8 | - "Cargo.lock" 9 | - "src/**" 10 | - "parser/**" 11 | - "site/**" 12 | - "pad/**" 13 | - "tests*/**" 14 | - "changelog.md" 15 | - "readme.md" 16 | - ".github/workflows/build_latest.yml" 17 | 18 | env: 19 | CARGO_TERM_COLOR: always 20 | 21 | permissions: 22 | contents: write 23 | 24 | concurrency: 25 | group: ${{ github.workflow }}-${{ github.ref }} 26 | cancel-in-progress: true 27 | 28 | jobs: 29 | # Test the interpreter 30 | test_bin: 31 | runs-on: ubuntu-latest 32 | steps: 33 | - uses: actions/checkout@v4 34 | - uses: actions/cache@v4 35 | with: 36 | path: target 37 | key: build-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} 38 | restore-keys: | 39 | build-${{ runner.os }}- 40 | - name: Run interpreter tests 41 | run: cargo test --lib 42 | # Test the site 43 | test_site: 44 | runs-on: ubuntu-latest 45 | steps: 46 | - uses: actions/checkout@v4 47 | - uses: actions/cache@v4 48 | with: 49 | path: target 50 | key: build-${{ runner.os }}-${{ hashFiles('Cargo.lock') }} 51 | restore-keys: | 52 | build-${{ runner.os }}- 53 | - name: Run site tests 54 | run: cargo test -p site 55 | # Build the site 56 | build_site: 57 | needs: test_site 58 | runs-on: ubuntu-latest 59 | steps: 60 | - uses: actions/checkout@v4 61 | with: 62 | fetch-depth: 0 63 | ref: main 64 | - uses: actions/cache@v4 65 | with: 66 | path: target 67 | key: build-${{ runner.os }}-${{ hashFiles('Cargo.lock', '.github/workflows/build_latest.yml') }} 68 | restore-keys: | 69 | build-${{ runner.os }}- 70 | - name: Authenticate git 71 | run: | 72 | git config user.name "github-actions[bot]" 73 | git config user.email "github-actions[bot]@users.noreply.github.com" 74 | git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git 75 | - name: Fetch site branch 76 | run: git fetch origin site:site 77 | - name: Install dependencies 78 | run: | 79 | rustup target add wasm32-unknown-unknown 80 | cargo install trunk --locked --root target 81 | - name: Build site 82 | run: | 83 | git checkout site 84 | git branch --set-upstream-to=origin/site 85 | git reset --hard origin/site 86 | git rebase main || { echo "Rebase failed, aborting."; git rebase --abort; exit 1; } 87 | cd site 88 | cargo test -p site gen_blog_html 89 | ../target/bin/trunk build --release -d ../docs 90 | git add --all 91 | git commit --amend --no-edit 92 | git push --force 93 | git checkout main 94 | # Create the release without assets 95 | create_release: 96 | name: Create release 97 | needs: [test_bin, build_site] 98 | runs-on: ubuntu-latest 99 | env: 100 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 101 | steps: 102 | - uses: actions/checkout@v4 103 | - name: Delete old release 104 | run: gh release delete latest --yes --cleanup-tag || true 105 | - name: Prepare release notes 106 | run: echo "This release contains binaries for the latest \`main\` branch." >> release_notes.md 107 | - name: Create release 108 | uses: softprops/action-gh-release@v1 109 | with: 110 | tag_name: latest 111 | name: Latest Build 112 | body_path: ./release_notes.md 113 | prerelease: true 114 | # Create the binaries and upload them as release assets 115 | create_binaries: 116 | name: Create binary 117 | needs: [test_bin, create_release] 118 | runs-on: ${{ matrix.os }} 119 | env: 120 | BINARY_EXT: ${{ matrix.os == 'windows-latest' && '.exe' || '' }} 121 | strategy: 122 | fail-fast: false 123 | matrix: 124 | include: 125 | - { os: macos-latest, target: x86_64-apple-darwin, features: "audio,window" } 126 | - { os: macos-latest, target: aarch64-apple-darwin, features: "audio,window" } 127 | - { os: ubuntu-latest, target: x86_64-unknown-linux-gnu, features: "full" } 128 | - { os: ubuntu-latest, target: x86_64-unknown-linux-gnu, features: "window", name: "-no-audio" } 129 | - { os: windows-latest, target: x86_64-pc-windows-msvc, features: "full" } 130 | - { os: windows-latest, target: aarch64-pc-windows-msvc, features: "audio,window" } 131 | steps: 132 | - uses: actions/checkout@v4 133 | 134 | # Install dependencies 135 | - if: matrix.target == 'x86_64-unknown-linux-musl' 136 | run: sudo apt-get install -y musl-tools 137 | - if: matrix.os == 'ubuntu-latest' 138 | run: sudo apt-get install -y libasound2-dev libudev-dev libx11-dev libjpeg-dev libclang-dev 139 | 140 | # Build 141 | - name: Install target 142 | run: rustup target add ${{matrix.target}} 143 | - name: Build 144 | run: cargo build --bin uiua --features ${{matrix.features}} --release --target ${{matrix.target}} --verbose 145 | 146 | - name: Zip 147 | run: 7z a -tzip uiua-bin-${{matrix.target}}${{matrix.name}}.zip ./target/${{matrix.target}}/release/uiua${{env.BINARY_EXT}} 148 | 149 | - name: Upload release assets 150 | uses: softprops/action-gh-release@v1 151 | with: 152 | tag_name: latest 153 | files: | 154 | uiua-bin-${{matrix.target}}${{matrix.name}}.zip 155 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | permissions: 3 | contents: write 4 | 5 | on: 6 | push: 7 | tags: 8 | - '[0-9]+.[0-9]+.[0-9]+' 9 | - '[0-9]+.[0-9]+.[0-9]+-dev.[0-9]+' 10 | - '[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+' 11 | 12 | env: 13 | CARGO_TERM_COLOR: always 14 | 15 | jobs: 16 | # Create the release without assets 17 | create_release: 18 | name: Create release 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | - name: Ensure tag matches cargo version 23 | run: | 24 | CARGO_PKG_VERSION=$(cargo pkgid | cut -d# -f2) 25 | if [ "${{ github.ref_name }}" != "$CARGO_PKG_VERSION" ]; then 26 | echo "Tag ${{ github.ref_name }} does not match cargo version $CARGO_PKG_VERSION" 27 | exit 1 28 | fi 29 | - name: Prepare release notes 30 | run: node .github/scripts/get-release-notes.js ${{ github.ref_name }} >> release_notes.md 31 | - name: Create release 32 | uses: softprops/action-gh-release@v1 33 | with: 34 | body_path: ./release_notes.md 35 | prerelease: ${{ contains(github.ref_name, 'dev') || contains(github.ref_name, 'rc') }} 36 | 37 | # Create the binaries and upload them as release assets 38 | create_binaries: 39 | name: Create binary 40 | needs: create_release 41 | runs-on: ${{ matrix.os }} 42 | env: 43 | BINARY_EXT: ${{ matrix.os == 'windows-latest' && '.exe' || '' }} 44 | strategy: 45 | fail-fast: false 46 | matrix: 47 | include: 48 | - { os: macos-latest, target: x86_64-apple-darwin, features: "audio,window" } 49 | - { os: macos-latest, target: aarch64-apple-darwin, features: "audio,window" } 50 | - { os: ubuntu-latest, target: x86_64-unknown-linux-gnu, features: "full" } 51 | - { os: ubuntu-latest, target: x86_64-unknown-linux-gnu, features: "window", name: "-no-audio" } 52 | - { os: windows-latest, target: x86_64-pc-windows-msvc, features: "full" } 53 | - { os: windows-latest, target: aarch64-pc-windows-msvc, features: "audio,window" } 54 | steps: 55 | - uses: actions/checkout@v4 56 | 57 | # Install dependencies 58 | - if: matrix.target == 'x86_64-unknown-linux-musl' 59 | run: sudo apt-get install -y musl-tools 60 | - if: matrix.os == 'ubuntu-latest' 61 | run: sudo apt-get install -y libasound2-dev libudev-dev libx11-dev libjpeg-dev libclang-dev 62 | 63 | # Build 64 | - name: Install target 65 | run: rustup target add ${{matrix.target}} 66 | - name: Build 67 | run: cargo build --bin uiua --features ${{matrix.features}} --release --target ${{matrix.target}} --verbose 68 | 69 | - name: Zip 70 | run: 7z a -tzip uiua-bin-${{matrix.target}}${{matrix.name}}.zip ./target/${{matrix.target}}/release/uiua${{env.BINARY_EXT}} 71 | 72 | - name: Upload release assets 73 | uses: softprops/action-gh-release@v1 74 | with: 75 | files: | 76 | uiua-bin-${{matrix.target}}${{matrix.name}}.zip 77 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: Validate 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | paths: 7 | - "Cargo.toml" 8 | - "Cargo.lock" 9 | - "src/**" 10 | - "parser/**" 11 | - "site/**" 12 | - "pad/**" 13 | - "tests*/**" 14 | - "changelog.md" 15 | - "readme.md" 16 | pull_request: 17 | branches: ["main"] 18 | paths: 19 | - "Cargo.toml" 20 | - "Cargo.lock" 21 | - "src/**" 22 | - "parser/**" 23 | - "site/**" 24 | - "pad/**" 25 | - "tests*/**" 26 | - "changelog.md" 27 | - "readme.md" 28 | 29 | env: 30 | CARGO_TERM_COLOR: always 31 | 32 | concurrency: 33 | group: ${{ github.workflow }}-${{ github.ref }} 34 | cancel-in-progress: true 35 | 36 | jobs: 37 | build: 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@v4 41 | - name: Check formatting 42 | run: cargo fmt --all --check 43 | - name: Install deps 44 | run: sudo apt-get install libasound2-dev libudev-dev pkg-config libx11-dev libjpeg-dev 45 | - name: Install WASM target 46 | run: rustup target add wasm32-unknown-unknown 47 | - name: Check feature combinations 48 | run: cargo run ./.github/features.ua 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | /target 4 | /docs 5 | /site/blog/*.html 6 | site/dist 7 | /uiua-modules 8 | 9 | *.wav 10 | *.png 11 | *.jpg 12 | *.txt 13 | *.db 14 | !*/assets/* 15 | !src/primitive/assets/* 16 | 17 | *.ua 18 | *.uasm 19 | *.dll 20 | profile.yaml 21 | uiua.tmLanguage.json 22 | !/tests*/* 23 | !/examples/* 24 | !/site/*.ua 25 | !/site/text/*.ua 26 | 27 | # symlink created by `nix build` 28 | result 29 | .direnv -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch (Linux or macOS)", 6 | "type": "lldb", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/target/debug/uiua", 9 | "args": [ 10 | "run", 11 | "main.ua" 12 | ], 13 | "cwd": "${workspaceRoot}", 14 | }, 15 | { 16 | "name": "Launch (Windows)", 17 | "type": "cppvsdbg", 18 | "request": "launch", 19 | "program": "${workspaceRoot}/target/debug/uiua.exe", 20 | "args": [ 21 | "run", 22 | "main.ua" 23 | ], 24 | "stopAtEntry": false, 25 | "cwd": "${workspaceRoot}", 26 | "environment": [], 27 | "externalConsole": true 28 | }, 29 | ] 30 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.cargo.extraEnv": { 3 | "RUSTFLAGS": "--cfg=web_sys_unstable_apis" 4 | }, 5 | "rust-analyzer.cargo.features": [ 6 | "audio" 7 | ], 8 | "rust-analyzer.check.features": [ 9 | "audio" 10 | ], 11 | "rust-analyzer.showUnlinkedFileNotification": false, 12 | "cSpell.enableFiletypes": [ 13 | "!rust", 14 | "markdown" 15 | ], 16 | "cSpell.enabled": true, 17 | "cSpell.words": [ 18 | "Uiua" 19 | ], 20 | "spellright.language": [ 21 | "en" 22 | ], 23 | "spellright.documentTypes": [ 24 | "latex" 25 | ] 26 | } -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | categories = ["compilers", "algorithms", "multimedia", "parser-implementations"] 3 | description = "A stack-based array programming language" 4 | documentation = "https://docs.rs/uiua" 5 | edition = "2021" 6 | keywords = ["uiua", "array", "stack", "language", "apl"] 7 | license = "MIT" 8 | name = "uiua" 9 | readme = "readme.md" 10 | repository = "https://github.com/uiua-lang/uiua" 11 | rust-version = "1.82.0" 12 | version = "0.17.0-dev.1" 13 | 14 | [dependencies] 15 | # Uiua dependencies 16 | uiua_parser = {path = "parser"} 17 | 18 | # Core dependencies 19 | bitflags = {version = "2", features = ["serde"]} 20 | bytemuck = {version = "1.17", features = ["must_cast", "derive", "extern_crate_alloc"]} 21 | colored = "2" 22 | crossbeam-channel = "0.5.12" 23 | dashmap = {version = "5", features = ["serde"]} 24 | ecow = {version = "0.2.3", features = ["serde"]} 25 | enum-iterator = "2.1.0" 26 | indexmap = {version = "2", features = ["serde"]} 27 | num_cpus = "1.16.0" 28 | once_cell = "1" 29 | parking_lot = "0.12.1" 30 | paste = "1.0.14" 31 | pathdiff = "0.2.1" 32 | rand = {version = "0.8.5", features = ["small_rng"]} 33 | rayon = "1.9.0" 34 | regex = "1.10.3" 35 | serde = {version = "1", features = ["derive", "rc"]} 36 | serde_json = "1" 37 | serde_tuple = "0.5.0" 38 | smallvec = {version = "1.9", features = ["serde", "union", "const_new"]} 39 | thread_local = "1" 40 | threadpool = "1.8.1" 41 | time = {version = "0.3.36", features = ["local-offset"]} 42 | unicode-segmentation = "1.10" 43 | 44 | # Native dependencies 45 | httparse = {version = "1.8.0", optional = true} 46 | open = {version = "5", optional = true} 47 | rawrrr = {version = "0.2.1", optional = true} 48 | rustls = {version = "0.23.2", optional = true, default-features = false, features = [ 49 | "std", 50 | "tls12", 51 | "ring", 52 | ]} 53 | terminal_size = {version = "0.3.0", optional = true} 54 | trash = {version = "4.0.0", optional = true} 55 | viuer = {version = "0.9", optional = true} 56 | webpki-roots = {version = "0.26.0", optional = true} 57 | 58 | # Native audio dependencies 59 | hodaun = {version = "0.4.1", optional = true, features = ["output", "wav"]} 60 | lockfree = {version = "0.5.1", optional = true} 61 | 62 | # Binary dependencies 63 | clap = {version = "4", optional = true, features = ["derive"]} 64 | color-backtrace = {version = "0.6.1", optional = true} 65 | ctrlc = {version = "=3.4.4", optional = true} 66 | icy_sixel = {version = "0.1.2", optional = true} 67 | notify = {version = "6", optional = true} 68 | rustyline = {version = "14.0.0", optional = true} 69 | terminal-light = {version = "1.4.0", optional = true} 70 | tokio = {version = "1", optional = true, features = ["io-std", "rt"]} 71 | tower-lsp = {version = "0.20.0", optional = true, features = ["proposed"]} 72 | 73 | # Profiling dependencies 74 | serde_yaml = {version = "0.9.33", optional = true} 75 | 76 | # Feature dependencies 77 | arboard = {version = "3", optional = true} 78 | calamine = {version = "0.26.1", optional = true} 79 | color_quant = {version = "1.1", optional = true} 80 | cosmic-text = {version = "0.12.1", optional = true} 81 | csv = {version = "1", optional = true} 82 | gif = {version = "0.13.1", optional = true} 83 | hound = {version = "3", optional = true} 84 | image = {version = "0.25", optional = true, default-features = false, features = ["bmp", "gif", "ico", "jpeg", "png", "qoi", "webp"]} 85 | json5 = {version = "0.4.1", optional = true} 86 | libffi = {version = "4", optional = true} 87 | libloading = {version = "0.8.3", optional = true} 88 | nokhwa = {version = "0.10.7", optional = true, features = ["input-native"]} 89 | num-complex = {version = ">=0.4.1", optional = true, default-features = false, features = ["bytemuck"]} 90 | plist = {version = "1.7.1", optional = true} 91 | png = {version = "0.17.16", optional = true} 92 | rustfft = {version = "6.2.0", optional = true} 93 | rustls-pemfile = {version = "2.1.2", optional = true} 94 | simple_excel_writer = {version = "0.2.0", optional = true} 95 | skrifa = {version = "0.20.0", optional = true} 96 | sys-locale = {version = "0.3.1", optional = true} 97 | 98 | # Web-only dependencies 99 | js-sys = {version = "0.3", optional = true} 100 | wasm-bindgen = {version = "0.2.92", optional = true} 101 | web-sys = {version = "0.3.60", optional = true} 102 | 103 | # Window dependencies 104 | eframe = {version = "0.29.1", optional = true, features = ["persistence"]} 105 | native-dialog = {version = "0.7.0", optional = true} 106 | rmp-serde = {version = "1.3.0", optional = true} 107 | 108 | [features] 109 | apng = ["dep:png"] 110 | audio = ["hodaun", "lockfree", "audio_encode"] 111 | audio_encode = ["hound"] 112 | batteries = [ 113 | "gif", 114 | "apng", 115 | "image", 116 | "audio_encode", 117 | "csv", 118 | "xlsx", 119 | "json5", 120 | "fft", 121 | "font_shaping", 122 | ] 123 | binary = [ 124 | "ctrlc", 125 | "notify", 126 | "clap", 127 | "color-backtrace", 128 | "rustyline", 129 | "native_sys", 130 | "ffi", 131 | "terminal-light", 132 | "terminal_size", 133 | ] 134 | bytes = [] # No longer used 135 | clipboard = ["arboard"] 136 | debug = [] 137 | default = [ 138 | # "window", # Comment in for dev 139 | "binary", 140 | "terminal_image", 141 | "lsp", 142 | "stand", 143 | "tls", 144 | "invoke", 145 | "trash", 146 | "native_sys", 147 | "raw_mode", 148 | "clipboard", 149 | "opt", 150 | "batteries", 151 | ] 152 | ffi = ["libffi", "libloading"] 153 | fft = ["rustfft", "num-complex"] 154 | font_shaping = ["cosmic-text", "sys-locale", "skrifa"] 155 | full = ["audio", "webcam", "window"] # Enables all optional features 156 | gif = ["dep:gif", "image", "color_quant"] 157 | invoke = ["open"] 158 | lsp = ["tower-lsp", "tokio", "native_sys"] 159 | native_sys = [] 160 | opt = [] # Enables some optimizations but increases binary size 161 | profile = ["serde_yaml"] 162 | raw_mode = ["rawrrr", "native_sys"] 163 | stand = ["native_sys"] 164 | terminal_image = ["viuer", "image", "icy_sixel"] 165 | tls = ["httparse", "rustls", "webpki-roots", "rustls-pemfile"] 166 | web = ["wasm-bindgen", "js-sys", "web-sys"] 167 | webcam = ["image", "nokhwa"] 168 | window = ["eframe", "rmp-serde", "image", "native-dialog"] 169 | xlsx = ["calamine", "simple_excel_writer", "plist"] 170 | # Use system static libraries instead of building them 171 | system = ["libffi?/system"] 172 | 173 | [[bin]] 174 | name = "uiua" 175 | 176 | [workspace] 177 | members = ["site", "tests_ffi", "pad/editor", "parser"] 178 | 179 | [profile.dev] 180 | incremental = true 181 | -------------------------------------------------------------------------------- /code_of_conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | kaikaliischmidt@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are welcome! Here's how you can help: 4 | 5 | - Even if you don't know Rust (which the interpreter is written in) you can contribute by writing tests in Uiua! See the existing tests [`here`](https://github.com/uiua-lang/uiua/tree/main/tests). 6 | - If you find a bug, please [create an issue](https://github.com/uiua-lang/uiua/issues/new) describing the bug and how to reproduce it. 7 | - If you can fix a bug, please [fork the repository](https://github.com/uiua-lang/uiua/fork) and [create a pull request](https://github.com/uiua-lang/uiua/compare). 8 | - For more complex changes, you can [create an issue](https://github.com/uiua-lang/uiua/issues/new) to discuss your idea first. 9 | - For general discussion about the language including questions and ideas, see the [Discussions](https://github.com/uiua-lang/uiua/discussions) page. 10 | -------------------------------------------------------------------------------- /examples/audio_play.ua: -------------------------------------------------------------------------------- 1 | F ← ÷⧻⤙(≡/+ ∿×τ ⊞×) 2 | [[0 4 7 11] [¯1 2 5 9] [¯1 3 6 10]] 3 | ⊏ [0 0 0 0 1 1 1 2] 4 | ×220 ˜ⁿ2÷12 5 | ⊂./⊂≡⌞(×∿×τ⟜F) ÷⟜⇡&asr 6 | &ap 7 | -------------------------------------------------------------------------------- /examples/audio_stream.ua: -------------------------------------------------------------------------------- 1 | # A basic example of using the `&ast` system function to synthesize audio 2 | &ast( 3 | ⊃(⊸(×2+1⌊◿2)×1.5 # Modulation frequency 4 | | ±∿×π×110 # Square wave 5 | ) 6 | ×0.2∿×π×× # Apply modulation 7 | ) 8 | -------------------------------------------------------------------------------- /examples/goldbach.ua: -------------------------------------------------------------------------------- 1 | # Calculate the primes that add up to the first n even numbers 2 | 3 | Primes ← ▽⊸=⊣⊸°/×↘1⇡₁ 4 | Goldbach ← ≡(⊂⟜(⊏⤚(⊢⊚=(⊞+.))⊸Primes))×2⇡₂ 5 | Goldbach 10 6 | -------------------------------------------------------------------------------- /examples/http_server.ua: -------------------------------------------------------------------------------- 1 | # A simple, parallel HTTP server good enough to serve Uiua's website 2 | # 3 | # To do that, compile the site with trunk: 4 | # ``` 5 | # cd site 6 | # trunk build --release 7 | # cd .. 8 | # ``` 9 | # Then run: 10 | # ``` 11 | # uiua run examples/http_server.ua 12 | # ``` 13 | 14 | # Bind TCP listener 15 | Listener ← &tcpl "0.0.0.0:8080" 16 | &p $ Server started 17 | 18 | # Mime types 19 | GetExt ← °□⊣ ⊜□ ≠@. . 20 | °⊟⍉[ 21 | {"js" "text/javascript"} 22 | {"wasm" "application/wasm"} 23 | ] 24 | ExtMimeExt ← 25 | ExtMimeMime ← 26 | ExtMime ← °□⊏:⊂ExtMimeMime □⊂"text/": ⊗:ExtMimeExt□. 27 | 28 | # ? Status Mime Bytes 29 | Response ← ( 30 | ⊙⊙(⧻.) 31 | $$ HTTP/1.1 _ 32 | $$ Content-Type: _ 33 | $$ Content-Length: _ 34 | $$ 35 | $$ 36 | ⊂ utf₈ 37 | ) 38 | 39 | # Handlers 40 | NotFound ← Response "404 Not Found" "text/plain" utf₈"Not Found" 41 | ServerError ← Response "500 Internal Server Error" "text/plain" 42 | PageLoadError ← ⋅( 43 | /↥⌕"The system cannot find the file specified". 44 | ⨬(NotFound◌|ServerError) 45 | ) 46 | Page ← ⍣( 47 | ExtMime GetExt ⟜&frab 48 | Response "200 OK" 49 | )PageLoadError ⊂"docs" 50 | Home ← (Page "/index.html") 51 | 52 | Respond ← ◌pool( 53 | &p $"Request from _" &tcpaddr. 54 | # Extract path from request 55 | °□⊡1 ⊜□≠@ . &ru "\r\n\r\n". 56 | &p $"Request:\n_". 57 | 58 | # Route to handler 59 | ⨬(Page|Home) ⊸≍"/" 60 | &p⊸($"Response: _ bytes" ⧻) 61 | 62 | # Send response 63 | ⊃⋅&cl&w 64 | ) 65 | 66 | ⍢(⍣Respond⋅&p &tcpa Listener)1 67 | -------------------------------------------------------------------------------- /examples/life.ua: -------------------------------------------------------------------------------- 1 | Life ← ↥∩=₃⟜+⊸(/+↻⊂A₂C₂) 2 | ⁅×0.6gen⊙⚂ ⁅×2_0.5 &ts 3 | ⍢(&sl0.2⊸&imsLife)1 4 | -------------------------------------------------------------------------------- /examples/logo_gif.ua: -------------------------------------------------------------------------------- 1 | U ← /=⊞<0.2_0.7 /+×⟜ⁿ1_2 2 | I ← <⊙(⌵/ℂ) # Circle 3 | u ← +0.1↧¤ ⊃(I0.95|⊂⊙0.5⇌°√) 4 | A ← ×⊃U(I1) # Alpha 5 | Coords ← ⊞⊟.-1×2÷⟜⇡ 6 | Logo ← ⍜°⍉(⊂⊃u A) Coords 7 | Flag ← ▽⊃˜(÷⧻)≡↯ 8 | CFlag ← ⍜∩°⍉(↧¤I0.95)Coords ⟜Flag 9 | 10 | 512 # Size 11 | ⊃(≡◇CFlag⊙PrideFlags|⊣⊸°⍉Logo) 12 | ≡⍜°⍉⊂⊙¤ # Apply logo alpha to flags 13 | +∩×≡(⊙:¬.)⊸⊙⊙¤ 0.3 # Tint flags with logo 14 | +♭₄[..0.05 0] # Lighten 15 | ˜⊂ # Add logo 16 | &gifs 1 17 | -------------------------------------------------------------------------------- /examples/markov.ua: -------------------------------------------------------------------------------- 1 | # A Markov chain is a model that assigns a 2 | # probability to each token that comes after 3 | # the previous token. 4 | # It can be used to generate patterns that 5 | # look a bit like the source text. 6 | 7 | # Try running it a few times! 8 | 9 | # Build the Markov chain 10 | # Chain ? TokenLen Input 11 | Build ← ( 12 | ⬚@\0⊃(↘-1⟜⧈∘|↻) ⊙(⊂⊙@\n⊂@\n) 13 | ∧(⍜(°□⬚""get)⊂ ⊙˜⊙∘)⊙⊙[] 14 | ) 15 | Initial ↚ ⊏⌊×⚂⧻. ▽⊸(≡⊢=@\n)⊙◌°map 16 | Next ↚ ( 17 | ⊏⊸(⌊×⚂⧻) °□get # Next char 18 | ⍥↘₁⊸(↥⊃(×⁅÷2⚂=@\n|=@\0)) # End condition 19 | ) 20 | # Generate some text from a Markov chain 21 | # ? Init TokenSize Chain 22 | GenFrom ← ( 23 | ⊙˜⊙∘ (⨬⋅⊸Initial∘±⊸⧻) ⊙˜⊙∘ 24 | ↘¯1↘1⊙⋅◌⍥⊃(⊂⟜(Next˜↙⊙¯))⋅⊙∘∞ 25 | ) 26 | 27 | $ Hello there! 28 | $ How are you doing today? 29 | $ I am fine, thank you. 30 | $ That is good to hear. 31 | $ Nice weather we're having today isn't it? 32 | $ Yes, it's been very mild. 33 | &p GenFrom "" ⟜Build 2 34 | -------------------------------------------------------------------------------- /examples/n-body.ua: -------------------------------------------------------------------------------- 1 | G ← 2e4 2 | Dt ← 0.01 3 | Steps ← 120 4 | 5 | Step ← ( 6 | ⊞≠.°⊏ # Make comparison matrix 7 | ⊃(≡▽⊙¤)⋅∘ # Make others 8 | ⊃≡(-¤)∘˜⊙∘ # Get diffs 9 | ÷⊸⍜♭₂(≡/+×.) # Inverse square 10 | ≡/+×G # Get accs 11 | ⊃(+⊙⋅∘|⋅∘)×Dt # apply accs 12 | ⊃(+×Dt)∘ # Apply vels 13 | ) 14 | 15 | [0_60 150_0 30_15 80_110] 16 | ⟜(↯⊙0⊂⊙2⧻) # Init vels 17 | 18 | ⁅×0.5 ⍥⤚Step Steps # Run 19 | ⍜⊙♭₂-¤/↧⊸♭₂ # Normalize 20 | ⬚0≡°⊚ # Plot 21 | ≡⌞⧈(/↥♭)3_3 # Upscale 22 | 23 | &fwa "n-body.gif" gif 16 24 | &p "Wrote gif to n-body.gif" 25 | -------------------------------------------------------------------------------- /examples/nqueens.ua: -------------------------------------------------------------------------------- 1 | Orth ← /↥= 2 | Diag ← /=⌵- 3 | Conflict ← ↥⊃Orth Diag 4 | Permute ← ≡⌟∧⍜↘(↻¯1)⊸(♭₂⇡+1⇡⧻) 5 | NQueens ← ( 6 | ≡⌞(⍉⊟)⟜Permute⇡ 7 | ⊡⊢⊚¬⊸≡(/↥♭⊞(×⊃(¬≍)Conflict).) 8 | ) 9 | ⊸°⊚ NQueens 6 10 | -------------------------------------------------------------------------------- /examples/photobooth.ua: -------------------------------------------------------------------------------- 1 | # This example uses your webcam to take a photo, 2 | # then runs it through some effects and displays it. 3 | 4 | # Pixelate an image with the given ratio 5 | # ? Ratio Image 6 | Pixelate ← ◌⍥(÷⊙1⟜▽⟜≡▽)2 ÷⊙1 7 | 8 | # Run an edge-detection algorithm on an image. 9 | # Uses a 5x5 kernel. 10 | # ? Image 11 | Edges ← ( 12 | ÷⧻⟜/+°⍉ 13 | /+/+ ×⊏[2 1 0 1 2] [1_1_¯12_1_1 0_1_1_1_0 0_0_1_0_0] ⍉⍉ ⧈∘⊟.5 14 | ↥0↧1 15 | ¬⍥((⊂0⊂⊙0)≡(⊂0⊂⊙0))2 16 | ) 17 | 18 | # Show an image in the default program 19 | # ? Image 20 | Show ← &invk⟜&fwa $"img._" ⟜img "jpg" 21 | 22 | Show ×⊃(Pixelate32|⍜¬(×0.7)Edges) &camcap 0 23 | -------------------------------------------------------------------------------- /examples/raw.ua: -------------------------------------------------------------------------------- 1 | # Simple use of `&raw` to move a dot around an image 2 | &raw1 3 | Dirs ← [0_1 0_¯1 ¯1_0 1_0 0_0] 4 | Keys ← "wsad" 5 | Size ← ⊟.⊢&ts 6 | ◌◌⍢( 7 | ⊏⊙Dirs⬚4⊢⊚=Keys # Select input dir 8 | ↧-1Size↥⊚2+ # Move 9 | ) (&ims⇌⍉⍜⊡+₁⟜⊸(↯Size0) # Render 10 | ⊸≠@\x03⊢&rs1 0 # Get input 11 | ) [0 0] 12 | -------------------------------------------------------------------------------- /examples/shuffle_music.ua: -------------------------------------------------------------------------------- 1 | # Shuffle the `Music` constant to generate random permutations 2 | &ast( 3 | Music 4 | ♭↯2 5 | ▽1.2 6 | ⍜(⤸1 ≡(↘1⧈∘¤¤¯4) ⧈∘¤¤¯64)≡°⍆ 7 | ÷⟜⧈/+5 8 | ) 9 | -------------------------------------------------------------------------------- /examples/spiral.ua: -------------------------------------------------------------------------------- 1 | # Creates a number spiral that is common in code golf problems 2 | F ← ⌝⊡⊃( 3 | ⟜(↘¯1 ▽⊃(▽2+1⇡|◿4⇡+⊸-1) # Orientations 4 | ⊏⊙A₂ # Directions 5 | ⊂0\+ # Offsets 6 | ) 7 | +¤⌊÷2⊟. # Indices 8 | | +1⇡×. # Numbers 9 | ) 10 | 11 | F 3 12 | F 5 13 | F 7 14 | -------------------------------------------------------------------------------- /examples/yahtzee.ua: -------------------------------------------------------------------------------- 1 | ⍢(|/↥⧈≠ ⟜&p ⍥₅⚂₆) 2 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "crane": { 4 | "locked": { 5 | "lastModified": 1727235847, 6 | "narHash": "sha256-MoEot8izwkfGm1h5ak8hS2bu59mLmKeevlP/OvFLCzM=", 7 | "owner": "ipetkov", 8 | "repo": "crane", 9 | "rev": "08f45b5a2e01cf34ca6081188c6d16aa35581b09", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "ipetkov", 14 | "repo": "crane", 15 | "type": "github" 16 | } 17 | }, 18 | "flake-parts": { 19 | "inputs": { 20 | "nixpkgs-lib": [ 21 | "nixpkgs" 22 | ] 23 | }, 24 | "locked": { 25 | "lastModified": 1727826117, 26 | "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", 27 | "owner": "hercules-ci", 28 | "repo": "flake-parts", 29 | "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", 30 | "type": "github" 31 | }, 32 | "original": { 33 | "owner": "hercules-ci", 34 | "repo": "flake-parts", 35 | "type": "github" 36 | } 37 | }, 38 | "nixpkgs": { 39 | "locked": { 40 | "lastModified": 1741246872, 41 | "narHash": "sha256-Q6pMP4a9ed636qilcYX8XUguvKl/0/LGXhHcRI91p0U=", 42 | "owner": "NixOS", 43 | "repo": "nixpkgs", 44 | "rev": "10069ef4cf863633f57238f179a0297de84bd8d3", 45 | "type": "github" 46 | }, 47 | "original": { 48 | "owner": "NixOS", 49 | "ref": "nixos-unstable", 50 | "repo": "nixpkgs", 51 | "type": "github" 52 | } 53 | }, 54 | "root": { 55 | "inputs": { 56 | "crane": "crane", 57 | "flake-parts": "flake-parts", 58 | "nixpkgs": "nixpkgs" 59 | } 60 | } 61 | }, 62 | "root": "root", 63 | "version": 7 64 | } 65 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A stack-based array programming language"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 | flake-parts = { 7 | url = "github:hercules-ci/flake-parts"; 8 | inputs.nixpkgs-lib.follows = "nixpkgs"; 9 | }; 10 | crane.url = "github:ipetkov/crane"; 11 | }; 12 | outputs = 13 | { 14 | nixpkgs, 15 | flake-parts, 16 | crane, 17 | ... 18 | }@inputs: 19 | flake-parts.lib.mkFlake { inherit inputs; } { 20 | systems = nixpkgs.lib.platforms.all; 21 | perSystem = 22 | { 23 | self', 24 | pkgs, 25 | ... 26 | }: 27 | let 28 | craneLib = crane.mkLib pkgs; 29 | libPath = with pkgs; lib.makeLibraryPath [ 30 | libGL 31 | libxkbcommon 32 | wayland 33 | xorg.libX11 34 | xorg.libXcursor 35 | xorg.libXi 36 | xorg.libXrandr 37 | ]; 38 | in 39 | { 40 | packages.default = pkgs.callPackage ./nix/package.nix { inherit craneLib libPath; }; 41 | packages.fonts = pkgs.callPackage ./nix/fonts.nix {}; 42 | devShells.default = pkgs.mkShell { 43 | inputsFrom = builtins.attrValues self'.packages; 44 | packages = with pkgs; [ 45 | lld_18 46 | trunk 47 | clippy 48 | rust-analyzer 49 | rustfmt 50 | cargo 51 | rustc 52 | libffi 53 | ]; 54 | LD_LIBRARY_PATH = libPath; 55 | }; 56 | }; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Kaikalii 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /nix/fonts.nix: -------------------------------------------------------------------------------- 1 | { 2 | lib, 3 | runCommandLocal, 4 | }: 5 | runCommandLocal "uiua-fonts" 6 | { 7 | src = lib.fileset.toSource { 8 | root = ../site; 9 | fileset = lib.fileset.fileFilter ({ hasExt, ... }: hasExt "ttf") ../site; 10 | }; 11 | uiua386 = ../src/algorithm/Uiua386.ttf; 12 | } 13 | '' 14 | mkdir -p "$out/share/fonts/truetype" 15 | cp "$src"/* "$out/share/fonts/truetype/" 16 | cp "$uiua386" "$out/share/fonts/truetype/Uiua386.ttf" 17 | '' 18 | -------------------------------------------------------------------------------- /nix/package.nix: -------------------------------------------------------------------------------- 1 | { 2 | craneLib, 3 | libPath, 4 | makeBinaryWrapper, 5 | stdenv, 6 | lib, 7 | pkg-config, 8 | libffi, 9 | libiconv, 10 | alsa-lib, 11 | darwin, 12 | rustPlatform, 13 | doCheck ? true, 14 | }: 15 | let 16 | commonArgs = { 17 | src = lib.fileset.toSource { 18 | root = ../.; 19 | fileset = lib.fileset.unions ( 20 | [ 21 | (lib.fileset.fromSource (craneLib.cleanCargoSource ../.)) 22 | ../src/assets 23 | ../src/algorithm/Uiua386.ttf 24 | ] 25 | ++ lib.optionals doCheck [ 26 | ../site/favicon.ico 27 | ../tests 28 | ../tests_special 29 | ] 30 | ); 31 | }; 32 | strictDeps = true; 33 | cargoExtraArgs = "--features system,full"; 34 | inherit doCheck; 35 | nativeBuildInputs = [ 36 | pkg-config 37 | rustPlatform.bindgenHook 38 | makeBinaryWrapper 39 | ]; 40 | buildInputs = 41 | [ libffi ] 42 | ++ lib.optionals stdenv.isLinux [ alsa-lib ] 43 | ++ lib.optionals stdenv.isDarwin ( 44 | with darwin.apple_sdk.frameworks; 45 | [ 46 | libiconv 47 | AppKit 48 | Foundation 49 | CoreAudio 50 | CoreMedia 51 | AVFoundation 52 | ] 53 | ); 54 | # https://crane.dev/faq/rebuilds-bindgen.html 55 | env.NIX_OUTPATH_USED_AS_RANDOM_SEED = "uiuarustbg"; 56 | }; 57 | cargoArtifacts = craneLib.buildDepsOnly commonArgs; 58 | totalArgs = commonArgs // { 59 | inherit cargoArtifacts; 60 | cargoTestExtraArgs = "-- --skip format::generate_format_cfg_docs"; 61 | postInstall = '' 62 | wrapProgram "$out/bin/uiua" --prefix LD_LIBRARY_PATH : "${libPath}" 63 | ''; 64 | }; 65 | in 66 | craneLib.buildPackage totalArgs 67 | -------------------------------------------------------------------------------- /pad/editor/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uiua-editor" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | 9 | [dependencies] 10 | leptos = { version = "0.6.10", features = ["csr"] } 11 | js-sys = "0.3.69" 12 | web-sys = { version = "0.3.70", features = [ 13 | "Window", 14 | "CustomElementRegistry", 15 | "CssStyleDeclaration", 16 | "DomRect", 17 | "Storage", 18 | "HtmlAudioElement", 19 | "HtmlBrElement", 20 | "Selection", 21 | "Node", 22 | "Clipboard", 23 | "ClipboardEvent", 24 | "DataTransfer", 25 | "Navigator", 26 | "Permissions", 27 | "ScrollIntoViewOptions", 28 | "ScrollBehavior", 29 | "ScrollLogicalPosition", 30 | "StorageManager", 31 | "FileReader", 32 | "EventInit", 33 | "DataTransfer", 34 | "File", 35 | "FileList", 36 | "ResizeObserver", 37 | "ResizeObserverEntry", 38 | "Performance", 39 | ] } 40 | base64 = "0.22.0" 41 | leptos_router = {version = "0.6.11", features = ["csr"]} 42 | uiua = {path = "../..", default-features = false, features = ["batteries", "web"]} 43 | image = "0.25" 44 | unicode-segmentation = "1.10" 45 | urlencoding = "2" 46 | wasm-bindgen = "0.2.93" 47 | wasm-bindgen-futures = "0.4.43" 48 | hound = "3.5.1" 49 | serde_json = "1.0.115" 50 | futures = "0.3.30" 51 | 52 | # logging 53 | log = "0.4" 54 | wasm-logger = "0.2.0" 55 | console_error_panic_hook = "0.1.5" 56 | -------------------------------------------------------------------------------- /parser/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | categories = ["parser-implementations"] 3 | description = "Uiua parser implementation" 4 | documentation = "https://docs.rs/uiua_parser" 5 | edition = "2021" 6 | keywords = ["uiua", "array", "stack", "language", "apl"] 7 | license = "MIT" 8 | name = "uiua_parser" 9 | repository = "https://github.com/uiua-lang/uiua" 10 | rust-version = "1.82.0" 11 | version = "0.17.0-dev.1" 12 | 13 | [dependencies] 14 | bytemuck = {version = "1.17", features = ["must_cast", "derive", "extern_crate_alloc"]} 15 | colored = "2" 16 | dashmap = {version = "5", features = ["serde"]} 17 | ecow = {version = "0.2.3", features = ["serde"]} 18 | enum-iterator = "2.1.0" 19 | once_cell = "1" 20 | serde = {version = "1", features = ["derive", "rc"]} 21 | serde_tuple = "0.5.0" 22 | unicode-segmentation = "1.10" 23 | -------------------------------------------------------------------------------- /parser/src/inputs.rs: -------------------------------------------------------------------------------- 1 | use std::{fmt, path::PathBuf}; 2 | 3 | use dashmap::DashMap; 4 | use ecow::{EcoString, EcoVec}; 5 | use serde::*; 6 | 7 | use crate::{CodeSpan, InputSrc, IntoInputSrc}; 8 | 9 | /// A repository of code strings input to the compiler 10 | #[derive(Debug, Clone, Default, Serialize, Deserialize)] 11 | #[serde(default)] 12 | pub struct Inputs { 13 | /// A map of file paths to their string contents 14 | #[serde(skip_serializing_if = "DashMap::is_empty")] 15 | pub files: DashMap, 16 | /// A list of input strings without paths 17 | #[serde(skip_serializing_if = "EcoVec::is_empty")] 18 | pub strings: EcoVec, 19 | /// A map of spans to macro strings 20 | #[serde(skip)] 21 | pub macros: DashMap, 22 | } 23 | 24 | impl Inputs { 25 | /// Add an input source 26 | pub fn add_src(&mut self, src: impl IntoInputSrc, input: impl Into) -> InputSrc { 27 | let src = src.into_input_src(self.strings.len()); 28 | match &src { 29 | InputSrc::File(path) => { 30 | self.files.insert(path.to_path_buf(), input.into()); 31 | } 32 | InputSrc::Str(i) => { 33 | while self.strings.len() <= *i { 34 | self.strings.push(EcoString::default()); 35 | } 36 | self.strings.make_mut()[*i] = input.into(); 37 | } 38 | InputSrc::Macro(span) => { 39 | self.macros.insert((**span).clone(), input.into()); 40 | } 41 | InputSrc::Literal(_) => {} 42 | } 43 | src 44 | } 45 | /// Get an input string 46 | pub fn get(&self, src: &InputSrc) -> EcoString { 47 | match src { 48 | InputSrc::File(path) => self 49 | .files 50 | .get(&**path) 51 | .unwrap_or_else(|| panic!("File {:?} not found", path)) 52 | .clone(), 53 | InputSrc::Str(index) => self 54 | .strings 55 | .get(*index) 56 | .unwrap_or_else(|| panic!("String {} not found", index)) 57 | .clone(), 58 | InputSrc::Macro(span) => self 59 | .macros 60 | .get(span) 61 | .unwrap_or_else(|| panic!("Macro at {} not found", span)) 62 | .clone(), 63 | InputSrc::Literal(s) => s.clone(), 64 | } 65 | } 66 | /// Get an input string and perform an operation on it 67 | #[track_caller] 68 | pub fn get_with(&self, src: &InputSrc, f: impl FnOnce(&str) -> T) -> T { 69 | match src { 70 | InputSrc::File(path) => { 71 | if let Some(src) = self.files.get(&**path) { 72 | f(&src) 73 | } else { 74 | panic!( 75 | "File {} not found. Available sources are {}", 76 | path.display(), 77 | self.available_srcs() 78 | ) 79 | } 80 | } 81 | InputSrc::Str(index) => { 82 | if let Some(src) = self.strings.get(*index) { 83 | f(src) 84 | } else { 85 | panic!( 86 | "String {} not found. Available sources are {}", 87 | index, 88 | self.available_srcs() 89 | ) 90 | } 91 | } 92 | InputSrc::Macro(span) => { 93 | if let Some(src) = self.macros.get(span) { 94 | f(src.value()) 95 | } else { 96 | panic!( 97 | "Macro at {} not found. Available sources are {}", 98 | span, 99 | self.available_srcs() 100 | ) 101 | } 102 | } 103 | InputSrc::Literal(s) => f(s), 104 | } 105 | } 106 | fn available_srcs(&self) -> String { 107 | (self.files.iter().map(|e| e.key().display().to_string())) 108 | .chain(self.strings.iter().map(|i| format!("string {i}"))) 109 | .collect::>() 110 | .join(", ") 111 | } 112 | /// Get an input string and perform an operation on it 113 | pub fn try_get_with(&self, src: &InputSrc, f: impl FnOnce(&str) -> T) -> Option { 114 | match src { 115 | InputSrc::File(path) => self.files.get(&**path).map(|src| f(&src)), 116 | InputSrc::Str(index) => self.strings.get(*index).map(|src| f(src)), 117 | InputSrc::Macro(span) => self.macros.get(span).map(|src| f(&src)), 118 | InputSrc::Literal(s) => Some(f(s)), 119 | } 120 | } 121 | } 122 | 123 | /// Character counts for a binding 124 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] 125 | pub struct BindingCounts { 126 | /// The number of characters 127 | pub char: usize, 128 | /// The number of SBCS bytes 129 | pub sbcs: usize, 130 | } 131 | 132 | impl fmt::Display for BindingCounts { 133 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 134 | write!( 135 | f, 136 | "{} character{}", 137 | self.char, 138 | if self.char == 1 { "" } else { "s" } 139 | )?; 140 | if self.sbcs != self.char { 141 | write!(f, " ({} SBCS)", self.sbcs)?; 142 | } 143 | Ok(()) 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /parser/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod ast; 2 | mod complex; 3 | mod defs; 4 | mod error; 5 | mod inputs; 6 | mod lex; 7 | pub mod parse; 8 | mod primitive; 9 | mod signature; 10 | mod split; 11 | mod subscript; 12 | 13 | use bytemuck::must_cast; 14 | pub use { 15 | complex::*, defs::*, error::*, inputs::*, lex::*, parse::parse, primitive::*, signature::*, 16 | split::*, subscript::*, 17 | }; 18 | 19 | /// A Uiua identifier 20 | pub type Ident = ecow::EcoString; 21 | 22 | // NOTE: must_cast to f64 only works if f64 and u64 have same endianness. 23 | // This is true of all currently supported platforms for rust, 24 | // but may not be true in general. Swap out for f64::from_bits when 25 | // the MSRV passes 1.83 to ensure correctness on all future platforms. 26 | /// A NaN value that always compares as equal 27 | pub const WILDCARD_NAN: f64 = must_cast(0x7ff8_0000_0000_0000u64 | 0x0000_0000_0000_0003); 28 | /// A character value used as a wildcard that will equal any character 29 | pub const WILDCARD_CHAR: char = '\u{100000}'; 30 | -------------------------------------------------------------------------------- /parser/src/subscript.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | use serde::*; 4 | 5 | use crate::SUBSCRIPT_DIGITS; 6 | 7 | /// A subscripts 8 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] 9 | #[serde(default)] 10 | pub struct Subscript { 11 | /// The numeric part of the subscript 12 | #[serde(skip_serializing_if = "Option::is_none")] 13 | pub num: Option, 14 | /// The sided part of the subscript 15 | #[serde(skip_serializing_if = "Option::is_none")] 16 | pub side: Option, 17 | } 18 | 19 | impl Default for Subscript { 20 | fn default() -> Self { 21 | Self { 22 | num: None, 23 | side: None, 24 | } 25 | } 26 | } 27 | 28 | /// The numeric part of a subscript 29 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] 30 | #[serde(tag = "type", content = "value", rename_all = "snake_case")] 31 | pub enum NumericSubscript { 32 | /// Only a negative sign 33 | NegOnly, 34 | /// The number is too large to be represented 35 | TooLarge, 36 | /// A valid number 37 | #[serde(untagged)] 38 | N(i32), 39 | } 40 | 41 | /// The sided part of a subscript 42 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] 43 | pub struct SidedSubscript { 44 | /// The side 45 | pub side: SubSide, 46 | /// An additional quantifying number 47 | #[serde(skip_serializing_if = "Option::is_none")] 48 | pub n: Option, 49 | } 50 | 51 | /// A sided subscript 52 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] 53 | #[allow(missing_docs)] 54 | pub enum SubSide { 55 | Left, 56 | Right, 57 | } 58 | 59 | impl Subscript { 60 | /// Make a pure numeric subscript 61 | pub fn numeric(i: i32) -> Self { 62 | Self { 63 | num: Some(NumericSubscript::N(i)), 64 | side: None, 65 | } 66 | } 67 | /// Check if the subscript is useable 68 | pub fn is_useable(&self) -> bool { 69 | matches!(self.num, Some(NumericSubscript::N(_))) || self.side.is_some() 70 | } 71 | /// Get the numeric part of the subscript as an integer, if it exists 72 | pub fn n(&self) -> Option { 73 | self.num.and_then(|n| match n { 74 | NumericSubscript::N(n) => Some(n), 75 | _ => None, 76 | }) 77 | } 78 | } 79 | 80 | impl Subscript { 81 | /// Map the numeric part of the subscript 82 | pub fn map_num(self, f: impl FnOnce(N) -> M) -> Subscript { 83 | Subscript { 84 | num: self.num.map(f), 85 | side: self.side, 86 | } 87 | } 88 | } 89 | 90 | impl fmt::Display for SubSide { 91 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 92 | match self { 93 | SubSide::Left => write!(f, "⌞"), 94 | SubSide::Right => write!(f, "⌟"), 95 | } 96 | } 97 | } 98 | 99 | impl fmt::Display for NumericSubscript { 100 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 101 | match self { 102 | NumericSubscript::NegOnly => write!(f, "₋"), 103 | NumericSubscript::N(n) => { 104 | if *n < 0 { 105 | write!(f, "₋")?; 106 | } 107 | for c in n.abs().to_string().chars() { 108 | write!(f, "{}", SUBSCRIPT_DIGITS[(c as u32 as u8 - b'0') as usize])?; 109 | } 110 | Ok(()) 111 | } 112 | NumericSubscript::TooLarge => write!(f, "…"), 113 | } 114 | } 115 | } 116 | 117 | impl fmt::Display for SidedSubscript { 118 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 119 | self.side.fmt(f)?; 120 | if let Some(n) = self.n { 121 | for c in n.to_string().chars() { 122 | write!(f, "{}", SUBSCRIPT_DIGITS[(c as u32 as u8 - b'0') as usize])?; 123 | } 124 | } 125 | Ok(()) 126 | } 127 | } 128 | 129 | impl fmt::Display for Subscript { 130 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 131 | if self.num.is_none() && self.side.is_none() { 132 | return write!(f, ","); 133 | }; 134 | if let Some(num) = &self.num { 135 | num.fmt(f)?; 136 | } 137 | if let Some(side) = self.side { 138 | side.fmt(f)?; 139 | } 140 | Ok(()) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Uiua 5 | 6 | Uiua (pronounced *"wee-wuh"*) is a stack-based array programming language. 7 | 8 | Documentation, examples, and an online interpreter can be found at [uiua.org](https://uiua.org). 9 | 10 | You can also check out the [Discord server](https://discord.gg/3r9nrfYhCc). 11 | 12 | You can support Uiua's development via [GitHub Sponsors](https://github.com/sponsors/uiua-lang). 13 | 14 | ## Installation 15 | 16 | You can try the language without installing anything on [the website](https://uiua.org). 17 | 18 | If you want to install the interpreter locally there are 2 options: 19 | - If your OS is supported, you can simply download the [latest release](https://github.com/uiua-lang/uiua/releases). 20 | - If not, you will need to install via Cargo. 21 | This requires [Rust](https://www.rust-lang.org/tools/install) (>=1.75) to be installed. 22 | 23 | You can install with one of the following commands: 24 | ``` 25 | cargo install uiua -F full # Installs all features 26 | cargo install uiua # No audio, webcam, or window features 27 | ``` 28 | On Linux, you may need to install some dependencies first: 29 | ``` 30 | apt install libx11-dev libffi-dev 31 | ``` 32 | 33 | The following optional features are available but not enabled by default (enabled by passing `--features `): 34 | - `full`: Enables all optional features below 35 | - `audio`: Enables audio system functions (may require `libasound2-dev libudev-dev pkg-config` on Linux) 36 | - `webcam`: Enables webcam system functions (may require `libjpeg-dev` on Linux) 37 | - `window`: Enables output in a window 38 | 39 | - If you want the most recent development version of Uiua, you can install from the git repository. 40 | ``` 41 | cargo install --git https://github.com/uiua-lang/uiua uiua -F full 42 | cargo install --git https://github.com/uiua-lang/uiua uiua 43 | ``` 44 | - If you use Nix or NixOS, you can clone this repo and do following: 45 | ``` 46 | nix develop # to drop into a shell prompt with all the dependencies 47 | cargo check # to make sure you can compile/build latest version 48 | cargo build # to build latest debug version of uiua 49 | cargo run repl # to get uiua repl 50 | ``` 51 | `nix develop` is not necessary if you have direnv active, in that case `direnv allow` will activate the flake devshell. 52 | 53 | *Note:* If you encounter errors such as rustc or any other package 54 | version mismatch, it is most likely that flake.lock file needs to be 55 | updated to pull in updated dependencies for nix shell. 56 | 57 | ## Language and Font Support 58 | 59 | The Uiua native interpreter has a built-in language server that can be used by editor extensions. 60 | 61 | You can find a list of editor extensions [here](https://uiua.org/docs/install#editor-support). 62 | 63 | You can find a list of fonts that support Uiua's characters [here](https://uiua.org/docs/install#fonts). 64 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/rustfmt.toml -------------------------------------------------------------------------------- /site/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uiua 7 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /site/CNAME: -------------------------------------------------------------------------------- 1 | www.uiua.org -------------------------------------------------------------------------------- /site/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = "2021" 3 | name = "site" 4 | version = "0.1.0" 5 | 6 | [dependencies] 7 | base64 = "0.22.0" 8 | comrak = "0.39.0" 9 | console_error_panic_hook = "0.1.7" 10 | enum-iterator = "2.0.0" 11 | getrandom = {version = "0.2", features = ["js"]} 12 | hound = "3.5.1" 13 | image = "0.25" 14 | js-sys = "0.3" 15 | leptos = "0.6.11" 16 | leptos_meta = {version = "0.6.11", features = ["csr"]} 17 | leptos_router = {version = "0.6.11", features = ["csr"]} 18 | pathdiff = "0.2.1" 19 | rand = {version = "0.8.5", features = ["small_rng"]} 20 | serde = {version = "1", features = ["derive"]} 21 | serde_json = "1" 22 | uiua = {path = "..", default-features = false, features = ["batteries", "web"]} 23 | uiua-editor = {path = "../pad/editor"} 24 | unicode-segmentation = "1.10" 25 | urlencoding = "2" 26 | wasm-bindgen = "0.2.93" 27 | wasm-bindgen-futures = "0.4.43" 28 | 29 | [dependencies.web-sys] 30 | features = [ 31 | "CssStyleDeclaration", 32 | "DomRect", 33 | "Storage", 34 | "HtmlAudioElement", 35 | "HtmlBrElement", 36 | "HtmlElement", 37 | "Selection", 38 | "Node", 39 | "Clipboard", 40 | "ClipboardEvent", 41 | "DataTransfer", 42 | "Navigator", 43 | "Permissions", 44 | "ScrollIntoViewOptions", 45 | "ScrollBehavior", 46 | "ScrollLogicalPosition", 47 | "StorageManager", 48 | "FileReader", 49 | "EventInit", 50 | "DataTransfer", 51 | "File", 52 | "FileList", 53 | "ResizeObserver", 54 | "ResizeObserverEntry", 55 | "Performance", 56 | ] 57 | version = "0.3.70" 58 | 59 | [features] 60 | audio = [] # Dummy for rust-analyzer 61 | -------------------------------------------------------------------------------- /site/Pixua.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/Pixua.ttf -------------------------------------------------------------------------------- /site/assets/ooh-ee-ooh-ah.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/ooh-ee-ooh-ah.mp3 -------------------------------------------------------------------------------- /site/assets/rss.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /site/assets/sided-subscripts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/sided-subscripts.png -------------------------------------------------------------------------------- /site/assets/uiua-crayon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/uiua-crayon.jpg -------------------------------------------------------------------------------- /site/assets/uiua-logo-pride.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/uiua-logo-pride.gif -------------------------------------------------------------------------------- /site/assets/uiua-logo-pride.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/uiua-logo-pride.png -------------------------------------------------------------------------------- /site/assets/uiua-logo-scrambledine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/uiua-logo-scrambledine.png -------------------------------------------------------------------------------- /site/assets/uiua-logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/uiua-logo.gif -------------------------------------------------------------------------------- /site/assets/uiua-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/uiua-logo.png -------------------------------------------------------------------------------- /site/assets/uiua-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 26 | 27 | 30 | 33 | 36 | 38 | -------------------------------------------------------------------------------- /site/assets/wee-wah.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/wee-wah.mp3 -------------------------------------------------------------------------------- /site/assets/wee-wuh.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/wee-wuh.mp3 -------------------------------------------------------------------------------- /site/assets/weewuh-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/weewuh-logo.png -------------------------------------------------------------------------------- /site/assets/you-dont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/assets/you-dont.png -------------------------------------------------------------------------------- /site/blog/feed.rss: -------------------------------------------------------------------------------- 1 | Uiua Blog 2 | Blog of the Uiua Programming Language 3 | https://uiua.org/blog 4 | 5 | Fri, 30 May 2025 06:08:44 +0000 6 | https://uiua.org/blog/how-the-uiua-logo-works 7 | f7077c7c-3968-4f10-8e7d-140ebcaebc77 8 | Thu, 29 May 2025 00:00:00 +0000 9 | How the Uiua Logo Works 10 | https://uiua.org/blog/uiua-0.16.0 11 | 087f5d27-675c-47e6-85b2-e5f2a991e745 12 | Sun, 18 May 2025 00:00:00 +0000 13 | Announcing Uiua 0.16.0 14 | https://uiua.org/blog/uiua-0.15.0 15 | 52a5f6f8-6898-44f3-a193-2125945276b6 16 | Thu, 3 Apr 2025 00:00:00 +0000 17 | Announcing Uiua 0.15.0 18 | https://uiua.org/blog/its-so-over 19 | a3e86902-43f2-4fb5-bdd1-62b15bcc8fd0 20 | Sat, 15 Feb 2025 00:00:00 +0000 21 | It's So Over 22 | https://uiua.org/blog/uiua-0.14.0 23 | a516e01b-732f-4e30-aba2-9599fedfffab 24 | Fri, 20 Dec 2024 00:00:00 +0000 25 | Announcing Uiua 0.14.0 26 | https://uiua.org/blog/subscripts 27 | 820eeae1-7c05-4c3c-877c-0675dd7517aa 28 | Mon, 25 Nov 2024 00:00:00 +0000 29 | Subscripts 30 | https://uiua.org/blog/uiua-0.13.0 31 | 666c3590-e42d-4e75-a7bf-1552a098ccd2 32 | Mon, 21 Oct 2024 00:00:00 +0000 33 | Announcing Uiua 0.13.0 34 | https://uiua.org/blog/uiua-0.12.0 35 | 95d63645-10e4-4312-bbe3-f0a6254c0144 36 | Fri, 16 Aug 2024 00:00:00 +0000 37 | Announcing Uiua 0.12.0 38 | https://uiua.org/blog/uiua-0.11.0 39 | 32cba0cb-2378-4cf9-894c-ea65e2a3ffda 40 | Sun, 2 Jun 2024 00:00:00 +0000 41 | Announcing Uiua 0.11.0 42 | https://uiua.org/blog/uiua-0.10.0 43 | 6841da9d-9b35-4992-92b3-0c6820606733 44 | Thu, 4 Apr 2024 00:00:00 +0000 45 | Announcing Uiua 0.10.0 46 | https://uiua.org/blog/what-will-1-look-like 47 | 113ee6ab-1d29-4115-9a1e-4bb2701d23f0 48 | Fri, 19 Jan 2024 00:00:00 +0000 49 | What will Uiua 1.0 look like? 50 | https://uiua.org/blog/second-class-functions 51 | c6a7b400-5d2b-413a-888b-4cd675c8c1db 52 | Fri, 15 Dec 2023 00:00:00 +0000 53 | Why doesn't Uiua have first-class functions? -------------------------------------------------------------------------------- /site/blog/its-so-over-text.md: -------------------------------------------------------------------------------- 1 | # It's So [`over ,`](https://uiua.org/docs/over) 2 | 3 | 2025-02-15 4 | 5 | --- 6 | 7 | In the coming Uiua version 0.15.0, the [`over ,`](https://uiua.org/docs/over) function will be deprecated. This change is already live on the website and in new builds. 8 | 9 | [`over ,`](https://uiua.org/docs/over) copied the second-to-top value on the stack to the top of the stack. This is a pretty common primitive in many stack languages, so its removal may seem like an odd choice. 10 | 11 | This change is part of Uiua's general shift toward more structured forms of stack management. The last year has seen many [stack manipulation modifiers](https://uiua.org/tutorial/evenmorestack) added to the language. In particular, basically all uses of [`over ,`](https://uiua.org/docs/over) can be replaced with [`with ⤙`](https://uiua.org/docs/with) or [`below ◡`](https://uiua.org/docs/below). 12 | 13 | Here are some examples of how to replace common uses of [`over ,`](https://uiua.org/docs/over): 14 | 15 | The shortest literal replacement for [`over ,`](https://uiua.org/docs/over) is [`with ⤙`](https://uiua.org/docs/with) [`identity ∘`](https://uiua.org/docs/identity), though it is generally not preferred. 16 | 17 | ```uiua 18 | [⤙∘ 1 2] 19 | ``` 20 | 21 | Consider that this particular example could be written without [`identity ∘`](https://uiua.org/docs/identity) as well. This is because of [`with ⤙`](https://uiua.org/docs/with)'s behavior on noadic functions. 22 | 23 | ```uiua 24 | [⤙1 2] 25 | ``` 26 | The common pattern of `,,` preserved a dyadic function's arguments on the stack. This can be replaced with [`below ◡`](https://uiua.org/docs/below). 27 | 28 | ```uiua 29 | [◡+ 2 3] 30 | {◡⊟ 1_2_3 4_5_6} 31 | ``` 32 | 33 | Another common pattern is needing to call a monadic function on the second value on the stack, preserving that value and putting the result on top. This can be done with [`below ◡`](https://uiua.org/docs/below) [`gap ⋅`](https://uiua.org/docs/gap). 34 | 35 | ```uiua 36 | ◡⋅△ 1_2_3 [4_5 6_7] 37 | ``` 38 | 39 | Finally, [`over ,`](https://uiua.org/docs/over) was sometimes used to intersperse a value between constants. This can now be done with [`with ⤙`](https://uiua.org/docs/with). 40 | 41 | ```uiua 42 | 2⤙4 [1 2 3 4 5] 43 | ``` 44 | 45 | ```uiua 46 | ×⊓≥< 2⤙4 [1 2 3 4 5] 47 | ``` 48 | 49 | It's reasonable to ask, with the recent stabilization of [`backward ˜`](https://uiua.org/docs/backward), and the addition of the `# Experimental!` [`self ˙`](https://uiua.org/docs/self) modifier, is deprecation on the horizon for [`flip :`](https://uiua.org/docs/flip) and [`duplicate .`](https://uiua.org/docs/duplicate)? The short answer is no, not at the moment. [`flip :`](https://uiua.org/docs/flip) and [`duplicate .`](https://uiua.org/docs/duplicate) are a bit more fundamental than [`over ,`](https://uiua.org/docs/over) was, and they allow for certain nice notations. 50 | 51 | That's all! [`over ,`](https://uiua.org/docs/over) was one of the oldest primitives in Uiua, but part of the language has always been about exploring the best ways to write tacit code. [`over ,`](https://uiua.org/docs/over) can make the stack harder to reason about, as it requires keeping the state of the stack at various points in your head. We have since discovered better ways to do the same thing, and so we say goodbye to [`over ,`](https://uiua.org/docs/over). 🫡 -------------------------------------------------------------------------------- /site/blog/list.txt: -------------------------------------------------------------------------------- 1 | how-the-uiua-logo-works(f7077c7c-3968-4f10-8e7d-140ebcaebc77): 2025-05-29 - How the Uiua Logo Works 2 | uiua-0.16.0(087f5d27-675c-47e6-85b2-e5f2a991e745): 2025-05-18 - Announcing Uiua 0.16.0 3 | uiua-0.15.0(52a5f6f8-6898-44f3-a193-2125945276b6): 2025-04-03 - Announcing Uiua 0.15.0 4 | its-so-over(a3e86902-43f2-4fb5-bdd1-62b15bcc8fd0): 2025-02-15 - It's So Over 5 | uiua-0.14.0(a516e01b-732f-4e30-aba2-9599fedfffab): 2024-12-20 - Announcing Uiua 0.14.0 6 | subscripts(820eeae1-7c05-4c3c-877c-0675dd7517aa): 2024-11-25 - Subscripts 7 | uiua-0.13.0(666c3590-e42d-4e75-a7bf-1552a098ccd2): 2024-10-21 - Announcing Uiua 0.13.0 8 | uiua-0.12.0(95d63645-10e4-4312-bbe3-f0a6254c0144): 2024-08-16 - Announcing Uiua 0.12.0 9 | uiua-0.11.0(32cba0cb-2378-4cf9-894c-ea65e2a3ffda): 2024-06-02 - Announcing Uiua 0.11.0 10 | uiua-0.10.0(6841da9d-9b35-4992-92b3-0c6820606733): 2024-04-04 - Announcing Uiua 0.10.0 11 | what-will-1-look-like(113ee6ab-1d29-4115-9a1e-4bb2701d23f0): 2024-01-19 - What will Uiua 1.0 look like? 12 | second-class-functions(c6a7b400-5d2b-413a-888b-4cd675c8c1db): 2023-12-15 - Why doesn't Uiua have first-class functions? 13 | -------------------------------------------------------------------------------- /site/blog/second-class-functions-text.md: -------------------------------------------------------------------------------- 1 | # Why doesn't Uiua have first-class functions? 2 | 3 | 2023-12-15 4 | 5 | --- 6 | 7 | People often ask why Uiua doesn't have first-class functions. That is, functions that can be put on the stack and in arrays. 8 | 9 | In the beginning, functions *were* normal array elements. Modifiers popped their functions from the stack like regular values. Functions could be put in arrays, and lists of functions even had some special uses. There was a `! call` function which called the top function on the stack. Boxes were not even a dedicated type. They were just functions that took no arguments and returned a single value. 10 | 11 | However, as Uiua's development continued, the language began to rely more and more on stack signatures being well-defined. This property catches errors early, enables some optimizations, and allows modifiers to behave differently depending on their function's siganture. That last point lets us avoid having multiple modifiers that work the same way but on different numbers of arguments. For example, [Factor](https://factorcode.org/) has the words `bi`, `2bi`, `3bi`, `tri`, `2tri`, and `3tri`. Uiua can express all of these and more with just [fork](). 12 | 13 | Unfortunately, having first-class functions was at odds with this design. Because functions could be put into arrays and (conditionally) moved around on the stack, the compiler was not able to determine the signature of a function that called a function value. This meant that anywhere the `! call` function was used needed a signature annotation nearby, which you better hope was correct, or the code would break somewhere else. It also incurred additional interpreter overhead to get the functions from arrays and made certain types of optimizations impossible. 14 | 15 | Other than these design and implementation concerns, the ability to move functions around on the stack made code much harder to read when it was used. You had to keep in your mind not only the values, but the functions that worked on them as well. They were another value you had to deal with, and the related stack manipulation could get quite messy. 16 | 17 | And so I settled on a different approach. Functions were removed as an element type and were put elsewhere in the interpreter. Boxes became a type in their own right. The `! call` function was removed, and `!` was repurposed to be part of defining macros. [Macros](/docs/macros) capture the primary use case of first-class functions: injecting some variable code into a function. While they are technically more limited, their uniform structure makes them easier to both read and write. This change also massively simplified the interpreter, as well as the complexity of the language itself. 18 | 19 | Despite the downgrading of functions to second-class status, it should be noted that I do like functional programming languages. I just don't think that first-class functions are a good fit for Uiua. In practice, first-class functions are mostly unnecessary if you have higher-order functions, which array languages have had for decades. APL's operators, J's adverbs and conjunctions, and BQN and Uiua's modifiers are all versions of higher-order functions. They allow the mapping, reduction, and general transformation of data in the same way that first-class functions do in other languages. 20 | 21 | Now if only I could find a way to get rid of boxes... -------------------------------------------------------------------------------- /site/blog/uiua-0.10.0-text.md: -------------------------------------------------------------------------------- 1 | # Announcing Uiua 0.10.0 2 | 3 | 2024-04-04 4 | 5 | --- 6 | 7 | Uiua 0.10.0 is now available! 8 | 9 | You can find the full changelog [here](https://uiua.org/docs/changelog#0.10.0---2024-04-04). 10 | 11 | This release contains so many changes, improvements, and new features that I thought it deserved a blog post. 12 | From here on, major releases will be announced in this way. 13 | 14 | While there are many changes, I want to highlight a few of them here. 15 | 16 | ## Pattern Matching 17 | 18 | Using [`un`](https://uiua.org/docs/un) on a constant value will now match a pattern. When used with [`try`](https://uiua.org/docs/try), this can be used to conditionally match, extract, and process values. 19 | 20 | ```uiua 21 | F ← ⍣( 22 | ×10 °[1⊙3] # Extract and multiply.. 23 | | °(⊂5) # ..or remove leading 5.. 24 | | ⇌ # ..else reverse 25 | ) 26 | F [1 2 3] 27 | F [5 6 7] 28 | F "cool!" 29 | ``` 30 | You can read more in the [Pattern Matching](https://uiua.org/tutorial/patternmatching) tutorial. 31 | 32 | ## Array Macros 33 | 34 | Array macros are a powerful new feature that allow full compile-time metaprogramming. 35 | 36 | They allow Uiua code to directly manipulate other Uiua code, enabling a wide range of new possibilities. 37 | 38 | ```uiua 39 | F! ←^ ≡$"_ ← _\n" "ABC" 40 | F!(1|2|3) 41 | [A B C B B] 42 | ``` 43 | 44 | You can read more in the updated [Macros](https://uiua.org/tutorial/macros) tutorial. 45 | 46 | ## Git Modules 47 | 48 | You can now prefix a module path with `git:` to import a git repository from a URL. 49 | ```uiua 50 | ~ "git: github.com/uiua-lang/example-module" ~ Upscale 51 | Upscale 3 [1_2 3_4] 52 | ``` 53 | In the native interpreter, this automatically creates a Git submodule. 54 | 55 | On the web, it fetches a `lib.ua` file from the repository. 56 | 57 | You can read more in the updated [Modules](https://uiua.org/tutorial/modules) tutorial. 58 | 59 | ## [`mask`](https://uiua.org/docs/mask) 60 | 61 | [`mask`](https://uiua.org/docs/mask) is a new function that is similar to [`find`](https://uiua.org/docs/find), but it returns full masks of matches rather than just the first positions. 62 | 63 | ```uiua 64 | ⦷ " - " "Hey - how-are - you" 65 | ``` 66 | ```uiua 67 | ⊜□¬⦷⊙. " - " "Hey - how-are - you" 68 | ``` 69 | 70 | This simplifies a lot of string-processing code in particular. A new [strings](https://uiua.org/tutorial/strings) tutorial has been added as well. 71 | 72 | ## Other Changes 73 | 74 | Switch functions now format to use `⟨⟩` brackets. This makes them easier to distinguish from function packs. 75 | ```uiua 76 | F ← (×10|↥2)<2. # This.. 77 | F ← ⟨×10|↥2⟩<2. # Formats to this 78 | F 0 79 | F 5 80 | ``` 81 | 82 | [`map`](https://uiua.org/docs/map) and related functions are no longer experimental! See the [`map`](https://uiua.org/docs/map) docs for an overview. 83 | ```uiua 84 | map 1_2_3 4_5_6 85 | ``` 86 | 87 | The new [`&clget`](https://uiua.org/docs/&clget) and [`&clset`](https://uiua.org/docs/&clset) functions provide access to the clipboard. 88 | 89 | The interpreter's built-in language server now supports [many more features](https://marketplace.visualstudio.com/items?itemName=uiua-lang.uiua-vscode). 90 | 91 | There are a ton more! Again, you can read the full changelog [here](https://uiua.org/docs/changelog#0.10.0---2024-04-04). 92 | 93 | ## 💖 94 | 95 | As always, I'd like to thank everyone who contributed to this release, whether by directly contributing code, reporting bugs, or just using Uiua and providing feedback. 96 | 97 | Uiua is in many ways a novel and unique language, and I think it is only through our collective effort that we can properly explore its design space. 98 | 99 | With your help, I hope to continue to improve Uiua to the point of stability. -------------------------------------------------------------------------------- /site/blog/uiua-0.11.0-text.md: -------------------------------------------------------------------------------- 1 | # Announcing Uiua 0.11.0 2 | 3 | 2024-06-02 4 | 5 | --- 6 | 7 | Uiua 0.11.0 is now available! 8 | 9 | You can find the full changelog [here](https://uiua.org/docs/changelog#0.11.0---2024-06-02). 10 | 11 | Uiua is a general purpose, stack-based, array-oriented programming language with a focus on tacit code. 12 | 13 | While this release does not have any major new features, it extends the functionality of many primitives, optimizes many common patterns, and fixes a number of bugs. 14 | 15 | Here are some of the highlights: 16 | 17 | ## Multi-argument [`reduce /`](https://uiua.org/docs/reduce) 18 | 19 | [`reduce /`](https://uiua.org/docs/reduce) takes a dyadic function and applies it "between" all rows of an array. 20 | 21 | ```uiua 22 | /+ [1 2 3 4 5] 23 | ``` 24 | 25 | [`reduce /`](https://uiua.org/docs/reduce) can now take multiple arguments if its function takes more than two arguments. Additional arguments are interspersed between the rows and are passed above the main array on the stack. 26 | 27 | ```uiua 28 | /(⊂⊂) 0 [1 2 3 4] 29 | ``` 30 | 31 | This is particularly useful when used with [`content ◇`](https://uiua.org/docs/content) and [`join ⊂`](https://uiua.org/docs/join) to intersperse a delimiter between a list of strings. 32 | 33 | ```uiua 34 | /◇(⊂⊂) @, {"cat" "dog" "bird" "fish"} 35 | ``` 36 | 37 | ## [`json`](https://uiua.org/docs/json) and [`xlsx`](https://uiua.org/docs/xlsx) 38 | 39 | The [`json`](https://uiua.org/docs/json) and [`xlsx`](https://uiua.org/docs/xlsx) functions allow the encoding and decoding of JSON and XLSX data respectively. 40 | 41 | `json` converts an array to a JSON string. 42 | 43 | ```uiua 44 | json [1 2 3 4] 45 | ``` 46 | 47 | It works with `map`s as well. 48 | 49 | ```uiua 50 | json map {"name" "age"} {"Dan" 31} 51 | ``` 52 | 53 | [`un °`](https://uiua.org/docs/un) `json` decodes a JSON string. 54 | 55 | ```uiua 56 | °json $ {"type": "requires", "content": "json", "ids": [38, 22, 5]} 57 | ``` 58 | 59 | `xlsx` is similar, but is works with binary data rather than strings. 60 | 61 | ## [`take ↙`](https://uiua.org/docs/take)/[`drop ↘`](https://uiua.org/docs/drop) [`infinity ∞`](https://uiua.org/docs/infinity) 62 | 63 | [`take ↙`](https://uiua.org/docs/take) and [`drop ↘`](https://uiua.org/docs/drop) isolate part of an array. 64 | 65 | ```uiua 66 | ↙ 3 [1 2 3 4 5] 67 | ↘ 3 [1 2 3 4 5] 68 | ``` 69 | 70 | Multidimensional indices have always been supported. 71 | 72 | ```uiua 73 | ↙2_2 . ↯3_4⇡12 74 | ``` 75 | 76 | You can now provide [`infinity ∞`](https://uiua.org/docs/infinity) as one or more of the indices to [`take ↙`](https://uiua.org/docs/take) or [`drop ↘`](https://uiua.org/docs/drop) that entire axis. 77 | 78 | ```uiua 79 | ↙∞_2 . ↯3_4⇡12 80 | ``` 81 | ``` uiua 82 | ↙1_∞_2 . ↯2_3_4⇡24 83 | ``` 84 | 85 | ## Swizzles 86 | 87 | Swizzles are a new experimental feature that allow concise manipulation of the stack and extraction from arrays. 88 | 89 | Stack swizzles are written with a `λ` followed by some letters. The stack will be rearranged accordingly. `λ` formats from `'` when followed by letters. 90 | 91 | ```uiua 92 | # Experimental! 93 | [λccab 1 2 3] 94 | ``` 95 | 96 | Capital letters will [`fix ¤`](https://uiua.org/docs/fix) the corresponding array. This is useful with complex [`rows ≡`](https://uiua.org/docs/rows) operations. 97 | 98 | ```uiua 99 | # Experimental! 100 | ≡(⊂⊂) ? λaBC 1_2 3_4 5_6 101 | ``` 102 | 103 | *Array* swizzles are written with a `⋊` followed by some letters. Rows from the array that correspond to the letters will be put on the stack. `⋊` formats from `''` when followed by letters. 104 | 105 | ```uiua 106 | # Experimental! 107 | ⋊beef [1 2 3 4 5 6] 108 | ``` 109 | 110 | Capital letters will [`un °`](https://uiua.org/docs/un) [`box ◻`](https://uiua.org/docs/box) the corresponding row. 111 | 112 | ```uiua 113 | # Experimental! 114 | ⋊aCB {"Dave" 31 [38 22 5]} 115 | ``` 116 | 117 | Swizzles are experimental and may change in future versions as their place in the language is explored. 118 | 119 | ## The New Pad 120 | 121 | Much of the code for the [Uiua website pad](https://uiua.org/pad) has been rewritten. This new pad uses less custom behavior and should work better in more browsers. 122 | 123 | If you are reading this on the Uiua website (with full editor features), then all the examples above use this new pad! 124 | 125 | ## 💗 126 | 127 | Thank you as always to everyone who uses Uiua and helps with its development! Your enthusiasm for the language gives me life. 128 | 129 | A *special* thanks to all of [Uiua's sponsors](https://github.com/sponsors/uiua-lang) for their continued support 🥰 130 | 131 | Again, you can find the full changelog for this release [here](https://uiua.org/docs/changelog#0.11.0---2024-06-02). 132 | 133 | You can join the [Uiua Discord](https://discord.gg/3r9nrfYhCc) to chat about the language, ask questions, or get help. 134 | 135 | -------------------------------------------------------------------------------- /site/blog/uiua-0.15.0-text.md: -------------------------------------------------------------------------------- 1 | # Announcing Uiua 0.15.0 2 | 3 | 2025-04-03 4 | 5 | --- 6 | 7 | Uiua 0.15.0 is now available! 8 | 9 | You can find the full changelog [here](https://uiua.org/docs/changelog#0.15.0---2025-04-03). 10 | 11 | You can download pre-built binaries [here](https://github.com/uiua-lang/uiua/releases). 12 | 13 | Uiua is a general purpose, stack-based, array-oriented programming language with a focus on tacit code. 14 | 15 | Here are some highlights of this release: 16 | 17 | ## Data Definitions 18 | 19 | Data definitions are a newly stabilized feature that allows names to be given to the rows of heterogeneous arrays. This is similar to structures or classes in other languages. 20 | 21 | There is [new tutorial](https://uiua.org/tutorial/datadefs) detailing all the features of data definitions, but here are a few examples: 22 | 23 | Simple data definitions can be defined following a `~`. We can then use the name of the definition to construct an array, and we can use the field names to access the fields. 24 | 25 | ```uiua 26 | ~Customer {Name Phone Address} 27 | Customer "John Doe" "555-1234" "123 Main St" 28 | Customer~Name . 29 | ``` 30 | 31 | If we want to add functions associated with the data definition, we can put the definition inside a module. We can use a [module import macro](https://www.uiua.org/tutorial/modules#module-import-macros) to easily access the items in the module. 32 | 33 | ```uiua 34 | ┌─╴Customer 35 | ~ {Name Phone Address} 36 | Format ← $"_ lives at _" ⊃(Name|Address) 37 | HouseNum ← ⋕▽⊸∊+@0⇡10 Address 38 | └─╴ 39 | 40 | Customer!( 41 | New "Bob" "555-1234" "123 Main St" 42 | $"_'s house number is _" ⊃(Name|HouseNum) 43 | 44 | Format New "Alice" "555-2843" "456 Broadway St" 45 | ) 46 | ``` 47 | 48 | Enum-like data definitions can be defined in a module with `|`s. [Pattern matching](https://www.uiua.org/tutorial/patternmatching) can be used to do different things based on the variant. 49 | 50 | ```uiua 51 | ┌─╴Shape 52 | |Circle {Radius} 53 | |Rectangle {Width Height} 54 | |Point 55 | Area ← $Area ⍣( 56 | ×π×. °Circle 57 | | × °Rectangle 58 | | 0) 59 | Format ← ⍣( 60 | $"Circle has radius _" °Circle 61 | | $"Rectangle is _×_" °Rectangle 62 | | "Point" 63 | ) 64 | └─╴ 65 | 66 | Shape!(⊃(Area|Format) Circle 4) 67 | Shape!(⊃(Area|Format) Rectangle 3 5) 68 | ``` 69 | 70 | ## [`backward ˜`] Stabilization 71 | 72 | The [`backward ˜`](https://www.uiua.org/docs/backward) modifier has been stabilized. [`backward ˜`](https://www.uiua.org/docs/backward) [`flip :`](https://www.uiua.org/docs/flip)s the arguments of its function. 73 | 74 | ```uiua 75 | - 3 5 76 | ˜- 3 5 77 | ``` 78 | 79 | ```uiua 80 | map 1_2_3 "abc" 81 | ˜map 1_2_3 "abc" 82 | ``` 83 | 84 | ```uiua 85 | ⊂ 0 [1 2 3] 86 | ˜⊂ 0 [1 2 3] 87 | ``` 88 | 89 | ```uiua 90 | °˜⊂ [1 2 3 4] 91 | ``` 92 | 93 | [`backward ˜`](https://www.uiua.org/docs/backward) is usually used on dyadic functions, but it can also be used on tetradic (4 argument) functions. In this case, it swaps the second and third arguments, leaving the first and fourth arguments unchanged. This can be a useful stack permutation. 94 | 95 | ```uiua 96 | ⊟₄ 1 2 3 4 97 | ˜⊟₄ 1 2 3 4 98 | ``` 99 | 100 | ```uiua 101 | ˜∩⬚0↙ ◡˜∩⧻ [1 2 3] [4 5 6 7 8] 102 | ``` 103 | 104 | ## Sided Subscripts 105 | 106 | Sided subscripts are [subscripts](https://www.uiua.org/docs/subscripts) that instead of changing how a function works based on a number, do it based on a "side", either left or right. 107 | 108 | Sided subscripts are formatted from `,<` and `,>`. They are currently only stabilized for [`both ∩`](https://www.uiua.org/docs/both) and [`bracket ⊓`](https://www.uiua.org/docs/bracket). These cases simplify some common stack manipulation patterns. 109 | 110 | There is a [short tutorial section](https://www.uiua.org/tutorial/evenmorestack#sided-subscripts) about them, but here are some simple examples: 111 | 112 | ```uiua 113 | {∩⌟⊟ 1 2 3} 114 | {∩⌞⊟ 1 2 3} 115 | ``` 116 | 117 | ```uiua 118 | {⊓⌟⊂⊟ 1_2 3_4 5_6} 119 | {⊓⌞⊂⊟ 1_2 3_4 5_6} 120 | ``` 121 | 122 | ## [`over ,`](https://www.uiua.org/docs/over) Deprecation 123 | 124 | The [`over ,`](https://www.uiua.org/docs/over) function has been deprecated in favor of more structured stack manipulation modifiers. 125 | 126 | You can read more about this change in the short [blog post](https://www.uiua.org/blog/its-so-over). 127 | 128 | ## ✨ 129 | 130 | Thanks to everyone who contributed to this release! 131 | 132 | As always, a big thank you to Uiua's wonderful [GitHub sponsors](https://github.com/sponsors/uiua-lang)! 133 | 134 | Again, you can find the full changelog for this release [here](https://uiua.org/docs/changelog#0.15.0---2025-04-03). 135 | 136 | You can join the [Uiua Discord](https://discord.gg/3r9nrfYhCc) to chat about the language, ask questions, or get help. We also do code challenges and discuss language features! -------------------------------------------------------------------------------- /site/blog/uiua-0.16.0-text.md: -------------------------------------------------------------------------------- 1 | # Announcing Uiua 0.16.0 2 | 3 | 2025-05-18 4 | 5 | --- 6 | 7 | Uiua 0.16.0 is now available! 8 | 9 | You can find the full changelog [here](https://uiua.org/docs/changelog#0.16.0---2025-05-18). 10 | 11 | You can download pre-built binaries [here](https://github.com/uiua-lang/uiua/releases). 12 | 13 | Uiua is a general purpose array-oriented programming language with a focus on tacit code. 14 | 15 | Here are some highlights of this release: 16 | 17 | ## New Pretty Array Formatter 18 | 19 | The formatter that displays arrays in output has been overhauled. High-rank arrays now take up less vertical space and more horizontal space. Box arrays now use box-drawing characters. 20 | 21 | ```uiua 22 | °△2_2_3_4 23 | ``` 24 | 25 | ```uiua 26 | ⧈□ 2_3 °△3_5 27 | ``` 28 | 29 | You can read more about how axes are laid out [here](https://www.uiua.org/tutorial/arrays#output). You can also gaze upon the [*G R I D*](https://www.uiua.org/pad?src=0_16_0-rc_1__4omh4oKB4pahwrDilrMyXzJfMl8yXzJfMl8yXzJfMQo=). 30 | 31 | ## [`repeat ⍥`](https://uiua.org/docs/repeat) Collection 32 | 33 | ⚠️ *Breaking Change* ⚠️ 34 | 35 | [`repeat ⍥`](https://uiua.org/docs/repeat) (and [`do ⍢`](https://uiua.org/docs/do)) now *always* have static signatures. If their function returns more values than it takes, the values lower on the stack will be automatically collected into arrays. 36 | 37 | This makes it much easy to use [`repeat ⍥`](https://uiua.org/docs/repeat) to collect intermediate values. 38 | 39 | Here is a simple example that generates the fibonacci sequence. 40 | 41 | Old version: 42 | ```not uiua 43 | ⇌[⍥◡+9].1 44 | ``` 45 | New version: 46 | ```uiua 47 | ⍥◡+9 .1 48 | ``` 49 | 50 | As you can see, the fix for this is generally to remove wrapping `[]`s and potentially a `⇌`. 51 | 52 | ## Sided [`rows ≡`](https://uiua.org/docs/rows) 53 | 54 | Sided subscripts for [`rows ≡`](https://uiua.org/docs/rows) have been stabilized. 55 | 56 | As a reminder, sided subscripts are non-numeric subscripts that indicate a function or modifier should be augmented in a way that has a "side". 57 | 58 | Sided [`rows ≡`](https://uiua.org/docs/rows) rows makes one of the arguments repeat in each iteration instead of being iterated. 59 | 60 | ```uiua 61 | ≡⊂ 1_2_3 4_5_6 62 | ``` 63 | ```uiua 64 | ≡⌞⊂ 1_2_3 4_5_6 # Left argument is repeated 65 | ``` 66 | ```uiua 67 | ≡⌟⊂ 1_2_3 4_5_6 # Right argument is repeated 68 | ``` 69 | 70 | ## Mixed Subscripts 71 | 72 | Subscripts can now be both numeric and sided. 73 | 74 | One useful example is with [`both ∩`](https://uiua.org/docs/both). We can use mixed subscripts to both reuse a value and operate on more than 2 sets of values. 75 | 76 | ```uiua 77 | {∩₃⌞⊟} 1 2 3 4 78 | ``` 79 | 80 | You can even add another number after the side to reuse more than one value. 81 | 82 | ```uiua 83 | {∩₃⌞₂⊟₃} 1 2 3 4 5 84 | ``` 85 | 86 | You can read more about mixed subscripts [here](https://www.uiua.org/docs/subscripts#mixed). 87 | 88 | ## Inline Macros 89 | 90 | Previously experimental inline macros have been stabilized. 91 | 92 | Inline macros are macros that do not need to be given a name. They are defined and executed in the same place in the code. 93 | 94 | This example calculates the standard deviation and reuses the code that calculates the mean. 95 | 96 | ```uiua 97 | StdDev ← √(^0 ×. -⊸^0)!(÷⊃⧻/+) 98 | StdDev [1 2 3 4] 99 | ``` 100 | 101 | Here we use an inline code macro to output the signature of a function. 102 | 103 | ```uiua 104 | (⋅⊢)^!(⊃(+|-×)) 105 | ``` 106 | 107 | You can read more about inline macros [here](https://www.uiua.org/tutorial/macros#inline-macros). 108 | 109 | ## Other Notable Breaking Changes 110 | 111 | - [`rows ≡`](https://uiua.org/docs/rows)'s numeric subscript behavior has been replaced with that of [`each ∵`](https://uiua.org/docs/each), and [`each ∵`](https://uiua.org/docs/each) has been deprecated. 🫡 112 | 113 | [`each ∵`](https://uiua.org/docs/each)'s behavior can now be achieved with `≡₀`. 114 | 115 | ```uiua 116 | ≡₀(□⇡) [1_2 3_4] 117 | ``` 118 | - Number literals have been overhauled, including adding complex literals. 119 | ```uiua 120 | ≡¤ [2π/3 3r5i 4.1i 22/η] 121 | ``` 122 | - [`fft`](https://uiua.org/docs/fft) now works along every axis of an array rather than only the last. It is now stabilized! 123 | 124 | ## Thank You! 125 | 126 | As always, thank you to everyone in the Uiua community, and to Uiua's lovely [GitHub sponsors](https://github.com/sponsors/uiua-lang). 127 | 128 | Again, you can find the full changelog for this release [here](https://uiua.org/docs/changelog#0.16.0---2025-05-18). 129 | 130 | You can join the [Uiua Discord](https://discord.gg/3r9nrfYhCc) to chat about the language, ask questions, or get help. We also do code challenges and discuss language features! 131 | 132 | ```uiua 133 | # Experimental! 134 | ×1.3 -⊸¬ ÷⟜(°⍉⇡)↯3 50 # Coords 135 | -+⊃( 136 | ×9/200 /×ⁿ0_2_3 137 | | /×ⁿ2_0_3 138 | | ⁿ3 -1 /+×[1 9/4 1] °√ 139 | ) # Heart 140 | ⍉⊞× [1 0.3 0.3] ⤸2 ≤0 # Threshold/color 141 | ×τ ÷⟜⇡24 # Rotation angles 142 | ≡⌟(voxels Camera:[0.2 °∠] Fog:Black) 143 | ``` 144 | -------------------------------------------------------------------------------- /site/blog/what-will-1-look-like-text.md: -------------------------------------------------------------------------------- 1 | # What will Uiua 1.0 look like? 2 | 3 | 2024-01-19 4 | 5 | --- 6 | 7 | The [Uiua pad](https://uiua.org/pad) page prominently displays the words "Uiua is not yet stable". And so it has been asked: when will Uiua be stable? What features will it have? Is there a roadmap? 8 | 9 | This post is to organize and present my thoughts on the future of Uiua. 10 | 11 | ## Stability 12 | 13 | Uiua will be made officially stable only after it has been unofficially stable for some time. That is, not until no breaking changes have been made for a long time. 14 | 15 | The following language features will need to be nailed down before Uiua can ever be stable. 16 | 17 | ### Stack manipulation 18 | 19 | I think working with the stack, at least for up to 3 values, has become mostly pretty nice. However, things start to get complicated when working with more values, as is often necessary. There is some design work to be done here, and it's not out of the question that a very small amount of non-tacitness could be introduced to improve this. 20 | 21 | The experimental [`bind`](https://uiua.org/docs/experimental#swizzles) modifier is a potential solution to this problem. 22 | 23 | There is a balance to be struc between Uiua's goal of tacitness and its goal of being ergonomic. While the beauty of fully tacit code is a worthy goal, some problems involve data flows that are inherently complex, and so some kind of labeling system may be necessary to make such problems workable. 24 | 25 | ### Box Ergonomics 26 | 27 | While I've explored alternatives, I've come to the conclusion that nested arrays are a necessary pest. The data we work with is often nested or ragged, and while there are ways to represent such data with flat structures, those representations are cumbersome in their own ways. 28 | 29 | And so boxes are likely here to stay. However, I do think some design work can be done to improve their ergonomics. Currently, Uiua's boxes are very similar to J's, but I think it may be worth it to make their usage a bit more implicit in some cases, closer to the nested arrays of APL or BQN. 30 | 31 | ### System APIs 32 | 33 | The current [system functions](https://uiua.org/docs/system) are useful and *mostly* work. There are definitely implementation gaps which need to be filled. There are a good number of missing filesystem operations, and some other things like UDP sockets and proper interaction with child processes still need to be implemented. 34 | 35 | ### FFI 36 | 37 | An FFI system similar to [BQN's](https://mlochbaum.github.io/BQN/spec/system.html#foreign-function-interface) is planned. This will allow Uiua to call into C libraries and will enable a lot more functionality. -------------------------------------------------------------------------------- /site/blog_rss.ua: -------------------------------------------------------------------------------- 1 | Tag ← $"<__>_" ⊃⊙⊙∘∘ ⊃↙↘⊸⊗@ ⊙(⍥/$"_\n_"=2type.) 2 | Month ← ◇↙3⊏:Months-1⋕ 3 | Date ← $"_, _ +0000" ⊃( 4 | ◇↙3⊏:Days⌊◿7+4÷/×[60 60 24] 5 | | datetime 6 | °⋕⍜↙⇌3 # Flip date 7 | ⍜(↙¯3|□/(⊂⊂)@: ≡◇(⬚@0↙¯2)) # Collapse time 8 | ⍜(⊡1|□◇↙3⊏:Months-1⋕) # Month 9 | /$"_ _" 10 | ) 11 | 12 | # Parse out Path, Guid, Date, Title 13 | &fras $ site/blog/list.txt 14 | ⊜□⊸≠@\n 15 | ⍚°$"_(_): _ - _" 16 | 17 | Rss ← $ rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" 18 | AtomLink ← $ atom:link href="https://uiua.org/blog/feed.rss" rel="self" type="application/rss+xml" 19 | Tag Rss Tag "channel" ⊂ { 20 | Tag "title" $ Uiua Blog 21 | Tag "description" $ Blog of the Uiua Programming Language 22 | Tag "link" $ https://uiua.org/blog 23 | Tag AtomLink "" 24 | Tag "lastBuildDate" Date now 25 | } ⍚( 26 | ⊙⊙(Date °datetime ⋕⊜□⊸≠@-) # Convert date 27 | Tag "item" { 28 | ⊓(Tag "link" $"https://uiua.org/blog/_" 29 | | Tag "guid isPermaLink=\"false\"" 30 | | Tag "pubDate" 31 | | Tag "title" 32 | ) 33 | } 34 | ) 35 | ⊂ $ 36 | &fwa "site/blog/feed.rss" 37 | -------------------------------------------------------------------------------- /site/combinators/B.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /site/combinators/B1.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | b 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /site/combinators/C.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | a 15 | b 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /site/combinators/D.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | b 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /site/combinators/D2.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | b 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /site/combinators/E.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | b 17 | c 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /site/combinators/I.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | a 14 | a 15 | 16 | 17 | -------------------------------------------------------------------------------- /site/combinators/K.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | a 14 | a 15 | b 16 | 17 | 18 | -------------------------------------------------------------------------------- /site/combinators/KI.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | a 14 | b 15 | b 16 | 17 | 18 | -------------------------------------------------------------------------------- /site/combinators/N.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | b 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /site/combinators/R.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | b 18 | c 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /site/combinators/S.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /site/combinators/W.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | a 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /site/combinators/X.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | b 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /site/combinators/Ê.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | b 18 | c 19 | d 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /site/combinators/Δ.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | b 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /site/combinators/Σ.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /site/combinators/Φ.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /site/combinators/Φ1.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | b 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /site/combinators/Ψ.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | G 16 | a 17 | b 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /site/combinators/ε.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | b 17 | c 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /site/combinators/ν.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | a 16 | b 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /site/combinators/ρ.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | b 18 | c 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /site/combinators/χ.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | F 14 | G 15 | H 16 | a 17 | b 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /site/deploy.ua: -------------------------------------------------------------------------------- 1 | ✅ ← ⍤⤙≍ 0 &runi 2 | 3 | $Branch ⍣(°□⊡+1)"main"⊸(↧⊃(⊗□"-b"|⊗□"--branch")) &args 4 | $Resume ¬∊ &args □"resume" 5 | ⊸⍥( 6 | ✅ {"git" "checkout" "site" "--"} 7 | ✅ {"git" "reset" "--hard" "origin/site"} 8 | ✅ {"git" "rebase" ∘} 9 | ) 10 | &cd "site" 11 | ✅ {"cargo" "test" "-p" "site" "gen_blog_html"} 12 | ✅ {"trunk" "build" "--release" "-d" "../docs"} 13 | ✅ {"git" "add" "--all"} 14 | ✅ {"git" "commit" "--amend" "--no-edit"} 15 | ✅ {"git" "push" "-f"} 16 | ✅ {"git" "checkout" ∘} 17 | -------------------------------------------------------------------------------- /site/favicon-crayon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/favicon-crayon.ico -------------------------------------------------------------------------------- /site/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/site/favicon.ico -------------------------------------------------------------------------------- /site/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Uiua 6 | 7 | 14 | 15 | 37 | 38 | 39 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 | 73 |
74 | 88 |
89 |
90 |

Uiua (wee-wuh) is a general purpose array-oriented 91 | programming language with a focus on simplicity, beauty, and tacit code.

93 |

Uiua lets you write code that is as short as possible while remaining readable, so you can 94 | focus on problems rather than ceremony.

95 |

The language is not yet stable, as its design space is still being explored. However, it is 96 | already quite powerful and fun to use!

97 | 100 |

Loading...

101 |
102 |
103 | 104 | 105 | 110 | 111 | -------------------------------------------------------------------------------- /site/src/blog.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use leptos::*; 4 | use leptos_meta::*; 5 | use leptos_router::*; 6 | use uiua_editor::lang; 7 | 8 | use crate::markdown::*; 9 | 10 | #[derive(Debug, Clone, PartialEq, Eq, Params)] 11 | pub struct BlogParams { 12 | page: BlogParam, 13 | } 14 | 15 | #[derive(Debug, Clone, PartialEq, Eq)] 16 | struct BlogParam(String); 17 | impl IntoParam for BlogParam { 18 | fn into_param(value: Option<&str>, _: &str) -> Result { 19 | let s = value.unwrap_or_default(); 20 | let name = urlencoding::decode(s) 21 | .map(Into::into) 22 | .unwrap_or_else(|_| s.into()); 23 | Ok(BlogParam(name)) 24 | } 25 | } 26 | 27 | #[component] 28 | pub fn Blog() -> impl IntoView { 29 | view!({ 30 | move || match use_params::().get() { 31 | Ok(params) => { 32 | if params.page.0.is_empty() { 33 | view!() 34 | } else { 35 | view!() 36 | } 37 | } 38 | Err(_) => view!(), 39 | } 40 | }) 41 | } 42 | 43 | #[component] 44 | fn BlogHome() -> impl IntoView { 45 | view! { 46 | 47 | <h1>{lang}" Blog"</h1> 48 | <BlogRssButton/> 49 | { 50 | let list = include_str!("../blog/list.txt"); 51 | list.lines().filter(|line| !line.is_empty() && !line.starts_with('#')).map(|line| { 52 | let (path, name) = line.split_once(": ").unwrap_or_default(); 53 | let (path, _guid) = path.split_once('(').unwrap_or_default(); 54 | let (date, name) = name.split_once(" - ").unwrap_or_default(); 55 | let name = name.to_string(); 56 | let date = date.to_string(); 57 | view!(<h3><span class="output-faint">{date}" - "</span><A href={format!("/blog/{path}")}>{name}</A></h3>) 58 | }).collect::<Vec<_>>().into_view() 59 | } 60 | } 61 | } 62 | 63 | #[component] 64 | fn BlogPage(name: String) -> impl IntoView { 65 | view! { 66 | <Title text={format!("{name} - {} Blog", lang())}/> 67 | <A href="/blog">"Back to Blog Home"</A> 68 | <BlogRssButton/> 69 | <br/> 70 | <p> 71 | "This post is available in lightweight " 72 | <a href={format!("https://uiua.org/blog/{name}-html.html")}>"HTML"</a> 73 | " and " 74 | <a href={format!("https://github.com/uiua-lang/uiua/blob/main/site/blog/{name}-text.md")}>"markdown"</a> 75 | " formats." 76 | </p> 77 | <Markdown src={format!("/blog/{name}-text.md")}/> 78 | <br/> 79 | <br/> 80 | <A href="/blog">"Back to Blog Home"</A> 81 | } 82 | } 83 | 84 | #[component] 85 | fn BlogRssButton() -> impl IntoView { 86 | let (copied, set_copied) = create_signal(false); 87 | view! { 88 | <button 89 | href="/blog/feed.rss" 90 | class="editor-right-button" 91 | style="float: right" 92 | data-title={move || if copied.get() { "Copied!" } else { "Copy RSS Feed" }} 93 | on:click=move |_| { 94 | set_copied.set(true); 95 | let host = window().location().host().unwrap(); 96 | _ = window().navigator().clipboard().write_text(&format!("{host}/blog/feed.rss")); 97 | set_timeout( 98 | move || set_copied.set(false), 99 | Duration::from_secs(10), 100 | ); 101 | }> 102 | <img 103 | src="/assets/rss.svg" 104 | alt="RSS Feed" 105 | width="32" 106 | height="32" 107 | style="border-radius: 20%"/> 108 | </button> 109 | } 110 | } 111 | 112 | #[cfg(test)] 113 | #[test] 114 | fn gen_blog_html() { 115 | use std::{borrow::Cow, fs}; 116 | 117 | let list = include_str!("../blog/list.txt"); 118 | for line in list 119 | .lines() 120 | .filter(|line| !line.is_empty() && !line.starts_with('#')) 121 | { 122 | let (path, _) = line.split_once('(').unwrap_or_default(); 123 | let md_path = format!("blog/{}-text.md", path); 124 | let mut markdown = 125 | fs::read_to_string(&md_path).unwrap_or_else(|e| panic!("{md_path}: {e}")); 126 | let mut lines: Vec<Cow<str>> = markdown.lines().map(Cow::Borrowed).collect(); 127 | lines.insert( 128 | 0, 129 | Cow::Borrowed("[Uiua](https://uiua.org)\n\n[Blog Home](https://uiua.org/blog)"), 130 | ); 131 | lines.insert( 132 | 3, 133 | Cow::Owned(format!( 134 | "\n\n**You can read this post with full editor \ 135 | features [here](https://uiua.org/blog/{path}).**\n\n" 136 | )), 137 | ); 138 | markdown = lines.join("\n"); 139 | let html = markdown_html(&markdown); 140 | let html_path = format!("blog/{}-html.html", path); 141 | fs::write(html_path, html).unwrap(); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /site/src/examples.rs: -------------------------------------------------------------------------------- 1 | const AVG: &str = "\ 2 | [1 5 8 2] 3 | ⟜/+ # Sum 4 | ⧻ # Length 5 | ÷ # Divide"; 6 | const X_MATRIX: &str = "\ 7 | ⇡5 # 0 through 4 8 | ˙⊞= # Identity matrix 9 | ⊸⇌ # Reverse 10 | ↥ # Max"; 11 | pub const UIUA: &str = "\ 12 | \"Unabashedly I utilize arrays\" 13 | ⊸≠@ # Mask of non-spaces 14 | ⊜⊢ # All first letters"; 15 | pub const WEEWUH: &str = "\ 16 | \"We each eat whole ugly hams\" 17 | ⊸≠@ # Mask of non-spaces 18 | ⊜⊢ # All first letters"; 19 | const PRIMES: &str = "\ 20 | # Click Run to format! 21 | +1drop1range40 # Range 2 to 40 22 | deshapebytable*. # List of products 23 | keepnotbymember # Keep not in list"; 24 | pub const LOGO: &str = "\ 25 | U ← =∩⌟<0.2 0.7 /+×⟜ⁿ1_2 26 | I ← <⊙(⌵/ℂ) # Circle 27 | u ← +0.1↧¤ ⊃(I0.95|⊂⊙0.5⇌˙×) 28 | A ← ×⊃U(I1) # Alpha 29 | ⍜°⍉(⊂⊃u A) ˙⊞⊟-⊸¬÷⟜⇡200"; 30 | pub const WEEWUH_LOGO: &str = "\ 31 | Wee ← =∩⌟<¯0.5¯0.1 /+⍜⊣(+⊃(×4ⁿ4|ׯ3ⁿ2)) 32 | w ← <⊙(⌵/ℂ) # Circle 33 | u ← +0.1↧¤ ⊃(w0.95|⊂⊙0.5⇌˙×) 34 | h ← ×⊃Wee(w1) # Alpha 35 | ⍜°⍉(⊂⊃u h) ˙⊞⊟-⊸¬÷⟜⇡200"; 36 | const CHORD: &str = "\ 37 | [0 4 7 10] # Notes 38 | ×220 ˜ⁿ2÷12 # Freqs 39 | ∿×τ ⊞× ÷⟜⇡&asr # Generate 40 | ÷⧻⟜/+⍉ # Mix"; 41 | const SPIRAL: &str = "\ 42 | ↯⟜(×20-⊸¬÷⟜⇡)200 # Xs 43 | -⊃∠(⌵ℂ)⊸⍉ # Spiral field 44 | -π◿τ⊞-×τ÷⟜⇡20 # Animate"; 45 | const QUADRATIC: &str = "\ 46 | Disc ← -⊃(××4⊙⋅∘)⋅°√ 47 | Quad ← ÷⊃(×2|-⊃⋅∘(⊟⊸¯ √ℂ0 Disc)) 48 | Quad 1 ¯3 2"; 49 | const STRIPES: &str = "\ 50 | ⍉ ˙[⊞⊃⊃+↥-] ⇡300 51 | ÷2 +1.2 ∿ ÷10"; 52 | pub const PALINDROME: &str = r#"$ uiua racecar wow cool! 53 | ≡⊂ ˜⊏"❌✅" ⬚@ ⊜⊸(≍⊸⇌)⊸≠@ "#; 54 | pub const WEEWUH_PALINDROME: &str = r#"$ weewuh racecar wow cool! 55 | ≡⊂ ˜⊏"❌✅" ⬚@ ⊜⊸(≍⊸⇌)⊸≠@ "#; 56 | const AUTOMATA: &str = "\ 57 | Rule ← ˜⊏⊓⋯₈(°⋯⧈⇌3⊂⊂⊃⊣⟜⊢) 58 | =⌊⊃÷₂⇡ 500 # Init 59 | ⍥⟜⊸Rule ⌊÷2◡⋅⧻ 30 # Run"; 60 | const ROMAN: &str = r#"K ← "IVXLCDM" 61 | N ← [1 5 10 50 100 500 1000] 62 | F ← /+-⊃(↻1×|׬)⊸(⧈>⊂⊙0) ⊏⊙N ⊗⊙K 63 | F "LVII" 64 | F "MCMXCIV""#; 65 | const MANDELBROT: &str = "\ 66 | ×2 ⊞ℂ⤙-1/4 -1/2÷⟜⇡300 # Init 67 | >2⌵ ⍥⟜⊸(+⊙°√) 50 . # Run 68 | ÷⧻⟜/+ # Normalize"; 69 | const LIFE: &str = "\ 70 | Life ← ↥∩=₃⟜+⊸(/+↻⊂A₂C₂) 71 | ⁅×0.6 gen⊙⚂ ˙⊟30 # Init 72 | ⍥⊸Life100 # Run 73 | ≡(▽⟜≡▽) 4 # Upscale"; 74 | 75 | pub const EXAMPLES: &[&str] = &[ 76 | AVG, X_MATRIX, UIUA, PRIMES, LOGO, CHORD, SPIRAL, QUADRATIC, STRIPES, PALINDROME, AUTOMATA, 77 | ROMAN, MANDELBROT, LIFE, 78 | ]; 79 | 80 | #[cfg(test)] 81 | #[test] 82 | fn test_examples() { 83 | use uiua_editor::backend::WebBackend; 84 | 85 | for example in EXAMPLES { 86 | match uiua::Uiua::with_backend(WebBackend::default()).run_str(example) { 87 | Ok(mut comp) => { 88 | if let Some(diag) = comp.take_diagnostics().into_iter().next() { 89 | panic!("Example failed:\n{example}\n{diag}"); 90 | } 91 | } 92 | Err(e) => panic!("Example failed:\n{example}\n{e}"), 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /site/src/idioms.rs: -------------------------------------------------------------------------------- 1 | use leptos::*; 2 | use leptos_meta::*; 3 | use leptos_router::A; 4 | use uiua::Primitive; 5 | use uiua_editor::{lang, Editor}; 6 | 7 | use crate::{Hd, Prim}; 8 | 9 | fn idioms() -> impl IntoView { 10 | let src = include_str!("../text/idioms.ua"); 11 | let mut idioms = Vec::new(); 12 | for text in src.split("\n\n").flat_map(|s| s.split("\r\n\r\n")) { 13 | let mut comment = String::new(); 14 | let mut code = String::new(); 15 | let mut lines = text.split('\n').filter(|line| !line.is_empty()); 16 | for (i, line) in lines.by_ref().enumerate() { 17 | if line.starts_with("# ") { 18 | if i > 0 { 19 | comment.push('\n'); 20 | } 21 | comment.push_str(line.trim_start_matches("# ")); 22 | } else { 23 | code.push_str(line); 24 | for line in lines { 25 | code.push('\n'); 26 | code.push_str(line); 27 | } 28 | break; 29 | } 30 | } 31 | idioms.push(view!(<tr> 32 | <td style="text-wrap: wrap">{comment}</td> 33 | <td><Editor example={&code}/></td> 34 | </tr>)); 35 | } 36 | idioms 37 | } 38 | 39 | fn aliases() -> impl IntoView { 40 | Primitive::non_deprecated() 41 | .filter(|p| !p.aliases().is_empty()) 42 | .map(|p| { 43 | view!(<tr><td><Prim prim=p/></td><td>{ 44 | (p.aliases().iter()) 45 | .map(|&s| view!(<code>{s}</code>" ")) 46 | .collect::<Vec<_>>() 47 | }{ 48 | (p.aliases().iter().any(|a| a.contains("&")) || matches!(p, Primitive::Sys(_))) 49 | .then(|| view!(<span style="opacity: 0.7">"Temporary"</span>)) 50 | }</td></tr>) 51 | }) 52 | .collect::<Vec<_>>() 53 | } 54 | 55 | fn multi_aliases() -> impl IntoView { 56 | Primitive::multi_aliases() 57 | .iter() 58 | .map(|(name, prims)| { 59 | view!(<tr> 60 | <td><code>{*name}</code></td> 61 | <td>{ 62 | prims 63 | .iter() 64 | .map(|(p, _)| view!(<Prim prim=*p/>" ")) 65 | .collect::<Vec<_>>() 66 | }</td> 67 | </tr>) 68 | }) 69 | .collect::<Vec<_>>() 70 | } 71 | 72 | #[component] 73 | pub fn Idioms() -> impl IntoView { 74 | use Primitive::*; 75 | view! { 76 | <Title text=format!("Idioms - {} Docs", lang())/> 77 | <h1>"Idioms"</h1> 78 | <p>"This page contains short "{lang}" idioms that may be non-obvious from simply knowing the primitives themselves."</p> 79 | <p>"There are also lists of "<A href="#aliases">"aliases"</A>" below."</p> 80 | <p>"You can contribute to this list by submitting a PR to the repo. The list is defined "<a href="https://github.com/uiua-lang/uiua/blob/main/site/text/idioms.ua">"here"</a>". Keep in mind these are meant to be both short and useful. Idioms above 10 characters in length (without inputs), or which are not useful for everyday tasks, will not be accepted."</p> 81 | <table class="bordered-table" style="width: 100%; table-layout: fixed"> 82 | <colgroup> 83 | <col style="width: 50%"/> 84 | <col style="width: max(50%, 10em)"/> 85 | </colgroup> 86 | { idioms() } 87 | </table> 88 | 89 | <div class="wider"> 90 | <div> 91 | <Hd id="aliases">"Aliases"</Hd> 92 | <p>"Some primitives have aliases that are not prefixes of the primitive's name, not unique, or less than 3 characters long. These aliases are listed in the table below."</p> 93 | <table class="bordered-table" style="width: 100%"> 94 | <tr><th>"Primitive"</th><th>"Aliases"</th></tr> 95 | { aliases() } 96 | </table> 97 | </div> 98 | <div> 99 | <Hd id="multi-aliases">"Multi-aliases"</Hd> 100 | <p>"Some words serve as an alias for a sequence of primitives. Each primitive is typically represented by a single character in the word."</p> 101 | <Editor example="dor 10 # Try formatting!"/> 102 | <p>"These words are listed in the table below."</p> 103 | <table class="bordered-table" style="width: 100%"> 104 | <tr><th>"Word"</th><th>"Primitives"</th></tr> 105 | { multi_aliases() } 106 | </table> 107 | 108 | <Hd id="planet-aliases">"Planet Aliases"</Hd> 109 | <p>"As discussed in the "<A href="/tutorial/morestack#planet-notation">"Planet Notation"</A>" tutorial, sequences of some primitives can be represented by sequences of corresponding characters. These compose arbitrarily long."</p> 110 | <p>"The rules are:"</p> 111 | <table class="bordered-table all-centered-table" style="width: 100%"> 112 | <tr><th>"Where"</th><th>"Characters"</th><th>"Formats to"</th></tr> 113 | <tr><td>"Inner Sequence"</td><td><code>"d"</code>" / "<code>"g"</code></td><td><Prim prim=Dip/>" / "<Prim prim=Gap/></td></tr> 114 | <tr><td>"Ending"</td><td><code>"i"</code>" / "<code>"p"</code>" / "<code>"f"</code></td><td><Prim prim=Identity/>" / "<Prim prim=Pop/>" / "<Prim prim=Fix/></td></tr> 115 | <tr><td>"Beginning"</td><td><code>"f"</code></td><td><Prim prim=Fork/></td></tr> 116 | </table> 117 | <p>"Some examples:"</p> 118 | <Editor example="[dgdi] 1 2 3 4 # Try formatting!"/> 119 | <Editor example="[fggiddp] 1 2 3"/> 120 | <Editor example="{ddf} 1 2 3"/> 121 | </div> 122 | </div> 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /site/src/uiuisms.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::needless_raw_string_hashes)] 2 | 3 | use leptos::*; 4 | use leptos_meta::*; 5 | use leptos_router::*; 6 | 7 | #[derive(Debug, Clone, PartialEq, Eq, Params)] 8 | pub struct UiuismsParams { 9 | search: Option<String>, 10 | } 11 | 12 | #[component] 13 | pub fn Uiuisms() -> impl IntoView { 14 | view! { 15 | <Title text="Uiuisms - Uiua Docs"/> 16 | <h1>"Uiuisms"</h1> 17 | <p>"This page has been removed."</p> 18 | <ul> 19 | <li>"It provided a 'definitive' implementation of many algorithms where the best implementation is subjective and/or context-dependent"</li> 20 | <li>"It is not how I want people to approach learning Uiua"</li> 21 | <li>"It is not something I am interested in maintaining"</li> 22 | </ul> 23 | <p>"Community member "<strong>"TankorSmash"</strong>" has created a "<a href="https://tankorsmash.unison-services.cloud/s/uiuisms-service/">"new version"</a>"."</p> 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /site/text/code_tactility.md: -------------------------------------------------------------------------------- 1 | # Code Tactility 2 | 3 | One of the strengths of interpreted programming languages, and array languages in particular, is their high level of interactivity. It is very easy to experiment with code, moving data and functions around to get a better sense of the solution to a problem. 4 | 5 | This exercise can be likened to "feeling" the code, turning it around in your hand, poking it, prodding it, inspecting it. 6 | 7 | This section covers a few tools that Uiua provides for making code easier to work with and debug. 8 | 9 | ## [stack]() 10 | 11 | Uiua already prints out any values left on the stack when the program ends. This is usually enough for smaller programs, but sometimes, you need to be able to see what values are on the stack somewhere in the middle of the code. 12 | 13 | [stack]() was mentioned near the [beginning](/tutorial/basic#stack) of this tutorial. It prints out values from the stack without removing them. Subscripting [stack]() prints out only that many values. 14 | 15 | ```uiua 16 | 5 ? 1 [2 3] "uiua" 17 | ``` 18 | 19 | ```uiua 20 | 5 1 ?₁ ⇡3 "uiua" 21 | ``` 22 | As you can see, the line and column number is also printed. 23 | 24 | The formatter will convert multiple `?`s that come immediately after [stack]() a subscript. Try it below. 25 | 26 | ```uiua 27 | ??? √5 7 10 28 | ``` 29 | 30 | [stack]() will show you the boundaries of the functions that values are used in. 31 | 32 | ```uiua 33 | G ← /+?⇡ 34 | F ← ×G 35 | F 10 4 36 | ``` 37 | 38 | [stack]() allows you to inspect the stack at a given place in the code. It makes it easy to get a quick sense of what values a function is working with. 39 | 40 | ## Labels 41 | 42 | Labels allow you to tag an array with a debug-only name. They are written with a `$` immediately followed by an identifier. 43 | 44 | ```uiua 45 | $Numbers [1 2 3] 46 | ``` 47 | 48 | Labels are *only* visible in debugging outputs. This includes normal interpreter output as well as [stack](). 49 | 50 | Labels will *not* be shown when arrays are formatted using [`&p`]() or format strings. 51 | 52 | ```uiua 53 | &p $"--_--" . $TheThing ⇡5 54 | ``` 55 | 56 | You can easily label multiple values with [bracket](). 57 | 58 | ```uiua 59 | ⊓$Foo$Bar °⊂ [2 3 5 7] 60 | ``` 61 | 62 | Labeled arrays cannot be put into arrays together unless they are boxed. 63 | 64 | ```uiua 65 | [$a 1 $b 2 $c 3] # Wrong 66 | ``` 67 | ```uiua 68 | {$a 1 $b 2 $c 3} # Right 69 | ``` 70 | 71 | Labels are nice for keeping track of different values as they move around the stack. 72 | 73 | It is not possible to retrieve the label of a value using code. Labels are only for debugging, not for carrying data. 74 | 75 | ## Line Manipulation 76 | 77 | Uiua running code right-to-left has a couple unfortunate side effects when it comes to editing. The first you're likely to run into is having to constantly press the `←` key on your keyboard to move the cursor to the left. 78 | 79 | If you type a `;` character, the formatter will flip the current line across it. This allows you to enter code in the same order it is executed. 80 | 81 | ```uiua 82 | ⇡12;↯3_4 # Format to flip! 83 | ``` 84 | 85 | You can put many `;`s on the same line. 86 | ```uiua 87 | 1;2;3;4 88 | ``` 89 | 90 | Another problem is that if you want to split a line of code into two lines, it is not enough to simply place your cursor at the split point and press Enter, as this puts the lines in the wrong order! 91 | 92 | Instead, you can type `;;` at the point you want to split the code. Upon formatting, the line will be split in a way that preserves the same meaning! 93 | 94 | ```uiua 95 | ↥⊸⇌;;⊞=.⇡5 # Format to split! 96 | ``` 97 | 98 | You can put as many of these splitters in your code as you like, and the formatter will handle them all at once. 99 | 100 | ```uiua 101 | "lines";;"the";;"all";;"Split" 102 | ``` 103 | 104 | If used in a binding, the code will be wrapped in `()`s. 105 | 106 | ```uiua 107 | F ← ⁅≡₀⋅⚂;;↯⟜⊚ # Format it! 108 | F 5 109 | ``` 110 | 111 | Putting a splitter at the beginning or end of a line will *join* lines rather than splitting them. 112 | 113 | ```uiua 114 | 1 2 115 | ;3 4 116 | ``` 117 | 118 | ```uiua 119 | "Oh"; 120 | "boy!" 121 | ``` 122 | -------------------------------------------------------------------------------- /site/text/experimental.md: -------------------------------------------------------------------------------- 1 | ## Data Definitions 2 | 3 | [Data definitions](/tutorial/datadefs) have a few experimental features. 4 | 5 | ### Data Functions 6 | 7 | If the fields of a data definition are immediately follwed by some code, the data definition becomes a *data function*. Data functions have a `Call` function defined which is invoked instead of the normal `New` constructor when the data definition's name is used as a function. 8 | 9 | The normal constructor is called, then the constructed data is passed to the function. 10 | 11 | ```uiua 12 | # Experimental! 13 | ~Person {Name Surname ← ""} $"_ _"⊃(Name|Surname) 14 | Person "Dave" 15 | ``` 16 | 17 | But if the function is called immediately, how do we set `Surname`? 18 | 19 | In this case `Surname` is an *optional argument*. We can set optional arguments with their name followed by a `:` before calling the function. 20 | 21 | ```uiua 22 | # Experimental! 23 | ~Person {Name Surname ← ""} $"_ _"⊃(Name|Surname) 24 | Person "Dave" Surname:"Daveson" 25 | ``` 26 | 27 | The argument setter is just a `|1.0` function. Setters for multiple optional arguments can occur in any order. 28 | 29 | ```uiua 30 | # Experimental! 31 | ~F {A ← 0|B ← 0|C ← 0|D ← 0} ∘ 32 | F D:1 ⊓A:C: 2 B:3 4 33 | ``` 34 | 35 | We can bundle the function's arguments before calling it with the data definition's normal `New` constructor. The bundled arguments can then be used with the `Args` function. Both of these functions also accept optional arguments. 36 | 37 | ```uiua 38 | # Experimental! 39 | ~Run {A ← 0|B ← 1|C} $"A:_ B:_ C:_"⊃(A|B|C) 40 | Run 2 41 | Run~New A:2 5 42 | Run~Args B:8 . 43 | ``` 44 | 45 | If some argument patterns are common, we can give them names by putting the data function in a module and adding more functions (or even more data functions) to it. 46 | 47 | ```uiua 48 | # Experimental! 49 | ┌─╴Range 50 | ~ {Min ← 0|Max Inclusive ← 0} ⍜-⇡ ⊃Min(+⊃Max Inclusive) 51 | ~Incl {Min ← 0} Call Inclusive:1 Min:Min 52 | APL ← Call Inclusive:1 Min:1 53 | └─╴ 54 | Range 5 55 | Range~APL 5 56 | Range Min:4 10 57 | Range~Incl Min:4 10 58 | ``` 59 | 60 | Optional arguments *must* be used by the first named call (including primitives without glyphs). 61 | 62 | ```uiua should fail 63 | # Experimental! 64 | ~F {A ← 0|B ← 0} ∘ 65 | A:5 66 | ``` 67 | 68 | ```uiua should fail 69 | # Experimental! 70 | ~F {A ← 0|B ← 2} ∘ 71 | F C:6 72 | ``` 73 | 74 | Optional arguments can be set from scopes lower than the function that uses them, but the opposite is not true. 75 | 76 | ```uiua 77 | # Experimental! 78 | ~F {A ← 0|B ← 0} ∘ 79 | F (A:5) 80 | ``` 81 | 82 | ```uiua should fail 83 | # Experimental! 84 | ~F {A ← 0|B} ≡°□ 85 | ≡F A:5 ⇡3 86 | ``` 87 | 88 | To set an optional argument for a function inside a modifier, set the argument inside the modifier itself. 89 | 90 | ```uiua 91 | # Experimental! 92 | ~F {A ← 0|B} ≡°□ 93 | ≡(F A:) 5 ⇡3 94 | ``` 95 | 96 | --- 97 | 98 | ### Validators 99 | 100 | You can add validation functions to a field. This function will be called both upon construction (after the initializer) and upon mutation. 101 | 102 | The function should come after the name and a `:`, but before the initializer. 103 | 104 | A common use case for this is to validate the type of a field. 105 | 106 | ```uiua should fail 107 | # Experimental! 108 | ~MyData {Foo: °0type|Bar: °1type} 109 | MyData 1 "hi" # Works 110 | MyData 3 5 # Fails 111 | ``` 112 | 113 | ```uiua should fail 114 | # Experimental! 115 | ~MyData {Foo: °0type|Bar: °1type} 116 | MyData 1 "hi" 117 | °⊸MyData~Bar 5 118 | ``` 119 | 120 | ## Lexical Ordering 121 | 122 | Consider this example: 123 | 124 | ```uiua 125 | 3 6 126 | ⊃(+ 127 | | - 128 | | × 129 | | ÷ 130 | ) 131 | ``` 132 | Notice that even though [divide](/docs/divide) is on the last line of the pack, its result (`2`) is *under* the results of all the other functions. This is because the collapsed version of this code looks like this: 133 | 134 | ```uiua 135 | ⊃(+|-|×|÷) 3 6 136 | ``` 137 | 138 | Those need to do the same thing for consistency reasons, but the first example seems backwards! The function that is further down in the actual source runs first, so to read in execution order, we have to read from the bottom up. 139 | 140 | To solve this, we can prefix function pack with a `↓` symbol, which formats from `|,`. See how it changes the flow of the pack: 141 | 142 | ```uiua 143 | # Experimental! 144 | 3 6 145 | ⊃↓( 146 | + 147 | | - 148 | | × 149 | | ÷ 150 | ) 151 | ``` 152 | Now the result of `÷` is at the top of the stack! Each function in the pack lines up with its result in the output. 153 | 154 | Note that collapsing this code actually changes its behavior. 155 | 156 | ```uiua 157 | # Experimental! 158 | ⊃↓(+|-|×|÷) 3 6 159 | ``` 160 | 161 | This is because a pack with a `↓` ignores syntax tree ordering and only considers the layout of the code in the actual source. 162 | 163 | This kind of function pack is said to be *lexically ordered*. 164 | 165 | The lexical ordering symbol `↓` can also be used on stack array notation to make the lines run in the normal top-down order instead of bottom-up. 166 | 167 | ```uiua 168 | # Experimental! 169 | [1 2 170 | 3 4] 171 | ``` 172 | 173 | ```uiua 174 | # Experimental! 175 | ↓[1 2 176 | 3 4] 177 | ``` 178 | 179 | ## [derivative](/docs/derivative) and [integral](/docs/integral) 180 | 181 | These modifiers transform a mathematical expression. 182 | 183 | Currently, only polynomials are supported. 184 | 185 | ```uiua 186 | # Experimental! 187 | ∂(×.) 5 # x² → 2x 188 | ∂√ 1/9 # √x → 1/(2√x) 189 | ∂(-4+⊃(ⁿ2|ׯ2)) [0 1 2] # x² - 2x - 4 → 2x² - 2x 190 | ``` 191 | 192 | ```uiua 193 | # Experimental! 194 | ∫(×.) 3 # x² → x³/3 195 | ∫√ 1 # √x → (2x^1.5)/3 196 | ∫(+5×2) 2 # 2x + 5 → x² + 5x 197 | ``` -------------------------------------------------------------------------------- /site/text/files_and_streams.md: -------------------------------------------------------------------------------- 1 | # Files and Streams 2 | 3 | Uiua has support for reading and writing files from the filesystem. It has helper functions for reading and writing entire files, as well as a stream abstraction for processing files in chunks. This stream abstraction extends to other input/output sources, such as network sockets. 4 | 5 | ## Reading and Writing Entire Files 6 | 7 | Loading an entire file into an array is very simple. 8 | For demonstration purposes, this website has a built-in file called `example.txt` that we will work with. 9 | 10 | We can read an entire file as a string with [`&fras`]() (file read all string). 11 | 12 | ```uiua 13 | &fras "example.txt" 14 | ``` 15 | 16 | If we instead want to read the file into an array of bytes, we can use [`&frab`]() (file read all bytes). 17 | 18 | ```uiua 19 | &frab "example.txt" 20 | ``` 21 | 22 | To write an entire array to a file, we can use [`&fwa`]() (file write all). The type of the array determines whether the file is written as text or binary. 23 | 24 | ```uiua 25 | &fwa "file.txt" "Hello, world!" 26 | ``` 27 | 28 | Each editor on this site has a virtual file system, which means that we can read from files after they have been written to. This is useful for testing file writing functions. 29 | 30 | ```uiua 31 | &fwa "file.bin" ⇡10 32 | &frab "file.bin" 33 | ``` 34 | 35 | ## Streams 36 | 37 | Stream are an abstraction for sending and receiving data in chunks from some source. Similar concepts exist in many programming languages, inluding Uiua. 38 | 39 | In this tutorial, we will focus on using streams to interact with files. However, Uiua also uses streams for other input/output sources, particularly network sockets. 40 | 41 | ## Reading Streams 42 | 43 | Streams in Uiua are passed around as *handles* - boxed integer values that can be used to look up the stream in the interpreter. Functions that create streams return these handles, and they attach some metadata about what kind of stream it is for debugging purposes. 44 | 45 | We can use [`&fo`]() (file open) to open a file for reading. This function returns a stream handle. 46 | 47 | ```uiua 48 | &fo "example.txt" 49 | ``` 50 | 51 | There are a few functions for reading from streams. The most basic two are [`&rs`]() (read string) and [`&rb`]() (read bytes). These functions read at most a certain number of bytes from the stream and return them as a character or byte array, respectively. 52 | 53 | Here, we open a file with [`&fo`]() and then read 10 bytes from it. [`&rb`]() simply puts the bytes in an array, while [`&rs`]() converts them to a string. 54 | ``` 55 | &rb 10 &fo "example.txt" 56 | &rs 10 &fo "example.txt" 57 | ``` 58 | 59 | If we pass [`infinity`]() as the number of bytes to read, the stream will read until the end of the file. This is functionally equivalent to [`&fras`]() or [`&frab`](). 60 | 61 | ```uiua 62 | &rs ∞ &fo "example.txt" 63 | ``` 64 | 65 | If we want to read up until some delimiter, we can use [`&ru`]() (read until). This function reads from the stream until it encounters a certain sequence of characters or bytes, and returns everything up to that point. 66 | If the delimiter is not found, the function will read until the end of the stream. 67 | 68 | ```uiua 69 | &ru "file" &fo "example.txt" 70 | ``` 71 | 72 | In general, you only need to use streams to read from a file if the file is too large to fit in memory. For most use cases, [`&fras`]() and [`&frab`]() are sufficient. 73 | 74 | ## Writing Streams 75 | 76 | The [`&w`]() (write) function writes a character or byte array to a stream. It takes the data to write and the stream handle as arguments. 77 | 78 | ```uiua 79 | &w "Hello, world!" &fc "file.txt" 80 | ``` 81 | 82 | But wait, if we try to read from the file now, it is empty! 83 | 84 | ```uiua 85 | &w "Hello, world!" &fc "file.txt" 86 | &fras "file.txt" 87 | ``` 88 | 89 | This is because the writes we have made have not been flushed to the file. 90 | Streams should always be closed with [`&cl`]() (close) when they are no longer needed. This will flush any remaining writes to the file and close the file handle. 91 | 92 | ```uiua 93 | &cl &w "Hello, world!" . &fc "file.txt" 94 | &fras "file.txt" 95 | ``` 96 | 97 | Knowing this, we see that the examples in the section above are actually incorrect! We should close the file even after reading from it. 98 | 99 | [`under`]() can help here. It will automatically close the stream with [`&cl`]() after the block of code is executed. 100 | 101 | ```uiua 102 | ⍜(&fc "file.txt"|&w "Hello, world!") 103 | &fras "file.txt" 104 | ``` -------------------------------------------------------------------------------- /site/text/format_config.md: -------------------------------------------------------------------------------- 1 | 2 | # Uiua Formatter Configuration 3 | 4 | You can configure Uiua's formatter by creating a file called `.fmt.ua` in the directory from which you run the interpreter. This configuration file is also a Uiua program. 5 | 6 | Configuration options are specified by binding values to specific names. 7 | 8 | Example with default values: 9 | ```uiua 10 | TrailingNewline ← 1 11 | CommentSpaceAfterHash ← 1 12 | MultilineIndent ← 2 13 | AlignComments ← 1 14 | IndentItemImports ← 1 15 | ``` 16 | The following configuration options are available: 17 | 18 | ### TrailingNewline 19 | Type: boolean 20 | 21 | Default: `1` 22 | 23 | Whether to add a trailing newline to the output. 24 | 25 | --- 26 | 27 | ### CommentSpaceAfterHash 28 | Type: boolean 29 | 30 | Default: `1` 31 | 32 | Whether to add a space after the `#` in comments. 33 | 34 | --- 35 | 36 | ### MultilineIndent 37 | Type: natural number 38 | 39 | Default: `2` 40 | 41 | The number of spaces to indent multiline arrays and functions 42 | 43 | --- 44 | 45 | ### AlignComments 46 | Type: boolean 47 | 48 | Default: `1` 49 | 50 | Whether to align consecutive end-of-line comments 51 | 52 | --- 53 | 54 | ### IndentItemImports 55 | Type: boolean 56 | 57 | Default: `1` 58 | 59 | Whether to indent item imports 60 | 61 | --- 62 | 63 | -------------------------------------------------------------------------------- /site/text/idioms.ua: -------------------------------------------------------------------------------- 1 | # Enumerate an array, but keep it on the stack 2 | °⊏ "Hello" 3 | 4 | # Create an incrementing array with the given shape 5 | # Useful for testing 6 | °△3_4 7 | 8 | # Remove a row at an index 9 | ⍜↻↘₁ 2 "abcde" 10 | 11 | # Replace a row at an index 12 | ⍜⊡◌ 2 [1 2 3 4] 10 13 | ⍜⊙⊡⊙◌ 10 2 [1 2 3 4] 14 | 15 | # Split on a scalar 16 | ⊜□⊸≠ @, "a,bc,d" 17 | °/$"_,_" "a,bc,d" 18 | 19 | # Split on a list 20 | ⊜□¬⊸⦷ " - " "a - bc - d" 21 | °/$"_ - _" "a - bc - d" 22 | 23 | # Check that all rows of an array are equal 24 | ≍⊸↻1 [5 5 5] 25 | ≍⊸↻1 [1 2 3] 26 | 27 | # Get the prime factorization of a number 28 | # (or array of numbers) 29 | °/× 84 30 | 31 | # Scale an array along the first two axes 32 | # Useful for scaling images 33 | # Can scale both up and down 34 | ▽⟜≡▽ 2 [1_2 3_4] 35 | -------------------------------------------------------------------------------- /site/text/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Welcome to the Uiua tutorial! Each page of this tutorial will introduce you to a new concept in the language. The tutorial is designed to be read in order, but you can jump around if you want. 4 | 5 | Uiua is an array programming language in the same family as APL, J, and BQN. Uiua focuses particularly on tacit programming, that is, writing code without naming variables. It does this by putting all values on a global stack. 6 | 7 | ## What is Array Programming? 8 | 9 | Before jumping into Uiua, it may be helpful to understand the paradigm of which it is a part. 10 | 11 | [Array Programming](https://en.wikipedia.org/wiki/Array_programming) is a way of writing programs first developed by Ken Iverson in the 1960s. It emphasizes the use of arrays as the primary data structure, and many operations work on entire arrays at once. An array language also has a rich set of operations for manipulating arrays in various ways, to the point where many data structures and control flow constructs are replaced with operations on arrays. 12 | 13 | ## Why Array Programming? 14 | 15 | There are many reasons that Array Programming is cool, but here are a few: 16 | 17 | Perhaps the most practical reason is that arrays as a data structure are what some refer to as "machine-sympathetic". Because array elements exist in contiguous memory, they can be processed very quickly by modern CPUs. Many operations can be *vectorized*, meaning that the CPU can apply the operation to many elements in parallel. In addition, allocating memory for a large array can be done all at once. Although most array languages are dynamic and interpreted, they can often compete in performance with compiled, static languages, at least for certain kinds of tasks. 18 | 19 | Array programming can change the way you think about programs. All operations you use act on a single, unified data structure. You stop thinking about individual items and start thinking about entire collections and how they can interact and transform. 20 | 21 | Finally, many common algorithms are built-in to array languages, and are often written with a single glyph. This makes array code very concise and expressive. Several lines of code in a language like C or Python can often be just a few characters in an array language. Array languages do away with much of the *ceremony* that is present in other languages, so you can focus more on the problem you are trying to solve. 22 | 23 | ## Why Uiua? 24 | 25 | Uiua retains many of the array operations and semantics of its predecessor array languages. However, while APL, J, and BQN structure code with syntax and semantics based on mathematical notation: 26 | 27 | `1 + 2`, `4×ω-2`, etc. 28 | 29 | Uiua puts values on a stack, and operators appear to the left of their arguments: 30 | 31 | `+ 1 2`, `×4-2`, etc. 32 | 33 | This allows Uiua to be, in most cases, even more terse than other array languages. That being said, Uiua has been designed to remain readable as much as possible, even without named local variables. While writing tacit code can quickly become unwieldy in other array languages, Uiua embraces tacitness as the only way. 34 | 35 | Uiua also features built-in functionality for working with images, audio, and GIFs, so once you learn the language, you can very quickly get started writing programs that do interesting things! 36 | 37 | Note that Uiua is not yet stable. While most of the core features are unlikely to change much, more complex ones are still in flux. This tutorial is based on the current state of the language, and it is updated as the language changes. 38 | 39 | **Important Note**: This website usually uses the most recent development version of Uiua, rather than the stable release. This is so people can test new features easily. Some features available here may not be available if you install Uiua locally in the default way. The version of Uiua currently running on this site is `UIUA_VERSION`. 40 | 41 | ## Who is this tutorial for? 42 | 43 | This tutorial is targeted at people who have at least a little bit of experience with programming. While you don't need to be proficient in any particular language, it will be helpful to understand concepts like variables and functions. However, even if you are a beginner, you can likely find your way through by taking the time to understand each example. 44 | 45 | Click the link to the next section to get started! 46 | -------------------------------------------------------------------------------- /site/text/more_array.md: -------------------------------------------------------------------------------- 1 | # More Array Manipulation 2 | 3 | Sometimes the operation you need to perform on an array is more complicated than modifiers like [reduce](), [rows](), or [table]() allow. 4 | 5 | ## [fix]() 6 | 7 | [rows]() can be used to iterate over multiple arrays. The nth row of each array will be passed to the function, and the result will be put in a new array. 8 | 9 | ```uiua 10 | ≡⊂ 1_2_3 4_5_6 11 | ``` 12 | 13 | This works because both arrays have the same shape (in this case, `[3]`). If they didn't, we would get an error. 14 | 15 | ```uiua should fail 16 | ≡⊂ 1_2_3 4_5 17 | ``` 18 | 19 | However, there is an exception to this rule. If one of the arrays has exactly one row, that array will be repeated for each row of the other array. This includes scalars. 20 | 21 | ```uiua 22 | ≡⊂ 1 2_3_4 23 | ``` 24 | 25 | ```uiua 26 | ≡⊂ 1_2_3 4 27 | ``` 28 | 29 | ```uiua 30 | ≡⊂ [1_2] 3_4_5 31 | ``` 32 | 33 | ```uiua 34 | ≡⊂ 1_2_3 [4_5] 35 | ``` 36 | 37 | Notice how in this last example, the array `[4_5]` is an array of a single row, so that row is repeated across all iterations. It would be equivalent to: 38 | 39 | ```uiua 40 | [ 41 | ⊂ 1 4_5 42 | ⊂ 2 4_5 43 | ⊂ 3 4_5 44 | ] 45 | ``` 46 | 47 | The [fix]() function turns an array into an array of a single row by prepending a `1` to the array's shape. This is equivalent to wrapping in `[]` as above, but it is shorter and better communicates the intention of "fixing" an array during iteration. 48 | 49 | ```uiua 50 | ¤1_2_3 # Fixing is equivalent to... 51 | [1_2_3] # ...surrounding with brackets 52 | ``` 53 | 54 | With [fix](), we can rewrite the previous examples. 55 | 56 | ```uiua 57 | ≡⊂ ¤1_2 3_4_5 58 | ``` 59 | 60 | ```uiua 61 | ≡⊂ 1_2_3 ¤4_5 62 | ``` 63 | 64 | If we have several arrays and want to choose which ones are fixed and which are not, we can use planet notation. 65 | 66 | ```uiua 67 | ≡⊂ ⊙¤ 1_2_3 4_5_6 68 | ``` 69 | 70 | ```uiua 71 | ≡(⊂⊂⊂) ⊙∩¤ 1_2_3 4_5_6 7_8_9 10_11_12 72 | ``` 73 | 74 | [fix]() also works with pervasive dyadic functions without [rows](). 75 | 76 | ```uiua 77 | + [1 2 3] [10 20 30] 78 | + ¤[1 2 3] [10 20 30] 79 | + [1 2 3] ¤[10 20 30] 80 | ``` 81 | 82 | ```uiua should fail 83 | - 1_2 [3_4 5_6 7_8] 84 | ``` 85 | 86 | ```uiua 87 | -¤1_2 [3_4 5_6 7_8] 88 | ``` 89 | 90 | ## Sided [rows]() 91 | 92 | Needing [fix]() or `dipfix` with [rows]() is extremely common. However, it can be a bit odd to read when you [fix]()ing is detatched from the [rows]() itself. 93 | 94 | For this reason, [rows]() supports *sided* subscripts. This syntax allows you to specify a "side" for a modifier or function. 95 | 96 | Sided subscripts are typed with `__` followed by a `<` for left or a `>` for right. The formatter will turn them into subscript bottom corner characters. 97 | 98 | Left [rows]() [fix]()es the first argument and right [rows]() [fix]()es the last argument. 99 | 100 | ```uiua 101 | ≡⌞⊂ "ro" "wt" # Reuses "ro" 102 | ≡⌟⊂ "cm" "at" # Reuses "at" 103 | ``` 104 | 105 | This makes the actual behavior of [rows]() here more visually apparent. 106 | 107 | A number can be specified after the side to [fix]() multiple arguments. 108 | 109 | ```uiua 110 | # Try formatting! 111 | ≡__<2(⊂⊂) "ui" "ua" "ns" 112 | ``` 113 | 114 | While [fix]() is still necessary for certain complex cases, sided subscripts should work about 95% of the time. 115 | 116 | [rows]() can accept both numeric and sided subscripts at the same time. The number to select the rank comes before the side indicator. 117 | 118 | ```uiua 119 | ≡₂⌟₁□₃ °△2_2_3 "hi" "there" 120 | ``` 121 | 122 | ## Operating at Different Ranks 123 | 124 | [rows]() is the bread and butter of traversing an array's structure. It calls its function on each row of an array, but what if you want to go deeper? 125 | 126 | One option is to simply chain [rows]() multiple times. 127 | 128 | ```uiua 129 | ≡□ °△ 2_3_4 130 | ≡≡□ °△ 2_3_4 131 | ≡≡≡□ °△ 2_3_4 132 | ``` 133 | 134 | This can get a bit unwieldy if an array has a lot of dimensions. You can instead use [numeric subscripts](/tutorial/morestack#subscripts) with [rows]() to specify the rank of the arrays you want to work on. 135 | 136 | ```uiua 137 | ≡₀□ °△ 2_3_4 # Scalars 138 | ≡₁□ °△ 2_3_4 # Vectors 139 | ≡₂□ °△ 2_3_4 # Matrices 140 | ≡₃□ °△ 2_3_4 141 | ``` 142 | 143 | This is useful when you are approaching the array's structure from the bottom up, but what if you want to start at the top, like [rows]() normally does? 144 | This is what *negative* subscripts do. [rows]()`₋₁` is equivalent to normal [rows](), [rows]()`₋₂` is equivalent to `rowsrows`, etc. 145 | 146 | ```uiua 147 | ≡₋₁□ °△2_3_4 148 | ≡₋₂□ °△2_3_4 149 | ≡₋₃□ °△2_3_4 150 | ``` 151 | 152 | Sometimes you simply want to collapse the dimensions of an array to make it a certain rank. This can be done with subscripted [deshape](). 153 | 154 | ```uiua 155 | △ ♭ °△2_3_4_5 156 | △ ♭₂ °△2_3_4_5 157 | △ ♭₃ °△2_3_4_5 158 | △ ♭₄ °△2_3_4_5 159 | ``` 160 | 161 | Combined with [range](), this is a nice way to generate all combinations of indices given a list of maximums. 162 | 163 | ```uiua 164 | ⍉ ♭₂ ⇡2_2_3 165 | ``` 166 | 167 | Subscripting these works in the vast majority of cases. However, subscripts are static. The rank to use cannot be taken from the stack. 168 | 169 | In the rare event that you need a dynamic rank, you can use the `unby` `(` `lengthshape` `)` idiom introduced in the [Inverses](/tutorial/inverses#un-by) tutorial. 170 | 171 | ```uiua 172 | ⍉ °⊸(⧻△) 2 ⇡2_2_2 173 | ``` 174 | 175 | ```uiua 176 | °⊸(⧻△) 1 °△2_3_3 177 | ``` 178 | -------------------------------------------------------------------------------- /site/text/ranges.md: -------------------------------------------------------------------------------- 1 | # Ranges 2 | 3 | Working with regular sequences of numbers is a common task in programming. Many languages handle this with with a `for` loop, but Uiua uses the same construct it uses for most things: arrays. 4 | 5 | ## [`range`]() 6 | 7 | [`range`]() is the fundamental range-generating function. It generates an array that is the range of integers `[0, n)`. 8 | 9 | ```uiua 10 | ⇡5 11 | ⇡12 12 | ``` 13 | 14 | If you want to include the end value to get the range `[0, n]`, you can [`add`]()`1` first. 15 | 16 | ```uiua 17 | ⇡+1 5 18 | ⇡+1 12 19 | ``` 20 | 21 | [`add`]()`1` afterward to get the range `[1, n]`. 22 | 23 | ```uiua 24 | +1⇡ 5 25 | +1⇡ 12 26 | ``` 27 | 28 | The [`range`]() of a negative number gives the range `(0, n]`. 29 | ```uiua 30 | ⇡¯5 31 | ⇡¯12 32 | ``` 33 | 34 | ## [`under`]() Tricks 35 | 36 | [`under`]() makes getting more complex ranges simple. 37 | 38 | For example, here is a simple way to get the range `[a, b)`: 39 | 40 | ```uiua 41 | ⍜-⇡ 3 10 42 | ``` 43 | The order of operations here is: 44 | - Subtract `3` from `10` to get `7` 45 | - Generate the range `[0, 7)` 46 | - Add `3` back to that range to get `[3, 10)` 47 | 48 | The definition of [`range`]() on negative numbers means that this idiom also works in reverse. 49 | 50 | ```uiua 51 | ⍜-⇡ 10 3 52 | ``` 53 | 54 | You can replace [`subtract`]() with [`divide`]() to use a step size. 55 | 56 | ```uiua 57 | ⍜÷⇡ 0.5 4 58 | ``` 59 | 60 | This only works if the numbers are divisible. If they are not, you need to use [`floor`](), [`ceiling`](), or [`round`](). 61 | 62 | ```uiua 63 | ⍜÷(⇡⌊) 3 10 64 | ⍜÷(⇡⌈) 3 10 65 | ⍜÷(⇡⁅) 3 10 66 | ``` 67 | 68 | These techniques can be combined to get more complex ranges: 69 | 70 | ```uiua 71 | ⍜(÷⊙-|⇡⌈) 3 10 20 72 | ``` 73 | 74 | ## [`un`]() Ranges 75 | 76 | It is often necessary to generate a range that has as many elements as an array has rows. 77 | 78 | The intuitive way to do this is with [`length`](). 79 | 80 | ```uiua 81 | ⇡⧻. "Hello!" 82 | ``` 83 | 84 | This is a very common operation. [`un`]() [`select`]() is defined as a shortcut for this. 85 | [`select`]() takes a list of indices, so [`un`]() [`select`]() *returns* a list of indices. 86 | 87 | ```uiua 88 | °⊏ "Hello!" 89 | ``` 90 | 91 | This same pattern is used for the [`un`]()-inverses of [`pick`]() and [`orient`](). 92 | 93 | ```uiua 94 | A ← ["Hello" "World"] 95 | ≍ ⊃(⇡⧻|⊙◌°⊏) A # Range of length 96 | ≍ ⊃(⇡△|⊙◌°⊡) A # Range of shape 97 | ≍ ⊃(⇡⧻△|⊙◌°⤸) A # Range of rank 98 | ``` 99 | 100 | It is simple to verify that these inverses are correct. 101 | 102 | ```uiua 103 | A ← ["Hello" "World"] 104 | ⊏°⊏ A 105 | ⊡°⊡ A 106 | ⤸°⤸ A 107 | ``` 108 | -------------------------------------------------------------------------------- /site/text/testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Testing is important for ensuring that code works as expected, especially in a dynamic language like Uiua. 4 | 5 | The language has a couple built-in mechanisms for streamlining testing. 6 | 7 | ## [assert](/docs/assert) Tests 8 | 9 | The [assert](/docs/assert) function will return an error when its second argument is anything other than `1`. 10 | 11 | While this can be used in some forms of [control flow](/tutorial/controlflow), it is also useful for testing. 12 | 13 | When testing is enabled (as it is in all editors on this website), a line with [assert](/docs/assert) at the beginning will be interpreted as a test. 14 | 15 | ```uiua should fail 16 | Square ← ×. 17 | ⍤. =9 Square 3 18 | ⍤. =12 Square 4 19 | ⍤. =225 Square 15 20 | ``` 21 | 22 | As you can see, these when one of these top-level [assert](/docs/assert)s fails, the program continues running. 23 | When the program is done running, the successes and failures are aggregated and displayed. 24 | 25 | ## Test Scopes 26 | 27 | A [scoped module](/tutorial/modules#scoped-modules) with the name `test` is special in that code inside it will *not* be run when using the `uiua run` command. The `uiua test` and `uiua watch` commands *will* run test scope code. Test scopes are also always run on this website. 28 | 29 | ```uiua 30 | Square ← ×. 31 | ┌─╴test 32 | ⍤. =9 Square 3 33 | ⍤. =225 Square 15 34 | └─╴ 35 | ``` 36 | 37 | Importantly, `uiua run` will not run test scopes, but it will *also* not interpret any [assert](/docs/assert)s as tests. 38 | 39 | ## Testing Patterns 40 | 41 | The first argument to [assert](/docs/assert) is the value that will be thrown if the assertion fails. In the examples above, we have simply been [duplicate](/docs/duplicate)ing the test value. We can throw a message instead. 42 | 43 | If the result does not match the expectation, that incorrect result will be thrown. 44 | 45 | ```uiua should fail 46 | Square ← ×. 47 | ⍤"3² is not 9!" =9 Square 3 48 | ⍤"4² is not 12!" =12 Square 4 49 | ⍤"15² is not 225!" =225 Square 15 50 | ``` 51 | 52 | One nice pattern for writing tests is to put the expected result before the test computation and use `assert``with``match`. This has the nice mnemonic spelling "assert with match". 53 | 54 | This should be immediately followed by the expected result. 55 | 56 | ```uiua should fail 57 | Square ← ×. 58 | ⍤⤙≍ 9 Square 3 59 | ⍤⤙≍ 12 Square 4 60 | ⍤⤙≍ 225 Square 15 61 | ⍤⤙≍ [1 2 3] ⊂ 1 [2 3] 62 | ``` 63 | 64 | Notice how the expected value appears in the error message. 65 | 66 | ```uiua 67 | F ← ⍣⍜⊢(+1)∘ 68 | ┌─╴test 69 | ⍤⤙≍ [2 2 3] F [1 2 3] 70 | ⍤⤙≍ [4 5 7] F [3 5 7] 71 | ⍤⤙≍ "viua" F "uiua" 72 | ⍤⤙≍ [] F [] 73 | └─╴ 74 | ``` 75 | 76 | If a function returns multiple values, you can simply box them with `{}`s. 77 | 78 | ```uiua 79 | ⍤⤙≍ {1 2_3} {°⊂} [1 2 3] 80 | ⍤⤙≍ {1_2 3_4_5} {⊃↙↘2} [1 2 3 4 5] 81 | ``` -------------------------------------------------------------------------------- /site/trunk.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | dist = "../docs" 3 | no_sri = true 4 | public_url = "/" 5 | 6 | [watch] 7 | watch = [".", "../src", "../pad/editor", "../changelog.md"] 8 | 9 | [serve] 10 | address = "0.0.0.0" 11 | port = 8080 12 | -------------------------------------------------------------------------------- /src/algorithm/Uiua386.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/src/algorithm/Uiua386.ttf -------------------------------------------------------------------------------- /src/assets/cats.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/src/assets/cats.webp -------------------------------------------------------------------------------- /src/assets/cats_depth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/src/assets/cats_depth.png -------------------------------------------------------------------------------- /src/assets/elevation.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/src/assets/elevation.webp -------------------------------------------------------------------------------- /src/assets/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/src/assets/lena.jpg -------------------------------------------------------------------------------- /src/assets/lena_depth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/src/assets/lena_depth.png -------------------------------------------------------------------------------- /src/assets/uiua-logo-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uiua-lang/uiua/79d57c9b376aae09488efc1cba47faaeacddbe88/src/assets/uiua-logo-512.png -------------------------------------------------------------------------------- /src/boxed.rs: -------------------------------------------------------------------------------- 1 | //! The [`Boxed`] type 2 | 3 | use std::{ 4 | borrow::{Borrow, BorrowMut}, 5 | fmt, 6 | }; 7 | 8 | use serde::*; 9 | 10 | use crate::value::Value; 11 | 12 | /// The element type for box arrays 13 | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize)] 14 | #[serde(from = "BoxedRep", into = "BoxedRep")] 15 | pub struct Boxed(pub Value); 16 | 17 | #[derive(Serialize, Deserialize)] 18 | struct BoxedRep { 19 | b: Value, 20 | } 21 | 22 | impl From<Boxed> for BoxedRep { 23 | fn from(b: Boxed) -> Self { 24 | Self { b: b.0 } 25 | } 26 | } 27 | 28 | impl From<BoxedRep> for Boxed { 29 | fn from(b: BoxedRep) -> Self { 30 | Self(b.b) 31 | } 32 | } 33 | 34 | impl fmt::Debug for Boxed { 35 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 36 | self.0.fmt(f) 37 | } 38 | } 39 | 40 | impl fmt::Display for Boxed { 41 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 42 | self.0.fmt(f) 43 | } 44 | } 45 | 46 | impl From<Value> for Boxed { 47 | fn from(v: Value) -> Self { 48 | Self(v) 49 | } 50 | } 51 | 52 | impl AsRef<Value> for Boxed { 53 | fn as_ref(&self) -> &Value { 54 | &self.0 55 | } 56 | } 57 | 58 | impl AsMut<Value> for Boxed { 59 | fn as_mut(&mut self) -> &mut Value { 60 | &mut self.0 61 | } 62 | } 63 | 64 | impl Borrow<Value> for Boxed { 65 | fn borrow(&self) -> &Value { 66 | &self.0 67 | } 68 | } 69 | 70 | impl BorrowMut<Value> for Boxed { 71 | fn borrow_mut(&mut self) -> &mut Value { 72 | &mut self.0 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/function.rs: -------------------------------------------------------------------------------- 1 | use std::{fmt, hash::Hash}; 2 | 3 | use serde::*; 4 | 5 | use crate::{CodeSpan, Ident, Primitive, Signature}; 6 | 7 | /// A function that executes Rust code 8 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] 9 | pub struct DynamicFunction { 10 | /// An index used to look up the function 11 | pub(crate) index: usize, 12 | /// The function's signature 13 | pub(crate) sig: Signature, 14 | } 15 | 16 | impl From<(usize, Signature)> for DynamicFunction { 17 | fn from((index, sig): (usize, Signature)) -> Self { 18 | Self { index, sig } 19 | } 20 | } 21 | 22 | impl From<DynamicFunction> for (usize, Signature) { 23 | fn from(func: DynamicFunction) -> Self { 24 | (func.index, func.sig) 25 | } 26 | } 27 | 28 | impl DynamicFunction { 29 | /// Get the function's signature 30 | pub fn signature(&self) -> Signature { 31 | self.sig 32 | } 33 | } 34 | 35 | impl fmt::Debug for DynamicFunction { 36 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 37 | write!(f, "<dynamic#{:x}>", self.index) 38 | } 39 | } 40 | 41 | /// A Uiua function id 42 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] 43 | #[serde(untagged)] 44 | pub enum FunctionId { 45 | /// Just a primitive 46 | Primitive(Primitive), 47 | /// A named function 48 | Named(Ident), 49 | /// A macro expansion 50 | Macro(Option<Ident>, CodeSpan), 51 | /// The top-level function 52 | Main, 53 | #[doc(hidden)] 54 | /// Implementation detail 55 | Unnamed, 56 | } 57 | 58 | impl PartialEq<&str> for FunctionId { 59 | fn eq(&self, other: &&str) -> bool { 60 | match self { 61 | FunctionId::Named(name) => &&**name == other, 62 | _ => false, 63 | } 64 | } 65 | } 66 | 67 | impl From<Ident> for FunctionId { 68 | fn from(name: Ident) -> Self { 69 | Self::Named(name) 70 | } 71 | } 72 | 73 | impl From<Primitive> for FunctionId { 74 | fn from(op: Primitive) -> Self { 75 | Self::Primitive(op) 76 | } 77 | } 78 | 79 | impl fmt::Display for FunctionId { 80 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 81 | match self { 82 | FunctionId::Named(name) => write!(f, "{name}"), 83 | FunctionId::Primitive(prim) => write!(f, "{prim}"), 84 | FunctionId::Macro(Some(name), span) => write!(f, "macro expansion of {name} at {span}"), 85 | FunctionId::Macro(None, span) => write!(f, "macro expansion of at {span}"), 86 | FunctionId::Main => write!(f, "main"), 87 | FunctionId::Unnamed => write!(f, "unnamed"), 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/stand.rs: -------------------------------------------------------------------------------- 1 | use std::{env, fs, io, path::Path}; 2 | 3 | use once_cell::sync::Lazy; 4 | 5 | use crate::{Assembly, Compiler, NativeSys, UiuaResult}; 6 | 7 | const STAND_DATA_SIGNATURE: &[u8] = b"Uiua standalone"; 8 | 9 | pub fn build_exe(root: &Path) -> UiuaResult<Vec<u8>> { 10 | let asm = Compiler::with_backend(NativeSys).load_file(root)?.finish(); 11 | // Serialize the files 12 | let asm_bytes = asm.to_uasm().into_bytes(); 13 | // Append the files to the current exe 14 | let mut bytes = env::current_exe() 15 | .and_then(fs::read) 16 | .unwrap_or_else(|e| panic!("Unable to read current exe: {e}")); 17 | bytes.extend_from_slice(&asm_bytes); 18 | // Append the length of the serialized files and a signature 19 | bytes.extend((asm_bytes.len() as u64).to_le_bytes()); 20 | bytes.extend(STAND_DATA_SIGNATURE); 21 | Ok(bytes) 22 | } 23 | 24 | fn load_asm() -> io::Result<Option<Assembly>> { 25 | // Read the current exe 26 | let bytes = fs::read(env::current_exe()?)?; 27 | // Check if it is a standalone exe 28 | let Some(bytes) = bytes.strip_suffix(STAND_DATA_SIGNATURE) else { 29 | return Ok(None); 30 | }; 31 | // Get the length of the serialized files 32 | let (bytes, len_bytes) = bytes.split_at(bytes.len() - 8); 33 | let asm_len = u64::from_le_bytes(len_bytes.try_into().unwrap()); 34 | let start = bytes.len() - asm_len as usize; 35 | // Deserialize the files 36 | let uasm: String = std::str::from_utf8(&bytes[start..]).unwrap().to_string(); 37 | let asm = Assembly::from_uasm(&uasm).map_err(|e| { 38 | io::Error::new( 39 | io::ErrorKind::InvalidData, 40 | format!("Failed to deserialize assembly: {e}\n\nuasm text:\n{uasm}"), 41 | ) 42 | })?; 43 | Ok(Some(asm)) 44 | } 45 | 46 | pub static STAND_ASM: Lazy<Option<Assembly>> = 47 | Lazy::new(|| load_asm().unwrap_or_else(|e| panic!("{e}"))); 48 | -------------------------------------------------------------------------------- /tests/box.ua: -------------------------------------------------------------------------------- 1 | ⍤⤙≍ 1 ¬0 2 | ⍤⤙≍ □1 ¬□0 3 | ⍤⤙≍ □□1 ¬□□0 4 | 5 | ⍤⤙≍ 1 =0 0 6 | ⍤⤙≍ 1 =□0 □0 7 | ⍤⤙≍ □1 =□0 0 8 | ⍤⤙≍ □□1 =□□0 0 9 | ⍤⤙≍ 0 =□0 □□0 10 | ⍤⤙≍ 0 =□□0 □0 11 | 12 | ⍤⤙≍ 1 ≥0 1 13 | ⍤⤙≍ 1 ≥□0 □1 14 | ⍤⤙≍ □1 ≥□0 1 15 | ⍤⤙≍ □□1 ≥□□0 1 16 | ⍤⤙≍ 1 ≥□0 □□1 17 | ⍤⤙≍ 0 ≥□□0 □1 18 | 19 | ⍤⤙≍ 1 ≤1 0 20 | ⍤⤙≍ 1 ≤□1 □0 21 | ⍤⤙≍ □1 ≤□1 0 22 | ⍤⤙≍ □□1 ≤□□1 0 23 | ⍤⤙≍ 0 ≤□1 □□0 24 | ⍤⤙≍ 1 ≤□□1 □0 25 | 26 | ⍤⤙≍ □"cat" ↥∩□ "bird" "cat" 27 | 28 | ⍤⤙≍ 5 5 29 | ⍤⊃⋅∘(¬≍) □5 5 30 | ⍤⊃⋅∘(¬≍) 5 □5 31 | ⍤⤙≍ □5 □5 32 | 33 | ⍤⊃⋅∘(¬≍) □"apples" □"oranges" 34 | ⍤⤙≍ [0 0 0] ={0 ¯3 49593} {1 1 1} 35 | 36 | ⍤⤙≍ "hellomyfriend" /◇⊂ {"hello" "my" "friend"} 37 | ⍤⤙≍ [1_2_3 4_5_6] /◇⊟{1_2_3 4_5_6} 38 | ⍤⤙≍ [1_2 3_4 5_6] ≡◇∘ {1_2 3_4 5_6} 39 | ⍤⤙≍ [1_2 3_4 5_6] ≡°□ {1_2 3_4 5_6} 40 | ⍤⤙≍ 5 /◇+ {5} 41 | 42 | ⍤⤙≍ 5 ◇∘ □5 43 | ⍤⤙≍ □5 °◇∘ 5 44 | 45 | ⍤⤙≍ {{5_6 7_8} {1_2 3_4}} ⇌ {{1_2 3_4} {5_6 7_8}} 46 | ⍤⤙≍ {{3_4 1_2} {7_8 5_6}} ≡⍜°□⇌ {{1_2 3_4} {5_6 7_8}} 47 | ⍤⤙≍ {{3_4 1_2} {7_8 5_6}} ≡⇌ {{1_2 3_4} {5_6 7_8}} 48 | ⍤⤙≍ {{3_4 1_2} {7_8 5_6}} ≡⍜°□⇌♭ {{1_2 3_4} {5_6 7_8}} 49 | ⍤⤙≍ {{3_4 1_2} {7_8 5_6}} ≡⇌♭ {{1_2 3_4} {5_6 7_8}} 50 | ⍤⤙≍ {{3_4 1_2} {7_8 5_6}} ≡⍜°□⇌ {{1_2 3_4} {5_6 7_8}} 51 | ⍤⤙≍ {{3_4 1_2} {7_8 5_6}} ≡⇌ {{1_2 3_4} {5_6 7_8}} 52 | 53 | ⍤⤙≍ {"olleh" "dlrow"} ≡⇌{"hello" "world"} 54 | ⍤⤙≍ {"olleh" "dlrow"} ≡(⇌){"hello" "world"} 55 | ⍤⤙≍ ¤{"olleh" "dlrow"} ≡₀⇌¤{"hello" "world"} 56 | ⍤⤙≍ ¤{"olleh" "dlrow"} ≡₀(⇌)¤{"hello" "world"} 57 | 58 | ⍤⤙≍ □[2 3 1] ↻1 □[1 2 3] 59 | ⍤⤙≍ {2_3_1 5_6_4} ≡↻1 {1_2_3 4_5_6} 60 | -------------------------------------------------------------------------------- /tests/data_defs.ua: -------------------------------------------------------------------------------- 1 | ┌─╴M 2 | |Foo {Bar Baz} 3 | |Qux [x y z] 4 | |Sed {M N} 5 | |Wir 6 | 7 | Format ← ⍣( 8 | $"_ and _" °Foo 9 | | $"⟨_ _ _⟩" °Qux 10 | | $"_: _" °Sed 11 | | "Wir!" °Wir 12 | ) 13 | └─╴ 14 | ⍤⤙≍ "2 and 5" M~Format M~Foo 2 5 15 | ⍤⤙≍ "⟨0 4 1⟩" M~Format M~Qux 0 4 1 16 | ⍤⤙≍ "Name: Dan" M~Format M~Sed "Name" "Dan" 17 | ⍤⤙≍ "Wir!" M~Format M~Wir 18 | 19 | ~Foo [Bar Baz ← +] 20 | ⍤⤙≍ [5 5] Foo 5 2 3 21 | 22 | ┌─╴Foo 23 | |Bar {a} 24 | |Baz {a} 25 | └─╴ 26 | ⍤⤙≍ 5 Foo~Bar~a Foo~Bar 5 27 | 28 | ┌─╴S 29 | ~ {A B C} 30 | PopA ← ˜⊙∘⍜A(˜⊙∘⍜⇌°⊂) 31 | PushB ← ⍜⊙B˜⊂ 32 | └─╴ 33 | S [1 2 3] [4 5 6] [7 8 9] 34 | S~PopA 35 | S~PushB 36 | ⍤⤙≍ S [1 2] [4 5 6 3] [7 8 9] 37 | 38 | ┌─╴Foo 39 | |Bar [A] 40 | |Baz [A] 41 | |Qux 42 | └─╴ 43 | ⍤⤙≍ 1 /↥⌕"Non-boxed variant" ⍣Foo~Bar⋅∘ @a 44 | ⍤⤙≍ 1 /↥⌕"Non-boxed variant" ⍣Foo~Baz⋅∘ [1 2 3] 45 | ⍤⤙≍ [0 5] Foo~Bar 5 46 | ⍤⤙≍ [1 5] Foo~Baz 5 47 | ⍤⤙≍ 2 Foo~Qux 48 | 49 | ~Foo [Bar] 50 | ⍤⤙≍ ¤[1 2 3] Foo [1 2 3] 51 | 52 | ~Foo {Bar ← 5} 53 | F! ← ^0 Foo 54 | ⍤⤙≍ 5 F!Foo!Bar 55 | 56 | # Unnamed top-level def 57 | ~ {Foo Bar} 58 | ⍤⤙≍ [3 5] [⊃Foo Bar] New 3 5 59 | 60 | # Experimental! 61 | 62 | # Field validators 63 | ~Foo {Bar: °1type|Baz: ×2 ← +1} 64 | ⍤⤙≍ {@a 6} {Foo!⊃Bar Baz} Foo @a 5 65 | ⍤⤙≍ Foo @a 9 °⊸Foo~Baz 10 Foo @a 5 66 | 67 | ~Foo {A: °0type|B: °0type} 68 | ⍤⤙≍ [7 42] ⊟ °Foo Foo 7 42 69 | ~Foo [A: °0type|B: °0type] 70 | ⍤⤙≍ [7 42] ⊟ °Foo Foo 7 42 71 | 72 | # Data functions 73 | ~Foo [X ← 0] ⊟ ⊓X(/+ 1_2_3) 74 | ⍤⤙≍ [0 6] Foo 75 | ⍤⤙≍ [5 6] Foo X:5 76 | 77 | ~F {A ← 1|B ← 2|C ← 3} ∘ 78 | ⍤⤙≍ {1 2 3} F 79 | ⍤⤙≍ {1 2 5} F C:5 80 | ⍤⤙≍ {0 2 5} F A:0 C:5 81 | ⍤⤙≍ {0 2 5} F C:5 A:0 82 | ⍤⤙≍ {0 9 5} F C:5 A:0 B:9 83 | 84 | ~F {A ← +|B C ← 0} ∘ 85 | ⍤⤙≍ {3 4 0} F 1 2 4 86 | ⍤⤙≍ {3 4 5} F 1 C:5 2 4 87 | 88 | ~F {A ← 0|B C ← 0} ∘ 89 | M! ← F^0 90 | ⍤⤙≍ F A:2 3 M!A:2 3 91 | 92 | ┌─╴Range 93 | ~ {Min ← 0|Max Inclusive ← 0} ⍜-⇡ ⊃Min(+⊃Max Inclusive) 94 | ~Incl {Min ← 0} Call Inclusive:1 Min:Min 95 | APL ← Call Inclusive:1 Min:1 96 | └─╴ 97 | ⍤⤙≍ ⇡5 Range 5 98 | ⍤⤙≍ ⇡₁5 Range~APL 5 99 | ⍤⤙≍ ⇡₄6 Range Min:4 10 100 | ⍤⤙≍ ⇡₄7 Range~Incl Min:4 10 101 | 102 | ~Run {A ← 0|B ← 1|C} ≡°□ 103 | ⍤⤙≍ [0 1 2] Run 2 104 | ⍤⤙≍ {2 1 5} Run~New A:2 5 105 | ⍤⤙≍ [2 8 5] Run~Args B:8 Run~New A:2 5 106 | 107 | ~F {A ← 0|B ← 0|C ← 0|D ← 0} ∘ 108 | ⍤⤙≍ {2 3 4 1} F D:1 ⊓A:C: 2 B:3 4 109 | -------------------------------------------------------------------------------- /tests/ga.ua: -------------------------------------------------------------------------------- 1 | # Experimental! 2 | 3 | # Complex product 4 | ⍤⤙≍ [¯5 10] ⩜× [1 2] [3 4] 5 | ⍤⤙≍ [¯5 0 0 10] ⩜₂× [1 2] [3 0 0 4] 6 | ⍤⤙≍ [¯5 0 0 10] ⩜₂× [1 0 0 2] [3 4] 7 | ⍤⤙≍ [0_1 0_2 ¯1_0] ⩜× [0 1] [1_0 2_0 0_1] 8 | 9 | # Vector product 10 | ⍤⤙≍ [32 3 ¯6 3] ⩜₃× [1 2 3] [4 5 6] 11 | 12 | # Scalar product 13 | ⍤⤙≍ [2 4 6] ⩜× 2 [1 2 3] 14 | ⍤⤙≍ [2 4 6] ⩜× [2] [1 2 3] 15 | ⍤⤙≍ [2_4_6 3_6_9] ⩜× [¤2 ¤3] [1 2 3] 16 | 17 | # Other products 18 | ⍤⤙≍ [1 1 1 ¯1] ⩜₂× [1 1 0 0] [0 1 1 0] 19 | ⍤⤙≍ [[0 0 0 1] [0 0 0 2] [¯1 0 0 0]] ⩜₂× [0 0 0 1] [1_0 2_0 0_1] 20 | ⍤⤙≍ [[0 0 0 1] [0 0 0 2] [¯1 0 0 0]] ⩜₂× [0 0 0 1] [[1 0 0 0] [2 0 0 0] [0 0 0 1]] 21 | 22 | # Divide 23 | ⍤⤙≍ [0 ¯1] ⩜÷ [0 1] [1 0] 24 | ⍤⤙≍ [4_0 0_¯1] ⩜÷ [0.5_0 0_1] [2_0 1_0] 25 | 26 | # Add 27 | ⍤⤙≍ [4 5] ⩜+ 1 [3 5] 28 | ⍤⤙≍ [4 0 0 5] ⩜₂+ 1 [3 0 0 5] 29 | ⍤⤙≍ [4 0 0 5] ⩜₃+ 1 [3 0 0 5] 30 | ⍤⤙≍ [4 12] ⩜+ [1 7] [3 5] 31 | ⍤⤙≍ [4 0 0 12] ⩜₂+ [1 7] [3 0 0 5] 32 | ⍤⤙≍ [1 1 0] ⩜₃+ [0 1 0] [1 0 0] 33 | ⍤⤙≍ [1 2 3 4 0 0 0 0] ⩜+ 1 [2 3 4] 34 | 35 | # Magnitude 36 | ⍤⤙≍ 5 ⩜⌵ [3 4] 37 | ⍤⤙≍ [1 5 13] ⩜⌵ [0_1 3_4 5_12] 38 | ⍤⤙≍ 0¯ ⩜⌵ [0 0] 39 | ⍤⤙≍ √2 ⩜⌵ [1 1] 40 | ⍤⤙≍ √3 ⩜⌵ [1 1 1] 41 | 42 | # Normalize 43 | ⍤⤙≍ [0.6 0.8] ⩜± [3 4] 44 | ⍤⤙≍ [0.6 0 0 0.8] ⩜± [3 0 0 4] 45 | ⍤⤙≍ ⟜⩜± [0 0 0 0] 46 | 47 | # Reverse 48 | ⍤⤙≍ [1 ¯2] ⩜¯ [1 2] 49 | ⍤⤙≍ [1 2 3 ¯4] ⩜₂¯ [1 2 3 4] 50 | ⍤⤙≍ [1 ¯2 ¯3 ¯4] ⩜¯ [1 2 3 4] 51 | ⍤⤙≍ [1 2 3 4 ¯5 ¯6 ¯7 ¯8] ⩜₃¯ [1 2 3 4 5 6 7 8] 52 | 53 | # Dual 54 | ⍤⤙≍ [0 1] ⩜¬ [1] 55 | ⍤⤙≍ [0 3 2 1] ⩜¬ [1 2 3] 56 | ⍤⤙≍ [¯4 3 ¯2 1] ⩜₄(⊏3¬) [1 2 3 4] 57 | ⍤⤙≍ [0 0 0 0 0 0 0 0 0 0 0 5 ¯4 3 ¯2 1] ⩜¬ [1 2 3 4 5] 58 | 59 | # Inner 60 | ⍤⤙≍ [1 1 0 0] ⩜₂↥ [1 1 0 0] [0 1 0 0] 61 | ⍤⤙≍ [1 1 1 0] ⩜₂↥ [1 1 0 0] [0 1 1 0] 62 | ⍤⤙≍ [2 2 1 0] ⩜₂↥ [1 1 0 0] [1 1 1 0] 63 | 64 | # Wedge 65 | ⍤⤙≍ [0 ¯1 1 ¯3] ⩜↧ [1 2 ¯1] [0 1 1] 66 | [1 4 ¯3] # 1 + 4x - 3y 67 | [1 ¯2 1] # 1 - 2x + y 68 | ⍤⤙≍ [2 3] ⇌÷⊃↙↘¯1 ⩜₃(⊏2↧) 69 | 70 | # Regressive 71 | ⍤⤙≍ [0 0 ¯1 2 0 0 0 0] ⩜₃∨ [0 0 0 0 1 2 1 0] [0 0 0 0 2 4 1 0] 72 | ⍤⤙≍ [¯6 5 4] ⩜₃(∨∩¬) [1 ¯2 4] [1 2 ¯1] 73 | 74 | # Rotor 75 | ⍤⤙≍ [¯1 1 2] ⁅₉ ⩜₃(⊏1×⊃¯˜× ∠ ∩₃⌞⌝⊏1) [0 1 0] [1 0 0] [1 1 2] 76 | ⍤⤙≍ [¯1 1 2] ⁅₉ ⩜₃(⊏1×⊃¯˜× ∠) [0 1 0] [1 0 0] [1 1 2] 77 | ⍤⤙≍ ∩⁅₉ [.÷2√2 0 0] ⩜₃∠ [1 0 0] [0 1 0] 78 | ⍤⤙≍ ∩⁅₉ [.÷2√2 0 0] ⩜∠ [1 0 0] [0 1 0] 79 | 80 | # Sandwich 81 | ⍤⤙≍ [¯2 1 3] ⁅₉ ⩜₃(↻ ±) [1 ¯1 0 0] [1 2 3] 82 | ⍤⤙≍ [2 ¯1 3] ⁅₉ ⩜₃(⌝↻±) [1 ¯1 0 0] [1 2 3] 83 | ⍤⤙≍ [¯3_2 ¯5_4 ¯7_6] ⁅₉⩜₂(⊏1 ↻∠ ∩₃⌞⌝⊏1) [0 1] [1 0] [2_3 4_5 6_7] 84 | 85 | # Pad blades 86 | ⍤⤙≍ [1 0 0 0] ⩜₂⌝⊏ 0 [1] 87 | ⍤⤙≍ [0 1 2 0] ⩜₂⌝⊏ 1 [1 2] 88 | ⍤⤙≍ [0 0 0 1] ⩜₂⌝⊏ 2 [1] 89 | ⍤⤙≍ [1 0 0 0 0 0 0 0] ⩜₃⌝⊏ 0 [1] 90 | ⍤⤙≍ [0 1 2 3 0 0 0 0] ⩜₃⌝⊏ 1 [1 2 3] 91 | ⍤⤙≍ [0 0 0 0 1 2 3 0] ⩜₃⌝⊏ 2 [1 2 3] 92 | ⍤⤙≍ [0 0 0 0 0 0 0 1] ⩜₃⌝⊏ 3 [1] 93 | 94 | # Extract blades 95 | ⍤⤙≍ [1] ⩜₂⊏ 0 [1 2 3 4] 96 | ⍤⤙≍ [2 3] ⩜₂⊏ 1 [1 2 3 4] 97 | ⍤⤙≍ [4] ⩜₂⊏ 2 [1 2 3 4] 98 | ⍤⤙≍ [2] ⩜₂⊏ 2 [1 2] 99 | ⍤⤙≍ [1] ⩜₃⊏ 0 [1 2 3 4 5 6 7 8] 100 | ⍤⤙≍ [2 3 4] ⩜₃⊏ 1 [1 2 3 4 5 6 7 8] 101 | ⍤⤙≍ [5 6 7] ⩜₃⊏ 2 [1 2 3 4 5 6 7 8] 102 | ⍤⤙≍ [2 3 4] ⩜₃⊏ 2 [1 2 3 4] 103 | ⍤⤙≍ [8] ⩜₃⊏ 3 [1 2 3 4 5 6 7 8] 104 | ⍤⤙≍ [1 5 6 7] ⩜₃⊏ 0_2 [1 2 3 4 5 6 7 8] 105 | ⍤⤙≍ [1 2 3 4] ⩜₃⊏ 0_1 [1 2 3 4 5 6 7 8] 106 | ⍤⤙≍ [2 3 4 5 6 7] ⩜₃⊏ 1_2 [1 2 3 4 5 6 7 8] 107 | 108 | # PGA 109 | ⍤⤙≍ [0 14 15 1] ⩜(0_1|↻±+1±˜×⊙¯) [0 6 10 1] [0 2 5 1] [0 10 10 1] 110 | ⍤⤙≍ [0 14 15 1] ⩜(0_1|↻∠) [0 6 10 1] [0 2 5 1] [0 10 10 1] 111 | 112 | # Sqrt 113 | ⍤⤙≍ [0_1 0_2] ⩜√ [¯1_0 ¯4_0] 114 | ⍤⤙≍ [1_1 2_2] ⁅₉ ⩜√ [0_2 0_8] 115 | 116 | # Couple 117 | ⍤⤙≍ [1_2 1_3] ⩜⊟ 1 2_3 118 | ⍤⤙≍ [1_3 2_3] ⩜⊟ 1_2 3 119 | ⍤⤙≍ [[1_5 2_5] [3_6 4_6]] ⩜⊟ [1_2 3_4] 5_6 120 | ⍤⤙≍ [[1_3 1_4] [2_5 2_6]] ⩜⊟ 1_2 [3_4 5_6] 121 | 122 | # Uncouple 123 | ⍤⤙≍ {1_3_5 2_4_6} {⩜°⊟} [1_2 3_4 5_6] 124 | ⍤⤙≍ {1_2_3 0_0_0} {⩜°⊟} [¤1 ¤2 ¤3] 125 | 126 | # Unparse 127 | ⍤⤙≍ "1 + 2e₁ + 3e₂ + 4e₁₂" ⩜₂°⋕ [1 2 3 4] 128 | ⍤⤙≍ "5+2i" ⩜°⋕ [5 2] 129 | ⍤⤙≍ {"1 + 2e₁₂ + 3e₃₁ + 4e₂₃" "5 + 6e₁₂ + 7e₃₁ + 8e₂₃"} ⩜°⋕ [[1 2 3 4] [5 6 7 8]] 130 | ⍤⤙≍ "e₀₁ + 2e₂₀ + 3e₁₂" ⩜(0_1|°⋕) [0 1 2 3] 131 | -------------------------------------------------------------------------------- /tests/grid.ua: -------------------------------------------------------------------------------- 1 | Unique! ←^ ( 2 | ⧅<2 3 | /$"_\n_" ⍚( 4 | $"_\n_" ⊃( 5 | /$"¬≍ pretty _ pretty _" 6 | | /$"⍤$ (_) and (_) give ambiguous output" 7 | ) 8 | ) 9 | ) 10 | 11 | Unique!( 12 | {5} | {□5} | {□□5} 13 | | {[5]} | {□[5]} | {□□[5]} 14 | | {{5}} | {□{5}} 15 | ) 16 | 17 | Unique!( 18 | {1 2 3} 19 | | {1 2_3} 20 | | {1 {2 3}} 21 | | {1 {2_3}} 22 | ) 23 | 24 | Unique!( 25 | {°△2} 26 | | {°△1_2} 27 | | {°△2_1} 28 | | {°△1_1_2} 29 | | {°△2_1_1} 30 | ) 31 | 32 | Unique!( 33 | {°△1_2_2} 34 | | {°△2_1_2} 35 | | {°△2_2_1} 36 | ) 37 | 38 | Unique!( 39 | {°△2 °△2_2} 40 | | {°△1_2 °△2_2} 41 | | {°△1_1_2 °△2_2} 42 | | {°△1_1_2 °△1_2_2} 43 | ) 44 | 45 | Unique!( 46 | {"hi" °△2_2} 47 | | {"hi" °△1_2_2} 48 | | {¤"hi" °△2_2} 49 | | {¤"hi" °△1_2_2} 50 | ) 51 | 52 | Unique!({@a}|{□@a}) 53 | 54 | Unique!( 55 | {°△2_2_2 2} 56 | | {°△2_2_2 ¤2} 57 | | {°△2_2_2 ¤¤2} 58 | | {°△2_2_2 ¤¤¤2} 59 | ) 60 | -------------------------------------------------------------------------------- /tests/macros.ua: -------------------------------------------------------------------------------- 1 | # Index macros 2 | F! ← ^0 5 3 | G! ← F!^0 4 | ⍤⤙≍ ¯5 G!¯ 5 | Four! ← ∩∩^0 6 | ⍤⤙≍ [4 6 8 10] [Four!(×2) 2 3 4 5] 7 | Dyad‼ ← ^0^1 8 | ⍤⤙≍ 12 Dyad‼(×2|+1) 5 9 | F‼‼ ← ^1^0^2^2^3^0 10 | ⍤⤙≍ [1 0 2 2 3 0] F‼‼(⊂0|⊂1|⊂2|⊂3) [] 11 | 12 | F! ← ( 13 | ^0 14 | ^0 15 | ) 16 | ⍤⤙≍ 6 F!+ 1 2 3 17 | F! ← [ 18 | ^0 19 | ^0 20 | ] 21 | ⍤⤙≍ [6] F!+ 1 2 3 22 | F! ← ⨬( 23 | ^0 24 | | ^0 25 | ) 26 | ⍤⤙≍ ¯5 F!¯ 0 5 27 | 28 | F! ← -^0 i 29 | ⍤⤙≍ i F!0 30 | 31 | # Code macros 32 | F! ←^ 33 | G! ←^ ⇌ 34 | H‼ ←^ ⊂⊢. 35 | ⍤⤙≍ [1 2] F!(⊂1|⊂2) [] 36 | ⍤⤙≍ [2 1] G!(⊂1|⊂2) [] 37 | ⍤⤙≍ [1 1 2] H‼(⊂1|⊂2) [] 38 | ⍤⤙≍ [1 1 2] H‼(⊂1)(⊂2) [] 39 | 40 | X ← 1 41 | F! ←^ ⊂□°⋕X 42 | ⍤⤙≍ [1 2] [F!2] 43 | 44 | F‼ ←^ $"_ ← _\n" °⊟ 45 | F‼Y5 46 | ⍤⤙≍ 5 Y 47 | 48 | Foo! ←^ "t ←rand" ◌ 49 | Hi ← Foo!+"a" 50 | ⍤⤙≍ "a" Hi 51 | 52 | a ← 4 53 | b ← (⚂) 54 | c ← comptime(⚂) 55 | e ← gen [] 1 56 | 57 | A! ←^ $"_" a ◌ 58 | B! ←^ $"_" b ◌ 59 | C! ←^ $"_" c ◌ 60 | E! ←^ $"_" e ◌ 61 | 62 | ◌A!1 63 | ◌B!2 64 | ◌C!3 65 | ◌E!5 66 | ◌E!5 # Ensure evaluated constant is set 67 | 68 | F! ←^ {"+" "1"}◌ 69 | ⍤⤙≍ [2 3 4] ≡F!∘ [1 2 3] 70 | 71 | Struct‼ ←^ $"---_\n_\n---" ⊙( 72 | /$"_\n_"⊂□$"New ← {_}"≡⋅@⊙⟜⍚$"_ ← °□⊡_"°˜⊏⊜□⊸≠@ °$"[_]" 73 | )°{⊙∘} 74 | 75 | Struct‼Person[Name Age][] # Ensure that a word on the same line as binding generation works 76 | ◌◌Person~New "Dave" 15 77 | 78 | F‼ ←^ 79 | ⍤⤙≍ [1 2 3] [F‼(1|2|3)] 80 | 81 | M! ←^ ⋅"∘" 82 | @a @b 83 | ⍤⤙≍ "b" [⋅M!∘] 84 | 85 | Join! ←^ ↯⊙@⊂↥0-1⋕ 86 | {Join!0 "a" "bc" "def"} 87 | {Join!1 "a" "bc" "def"} 88 | {Join!2 "a" "bc" "def"} 89 | ◌◌◌ 90 | 91 | M! ←^ ˜⊂□"5" ⍚$"_ ←\n" °{$"[_]"/$"_ _"} 92 | ⇡3 93 | ⍤⤙≍ 5 M![A B C] 94 | ⍤⤙≍ ⇡3 A 95 | ⍤⤙≍ [] B [] 96 | ⍤⤙≍ [] C [] 97 | 98 | M! ←^ /$"_\n_" ⊂□$"°⊟_"+@₀-@0°⋕⊸⧻ ⍚$"_ ← " °{$"[_]"/$"_ _"} 99 | 100 | ⇡3 101 | M![D E F] 102 | ⍤⤙≍ [0] [D] 103 | ⍤⤙≍ [1] [E] 104 | ⍤⤙≍ [2] [F] 105 | 106 | M![G H I] ⇡3 107 | ⍤⤙≍ [0] [G] 108 | ⍤⤙≍ [1] [H] 109 | ⍤⤙≍ [2] [I] 110 | 111 | # Macro arg validation should ignore error from code macro args 112 | ┌─╴Wup 113 | X ← 5 114 | └─╴ 115 | A! ←^ $"Wup!(_)" ⊢ 116 | B! ← A!X ^0 117 | ⍤⤙≍ 5 B! 118 | 119 | # Modules should overwrite macros 120 | Foo! ←^ repr⊢ 121 | ┌─╴Foo 122 | X ← 5 123 | └─╴ 124 | ⍤⤙≍ 5 Foo!(X) 125 | 126 | # Macros use correct identifiers 127 | ┌─╴M ~ F! 128 | X ← 5 129 | F! ← +X^0 130 | └─╴ 131 | X ← 3 132 | ⍤⤙≍ 8 F!X 133 | 134 | # Inline macros 135 | ⍤⤙≍ [1 2 1 2] (^0^1^0^1)‼(⊂1|⊂2) [] 136 | ⍤⤙≍ ≡⊂¤1_2_1_2 ⟜≡(^0^1^0^1)‼(⊂1|⊂2) [3 4 5] 137 | ⍤⤙≍ 12 ( 138 | ^0 139 | +1 140 | ×2 141 | )!5 142 | F ← 5 143 | ⍤⤙≍ 5 (^0)!F 144 | 145 | F! ←^ ( 146 | G ← 5 147 | ⋅G 148 | ) 149 | ⍤⤙≍ 5 F!+ 150 | 151 | # These just need to parse 152 | A₇₂₇! ← ^0 153 | A⌞! ← ^0 154 | -------------------------------------------------------------------------------- /tests/map.ua: -------------------------------------------------------------------------------- 1 | {1 3 "hi" [1 2 3]} 2 | {2 4 "there" [4 5 6]} 3 | ˜map 4 | MapA ← 5 | MapB ← insert 5 6 MapA 6 | MapsI ← MapA MapB 7 | 8 | ∩(⍤. has 1) MapsI 9 | ∩(⍤. has 3) MapsI 10 | ∩(⍤. has "hi") MapsI 11 | ∩(⍤. has [1 2 3]) MapsI 12 | 13 | ∩(⍤⤙≍ □2 get 1) MapsI 14 | ∩(⍤⤙≍ □4 get 3) MapsI 15 | ∩(⍤⤙≍ □"there" get "hi") MapsI 16 | ∩(⍤⤙≍ □[4 5 6] get [1 2 3]) MapsI 17 | 18 | MapsII ← ∩(remove 1) MapsI 19 | ∩(⍤. ¬has 1) MapsII 20 | ∩(⍤. has 3) MapsII 21 | ∩(⍤. has "hi") MapsII 22 | ∩(⍤. has [1 2 3]) MapsII 23 | ⍤⤙≍ {{3 "hi" [1 2 3]} {4 "there" [4 5 6]} {3 "hi" [1 2 3] 5} {4 "there" [4 5 6] 6}} {∩°map MapsII} 24 | 25 | ⍤⤙≍ 5 get 1_2 map [1_2 3_4] 5_6 26 | ⍤⤙≍ 6 get 3_4 map [1_2 3_4] 5_6 27 | 28 | ⍤⤙≍ map 1_2_3 10_5_6 insert 1 10 map 1_2_3 4_5_6 29 | 30 | ⍤⤙≍ [2 3 4 1] ≡get[2 3 4 5]¤ ∧(insert) [5 2 3 4] [1 2 3 4] map[][] 31 | ⍤⤙≍ map"abc" [1_2 9_9 5_6] insert @b [9 9] map "abc" [1_2 3_4 5_6] 32 | 33 | ⍤⤙≍ map 1_2_3 6_10_15 ≡(/+⇡) map 1_2_3 4_5_6 34 | ⍤⤙≍ map 1_2_3 6_10_15 ≡₀(/+⇡) map 1_2_3 4_5_6 35 | ⍤⤙≍ map 1_2_3 14_25_36 ≡+ 10_20_30 map 1_2_3 4_5_6 36 | ⍤⤙≍ ⍉⟜(⍉ map 1_2_3) [4_5 6_7 8_9] 37 | 38 | ⍤⤙≍ [1_2_5_7 3_4_7_8] [°map] ⊂ map 1_2 3_4 map 5_7 7_8 39 | ⍤⤙≍ [2_3_4_1 6_7_8_5] [°map] ↻1 map 1_2_3_4 5_6_7_8 40 | ⍤⤙≍ [2_3_4 6_7_8] [°map] ↘1 map 1_2_3_4 5_6_7_8 41 | ⍤⤙≍ [[1] [5]] [°map] ↙1 map 1_2_3_4 5_6_7_8 42 | 43 | ⍤⤙≍ 0 ≍ ⟜map [1 2 3] [4 5 6] 44 | ⍤⤙≍ 1 ≍ .map [1 2 3] [4 5 6] 45 | 46 | ⍤⤙≍ map [1] {"a"} insert 1 □"a" map 1 □"a" 47 | 48 | # Fix 49 | ⍤⤙≍ ≡¤[4 5 6] ⊞get 1_2_3 ¤ map 1_2_3 4_5_6 50 | ⍤⤙≍ [4 5 6] ≡get 1_2_3 ¤ map 1_2_3 4_5_6 51 | ⍤⤙≍ ↯3≡¤ [4 5 6] ⊞⋅get . 1_2_3 ¤ map1_2_3 4_5_6 52 | 53 | # Empty keys 54 | ⍤⟜≍ insert[][] map[]°△0_0 insert[][] °△0_0 55 | ⍤⤙≍ 5 get [] insert [] 5 map°△0_0 [] 56 | ⍤⤙≍ 5 get [] insert [] 5 insert[]3 map°△0_0[] 57 | 58 | # Weird probe patterns 59 | map {"x" "y" "z"} [1 2 3] 60 | remove "y" 61 | insert "z" 4 62 | ⍤⤙≍ map {"x" "z"} [1 4] 63 | ⍤⤙≍ ⤙⍜remove∘ @a map "abc" [1 2 3] 64 | {"a" "b" "f" "v" "r" "l" "c" "d" "e" "g" "h" "i" "j" "k" "m" "18" "1" "zh" "qvq" "dp" "sh" "D" "C" "A" "B" "kmsq"} 65 | map ⟜(⇡⧻) 66 | remove "zh" 67 | insert "kmsq" 0 68 | ⍤⤙≍ ∩⧻°map 69 | map {"a" "b" "c"} [1 2 3] 70 | remove "b" 71 | insert "d" 4 72 | insert "e" 42 73 | ⍤⤙≍ map {"a" "c" "d" "e"} [1 3 4 42] 74 | 75 | # Duplicate init keys 76 | ⍤⤙≍ map [0 1] [3 4] map [0 0 0 1] [1 2 3 4] 77 | 78 | # Sort correctness 79 | map "abc" [2 3 1] 80 | map "cba" [1 3 2] 81 | ⍤⤙≍ [1 1] [∩≍] ⊃∩⍆∩(⇌⍆) 82 | 83 | # Selection 84 | ⍤⤙≍ ⤙⊏⇡3 map "abc" [1 2 3] 85 | ⍤⤙≍ ⊃⇌(⊏⇌°⊏) map "abc" [1 2 3] 86 | 87 | # Multi-key get 88 | ⍤⤙≍ "bdd" get 2_4_4 map [1 2 3 4] "abcd" 89 | ⍤⤙≍ "dcba" get 4_3_2_1 map [1 2 3 4] "abcd" 90 | 91 | # # Multi-key insert (not currently allowed because of ambiguity) 92 | # ⍤⤙≍ map 1_2 "ab" insert 1_2 "ab" map [] "" 93 | # ⍤⤙≍ map [1_2] ["ab"] insert 1_2 "ab" map ⤙+@a °△0_2 94 | 95 | # Multi-key remove 96 | ⍤⤙≍ map 1_3 "ac" remove 2_4 map [1 2 3 4] "abcd" 97 | ⍤⤙≍ map [3_4] "b" remove 1_2 map [1_2 3_4] "ab" 98 | 99 | # Unmap type/shape 100 | ⍤⤙≍ {+@0°△0_2 []} {°map} remove "df"_"as" map "as"_"df" 1_2 101 | 102 | ⍤⤙≍ {[] map [¯1] [5]} ⨬⋅∘⍚(insert⊙5) [0 1] [¯1 ¯1] {[] []} 103 | 104 | # Put in arrays 105 | ⍤⤙≍ ⊃¤[∘] map [1 2 3] [4 5 6] 106 | ⍤⤙≍ [3_4 7_8] [map 1_2 3_4 map 5_6 7_8] 107 | -------------------------------------------------------------------------------- /tests/module.ua: -------------------------------------------------------------------------------- 1 | ThisFileDir 2 | ┌─╴test 3 | ThisFileDir 4 | └─╴ 5 | ⍤⤙≍ 6 | 7 | # Imports 8 | Ex ~ "example.ua" 9 | Foo ← Ex~Foo 10 | Incr ← Ex~Increment 11 | Dub ← Ex~Double 12 | ⍤⤙≍ 12 Dub Incr Foo 13 | ~ "example" ~ Square 14 | ⍤⤙≍ 25 Square 5 15 | ⍤⤙≍ 15 Ex~Mac!+ 16 | 17 | ~ "example.ua" ~ Increment 18 | ~ "example.ua" ~ Increment 19 | ~ "example.ua" ~ Increment 20 | ⍤⤙≍ 7 Increment Increment 5 21 | F! ← ^0 22 | ⍤⤙≍ 15 Ex~Mac!F!+ 23 | 24 | # Scoped 25 | ┌─╴M 26 | F ← +1 27 | └─╴ 28 | N ↚ M 29 | ⍤⤙≍ 6 N~F 5 30 | ⍤⤙≍ 6 N!F 5 31 | 32 | ┌─╴M ~ X 33 | X ← + 34 | └─╴ 35 | ┌─╴N ~ Y 36 | Y ← X X 37 | └─╴ 38 | ⍤⤙≍ 6 Y 1 2 3 39 | 40 | ┌─╴A 41 | ┌─╴B ~ C 42 | C ← 5 43 | └─╴ 44 | D ← C 45 | └─╴ 46 | ⍤⤙≍ 5 A~B~C 47 | ⍤⤙≍ 5 A~D 48 | 49 | ┌─╴Foo 50 | New ← 5 51 | └─╴ 52 | M! ← ^0 Foo!New 53 | 54 | # Experimental! 55 | 56 | ┌─╴F ~ D‼ M! 57 | R! ← |1 ⨬^0R!^0 0 58 | M! ← R!^0 59 | D‼ ← ^0^1 60 | └─╴ 61 | ⍤⤙≍ 6 M!D‼++ 1 2 3 62 | -------------------------------------------------------------------------------- /tests/signature.ua: -------------------------------------------------------------------------------- 1 | B ← |0.0 2 | # Parens 3 | F ← |1 ×. 4 | F ← |1 (×.) 5 | # Basic 6 | F ← |2 + 7 | F ← |1 +1 8 | # Reduction 9 | F ← |1 /+ 10 | F ← |1 \+ 11 | # Iteration 12 | F ← |1 ≡⇌ 13 | # Table 14 | F ← |2 ⊞+ 15 | F ← |3 ⊞(++) 16 | # Dip 17 | F ← |2 ⊙◌ 18 | F ← |2.2 ⊙∘ 19 | F ← |2.3 ⊙. 20 | F ← |3.4 ⊙⊙. 21 | F ← |3.3 ⋅⊙. 22 | F ← |3 ↙⊙↘ 23 | # Under 24 | F ← |1 ⍜°□∘ 25 | F ← |1 ⍜(↙2)⇌ 26 | F ← |2 ⍜↙⇌ 27 | F ← |3 ⍜(↙⊙↘)⇌ 28 | F ← |3 ⍜∩°□(⊂⊂) 29 | F ← |1 ⌅(⍥¯⧻△.|+1) 30 | G ← |2 ⍜∩F× 31 | F ← |1.2 ⍜⊙⇌∩\↥ . 32 | # Try 33 | F ← |1 ⍣⋕∘ 34 | F ← ⍣(°$"_-_"⊙◌|⍤.˜$"Invalid string on line _: \"_\"") 35 | # Repeat 36 | F ← |1 {⍥(⊜⧻..)∞} 37 | F ← |3 ⍥+ 38 | F ← |2 ⍥◡+10 39 | F ← |2.2 ⍥⊸◡+10 40 | # Fold 41 | F ← |0.0 ∧ 42 | F ← |0.0 ∧∧ 43 | F ← |2 ∧+ 44 | F ← |2 ∧⊸+ 45 | # Do 46 | C ← ⨬(+1×3|÷2)=0⊸◿2 47 | F ← |1 ◌⍢⊂⊸(¬⊸∊⟜(C⊢)) 48 | ◌F [7] 49 | F ← |1 ⍢(|1 ×2||1 <1000) 50 | ◌F 1 51 | F ← |1 ⍢(|1 ×2||1.2 <1000.) 52 | ◌F 1 53 | F ← |2 ⍢(+|?) 54 | G ← |2 ⍢(?+|>2) 55 | F ← |2 ⍢(×|<100) 56 | F ← |1 ⍢(⊸×2|<100) 57 | F ← |1 ⍢(.×2|<100) 58 | # On 59 | F ← |1 ⟜() 60 | # By 61 | F ← |1 ⊸() 62 | # Obverse 63 | F ← |1 ⌅+₁ 64 | G ← |1 °F 65 | -------------------------------------------------------------------------------- /tests/try.ua: -------------------------------------------------------------------------------- 1 | # |2.1 |n.0/1 2 | F ← ⍣+∘ 3 | ⍤⤙≍ 5 F 2 3 4 | ⍤⤙≍ @a F @a @b 5 | F ← ⍣+⋅∘ 6 | ⍤⤙≍ 5 F 2 3 7 | ⍤⤙≍ @b F @a @b 8 | F ← ⍣+◌ 9 | ⍤⤙≍ 5 F 2 3 10 | ⍤⤙≍ @b F @a @b 11 | F ← ⍣+⋅⋅∘ 12 | ⍤⤙≍ 5 F 2 3 13 | ⍤⤙≍ [1 1] [⊃type(⧻△)] F @a @b 14 | F ← ⍣+⋅◌ 15 | ⍤⤙≍ 5 F 2 3 16 | ⍤⤙≍ [1 1] [⊃type(⧻△)] F @a @b 17 | 18 | # |3.1 |n.0/1 19 | F ← ⍣(++)∘ 20 | ⍤⤙≍ 6 F 1 2 3 21 | ⍤⤙≍ @a F @a @b @c 22 | F ← ⍣(++)⋅∘ 23 | ⍤⤙≍ 6 F 1 2 3 24 | ⍤⤙≍ @b F @a @b @c 25 | F ← ⍣(++)◌ 26 | ⍤⤙≍ 6 F 1 2 3 27 | ⍤⤙≍ @b F @a @b @c 28 | F ← ⍣(++)⋅⋅∘ 29 | ⍤⤙≍ 6 F 1 2 3 30 | ⍤⤙≍ @c F @a @b @c 31 | F ← ⍣(++)⋅◌ 32 | ⍤⤙≍ 6 F 1 2 3 33 | ⍤⤙≍ @c F @a @b @c 34 | F ← ⍣(++)⋅⋅⋅∘ 35 | ⍤⤙≍ 6 F 1 2 3 36 | ⍤⤙≍ [1 1] [⊃type(⧻△)] F @a @b @c 37 | F ← ⍣(++)⋅⋅◌ 38 | ⍤⤙≍ 6 F 1 2 3 39 | ⍤⤙≍ [1 1] [⊃type(⧻△)] F @a @b @c 40 | 41 | # |2.2 |n.0/1 42 | F ← ⍣(.+)∘ 43 | ⍤⤙≍ [5 5] [F] 2 3 44 | ⍤⤙≍ "ab" [F] @a @b 45 | F ← ⍣(.+)⋅∘ 46 | ⍤⤙≍ [5 5] [F] 2 3 47 | ⍤⤙≍ {@b [1 1]} {⊙[⊃type(⧻△)] F} @a @b 48 | F ← ⍣(.+)◌ 49 | ⍤⤙≍ [5 5] [F] 2 3 50 | ⍤⤙≍ {@b [1 1]} {⊙[⊃type(⧻△)] F} @a @b 51 | F ← ⍣(.+)⋅⋅∘ 52 | ⍤⤙≍ [5 5] [F] 2 3 4 53 | ⍤⤙≍ {@c [1 1]} {⊙[⊃type(⧻△)] F} @a @b @c 54 | F ← ⍣(.+)⋅◌ 55 | ⍤⤙≍ [5 5] [F] 2 3 4 56 | ⍤⤙≍ {@c [1 1]} {⊙[⊃type(⧻△)] F} @a @b @c 57 | 58 | # |2.1 |n.n 59 | F ← ⍣+⊙∘ 60 | ⍤⤙≍ [5 4] [F] 2 3 4 61 | ⍤⤙≍ "ab" [F] @a @b @c 62 | 63 | # |3.3 |n.n 64 | F ← ⍣(++)⊙∘ 65 | ⍤⤙≍ [9 5] [F] 2 3 4 5 66 | ⍤⤙≍ "ab" [F] @a @b @c @d 67 | F ← ⍣(++)⊙⊙∘ 68 | ⍤⤙≍ [9 5 6] [F] 2 3 4 5 6 69 | ⍤⤙≍ "abc" [F] @a @b @c @d @e 70 | 71 | # |2.2 |n.2 72 | F ← ⍣(.+)⊙∘ 73 | ⍤⤙≍ [5 5] [F] 2 3 74 | ⍤⤙≍ "ab" [F] @a @b 75 | F ← ⍣(.+)⋅⊙∘ 76 | ⍤⤙≍ [5 5] [F] 2 3 77 | ⍤⤙≍ {@b [1 1]} {⊙[⊃type(⧻△)] F} @a @b 78 | F ← ⍣(.+)⋅⋅⊙∘ 79 | ⍤⤙≍ [5 5] [F] 2 3 4 80 | ⍤⤙≍ {@c [1 1]} {⊙[⊃type(⧻△)] F} @a @b @c 81 | 82 | # |3.2 |n.0/1 83 | F ← ⍣(..+)∘ 84 | ⍤⤙≍ [5 5 5] [F] 2 3 85 | ⍤⤙≍ {@a @b [1 1]} {⊙⊙[⊃type(⧻△)] F} @a @b 86 | 87 | # Tried noreturn 88 | F ← (⍣(⍤@!0)∘) 89 | ⍤⤙≍ @! F 90 | F ← (⍣(5⍤@!0)∘) 91 | ⍤⤙≍ @! F 92 | F ← ⍣(⍤@!0){⊙∘} 93 | ⍤⤙≍ {1 @!} F 1 94 | F ← ⍣(⍤@!0)⊙∘ 95 | ⍤⤙≍ {1 @!} {F} 1 96 | 97 | # Handler noreturn 98 | F ← ⍣+(⍤.□₃) 99 | ⍤⤙≍ 5 F 2 3 100 | ⍤⤙≍ {@a @b [1 1]} ⍜(°□⊣)[⊃type(⧻△)] ⍣(F @a @b)∘ 101 | ⍤⤙≍ {@a @b [1 1]} ⍜(°□⊣)[⊃type(⧻△)] ⍣F⋅⋅∘ @a @b 102 | F ← ⍣+(⍤.□₄) 103 | ⍤⤙≍ 5 F 2 3 4 104 | ⍤⤙≍ {@a @b @c [1 1]} ⍜(°□⊣)[⊃type(⧻△)] ⍣(F @a @b @c)∘ 105 | ⍤⤙≍ {@a @b @c [1 1]} ⍜(°□⊣)[⊃type(⧻△)] ⍣F⋅⋅⋅∘ @a @b @c 106 | 107 | # Others 108 | 109 | F ← ⍣⨬(⍤.$"_"|¯)⋅⋅∘ 110 | ⍤⤙≍ "5" F 0 5 111 | ⍤⤙≍ ¯5 F 1 5 112 | 113 | {"cat" "sand"} "dog" {"cat" "cats" "and" "sand" "dog"} 114 | ⍤⤙≍ {{"cat" "sand"} {"dog"} {""}} {⊙(∩⌞▽≡°□˜⍚⍣(1°.⊙⊃↙↘⟜⧻|0⊙∘)¤)} 115 | ⍤⤙≍ [2 2] [⍣√⋅. 4 2] 116 | ⍤⤙≍ [3] [⍣(⋅2⍤.0)3] 1 117 | 118 | F ← °22 119 | G ← ⋅⍣°8 2 120 | H ← ⍣F G 121 | ⍤⤙≍ 2 H 7 19 122 | -------------------------------------------------------------------------------- /tests_ffi/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = "2021" 3 | name = "tests_ffi" 4 | version = "0.1.0" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | name = "ffi_lib" 9 | 10 | [dependencies] 11 | uiua.path = ".." 12 | -------------------------------------------------------------------------------- /tests_ffi/test.ua: -------------------------------------------------------------------------------- 1 | # Experimental! 2 | 3 | LibPath ← ⊡1&args 4 | Lib ← &ffi ⊂LibPath # Track caller! 5 | 6 | ⍤⟜≍: 8 Lib {"int" "add" "int" "int"} {3 5} 7 | ⍤⟜≍: 13 Lib {"int" "strlen" "const char*"} {"Hello, World!"} 8 | ⍤⟜≍: [3 2 1] Lib {"void" "reverse" "int:1" "int"} {[1 2 3]} 9 | ⍤⟜≍: [3 2 1] Lib {"int:1" "reversed" "const int:1" "int"} {[1 2 3]} 10 | ⍤⟜≍: {1 [2 3]} Lib {"int" "head_tail" "int:1" "int*"} {[1 2 3]} 11 | ⍤⟜≍: [0 1 2 3] Lib {"void" "multi_list" "const int:1" "int" "const int:3" "int" "int:5" "int"} {1_2 3_4 [...0]} 12 | ⍤⟜≍: "Hello, World!" Lib {"void" "change_string" "const char**"} {"xxx"} 13 | ⍤⟜≍: "1 + 2 = 3" Lib {"void" "change_string_to_sum" "int" "int" "const char**"} {1 2 "xxx"} 14 | 15 | VecII ← "{double; double}" 16 | ⍤⟜≍: 5 Lib {"double" "vec2_len" VecII} {[3 4]} 17 | ⍤⟜≍: 5 Lib {"double" "vec2_len_ref" $"const _*"VecII} {[3 4]} 18 | ⍤⟜≍: [4 6] Lib {VecII "vec2_add" VecII VecII} {[1 2] [3 4]} 19 | ⍤⟜≍: [1 0] Lib {"void" "vec2_normalize" $"_*" VecII} {[5 0]} 20 | ⍤⟜≍: [9 12] Lib {VecII "vec2_list_sum" $"const _:1"VecII "int"} {[1_2 3_4 5_6]} 21 | ⍤⟜≍: [5_6 3_4 1_2] Lib {"void" "vec2_list_reverse" $"_:1"VecII "int"} {[1_2 3_4 5_6]} 22 | 23 | Person ← "{const char*; int}" 24 | ⍤⟜≍: {"Dave" 31} Lib {Person "person_new" "const char*" "int"} {"Dave" 31} 25 | ⍤⟜≍: {"Dave" 31} Lib {⊂⊙@*Person "person_new_ptr" "const char*" "int"} {"Dave" 31} 26 | ⍤⟜≍: 31 Lib {"int" "person_val_age" Person} {{"Dave" 31}} 27 | ⍤⟜≍: 31 Lib {"int" "person_ptr_age" $"const _*"Person} {{"Dave" 31}} 28 | TwoPeople ← $"{_; _}" .Person 29 | ⍤⟜≍ {{"a" 1} {"b" 2}} Lib {TwoPeople "two_people_new" Person Person} {{"a" 1} {"b" 2}} 30 | TwoPeoplePtrs ← $"{_*; _*}" .Person 31 | ⍤⟜≍ {{"a" 1} {"b" 2}} Lib {TwoPeoplePtrs "two_people_new_ptr" .$"const _*"Person} {{"a" 1} {"b" 2}} 32 | TwoInts ← "{const int*; const int*}" 33 | ⍤⟜≍: {1 2} Lib {TwoInts "two_ints_new" "const int*" "const int*"} {1 2} 34 | 35 | ⍤⟜≍: [1 2 3] ⊃&memfree(&memcpy "int"⊙3) Lib {"int*" "array_ptr" "const int:1" "int"} {[1 2 3]} 36 | 37 | MDF ← Lib {"const unsigned char*" "dummy_md5" "const unsigned char:1" "unsigned long" "const unsigned char*"} 38 | ⍤⟜≍: "hello" &memcpy "char":5 MDF {"hello" NULL} 39 | MDF ← Lib {"const unsigned char*" "dummy_md5" "const unsigned char:1" "unsigned long" "unsigned char*"} 40 | ⍤⟜≍: {"hello" NULL} ⍜(°□⊢|&memcpy "char":5) MDF {"hello" NULL} 41 | ⍤⟜≍: {.utf₈"hello"} ⍚(&memcpy "unsigned char":5) MDF {"hello" ▽5 0} 42 | 43 | VoidStruct ← "{void*; void*}" 44 | ⍤⤙≍ {NULL NULL} Lib {VoidStruct "make_void_struct" "int"} {5} 45 | °□₂ Lib {VoidStruct "make_void_struct_a" "int"} {5} 46 | ⍤⤙≍ [5] ⊃&memfree(&memcpy "int"⊙1) 47 | ⍤⤙≍ NULL 48 | 49 | ⍤⤙≍ 1 Lib {"unsigned char" "first_byte" "const unsigned char*"} {[1 2 3]} 50 | Bytes ← "{unsigned char*}" 51 | ⍤⤙≍ 1 Lib {"unsigned char" "bytes_first_byte" Bytes} {{[1 2 3]}} 52 | 53 | ⍤⤙≍ "0x" ↙2⊢pretty Lib {"int*" "pointerify" "int"} {5} 54 | -------------------------------------------------------------------------------- /tests_special/error.ua: -------------------------------------------------------------------------------- 1 | ⊟ [1 2 3] 4_5 2 | 3 | ≡⊟ [1 2 3] [4 5] 4 | 5 | ≡⊟ [1 2 3] [] 6 | ≡(⊂⊂) [1 2 3] [4 5 6] [] 7 | 8 | ≡₀⊟ [1 2 3] [4 5] 9 | 10 | ⊡ ↯0_2e [1] 11 | 12 | Ex ~ "example" 13 | Ex~RangeDiff 14 | 15 | F! ← F!^0 16 | F!+ 17 | 18 | regex "([a-z]" "hello world" 19 | 20 | "Hello"_"Worrld" 21 | 22 | ⍜⊏() ⊚. [ 23 | [0 0 1 0 0] 24 | [0 0 0 0 1] 25 | [1 0 0 0 0] 26 | [0 0 0 1 0] 27 | [0 1 0 0 0] 28 | ] 29 | 30 | F ← [⋅⋅◌⍢(-1:0|>0)]1 31 | F"oops" 32 | 33 | ⊕⊢ [0 2 2] [1 2 3] 34 | 35 | + ¤[1 2 3] [10_20_30_40 50_60_70_80] 36 | 37 | ⇡⇡50 38 | 39 | x ← &sc 40 | F! ←^ °⋕x◌ 41 | F!5 42 | 43 | ⇡1e20 44 | 45 | ⬚0≡(++) [1] [2 3 4] [5 6] 46 | 47 | 5 48 | ⊸∘◌ 49 | 50 | F ← |39 ⍥+ 51 | 52 | ⍜⊏(?≡⊂⊙9?) [0 2] [1_2 3_4 5_6 7_8] 53 | 54 | ┌─╴M 55 | F ↚ +1 56 | └─╴ 57 | M!F 5 58 | 59 | d ← gen [] ⚂ 60 | D! ←^ $"_" d ◌ 61 | ◌D!4 62 | 63 | ! ← ^0 64 | !(^0) 65 | 66 | F ← |0 spawnF 67 | F 68 | 69 | ┌─╴Foo 70 | |Bar {a} 71 | |Baz {a} 72 | └─╴ 73 | ⍤⤙≍ 5 Foo~Baz~a Foo~Bar 5 74 | 75 | °(⊂0?) 76 | 77 | ⟜(@a @b) 78 | 79 | ⊂?⟜(°△⍜⊢¬+1)⇡13 80 | 81 | ˜⊂?⟜(°△⍜⊢¬+1)⇡13 82 | 83 | °binary 0_1_10 84 | 85 | comptime(⍤@@@@) 86 | 87 | F! ← ^2 88 | 89 | ⬚0⌝⊏ ¯2 5 90 | ⬚0⌝⊡ ¯2 5 91 | 92 | °¤ 1 93 | 94 | °[∘] 1 95 | 96 | ⍥∘0 97 | 98 | ⧈∘ [1 2 3] 4 99 | 100 | ⧈∘ [1 2 3] 4_5 101 | 102 | ⧈∘ ¤[1 2 3] 4 103 | 104 | ⧈∘ ¤[1 2 3] 4_5 105 | 106 | ⧈∘.3 107 | 108 | ⬚[1_2 3_4]↙5 [1 2 3 4] 109 | 110 | # Experimental! 111 | ~MyData {Foo: °0type|Bar: °1type} 112 | MyData 3 5 # Fails 113 | 114 | ⍥∘ [1_2 3_4] [1_2_3 4_5_6] 115 | 116 | ⍜≡⊡⊂₁₀ 1 °△3_3 117 | 118 | ⍜▽(˜⊞+⇡5) ⊸≠@ "a bc" 119 | ⍜▽⋅(°△ 2_2_3) 1_0_1 [1_2 3_4 5_6] 120 | 121 | ⍜0? 122 | 123 | ⌝⬚0↻1 [1 2 3 4] 124 | 125 | F ← ( 126 | G ← 5 127 | ) 128 | G 129 | 130 | F! ← ( 131 | G ← 5 132 | ^0 G 133 | ) 134 | 135 | aπ 136 | 137 | # Experimental! 138 | ~F {A B ← 0} ≡°□ 139 | ≡F B:5 ⇡3 140 | 141 | # Experimental! 142 | ~F {A B ← 0} ≡°□ 143 | F ≡F B:5 ⇡3 144 | 145 | # Experimental! 146 | ~F {A ← 0|B C ← 0} ∘ 147 | F (F) A:5 ⇡3 148 | 149 | # Experimental! 150 | ~F {A ← 5} ∘ 151 | F A:[1] B:2 152 | 153 | # Experimental! 154 | ~F {A ← 1|B ← 1} ∘ 155 | F~Args [] A:5 B:2 156 | 157 | # Thing $ A B 158 | F ← (⚂) 159 | 160 | ┌─╴M 161 | ≁G {} 162 | └─╴ 163 | M~G 164 | 165 | ┌─╴M ~ G 166 | G ↚ 5 167 | └─╴ 168 | M~G 169 | 170 | ┌─╴M 171 | ≁ {A} 172 | └─╴ 173 | M 5 -------------------------------------------------------------------------------- /tests_special/uasm.ua: -------------------------------------------------------------------------------- 1 | {[] "" {} ×i[]} 2 | ⍤⤙≍ ⇡4 ≡◇type # No inline! 3 | 4 | {[5] "H" {1_2_3} [i]} 5 | {[] "" {} ×i[]} 6 | ⍤⤙≍ ⊙(⍚↘1) # No inline! 7 | 8 | ⍤⤙≍ ⊣"S " @ # No inline! 9 | 10 | F ← ≡⍣⋕() 11 | ⍤⤙≍ {1 "bn"} F {"1" "bn"} # No inline! 12 | 13 | C ← ℂ3 4 14 | ⍤⤙≍ ℂ3 4 C # No inline! 15 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | # Uiua Todo 2 | 3 | # 0.17 4 | - `Variants` field for module 5 | - Private modules 6 | - Sided `join` 7 | - `table` subscripts for rank selection 8 | - Mixed subscripts 9 | - `bracket` 10 | - Reserved modifier glyphs? 11 | - Implement some `under` inverses in terms of `un by`, rather than the other way around? 12 | - `un`/`anti` `stencil` 13 | - Compile-time code string evaluation? 14 | - Streaming gif and audio encoding 15 | 16 | ## Planned Features 17 | Features that are planned to be implemented in the future. 18 | 19 | - Stackless execution trees? 20 | - Step debugging 21 | - Better compiler IR sytem 22 | - Make the stack only exist at compile time? 23 | - Dead code elimination 24 | - Eliminate unused anonymous functions 25 | - Dynamic modules 26 | - A system by which the public interface of a module can be specified 27 | - Instances of a dynamic module can be loaded at runtime 28 | - Enabled things from simple config files to game mods 29 | - System APIs 30 | - UDP Sockets 31 | - `&udpb` to bind a socket 32 | - `&udpc` to connect a socket? 33 | - `&udpr` to receive data from a socket 34 | - Returns both data and source address 35 | - `&udps` to send data to a socket 36 | - Takes both data and destination address 37 | - Change `&tcpsnb`, `&tcpsrt`, `&tcpswt` to work for UDP sockets as well 38 | - Rename them 39 | - File metadata 40 | - `&fmeta` to get metadata about a file 41 | - Should somehow provide: 42 | - size 43 | - kind (file, directory, symlink) 44 | - create/modify/access times 45 | - permissions 46 | - It's possible this should be multiple functions 47 | - `&fsize` 48 | - `&fkind` 49 | - `&ftime` 50 | - `&fperm` 51 | 52 | ## Potential Features 53 | Features that could be implemented, but are not currently planned. 54 | 55 | - Channels 56 | - Multimedia 57 | - Sound input 58 | - Something akin to `&ast` but for input 59 | - `&arec` to record audio for some duration 60 | - Maybe it should be a modifier that records until its function returns false? 61 | 62 | ## Open to Implementation 63 | 64 | These features are not strictly on the roadmap, but PRs that implement them will likely be accepted. 65 | 66 | Feel free to make PRs to the list itself as well. 67 | 68 | - Better complex `⌈`/`⌊`/`⁅`/`◿`, `<`/`>`/`≤`/`≥`, `↥`/`↧` 69 | - Pad link from Gist 70 | - Additional optimizations 71 | - `/F⇌` 72 | - `⍜⇌/F` 73 | --------------------------------------------------------------------------------