Skip to content

First draft of concurrency chapter #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions _includes/code.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@


{% assign figure-number = figure-number | default: 0 | plus: 1 %}
{% assign figure-index = figure-number | minus: 1 %}
{% assign code-number = code-number | default: 0 | plus: 1 %}
{% assign code-index = code-number | minus: 1 %}

{% assign -figure-ref = '[figure ' | append: page.chapter | append: '.' | append: figure-number
{% assign -code-ref = '[code ' | append: page.chapter | append: '.' | append: code-number
| append: '](#' | append: include.name | append: ')' %}

{% if figure-reference %}
{% assign figure-reference = ((figure-reference | join: '$') | append: '$'
| append: -figure-ref) | split: '$' %}
{% if code-reference %}
{% assign code-reference = ((code-reference | join: '$') | append: '$'
| append: -code-ref) | split: '$' %}
{% else %}
{% assign figure-reference = -figure-ref | split: '$' %}
{% assign code-reference = -code-ref | split: '$' %}
{% endif %}

```cpp
{% include_relative code/{{include.name}}.cpp %}```
{% include_relative code/{{include.name}}.cpp %}
```
<p style='text-align: center;' markdown='1'>
Code {{page.chapter}}.{{figure-number}}: {{include.caption}}
Code {{page.chapter}}.{{code-number}}: {{include.caption}}
</p>{: #{{include.name}} }
2 changes: 1 addition & 1 deletion _includes/figure.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

![figure {{page.chapter}}.{{figure-number}}: {{include.caption}}][{{include.name}}]\\

figure {{page.chapter}}.{{figure-number}}: {{include.caption}}
Figure {{page.chapter}}.{{figure-number}}: {{include.caption}}
</p>{: #{{include.name}} }

[{{include.name}}]: figures/{{include.name}}.svg
2 changes: 2 additions & 0 deletions _layouts/book-page.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
---
layout: default
---
{% include mathjax.html %}

<article class="post">

<header class="post-header">
Expand Down
1 change: 1 addition & 0 deletions better-code/00-preface.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title: Preface
layout: book-page
tags: [ better-code ]
chapter: 0
---

To understand what _better code_ is, we first need to understand what _good code_ is. Students are taught that good code is code that does what the specification says it should. But such an answer begs the question of what is a good specification? Nearly every experienced developer I've met has a snippet of code filed away that has profound beauty - it likely has no corresponding specification and may not even contain a single comment. So what is good code?
Expand Down
1 change: 0 additions & 1 deletion better-code/01-types.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
title: Types
tagline: No Incomplete Types

layout: book-page
tags: [ better-code ]
chapter: 1
Expand Down
4 changes: 2 additions & 2 deletions better-code/02-algorithms.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: Algorithms
tagline: No Raw Loops

layout: page
layout: book-page
tags: [ better-code ]
chapter: 2
---

Testing 1.2.3...
9 changes: 4 additions & 5 deletions better-code/03-data-structures.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
title: Data Structures
tagline: No Incidental Data Structures

layout: book-page
tags: [ better-code ]
chapter: 3
Expand All @@ -23,7 +22,7 @@ As we saw in [chapter 1](01-types.html) a type is a pattern for storing and modi

Values are related to other values, for example, 3 is not equal to 4.

If two objects of the same type have the same representation then they represent the same value. Representational equality implies value equality. If the representation is unique then the converse is also true. A hash is a regular function on a representation or a value. Because it is regular, if two values are equal then the hash of the values are also equal.
If two objects of the same type have the same representation then they represent the same value. Representational equality implies value equality. If the representation is unique then the converse is also true. A hash is a regular function on a representation or a value. Because it is regular, if two values are equal then the hash of the values is also equal.

Because objects exist in memory, they have a _physical_ relationship. The value at the first location in an array is located before the value in the second location. If we sort the values, we establish a correspondence between the physical and value relationships, i.e. an element before another element is less than or equal to that element. We can represent locations as values (pointers) and use those to represent additional relationships, such as "is a child of".

Expand All @@ -37,15 +36,15 @@ The choice of encoding can make a dramatic difference on the performance of oper

Although data structures tend to be thought of simply in terms of containers such as arrays, lists, or maps, anytime a relationship is established between objects a data structure is created. However, to avoid confusion we will reserve the term _data structure_ to refer to types with a set of invariants which insure a set of relationships are maintained. More transient data structures will be referred to as _structured data_.

As an example of utilizing structured data_, consider the problem of finding the `nth` to `mth` elements of an array as if the array was in sorted order. The trivial way to do this is to simply sort the entire array and then print the `nth` to `mth` elements. In this example `[sf, sl)` is a subrange of `[f, l)`. {::comment}appendix to describe half open notation?{:/comment}
As an example of utilizing structured data_, consider the problem of finding the `nth` to `mth` elements of an array as if the array was in sorted order. The trivial way to do this is to simply sort the entire array and then print the `nth` to `mth` elements. In this example `[sf, sl)` is a subrange of `[f, l)`. {::comment}appendix to describe half-open notation?{:/comment}

{% include code.md name='sort-subrange-0' caption='inefficient sort subrange' %}

{::comment} Should this section start with partial_sort then add nth_element instead of the other way around? {:/comment}

This function, however, does more work than is necessary. There is a function in the standard library, `nth_element()` which given a position `nth` within a range `[f, l)` has the post condition that the element at `nth` is the same element that would be in that position if `[f, l)` were sorted. `nth_element()` is a special case of sort_subrange when the subrange is of length 1 (or 0 if `nth == l`).
This function, however, does more work than is necessary. There is a function in the standard library, `nth_element()` which given a position `nth` within a range `[f, l)` has the post-condition that the element at `nth` is the same element that would be in that position if `[f, l)` were sorted. `nth_element()` is a special case of sort_subrange when the subrange is of length 1 (or 0 if `nth == l`).

This would not be of much use to build `sort_subrang()` except that `nth_element()` has an additional post condition. The range `[f, l)` is partitioned such that all elements prior to `nth` are less than or equal to the final element at `nth`. This post condition leaves us with _structured data_ and we can take advantage of that structure. If we find the `nth_element()` where `nth` is `sf` then we only need to sort the remaining elements to `sl` which can be done with `partial_sort()`.
This would not be of much use to build `sort_subrang()` except that `nth_element()` has an additional post-condition. The range `[f, l)` is partitioned such that all elements prior to `nth` are less than or equal to the final element at `nth`. This post-condition leaves us with _structured data_ and we can take advantage of that structure. If we find the `nth_element()` where `nth` is `sf` then we only need to sort the remaining elements to `sl` which can be done with `partial_sort()`.

{% include code.md name='sort-subrange-1' caption='improved sort subrange' %}

Expand Down
4 changes: 2 additions & 2 deletions better-code/04-runtime-polymorphism.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: Runtime Polymorphism
tagline: No Public Inheritance

layout: page
layout: book-page
tags: [ better-code ]
chapter: 4
---

Object-oriented programming has been one of the paradigms supported by C++ from its invention. The idea of type inheritance and virtual functions were borrowed from Simula[^cpp-history]. Inheritance can represent a subtype or protocol relationship. Although the two are closely related, in this chapter we're primarily concerned with subtype relationships through class inheritance. Protocols are discussed in the next chapter. {::comment}link{:/comment}
Expand Down
Loading