Fixing grammar and spelling mistakes (#270)

pull/271/head
poly000 3 years ago committed by GitHub
parent 6a7088c25c
commit 9834f5719b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,8 +16,8 @@ If you want to be part of this effort here are some ways you can participate:
## Discussion board
If you have a question or an idea regarding certain content but you want to
have feedback of fellow community members and you think it may not be
If you have a question or an idea regarding certain content, but you want to
have feedback of fellow community members, and you think it may not be
appropriate to file an issue open a discussion in our [discussion board](https://github.com/rust-unofficial/patterns/discussions).
## Writing a new article
@ -29,14 +29,14 @@ there is an existing discussion or if someone is already working on that topic:
- [All issues](https://github.com/rust-unofficial/patterns/issues),
- [Pull Requests](https://github.com/rust-unofficial/patterns/pulls)
If you don't find an issue regarding your topic and you are sure it is not more
If you don't find an issue regarding your topic, and you are sure it is not more
feasible to open a thread in the [discussion board](https://github.com/rust-unofficial/patterns/discussions)
please open a new issue, so we can discuss about the ideas and future content
please open a new issue, so we can discuss the ideas and future content
of the article together and maybe give some feedback/input on it.
When writing a new article it's recommended to copy the [pattern template](https://github.com/rust-unofficial/patterns/blob/master/template.md)
into the appropriate directory and start editing it. You may not want to fill
out every section and remove it or you might want to add extra sections.
out every section and remove it, or you might want to add extra sections.
Consider writing your article in a way that has a low barrier of entry so also
[Rustlings](https://github.com/rust-lang/rustlings) can follow and understand
@ -53,7 +53,7 @@ in your article.
Don't forget to add your new article to the `SUMMARY.md` to let it be rendered
to the book.
Please make `Draft Pull requests` early so we can follow your progress and can
Please make `Draft Pull requests` early, so we can follow your progress and can
give early feedback (see the following section).
## Style guide

@ -5,7 +5,7 @@ language that you can read [here](https://rust-unofficial.github.io/patterns/).
## Contributing
You are missing content in this repository that can be helpful for others and
You are missing content in this repository that can be helpful for others, and
you are eager to explain it? Awesome! We are always happy about new contributions
(e.g. elaboration or corrections on certain topics) to this project.

@ -56,7 +56,7 @@ unauthorized parties' direct access to them.
“Functions should not produce abstract side effects...only commands
(procedures) will be permitted to produce side effects.” - Bertrand Meyer:
Object Oriented Software Construction
Object-Oriented Software Construction
## [Principle of least astonishment (POLA)](https://en.wikipedia.org/wiki/Principle_of_least_astonishment)
@ -66,30 +66,30 @@ to behave. The behavior should not astonish or surprise users
## Linguistic-Modular-Units
“Modules must correspond to syntactic units in the language used.” - Bertrand
Meyer: Object Oriented Software Construction
Meyer: Object-Oriented Software Construction
## Self-Documentation
“The designer of a module should strive to make all information about the
module part of the module itself.” - Bertrand Meyer: Object Oriented Software
module part of the module itself.” - Bertrand Meyer: Object-Oriented Software
Construction
## Uniform-Access
“All services offered by a module should be available through a uniform
notation, which does not betray whether they are implemented through storage or
through computation.” - Bertrand Meyer: Object Oriented Software Construction
through computation.” - Bertrand Meyer: Object-Oriented Software Construction
## Single-Choice
“Whenever a software system must support a set of alternatives, one and only
one module in the system should know their exhaustive list.” - Bertrand Meyer:
Object Oriented Software Construction
Object-Oriented Software Construction
## Persistence-Closure
“Whenever a storage mechanism stores an object, it must store with it the
dependents of that object. Whenever a retrieval mechanism retrieves a
previously stored object, it must also retrieve any dependent of that object
that has not yet been retrieved.” - Bertrand Meyer: Object Oriented Software
that has not yet been retrieved.” - Bertrand Meyer: Object-Oriented Software
Construction

@ -54,7 +54,7 @@ Even though `.clone()` is an indication of a bad pattern, sometimes
- the developer is still new to ownership
- the code doesn't have great speed or memory constraints
(like hackathon projects or prototypes)
- satisfying the borrow checker is really complicated and you prefer to
- satisfying the borrow checker is really complicated, and you prefer to
optimize readability over performance
If an unnecessary clone is suspected, The [Rust Book's chapter on Ownership](https://doc.rust-lang.org/book/ownership.html)

@ -25,7 +25,7 @@ This is called **monomorphization**, where different types are created from
generic parameters: different values for the generic type cause different types,
and different types can have different `impl` blocks.
In object oriented languages, classes can inherit behavior from their parents.
In object-oriented languages, classes can inherit behavior from their parents.
However, this allows the attachment of not only additional behavior to
particular members of a type class, but extra behavior as well.
@ -259,7 +259,7 @@ It is also used by several popular crates to allow API flexibility:
* The "type state" pattern -- where an object gains and loses API based on an
internal state or invariant -- is implemented in Rust using the same basic
concept, and a slightly different techinque. [^6]
concept, and a slightly different technique. [^6]
[^1]: See: [impl From\<CString\> for Vec\<u8\>](
https://doc.rust-lang.org/stable/src/std/ffi/c_str.rs.html#799-801)

@ -7,7 +7,7 @@ when you are deciding which argument type to use for a function argument.
In this way, the function will accept more input types.
This is not limited to slice-able or fat pointer types.
In fact you should always prefer using the __borrowed type__ over
In fact, you should always prefer using the __borrowed type__ over
__borrowing the owned type__.
Such as `&str` over `&String`, `&[T]` over `&Vec<T>`, or `&T` over `&Box<T>`.

@ -46,7 +46,7 @@ fn main() {
conf.check = true;
println!("conf = {:#?}", conf);
// partial initalization with default values, creates the same instance
// partial initialization with default values, creates the same instance
let conf1 = MyConfiguration {
check: true,
..Default::default()

@ -61,7 +61,7 @@ its data if the only way to access each datum is via the collection and the
collection is responsible for deleting the data (even in cases of shared
ownership, some kind of borrowed view may be appropriate). If a collection owns
its data, it is usually useful to provide a view of the data as borrowed so that
it can be multiply referenced.
it can be multiplied referenced.
Most smart pointers (e.g., `Foo<T>`) implement `Deref<Target=T>`. However,
collections will usually dereference to a custom type. `[T]` and `str` have some

@ -3,7 +3,7 @@
## Description
Rust does not provide the equivalent to `finally` blocks - code that will be
executed no matter how a function is exited. Instead an object's destructor can
executed no matter how a function is exited. Instead, an object's destructor can
be used to run code that must be run before exit.
## Example
@ -41,7 +41,7 @@ Panicking will also exit a function early.
## Advantages
Code in destructors will (nearly) always be run - copes with panics, early
Code in destructors will (nearly) be always run - copes with panics, early
returns, etc.
## Disadvantages
@ -49,7 +49,7 @@ returns, etc.
It is not guaranteed that destructors will run. For example, if there is an
infinite loop in a function or if running a function crashes before exit.
Destructors are also not run in the case of a panic in an already panicking
thread. Therefore destructors cannot be relied on as finalisers where it is
thread. Therefore, destructors cannot be relied on as finalizers where it is
absolutely essential that finalisation happens.
This pattern introduces some hard to notice, implicit code. Reading a function
@ -61,16 +61,16 @@ Requiring an object and `Drop` impl just for finalisation is heavy on boilerplat
## Discussion
There is some subtlety about how exactly to store the object used as a
finaliser. It must be kept alive until the end of the function and must then be
finalizer. It must be kept alive until the end of the function and must then be
destroyed. The object must always be a value or uniquely owned pointer (e.g.,
`Box<Foo>`). If a shared pointer (such as `Rc`) is used, then the finaliser can
`Box<Foo>`). If a shared pointer (such as `Rc`) is used, then the finalizer can
be kept alive beyond the lifetime of the function. For similar reasons, the
finaliser should not be moved or returned.
finalizer should not be moved or returned.
The finaliser must be assigned into a variable, otherwise it will be destroyed
The finalizer must be assigned into a variable, otherwise it will be destroyed
immediately, rather than when it goes out of scope. The variable name must start
with `_` if the variable is only used as a finaliser, otherwise the compiler
will warn that the finaliser is never used. However, do not call the variable
with `_` if the variable is only used as a finalizer, otherwise the compiler
will warn that the finalizer is never used. However, do not call the variable
`_` with no suffix - in that case it will be destroyed immediately.
In Rust, destructors are run when an object goes out of scope. This happens

@ -63,9 +63,9 @@ its parts to decide what to do next. In the second phase we may conditionally
change the value (as in the example above).
The borrow checker won't allow us to take out `name` of the enum (because
*something* must be there. We could of course `.clone()` name and put the clone
*something* must be there.) We could of course `.clone()` name and put the clone
into our `MyEnum::B`, but that would be an instance of the [Clone to satisfy
the borrow checker](../anti_patterns/borrow_clone.md) antipattern. Anyway, we
the borrow checker](../anti_patterns/borrow_clone.md) anti-pattern. Anyway, we
can avoid the extra allocation by changing `e` with only a mutable borrow.
`mem::take` lets us swap out the value, replacing it with it's default value,
@ -110,4 +110,4 @@ like Indiana Jones, replacing the artifact with a bag of sand.
## See also
This gets rid of the [Clone to satisfy the borrow checker](../anti_patterns/borrow_clone.md)
antipattern in a specific case.
anti-pattern in a specific case.

@ -3,7 +3,7 @@
## Description
`Option` can be viewed as a container that contains either zero or one
elements. In particular, it implements the `IntoIterator` trait, and as such
element. In particular, it implements the `IntoIterator` trait, and as such
can be used with generic code that needs such a type.
## Examples

@ -48,7 +48,7 @@ let closure = move || {
## Advantages
Copied data are grouped together with closure definition, so their purpose is
more clear and they will be dropped immediately even if they are not consumed
more clear, and they will be dropped immediately even if they are not consumed
by closure.
Closure uses same variable names as surrounding code whether data are copied or

@ -30,7 +30,7 @@ fn main(s: a::S) {
Adding a field to a struct is a mostly backwards compatible change.
However, if a client uses a pattern to deconstruct a struct instance, they
might name all the fields in the struct and adding a new one would break that
pattern. The client could name some of the fields and use `..` in the pattern,
pattern. The client could name some fields and use `..` in the pattern,
in which case adding another field is backwards compatible. Making at least one
of the struct's fields private forces clients to use the latter form of patterns,
ensuring that the struct is future-proof.

@ -44,7 +44,7 @@ impl Connection {
## Example
Instead of typing all of this boiler plate to create an `Connection` and
Instead of typing all of this boilerplate to create an `Connection` and
`Request` it is easier to just create a wrapping helper function which takes
them as arguments:
@ -71,7 +71,7 @@ impl Connection {
```
**Note** in the above example the line `assert!(response.is_ok());` will not
actually run while testing because it is inside of a function which is never
actually run while testing because it is inside a function which is never
invoked.
## Advantages

@ -9,7 +9,7 @@ If you are interested in contributing to this book, check out the
When developing programs, we have to solve many problems.
A program can be viewed as a solution to a problem.
It can also be viewed as a collection of solutions to many different problems.
It can also be viewed as a collection of solutions to many problems.
All of these solutions work together to solve a bigger problem.
## Design patterns in Rust

@ -205,7 +205,7 @@ fn main() {
If our commands are small and may be defined as functions or passed as a closure
then using function pointers might be preferable since it does not exploit
dynamic dispatch. But if our command is a whole struct with a bunch of functions
and variables defined as seperate module then using trait objects would be
and variables defined as seperated module then using trait objects would be
more suitable. A case of application can be found in [`actix`](https://actix.rs/),
which uses trait objects when it registers a handler function for routes.
In case of using `Fn` trait objects we can create and use commands in the same

@ -23,7 +23,7 @@ operations `+`, `-`. For example, the expression `2 + 4` is translated into
## Context Free Grammar for our problem
Our task is translate infix expressions into postfix ones. Let's define a context
Our task is translated infix expressions into postfix ones. Let's define a context
free grammar for a set of infix expressions over `0`, ..., `9`, `+`, and `-`,
where:

@ -1,7 +1,7 @@
# Newtype
What if in some cases we want a type to behave similar to another type or
enforce some behaviour at compile time where using only type aliases would
enforce some behaviour at compile time when using only type aliases would
not be enough?
For example, if we want to create a custom `Display` implementation for `String`

@ -8,7 +8,7 @@ It also allows to decouple software modules through [Dependency Inversion](https
The basic idea behind the Strategy pattern is that, given an algorithm solving
a particular problem, we define only the skeleton of the algorithm at an abstract
level and we separate the specific algorithms implementation into different parts.
level, and we separate the specific algorithms implementation into different parts.
In this way, a client using the algorithm may choose a specific implementation,
while the general algorithm workflow remains the same. In other words, the abstract
@ -21,7 +21,7 @@ This is why we call it "Dependency Inversion".
Imagine we are working on a project that generates reports every month.
We need the reports to be generated in different formats (strategies), e.g.,
in `JSON` or `Plain Text` formats.
But things vary over time and we don't know what kind of requirement we may get
But things vary over time, and we don't know what kind of requirement we may get
in the future. For example, we may need to generate our report in a completly new
format, or just modify one of the existing formats.

@ -62,7 +62,7 @@ fn builder_test() {
## Motivation
Useful when you would otherwise require many different constructors or where
Useful when you would otherwise require many constructors or where
construction has side effects.
## Advantages

@ -102,7 +102,7 @@ reused; however, a node must be cloned even if unchanged, which can be
expensive.
Using a reference counted pointer gives the best of both worlds - we can reuse
the original data structure and we don't need to clone unchanged nodes. However,
the original data structure, and we don't need to clone unchanged nodes. However,
they are less ergonomic to use and mean that the data structures cannot be
mutable.

@ -43,7 +43,7 @@ The POSIX standard defines the API to access an on-file database, known as [DBM]
It is an excellent example of an "object-based" API.
Here is the definition in C, which hopefully should be easy to read for those
involved in FFI. The commentary below should help explaining it for those who
involved in FFI. The commentary below should help explain it for those who
miss the subtleties.
```C
@ -105,7 +105,7 @@ This may all seem speculative, but this is what a pointer means in C.
It means the same thing as Rust: "user defined lifetime."
The user of the library needs to read the documentation in order to use it correctly.
That said, there are some decisions that have fewer or greater consequences if users
do it wrong. Minimizing those is what this best practice is about, and the key
do it wrong. Minimizing those are what this best practice is about, and the key
is to *transfer ownership of everything that is transparent*.
## Advantages
@ -229,7 +229,7 @@ datum dbm_firstkey(DBM *);
datum dbm_nextkey(DBM *);
```
Thus, all of the lifetimes were bound together, and such unsafety was prevented.
Thus, all the lifetimes were bound together, and such unsafety was prevented.
## Disadvantages

@ -13,7 +13,7 @@ about a programming language.
## Design patterns in Rust
Rust has many very unique features. These features give us great benefit by removing
Rust has many unique features. These features give us great benefit by removing
whole classes of problems. Some of them are also patterns that are _unique_ to Rust.
## YAGNI

Loading…
Cancel
Save