Skip to content

Commit

Permalink
Merge pull request #71 from pedropark99/spelling-fixes
Browse files Browse the repository at this point in the history
Fix multiple spelling errors
  • Loading branch information
pedropark99 authored Oct 12, 2024
2 parents 7ce5cb5 + 6729ee7 commit 9c2f595
Show file tree
Hide file tree
Showing 43 changed files with 211 additions and 200 deletions.
6 changes: 3 additions & 3 deletions Chapters/01-base64.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ But the input string does not have enough bytes to create a fourth 6-bit group.
Every time this happens, where an entire group of 6 bits is empty,
this group becomes a "padding group". Every "padding group" is mapped to
the character `=` (equal sign), which represents "null", or, the end
of meaninful characters in the sequence. Hence, everytime that the algorithm produces a
of meaningful characters in the sequence. Hence, everytime that the algorithm produces a
"padding group", this group is automatically mapped to `=`.

As another example, if you give the string "0" as input to a base64 encoder, this string is
Expand Down Expand Up @@ -221,7 +221,7 @@ summarized these transformations as "Some bit shifting and additions ..." in the
will be described in depth later.

Besides that, if you look again at @fig-base64-algo2, you will notice that the character `=` was completely
ignored by the algorithm. Remember, this is just a special character that marks the end of meaninful characters
ignored by the algorithm. Remember, this is just a special character that marks the end of meaningful characters
in the base64 sequence. So, every `=` character in a base64 encoded sequence should be ignored by a base64 decoder.


Expand Down Expand Up @@ -738,7 +738,7 @@ Notice that the output byte is the sequence `ABCDEFGH`, which is the original by

![How the 1st byte in the decoder output is produced from the 1st byte (dark purple) and the 2nd byte (orange) of the input](../Figures/base64-decoder-bit-shift.png){#fig-decoder-bitshift}

The @tbl-6bit-decode presents how the three steps described ealier translate into Zig code:
The @tbl-6bit-decode presents how the three steps described earlier translate into Zig code:



Expand Down
4 changes: 2 additions & 2 deletions Chapters/01-memory.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,14 @@ But in reality, there are two very common instances where this "fixed length lim
Also, there is another instance where you might want to use an allocator, which is when you want to write a function that returns a pointer
to a local object. As I described at @sec-stack, you cannot do that if this local object is stored in the
stack. However, if this object is stored in the heap, then, you can return a pointer to this object at the
end of the function. Because you (the programmer) control the lyfetime of any heap memory that you allocate. You decide
end of the function. Because you (the programmer) control the lifetime of any heap memory that you allocate. You decide
when this memory get's destroyed/freed.

These are common situations where the stack is not good for.
That is why you need a different memory management strategy to
store these objects inside your function. You need to use
a memory type that can grow together with your objects, or that you
can control the lyfetime of this memory.
can control the lifetime of this memory.
The heap fit this description.

Allocating memory on the heap is commonly known as dynamic memory management. As the objects you create grow in size
Expand Down
10 changes: 5 additions & 5 deletions Chapters/01-zig-weird.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ As we discussed before, in Zig, you can select specific portions of an existing
array. This is called *slicing* in Zig [@zigguide], because when you select a portion
of an array, you are creating a slice object from that array.

A slice object is essentially a pointer object accompained by a length number.
A slice object is essentially a pointer object accompanied by a length number.
The pointer object points to the first element in the slice, and the
length number tells the `zig` compiler how many elements there are in this slice.

Expand Down Expand Up @@ -1071,7 +1071,7 @@ have problems in Zig.
[^libiconv]: <https://www.gnu.org/software/libiconv/>

Let’s take for example the word "Hello". In UTF-8, this sequence of characters (H, e, l, l, o)
is represented by the sequence of decimal numbers 72, 101, 108, 108, 111. In xecadecimal, this
is represented by the sequence of decimal numbers 72, 101, 108, 108, 111. In hexadecimal, this
sequence is `0x48`, `0x65`, `0x6C`, `0x6C`, `0x6F`. So if I take this sequence of hexadecimal values,
and ask Zig to print this sequence of bytes as a sequence of characters (i.e. a string), then,
the text "Hello" will be printed into the terminal:
Expand Down Expand Up @@ -1123,7 +1123,7 @@ your trying to access memory that does not belong to you.

To achieve this same kind of safety in C, you have to do a lot of work that kind of seems pointless.
So getting this kind of safety is not automatic and much harder to do in C. For example, if you want
to track the length of your string troughout your program in C, then, you first need to loop through
to track the length of your string throughout your program in C, then, you first need to loop through
the array of bytes that represents this string, and find the null element (`'\0'`) position to discover
where exactly the array ends, or, in other words, to find how much elements the array of bytes contain.

Expand Down Expand Up @@ -1418,7 +1418,7 @@ N of replacements: 1
## Safety in Zig

A general trend in modern low-level programming languages is safety. As our modern world
become more interconnected with techology and computers,
become more interconnected with technology and computers,
the data produced by all of this technology becomes one of the most important
(and also, one of the most dangerous) assets that we have.

Expand Down Expand Up @@ -1466,7 +1466,7 @@ The tools listed below are related to memory safety. That is, they help you to a
memory safety in your Zig code:

- `defer` allows you to keep free operations phisically close to allocations. This helps you to avoid memory leaks, "use after free", and also "double-free" problems. Furthermore, it also keeps free operations logically tied to the end of the current scope, which greatly reduces the mental overhead about object lifetime.
- `errdefer` helps you to garantee that your program frees the allocated memory, even if a runtime error occurs.
- `errdefer` helps you to guarantee that your program frees the allocated memory, even if a runtime error occurs.
- pointers and objects are non-nullable by default. This helps you to avoid memory problems that might arise from de-referencing null pointers.
- Zig offers some native types of allocators (called "testing allocators") that can detect memory leaks and double-frees. These types of allocators are widely used on unit tests, so they transform your unit tests into a weapon that you can use to detect memory problems in your code.
- arrays and slices in Zig have their lengths embedded in the object itself, which makes the `zig` compiler very effective on detecting "index out-of-range" type of errors, and avoiding buffer overflows.
Expand Down
4 changes: 2 additions & 2 deletions Chapters/03-structs.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ This is what "exhaust all existing possibilities" means. The switch statement co
every possible case.

Therefore, you cannot write a switch statement in Zig, and leave an edge case
with no expliciting action to be taken.
with no explicit action to be taken.
This is a similar behaviour to switch statements in Rust, which also have to
handle all possible cases.

Expand Down Expand Up @@ -794,7 +794,7 @@ _ = eu;
```

However, in Zig, we can also write an anonymous struct literal. That is, you can write a
struct literal, but not especify explicitly the type of this particular struct.
struct literal, but not specify explicitly the type of this particular struct.
An anonymous struct is written by using the syntax `.{}`. So, we essentially
replaced the explicit type of the struct literal with a dot character (`.`).

Expand Down
12 changes: 6 additions & 6 deletions Chapters/04-http-server.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ a separate Zig module. I will name it `config.zig`.

In Zig, we can create a web socket using
the `std.posix.socket()` function, from the Zig Standard Library.
As I meantioned earlier at @sec-http-how-impl, every socket object that we create
As I mentioned earlier at @sec-http-how-impl, every socket object that we create
represents a communication channel, and we need to bind this channel to a specific address.
An "address" is defined as an IP address, or, more specifically, an IPv4 address^[It can be also an IPv6 address. But normally, we use a IPv4 address for that.].
Every IPv4 address is composed by two components. The first component is the host,
Expand All @@ -178,7 +178,7 @@ The sequence of 4 numbers (i.e. the host) identifies the machine (i.e. the compu
this socket will live in. Every computer normally have multiple "doors" available inside of him, because
this allows the computer to receive and work with multiple connections at the same time.
He simply use a single door for each connection. So the port number, is
essentially a number that identifies the specific door in the computer that will be resposible
essentially a number that identifies the specific door in the computer that will be responsible
for receiving the connection. That is, it identifies the "door" in the computer that the socket will use
to receive incoming connections.

Expand Down Expand Up @@ -374,8 +374,8 @@ we have provided as input.
Notice that I'm using the connection object that we created to read
the message from the client. I first access the `reader` object that lives inside the
connection object. Then, I call the `read()` method of this `reader` object
to effectivelly read and save the data sent by the client into the buffer object
that we created earlier. I'm discarting the return value
to effectively read and save the data sent by the client into the buffer object
that we created earlier. I'm discarding the return value
of the `read()` method, by assigning it to the underscore character (`_`),
because this return value is not useful for us right now.

Expand Down Expand Up @@ -493,7 +493,7 @@ needs to represent one of the primary colors, you can create an enum
that represents one of these colors.
In the example below, we are creating the enum `PrimaryColorRGB`, which
represents a primary color from the RGB color system. By using this enum,
I am garanteed that the `acolor` object for example, will contain
I am guaranteed that the `acolor` object for example, will contain
one of these three values: `RED`, `GREEN` or `BLUE`.

```{zig}
Expand Down Expand Up @@ -727,7 +727,7 @@ or a `Method` object as result. Since `GET` is currently the only value in our `
structure, it means that, the `init()` method will most likely return the value `Method.GET` as result.

Also notice that, in the `is_supported()` method, we are using the optional value returned
by the `get()` method from our `MethodMap` object. The if statement unwrapes the optional value
by the `get()` method from our `MethodMap` object. The if statement unwraps the optional value
returned by this method, and returns `true` in case this optional value is a not-null value.
Otherwise, it simply returns `false`.

Expand Down
16 changes: 8 additions & 8 deletions Chapters/05-pointers.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -239,17 +239,17 @@ you always get a single-item pointer as result.



## Pointer arithmethic
## Pointer arithmetic

Pointer arithmethic is available in Zig, and they work the same way they work in C.
Pointer arithmetic is available in Zig, and they work the same way they work in C.
When you have a pointer that points to an array, the pointer usually points to
the first element in the array, and you can use pointer arithmethic to
the first element in the array, and you can use pointer arithmetic to
advance this pointer and access the other elements in the array.


Notice in the example below, that initially, the `ptr` object was pointing
to the first element in the array `ar`. But then, I started to walk through the array, by advancing
the pointer with simple pointer arithmethic.
the pointer with simple pointer arithmetic.

```{zig}
#| eval: false
Expand All @@ -269,15 +269,15 @@ try stdout.print("{d}\n", .{ptr.*});
```

Although you can create a pointer to an array like that, and
start to walk through this array by using pointer arithmethic,
start to walk through this array by using pointer arithmetic,
in Zig, we prefer to use slices, which were presented at @sec-arrays.

Behind the hood, slices already are pointers,
and they also come with the `len` property, which indicates
how many elements are in the slice. This is good because the `zig` compiler
can use it to check for potential buffer overflows, and other problems like that.

Also, you don't need to use pointer arithmethic to walk through the elements
Also, you don't need to use pointer arithmetic to walk through the elements
of a slice. You can simply use the `slice[index]` syntax to directly access
any element you want in the slice.
As I mentioned at @sec-arrays, you can get a slice from an array by using
Expand Down Expand Up @@ -433,7 +433,7 @@ inside the if block.
Using the example below as a reference, if the object `num` is null,
then, the code inside the if statement is not executed. Otherwise,
the if statement will unwrap the object `num` into the `not_null_num`
object. This `not_null_num` object is garanteed to be not null inside
object. This `not_null_num` object is guaranteed to be not null inside
the scope of the if statement.

```{zig}
Expand Down Expand Up @@ -472,7 +472,7 @@ to this null value, and the most logic and sane path is to simply panic
and raise a loud error in your program when this null value is encountered,
you can use the `?` method of your optional object.

In essence, when you use this `?` method, the optional object is unwraped.
In essence, when you use this `?` method, the optional object is unwrapped.
If a not-null value is found in the optional object, then, this not-null value is used.
Otherwise, the `unreachable` keyword is used. You can read more about this
[`unreacheable` keyword at the official documentation](https://ziglang.org/documentation/master/#unreachable)[^un-docs].
Expand Down
2 changes: 1 addition & 1 deletion Chapters/07-build-system.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ that defines the binary file that we want to compile.
As an example, I will build the project as a static library file using the `addStaticLibrary()` method
to create the target object.
Also, since FreeType is a C library, I will also link the library
against `libc` through the `linkLibC()` method, to garantee that any use
against `libc` through the `linkLibC()` method, to guarantee that any use
of the C Standard Library is covered in the compilation process.


Expand Down
6 changes: 3 additions & 3 deletions Chapters/09-data-structures.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ and understand how they work.
Some professionals know this type of data structure by different terms, like "map",
"hashmap" or "associative arrays". But the most common term used is *hashtable*.
Every programming language normally have some implementation of a hashtable in their
stardard libraries. Python have `dict()`, C++ have `std::map` and `std::unordered_map`, Rust
standard libraries. Python have `dict()`, C++ have `std::map` and `std::unordered_map`, Rust
have `HashMap`, Javascript have `Object()` and `Map()`, etc.


Expand All @@ -328,7 +328,7 @@ This is how a key identifies a specific position (or location) inside the hashta
structure.

Therefore, you provide a key to the hashtable, and this key identifies a specific location
inside the hastable, then, the hashtable takes the input value that you provided,
inside the hashtable, then, the hashtable takes the input value that you provided,
and stores this value in the location identified by this input key.
You could say that the key maps to the value stored in the hashtable. You find
the value, by using the key that identifies the location where the value is stored.
Expand Down Expand Up @@ -778,7 +778,7 @@ and an `insertAfter()` (for `next`) methods available.

Thus, if we have used a doubly linked list, we can use the `insertBefore()` method
to store the pointer to the input node in the `prev` attribute. This would put the input
node as the "previous node", or, the node before the current node. In constrast, the `insertAfter()` method
node as the "previous node", or, the node before the current node. In contrast, the `insertAfter()` method
puts the pointer created to the input node in the `next` attribute of the current node,
and as result, the input node becomes the "next node" of the current node.

Expand Down
12 changes: 6 additions & 6 deletions Chapters/09-error-handling.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ into the `number` object.

This means that, if the `parseU64()` expression returns a valid value, this value becomes available
inside the scope of this "if branch" (i.e. the "true branch") through the object that we listed inside the pair
of pipe charactes (`|`), which is the object `number`.
of pipe character (`|`), which is the object `number`.

If an error occurs, we can use an "else branch" (or the "false branch") of the if statement
to handle the error. In the example below, we are using the `else` in the if statement
Expand Down Expand Up @@ -429,7 +429,7 @@ if (add_tasks_to_queue(&queue, tasks)) |_| {
// do something
},
error.QueueNotFound => {
// do somethimg
// do something
},
// and all the other error options ...
}
Expand All @@ -440,7 +440,7 @@ if (add_tasks_to_queue(&queue, tasks)) |_| {

A common pattern in C programs in general, is to clean resources when an error occurs during
the execution of the program. In other words, one common way to handle errors, is to perform
"cleanup actions" before we exit our program. This garantees that a runtime error does not make
"cleanup actions" before we exit our program. This guarantees that a runtime error does not make
our program to leak resources of the system.


Expand Down Expand Up @@ -475,7 +475,7 @@ fn create_user(db: Database, allocator: Allocator) !User {
```

By using `errdefer` to destroy the `user` object that we have just created,
we garantee that the memory allocated for this `user` object
we guarantee that the memory allocated for this `user` object
get's freed, before the execution of the program stops.
Because if the expression `try db.add(user)` returns an error value,
the execution of our program stops, and we lose all references and control over the memory
Expand Down Expand Up @@ -506,7 +506,7 @@ In other words, the allocated memory for the `user` object does not get
freed inside the `create_user()` function, if it returns successfully.
So, if an error does not occur inside this function, the `user` object
is returned from the function, and probably, the code that runs after
this `create_user()` function will be responsible for freeying
this `create_user()` function will be responsible for freeing
the memory of the `user` object.

But what if an error occurs inside the `create_user()` function? What happens then?
Expand All @@ -515,7 +515,7 @@ function, and, as a consequence, the code that runs after this `create_user()`
function would simply not run, and, as a result, the memory of the `user` object
would not be freed before your program stops.

This is the perfect scenario for `errdefer`. We use this keyword to garantee
This is the perfect scenario for `errdefer`. We use this keyword to guarantee
that our program will free the allocated memory for the `user` object,
even if an error occurs inside the `create_user()` function.

Expand Down
4 changes: 2 additions & 2 deletions Chapters/10-stack-project.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ what exactly data type that is. We will talk more about this at @sec-generics.

### Applying over an expression

When you apply the `comptime` keyword over an expression, then, it is garanteed that the `zig` compiler will
When you apply the `comptime` keyword over an expression, then, it is guaranteed that the `zig` compiler will
execute this expression at compile-time. If for some reason, this expression cannot be executed at compile-time
(e.g. for example, maybe this expression depends on a value that is only known at runtime), then, the `zig` compiler
will raise a compilation error.
Expand Down Expand Up @@ -201,7 +201,7 @@ We have talked about this at @sec-compile-time.

But when you use the `comptime` keyword on an expression, there is no "it might be executed
at compile-time" anymore. With the `comptime` keyword you are ordering the `zig` compiler
to execute this expression at compile-time. You are imposing this rule, it is garanteed
to execute this expression at compile-time. You are imposing this rule, it is guaranteed
that the compiler will always execute it at compile-time. Or, at least, the compiler
will try to execute it. If the compiler cannot execute the expression for whatever reason,
the compiler will raise a compilation error.
Expand Down
Loading

0 comments on commit 9c2f595

Please sign in to comment.