Skip to content

Commit

Permalink
Use dashes for list markers
Browse files Browse the repository at this point in the history
  • Loading branch information
JanCVanB committed Sep 9, 2022
1 parent de53e04 commit 9cf7bdc
Show file tree
Hide file tree
Showing 9 changed files with 375 additions and 376 deletions.
1 change: 0 additions & 1 deletion .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ config:
no-emphasis-as-heading: false
no-inline-html: false
no-trailing-punctuation: false
ul-style: false

ignores:
- "crates/vendor/**/*.md"
Expand Down
14 changes: 7 additions & 7 deletions BUILDING_FROM_SOURCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,16 @@ That will help us improve this document for everyone who reads it in the future!

To build the compiler, you need these installed:

* [Zig](https://ziglang.org/), see below for version
* `libxkbcommon` - macOS seems to have it already; on Ubuntu or Debian you can get it with `apt-get install libxkbcommon-dev`
* On Debian/Ubuntu `sudo apt-get install pkg-config`
* LLVM, see below for version
* [rust](https://rustup.rs/)
* Also run `cargo install bindgen` after installing rust. You may need to open a new terminal.
- [Zig](https://ziglang.org/), see below for version
- `libxkbcommon` - macOS seems to have it already; on Ubuntu or Debian you can get it with `apt-get install libxkbcommon-dev`
- On Debian/Ubuntu `sudo apt-get install pkg-config`
- LLVM, see below for version
- [rust](https://rustup.rs/)
- Also run `cargo install bindgen` after installing rust. You may need to open a new terminal.

To run the test suite (via `cargo test`), you additionally need to install:

* [`valgrind`](https://www.valgrind.org/) (needs special treatment to [install on macOS](https://stackoverflow.com/a/61359781)
- [`valgrind`](https://www.valgrind.org/) (needs special treatment to [install on macOS](https://stackoverflow.com/a/61359781)
Alternatively, you can use `cargo test --no-fail-fast` or `cargo test -p specific_tests` to skip over the valgrind failures & tests.

For debugging LLVM IR, we use [DebugIR](https://github.com/vaivaswatha/debugir). This dependency is only required to build with the `--debug` flag, and for normal development you should be fine without it.
Expand Down
20 changes: 10 additions & 10 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ In the interest of fostering an open and welcoming environment, we as participan

Examples of behavior that contributes to creating a positive environment include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Kindly giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Kindly giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall
community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address, without their explicit permission
* Telling others to be less sensitive, or that they should not feel hurt or offended by something
- The use of sexualized language or imagery, and sexual attention or advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address, without their explicit permission
- Telling others to be less sensitive, or that they should not feel hurt or offended by something

## Enforcement Responsibilities

Expand Down
78 changes: 39 additions & 39 deletions TUTORIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ addAndStringify = \num1, num2 ->

We did two things here:

* We introduced a local def named `sum`, and set it equal to `num1 + num2`. Because we defined `sum` inside `addAndStringify`, it will not be accessible outside that function.
* We added an `if` / `then` / `else` conditional to return either `""` or `Num.toStr sum` depending on whether `sum == 0`.
- We introduced a local def named `sum`, and set it equal to `num1 + num2`. Because we defined `sum` inside `addAndStringify`, it will not be accessible outside that function.
- We added an `if` / `then` / `else` conditional to return either `""` or `Num.toStr sum` depending on whether `sum == 0`.

Of note, we couldn't have done `total = num1 + num2` because that would be
redefining `total` in the global scope, and defs can't be redefined. (However, we could use the name
Expand Down Expand Up @@ -401,8 +401,8 @@ fromOriginal = { original & birds: 4, iguanas: 3 }
The `fromScratch` and `fromOriginal` records are equal, although they're assembled in
different ways.

* `fromScratch` was built using the same record syntax we've been using up to this point.
* `fromOriginal` created a new record using the contents of `original` as defaults for fields that it didn't specify after the `&`.
- `fromScratch` was built using the same record syntax we've been using up to this point.
- `fromOriginal` created a new record using the contents of `original` as defaults for fields that it didn't specify after the `&`.

Note that when we do this, the fields you're overriding must all be present on the original record,
and their values must have the same type as the corresponding values in the original record.
Expand Down Expand Up @@ -1093,9 +1093,9 @@ the lowest `U16` would be zero (since it always is for unsigned integers), and t

Choosing a size depends on your performance needs and the range of numbers you want to represent. Consider:

* Larger integer sizes can represent a wider range of numbers. If you absolutely need to represent numbers in a certain range, make sure to pick an integer size that can hold them!
* Smaller integer sizes take up less memory. These savings rarely matters in variables and function arguments, but the sizes of integers that you use in data structures can add up. This can also affect whether those data structures fit in [cache lines](https://en.wikipedia.org/wiki/CPU_cache#Cache_performance), which can easily be a performance bottleneck.
* Certain processors work faster on some numeric sizes than others. There isn't even a general rule like "larger numeric sizes run slower" (or the reverse, for that matter) that applies to all processors. In fact, if the CPU is taking too long to run numeric calculations, you may find a performance improvement by experimenting with numeric sizes that are larger than otherwise necessary. However, in practice, doing this typically degrades overall performance, so be careful to measure properly!
- Larger integer sizes can represent a wider range of numbers. If you absolutely need to represent numbers in a certain range, make sure to pick an integer size that can hold them!
- Smaller integer sizes take up less memory. These savings rarely matters in variables and function arguments, but the sizes of integers that you use in data structures can add up. This can also affect whether those data structures fit in [cache lines](https://en.wikipedia.org/wiki/CPU_cache#Cache_performance), which can easily be a performance bottleneck.
- Certain processors work faster on some numeric sizes than others. There isn't even a general rule like "larger numeric sizes run slower" (or the reverse, for that matter) that applies to all processors. In fact, if the CPU is taking too long to run numeric calculations, you may find a performance improvement by experimenting with numeric sizes that are larger than otherwise necessary. However, in practice, doing this typically degrades overall performance, so be careful to measure properly!

Here are the different fixed-size integer types that Roc supports:

Expand Down Expand Up @@ -1136,9 +1136,9 @@ As such, it's very important to design your integer operations not to exceed the

Roc has three fractional types:

* `F32`, a 32-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754)
* `F64`, a 64-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754)
* `Dec`, a 128-bit decimal [fixed-point number](https://en.wikipedia.org/wiki/Fixed-point_arithmetic)
- `F32`, a 32-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754)
- `F64`, a 64-bit [floating-point number](https://en.wikipedia.org/wiki/IEEE_754)
- `Dec`, a 128-bit decimal [fixed-point number](https://en.wikipedia.org/wiki/Fixed-point_arithmetic)

These are different from integers in that they can represent numbers with fractional components,
such as 1.5 and -0.123.
Expand Down Expand Up @@ -1248,8 +1248,8 @@ Roc compiler. That's why they're called "builtins!"

Besides being built into the compiler, the builtin modules are different from other modules in that:

* They are always imported. You never need to add them to `imports`.
* All their types are imported unqualified automatically. So you never need to write `Num.Nat`, because it's as if the `Num` module was imported using `imports [Num.{ Nat }]` (and the same for all the other types in the `Num` module).
- They are always imported. You never need to add them to `imports`.
- All their types are imported unqualified automatically. So you never need to write `Num.Nat`, because it's as if the `Num` module was imported using `imports [Num.{ Nat }]` (and the same for all the other types in the `Num` module).

## The app module header

Expand Down Expand Up @@ -1315,10 +1315,10 @@ platforms. Let's use the CLI platform in `examples/interactive/cli-platform/main

In the CLI platform, we have four operations we can do:

* Write a string to the console
* Read a string from user input
* Write a string to a file
* Read a string from a file
- Write a string to the console
- Read a string from user input
- Write a string to a file
- Read a string from a file

We'll use these four operations to learn about tasks.

Expand Down Expand Up @@ -1531,9 +1531,9 @@ This way, it reads like a series of instructions:

Some important things to note about backpassing and `await`:

* `await` is not a language keyword in Roc! It's referring to the `Task.await` function, which we imported unqualified by writing `Task.{ await }` in our module imports. (That said, it is playing a similar role here to the `await` keyword in languages that have `async`/`await` keywords, even though in this case it's a function instead of a special keyword.)
* Backpassing syntax does not need to be used with `await` in particular. It can be used with any function.
* Roc's compiler treats functions defined with backpassing exactly the same way as functions defined the other way. The only difference between `\text ->` and `text <-` is how they look, so feel free to use whichever looks nicer to you!
- `await` is not a language keyword in Roc! It's referring to the `Task.await` function, which we imported unqualified by writing `Task.{ await }` in our module imports. (That said, it is playing a similar role here to the `await` keyword in languages that have `async`/`await` keywords, even though in this case it's a function instead of a special keyword.)
- Backpassing syntax does not need to be used with `await` in particular. It can be used with any function.
- Roc's compiler treats functions defined with backpassing exactly the same way as functions defined the other way. The only difference between `\text ->` and `text <-` is how they look, so feel free to use whichever looks nicer to you!

## Appendix: Advanced Concepts

Expand All @@ -1555,9 +1555,9 @@ I can pass this function a record that has more fields than just
`firstName` and `lastName`, as long as it has *at least* both of those fields
(and both of them are strings). So any of these calls would work:

* `fullName { firstName: "Sam", lastName: "Sample" }`
* `fullName { firstName: "Sam", lastName: "Sample", email: "[email protected]" }`
* `fullName { age: 5, firstName: "Sam", things: 3, lastName: "Sample", role: Admin }`
- `fullName { firstName: "Sam", lastName: "Sample" }`
- `fullName { firstName: "Sam", lastName: "Sample", email: "[email protected]" }`
- `fullName { age: 5, firstName: "Sam", things: 3, lastName: "Sample", role: Admin }`

This `user` argument is an *open record* - that is, a description of a minimum set of fields
on a record, and their types. When a function takes an open record as an argument,
Expand Down Expand Up @@ -1611,9 +1611,9 @@ addHttps = \record ->

This function uses *constrained records* in its type. The annotation is saying:

* This function takes a record which has at least a `url` field, and possibly others
* That `url` field has the type `Str`
* It returns a record of exactly the same type as the one it was given
- This function takes a record which has at least a `url` field, and possibly others
- That `url` field has the type `Str`
- It returns a record of exactly the same type as the one it was given

So if we give this function a record with five fields, it will return a record with those
same five fields. The only requirement is that one of those fields must be `url : Str`.
Expand Down Expand Up @@ -1850,14 +1850,14 @@ the tags in the open union you're providing.

So if I have an `[Ok Str]*` value, I can pass it to functions with any of these types (among others):

* `[Ok Str]* -> Bool`
* `[Ok Str] -> Bool`
* `[Ok Str, Err Bool]* -> Bool`
* `[Ok Str, Err Bool] -> Bool`
* `[Ok Str, Err Bool, Whatever]* -> Bool`
* `[Ok Str, Err Bool, Whatever] -> Bool`
* `Result Str Bool -> Bool`
* `[Err Bool, Whatever]* -> Bool`
- `[Ok Str]* -> Bool`
- `[Ok Str] -> Bool`
- `[Ok Str, Err Bool]* -> Bool`
- `[Ok Str, Err Bool] -> Bool`
- `[Ok Str, Err Bool, Whatever]* -> Bool`
- `[Ok Str, Err Bool, Whatever] -> Bool`
- `Result Str Bool -> Bool`
- `[Err Bool, Whatever]* -> Bool`

That last one works because a function accepting an open union can accept any unrecognized tag, including
`Ok Str` - even though it is not mentioned as one of the tags in `[Err Bool, Whatever]*`! Remember, when
Expand All @@ -1881,10 +1881,10 @@ a catch-all `_ ->` branch, it might not know what to do with an `Ok Str` if it r
In summary, here's a way to think about the difference between open unions in a value you have, compared to a value you're accepting:

* If you *have* a closed union, that means it has all the tags it ever will, and can't accumulate more.
* If you *have* an open union, that means it can accumulate more tags through conditional branches.
* If you *accept* a closed union, that means you only have to handle the possibilities listed in the union.
* If you *accept* an open union, that means you have to handle the possibility that it has a tag you can't know about.
- If you *have* a closed union, that means it has all the tags it ever will, and can't accumulate more.
- If you *have* an open union, that means it can accumulate more tags through conditional branches.
- If you *accept* a closed union, that means you only have to handle the possibilities listed in the union.
- If you *accept* an open union, that means you have to handle the possibility that it has a tag you can't know about.

### Type Variables in Tag Unions

Expand Down Expand Up @@ -1932,8 +1932,8 @@ the `Foo Str` and `Bar Bool` we already know about).
If we removed the type annotation from `example` above, Roc's compiler would infer the same type anyway.
This may be surprising if you look closely at the body of the function, because:

* The return type includes `Foo Str`, but no branch explicitly returns `Foo`. Couldn't the return type be `[Bar Bool]a` instead?
* The argument type includes `Bar Bool` even though we never look at `Bar`'s payload. Couldn't the argument type be inferred to be `Bar *` instead of `Bar Bool`, since we never look at it?
- The return type includes `Foo Str`, but no branch explicitly returns `Foo`. Couldn't the return type be `[Bar Bool]a` instead?
- The argument type includes `Bar Bool` even though we never look at `Bar`'s payload. Couldn't the argument type be inferred to be `Bar *` instead of `Bar Bool`, since we never look at it?

The reason it has this type is the `other -> other` branch. Take a look at that branch, and ask this question:
"What is the type of `other`?" There has to be exactly one answer! It can't be the case that `other` has one
Expand Down
18 changes: 9 additions & 9 deletions crates/compiler/str/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ On a 64-bit system, this `struct` would take up 16B in memory. On a 32-bit syste

Here's what the fields mean:

* `pointer` is the memory address of the heap-allocated memory containing the `Bool` elements. For an empty list, the pointer is null (that is, 0).
* `length` is the number of `Bool` elements in the list. For an empty list, this is also 0.
- `pointer` is the memory address of the heap-allocated memory containing the `Bool` elements. For an empty list, the pointer is null (that is, 0).
- `length` is the number of `Bool` elements in the list. For an empty list, this is also 0.

## Nonempty list

Expand Down Expand Up @@ -115,8 +115,8 @@ We use a very simple system to distinguish the two: if the high bit in that `usi

This has a couple of implications:

* `capacity` actually has a maximum of `isize::MAX`, not `usize::MAX` - because if its high bit flips to 1, then now suddenly it's considered a refcount by the host. As it happens, capacity's maximum value is naturally `isize::MAX` anyway, so there's no downside here.
* `refcount` actually begins at `isize::MIN` and increments towards 0, rather than beginning at 0 and incrementing towards a larger number. When a decrement instruction is executed and the refcount is `isize::MIN`, it gets freed instead. Since all refcounts do is count up and down, and they only ever compare the refcount to a fixed constant, there's no real performance cost to comparing to `isize::MIN` instead of to 0. So this has no significant downside either.
- `capacity` actually has a maximum of `isize::MAX`, not `usize::MAX` - because if its high bit flips to 1, then now suddenly it's considered a refcount by the host. As it happens, capacity's maximum value is naturally `isize::MAX` anyway, so there's no downside here.
- `refcount` actually begins at `isize::MIN` and increments towards 0, rather than beginning at 0 and incrementing towards a larger number. When a decrement instruction is executed and the refcount is `isize::MIN`, it gets freed instead. Since all refcounts do is count up and down, and they only ever compare the refcount to a fixed constant, there's no real performance cost to comparing to `isize::MIN` instead of to 0. So this has no significant downside either.

Using this representation, hosts can trivially distinguish any list they receive as being either refcounted or having a capacity value, without any runtime cost in either the refcounted case or the capacity case.

Expand Down Expand Up @@ -146,14 +146,14 @@ Whenever a list grows, it will grow in-place if it's Unique and there is enough

Strings have several things in common with lists:

* They are a `2 * usize` struct, sometimes with a non-null pointer to some heap memory
* They have a length and a capacity, and they can grow in basically the same way
* They are reference counted in basically the same way
- They are a `2 * usize` struct, sometimes with a non-null pointer to some heap memory
- They have a length and a capacity, and they can grow in basically the same way
- They are reference counted in basically the same way

However, they also have two things going on that lists do not:

* The Small String Optimization
* Literals stored in read-only memory
- The Small String Optimization
- Literals stored in read-only memory

## The Small String Optimization

Expand Down
Loading

0 comments on commit 9cf7bdc

Please sign in to comment.