glossary: type signature + typos upgrade (#7776)

* glossary: type signature

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>

* ignore toolchain for typos

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>

* fix typos

* put toolchain file back

---------

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
This commit is contained in:
Anton-4 2025-05-07 17:35:56 +02:00 committed by GitHub
parent c320a1bca5
commit b552466755
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 89 additions and 63 deletions

View file

@ -23,9 +23,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: cargo install typos-cli --version 1.0.11
- run: rm rust-toolchain.toml
- name: do spell check with typos-cli 1.0.11
- run: cargo install typos-cli --version 1.32.0
- name: do spell check with typos-cli 1.32.0
run: typos
- name: setup Roc
@ -39,4 +41,4 @@ jobs:
- run: roc version
- run: roc ./ci/glossary-link-checker.roc
- run: roc ./ci/glossary-link-checker.roc

2
.gitignore vendored
View file

@ -81,7 +81,7 @@ roc_linux_x86_64.tar.gz
# macOS .DS_Store files
.DS_Store
# files geneated when formatting fails
# files generated when formatting fails
*.roc-format-failed
*.roc-format-failed-ast-after
*.roc-format-failed-ast-before

View file

@ -2,7 +2,7 @@ Here you can find definitions for words that are commonly used in the **compiler
with links to the codebase. Check https://www.roc-lang.org/tutorial if you want to know
about general Roc terms. Feel free to ask for a term to be added or add one yourself!
Contributor note: definitons should be roughly ordered like in a tutorial, e.g.
Contributor note: definitions should be roughly ordered like in a tutorial, e.g.
Parser should be explained before Canonicalization.
## CLI
@ -132,12 +132,28 @@ Desugaring in the compiler:
## Type Signature
TODO
Specifies the type of a variable. For example, the type signature of `Str.concat` is:
```
concat : Str, Str -> Str
```
Here it specifies `concat` takes two strings as input and produces one as output.
In the compiler, the type signature specified in the source code has priority over the type found by [type inference](#type-inference), although both need to match for your code to compile completely.
Type annotations are basically the same thing as type signatures and both terms are used interchangeably throughout the compiler.
Parsing of type signatures:
- New compiler: [Parser.zig](src/check/parse/Parser.zig) (search signature)
- Old compiler: [ast.rs](crates/compiler/parse/src/ast.rs) (search TypeAnnotation)
## Type Alias
TODO
## Type Variable
TODO
## Compiler Phase
A compiler phase is a distinct stage in the process the compiler goes through to translate high-level source code into machine code that a computer can execute. Compilers dont just do this in one big step, they break it down into several phases, each handling a specific task. Some examples of phases: [tokenization](#tokenization), [parsing](#parsing), [code generation](#code-gen),... .

View file

@ -326,7 +326,7 @@ fn llvmPaths(
};
}
// No user specified llvm. Go download it from roc-boostrap.
// No user specified llvm. Go download it from roc-bootstrap.
const raw_triple = target.result.linuxTriple(b.allocator) catch @panic("OOM");
if (!supported_deps_triples.has(raw_triple)) {
std.log.err("Target triple({s}) not supported by roc-bootstrap.\n", .{raw_triple});

View file

@ -30,7 +30,7 @@ main! = |_args|
when full_check_res is
Ok(_) ->
Stdout.line!("Successfuly checked $(List.len(md_links) |> Num.to_str) links.")
Stdout.line!("Successfully checked $(List.len(md_links) |> Num.to_str) links.")
Err(_) ->
Err(Exit(1, "Link check failed. Please check the above errors."))

View file

@ -962,8 +962,8 @@ code .keyword.operator {
}
/* Delimieters */
samp .delimeter,
code .delimeter {
samp .delimiter,
code .delimiter {
color: var(--gray);
}

View file

@ -85,7 +85,7 @@ pub fn highlight(code: &str) -> Vec<String> {
| Token::Comma
| Token::Bar
| Token::Decimal => {
buf = push_html_span(buf, current_text, "delimeter");
buf = push_html_span(buf, current_text, "delimiter");
}
// Types, Tags, and Modules
Token::UpperIdent | Token::AtSign => {

View file

@ -738,7 +738,7 @@ fn gen_elf_le(
}
}
// To correctly remove the JUMP_SLOT relocations for Roc functions we:
// 1. collect the indicies of all of them.
// 1. collect the indices of all of them.
// 2. move them all to the end of the relocation sections.
// 3. shrink the relocation section to ignore them.
// 4. update the dynamic section to reflect the shrink as well.

View file

@ -55,8 +55,8 @@ e.g. you have a test `calculate_sum_test` that only uses the function `add`, whe
- I think it could be possible to create a minimal reproduction of a program / block of code / code used by a single test. So for a failing unit test I would expect it to extract imports, the platform, types and functions that are necessary to run only that unit test and put them in a standalone roc project. This would be useful for sharing bugs with library+application authors and colleagues, for profiling or debugging with all "clutter" removed.
- Ability to share program state at a breakpoint with someone else.
- For debugging we should aim for maximal useful observability. For example Rust's enum values can not be easily viewed in the CodeLLDB debugger, you actually need to call a print method that does pattern matching to be able to view useful information.
- We previuously discussed recording full traces of programs so they do not have to be re-run multiple times in the debugging process. We should encourage roc developers to experiment with creating debugging representations of this AST+"execution trace", it could lead to some cool stuff.
- We previuously mentioned showing expression values next to the code. I think when debugging it would be valuable to focus more on these valuas/data. A possible way to do this would be to create scrollable view(without need to jump between files) of inputs and outputs of user defined functions. Clicking on a function could then show the code with the expression values side by side. Having a good overview of how the values change could make it easy to find where exactly things go wrong.
- We previously discussed recording full traces of programs so they do not have to be re-run multiple times in the debugging process. We should encourage roc developers to experiment with creating debugging representations of this AST+"execution trace", it could lead to some cool stuff.
- We previously mentioned showing expression values next to the code. I think when debugging it would be valuable to focus more on these valuas/data. A possible way to do this would be to create scrollable view(without need to jump between files) of inputs and outputs of user defined functions. Clicking on a function could then show the code with the expression values side by side. Having a good overview of how the values change could make it easy to find where exactly things go wrong.
- (Machine learning) algorithms to extract and show useful information from debug values.
- Ability to mark e.g. a specific record field for tracking(filter out the noise) that is being repeatedly updated throughout the program.
@ -147,7 +147,7 @@ e.g. you have a test `calculate_sum_test` that only uses the function `add`, whe
- open google/github/duckduckgo search for error...
- show editor plugins for library X
- commands to control log filtering
- collaps all arms of when
- collapse all arms of when
- "complex" filtered search: search for all occurrences of `"#` but ignore all like `"#,`
- color this debug print orange
- remove unused imports

View file

@ -348,7 +348,7 @@ isNotEq : Dict k v, Dict k v -> Bool
In this `Eq { isEq, isNotEq }` declaration, I'm saying that `isEq` and `isNotEq` are functions already in scope. I could also choose different names using record literal syntax, e.g. `Eq { isEq: dictIsEq, isNotEq: dictIsNotEq }` - the relevant part is that I'm specifying the names of the functions (which must also be in scope) which specify how `Eq` for Dict should work.
Now that I've specified this, when I use `==` on two `Dict` values, this `isEq` function will get run instead of the default `==` implementation. This solves [Problem #3](#problem-3-decoders-are-still-hard-to-learn)!
I can also write something like has `Num` and provide the relevant functions to obtain a unit-ful number type - which solves [Problem #2](#problem-2-custom-number-types-cant-use-arithmetic-operators).
I can also write something like has `Num` and provide the relevant functions to obtain a unit-ful number type, which solves [Problem #2](#problem-2-custom-number-types-cant-use-arithmetic-operators).
### Default Abilities for Newtypes

View file

@ -14,7 +14,7 @@ let
let
dirFilter = pathStr: (
let dirName = baseNameOf pathStr; in !(
# remove any folder whos name is `tests` or starts with `test_`
# remove any folder whose name is `tests` or starts with `test_`
dirName == "tests"
)
);

View file

@ -1,26 +1,26 @@
[toolchain]
# How to update version:
# - update `channel = "RUST_VERSION"`
# - update `channel = "RUST_VERSION"` in examples/platform-switching/rust-platform/rust-toolchain.toml
# - update `channel = "RUST_VERSION"` in examples/glue/rust-platform/rust-toolchain.toml
# - to update the nightly version:
# - Find the latest nightly release that matches RUST_VERSION here: https://github.com/oxalica/rust-overlay/tree/master/manifests/nightly/2024
# - update `channel = "nightly-OLD_DATE"` below
# - update nightly-OLD_DATE in .github/workflows/ubuntu_x86_64.yml
# - update nightly-OLD_DATE in .github/workflows/windows_tests.yml
# - update nightly-OLD_DATE in .github/workflows/windows_release_build.yml
# - update nightly-OLD_DATE in crates/compiler/build/src/link.rs
channel = "1.77.2" # check ^^^ when changing this
#
# channel = "nightly-2024-02-03" # 1.77.0 nightly to be able to use unstable features
profile = "default"
components = [
# for usages of rust-analyzer or similar tools inside `nix develop`
"rust-src"
]
targets = [
"wasm32-wasi", # for test_wasm.sh
"wasm32-unknown-unknown", # for repl_wasm
]
[toolchain]
# How to update version:
# - update `channel = "RUST_VERSION"`
# - update `channel = "RUST_VERSION"` in examples/platform-switching/rust-platform/rust-toolchain.toml
# - update `channel = "RUST_VERSION"` in examples/glue/rust-platform/rust-toolchain.toml
# - to update the nightly version:
# - Find the latest nightly release that matches RUST_VERSION here: https://github.com/oxalica/rust-overlay/tree/master/manifests/nightly/2024
# - update `channel = "nightly-OLD_DATE"` below
# - update nightly-OLD_DATE in .github/workflows/ubuntu_x86_64.yml
# - update nightly-OLD_DATE in .github/workflows/windows_tests.yml
# - update nightly-OLD_DATE in .github/workflows/windows_release_build.yml
# - update nightly-OLD_DATE in crates/compiler/build/src/link.rs
channel = "1.77.2" # check ^^^ when changing this
#
# channel = "nightly-2024-02-03" # 1.77.0 nightly to be able to use unstable features
profile = "default"
components = [
# for usages of rust-analyzer or similar tools inside `nix develop`
"rust-src"
]
targets = [
"wasm32-wasi", # for test_wasm.sh
"wasm32-unknown-unknown", # for repl_wasm
]

View file

@ -8,7 +8,7 @@ This table provides a summary of progress for the zig compiler re-write and shou
| **Canonicalize** | 🚧 | 🚧 | | | | | |
| **Resolve Imports** | | | | | | | |
| **Check Types** | | | | | | | |
| **Intepreter** | | | | | | | |
| **Interpreter** | | | | | | | |
| **Specialize Types** | | | | | | | |
| **Lift Functions** | | | | | | | |
| **Solve Functions** | | | | | | | |
@ -45,7 +45,7 @@ This fast config can also be used with `zls`. Simply follow these steps:
Otherwise, zig commands run manually can lead to the lsp breaking and requiring a restart.
5. Optionally, add `-Dfuzz` above as well to get type checking of fuzz scripts as well.
6. Note, I had to fully delete my `.zig-cache` to get `zls` to start.
Make sure to check the logs if you aren't geting type failures.
Make sure to check the logs if you aren't getting type failures.
7. Enjoy better lsp results.
### Simply testing feedback loop

View file

@ -40,7 +40,7 @@ Using it with roc can be as simple as `flamegraph --root -- ./zig-out/bin/roc fo
If you open the flamegraph in a browser, you can explore where time is spent.
There is a search button in the top right corner (almost not visible) that enables better discovery of percentage of time used in various functions.
For example, here is a flamegraph from parsing and formating a roc file.
For example, here is a flamegraph from parsing and formatting a roc file.
It was search for `memmove` and shows that 25% of time is spent moving bytes.
![example flamegraph](example-flamegraph.png)
@ -63,7 +63,7 @@ On top of that, we can see that 42% of `memmove`s happened during tokenization.
Unlike the above, tracy is not primarily a sampling profiler.
Instead, tracy focuses on tracing through explicit code annotations.
Tracy is significantly more complex than the other solutions, but is alway way more powerful.
Tracy is significantly more complex than the other solutions, but is always way more powerful.
Tracy has an [~100 page detailed manual](https://github.com/wolfpld/tracy/releases/latest/download/tracy.pdf) and an online interactive demo: https://tracy.nereid.pl/.
The most important part of the manual to read is probably `Analyzing captured data` (which is about the UI).
@ -74,7 +74,7 @@ As such, I have checked out the tracy github repro to the `v0.11.0` tag in my `~
Then, on my linux machine (which tracy works better on), I run ` zig build -Doptimize=ReleaseFast -Dtracy=$HOME/vendor/tracy roc`.
This builds tracy with all of the bells and whistles.
One of those cool features is tracy callstacks. This feature gives much more precision of information, but adds signifcant overhead.
One of those cool features is tracy callstacks. This feature gives much more precision of information, but adds significant overhead.
Often times, it is worth profiling once with `-Dtracy-callstack=false` to have much less overhead.
Now that I have the compiler built with tracy, I can launch the tracy server on my mac machine to record the result (you can also run it on the same machine if wanted).

View file

@ -141,7 +141,7 @@ pub const Url = struct {
const MISLEADING_CHARACTERS_IN_URL: [5]u32 = .{
// Since the TLD (top level domain) `.zip` is now available, there is a new attack
// vector where malicous URLs can be used to confuse the reader.
// vector where malicious URLs can be used to confuse the reader.
// Example of a URL which would take you to example.zip:
// https://github.comkuberneteskubernetesarchiverefstags@example.zip
// roc employs a checksum mechanism to prevent tampering with packages.

View file

@ -3449,7 +3449,7 @@ pub const NodeStore = struct {
/// Clears any WhenBranchIds added to scratch from start until the end.
/// Should be used wherever the scratch items will not be used,
/// as in when parsing fails.
pub fn clearScratchWhenBranchsFrom(store: *NodeStore, start: u32) void {
pub fn clearScratchWhenBranchesFrom(store: *NodeStore, start: u32) void {
store.scratch_when_branches.shrinkRetainingCapacity(start);
}

View file

@ -1820,7 +1820,7 @@ fn rebuildBufferForTesting(buf: []const u8, tokens: *TokenizedBuffer, alloc: std
}
},
.Int => {
// To ensure this value when reprinted tokenizes as an int, add a base if the number is 3 or more charcters.
// To ensure this value when reprinted tokenizes as an int, add a base if the number is 3 or more characters.
if (length >= 3) {
try buf2.append(alloc, '0');
try buf2.append(alloc, 'x');

View file

@ -18,7 +18,7 @@ const Self = @This();
/// Since strings are small, they are simply null terminated.
/// This uses only 1 byte to encode the size and is cheap to scan.
bytes: std.ArrayListUnmanaged(u8) = .{},
/// A deduplicated set of strings indicies referencing into bytes.
/// A deduplicated set of strings indices referencing into bytes.
/// The key is the offset into bytes.
strings: StringIdx.Table = .{},
/// A unique ID for every string. This is fundamentally an index into bytes.
@ -29,7 +29,7 @@ regions: std.ArrayListUnmanaged(Region) = .{},
/// A unique index for a deduped string in this interner.
pub const Idx = enum(u32) { _ };
/// Intiailize a `SmallStringInterner` with the specified capacity.
/// Initialize a `SmallStringInterner` with the specified capacity.
pub fn initCapacity(gpa: std.mem.Allocator, capacity: usize) Self {
// TODO: tune this. Rough assumption that average small string is 4 bytes.
const bytes_per_string = 4;

View file

@ -55,7 +55,7 @@ pub fn SafeList(comptime T: type) type {
range: Range,
};
/// Intialize the `SafeList` with the specified capacity.
/// Initialize the `SafeList` with the specified capacity.
pub fn initCapacity(gpa: Allocator, capacity: usize) SafeList(T) {
return .{
.items = std.ArrayListUnmanaged(T).initCapacity(gpa, capacity) catch |err| exitOnOom(err),
@ -190,7 +190,7 @@ pub fn SafeMultiList(comptime T: type) type {
return self.items.items(field_name)[@as(usize, @intFromEnum(idx))];
}
/// Intialize the `SafeMultiList` with the specified capacity.
/// Initialize the `SafeMultiList` with the specified capacity.
pub fn initCapacity(gpa: Allocator, capacity: usize) SafeMultiList(T) {
var items = std.MultiArrayList(T){};
items.ensureTotalCapacity(gpa, capacity) catch |err| exitOnOom(err);

View file

@ -21,7 +21,7 @@ const StatementIdx = NodeStore.StatementIdx;
const FormatFlags = enum { debug_binop, no_debug };
/// Count of successfully formated files along with files that failed to format.
/// Count of successfully formatted files along with files that failed to format.
pub const SuccessFailCount = struct { success: usize, failure: usize };
/// Formats all roc files in the specified path.
@ -2194,13 +2194,13 @@ test "Platform header - nonempty" {
try moduleFmtsSame(
\\platform # Comment after platform keyword
\\ "foo" # Comment after name
\\ requires # Coment after requires keyword
\\ requires # Comment after requires keyword
\\ { # Comment after rigids open
\\ Main, # Comment after rigid member
\\ } # Comment after rigids close
\\ { # Comment after signatures open
\\ main! : List(Str) => {}, # Comment after signature
\\ } # Comment after signatures clsoe
\\ } # Comment after signatures close
\\ exposes # Comment after exposes keyword
\\ [ # Comment after exposes open
\\ foo, # Comment after exposed item

View file

@ -1,3 +1,11 @@
[files]
extend-exclude = ["crates/vendor/", "examples/static-site-gen/input/", "COPYRIGHT", "crates/compiler/checkmate/www/package-lock.json"]
extend-exclude = ["design/language/Abilities.md", "src/snapshots/fuzz_crash", "crates/vendor/", "authors", "crates", "examples/static-site-gen/input/", "COPYRIGHT", "crates/compiler/checkmate/www/package-lock.json", "src/zig_llvm.h"]
[default]
extend-ignore-identifiers-re = [
".*_SME_.*"
]
[default.extend-words]
HSA = "HSA"
typ = "typ"

View file

@ -1468,7 +1468,7 @@ double = |num|
expect double(0) == 0
```
- `roc build` wil run `main`, ignore `expect 1 == 2` and just print `Hi there.`.
- `roc build` will run `main`, ignore `expect 1 == 2` and just print `Hi there.`.
- `roc dev` will run `main`, tell you `expect 1 == 2` failed but will still print `Hi there`.
- `roc test` will run `expect double(0) == 0` followed by `expect num > -1` and will print how many top level expects passed: `0 failed and 1 passed in 100 ms.`.
@ -1863,7 +1863,7 @@ main! = |_args|
(In this particular example, it's very unlikely that this would come up at all, and even if it did, we might not care which one caused the problem. But you can imagine having multiple HTTP requests, or file writes, and wanting to know which of them was the one that failed.)
If an error happended here, we wouldn't know which effectful function was the cause of the failure.
If an error happened here, we wouldn't know which effectful function was the cause of the failure.
One option is to "tag the error" using `Result.map_err` to wrap the error in a [tag](#tags) like so:

View file

@ -947,8 +947,8 @@ code .colon {
}
/* Delimieters */
samp .delimeter,
code .delimeter {
samp .delimiter,
code .delimiter {
color: var(--primary-1);
}