Skip to content

Commit

Permalink
Updated tooling, corrections from Kris
Browse files Browse the repository at this point in the history
  • Loading branch information
sean-parent committed May 20, 2021
1 parent 655c76f commit 32db9c6
Show file tree
Hide file tree
Showing 94 changed files with 970 additions and 506 deletions.
19 changes: 19 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"macFrameworkPath": [
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-x64"
}
],
"version": 4
}
2 changes: 1 addition & 1 deletion _jupyter/lab/workspaces/default-37a8.jupyterlab-workspace
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"data":{"layout-restorer:data":{"main":{"dock":{"type":"tab-area","currentIndex":0,"widgets":["notebook:better-code-class/00-introduction.ipynb","notebook:better-code-class/01-preface.ipynb","notebook:better-code-class/02-types.ipynb","notebook:better-code-class/03-algorithms.ipynb","notebook:better-code-class/04-data-structures.ipynb","notebook:better-code-class/05-runtime-polymorphism.ipynb","notebook:better-code-class/06-concurrency.ipynb","notebook:better-code-class/07-relationships.ipynb","notebook:better-code-class/08-epilogue.ipynb"]},"current":"notebook:better-code-class/00-introduction.ipynb"},"left":{"collapsed":false,"current":"@jupyterlab/toc:plugin","widgets":["filebrowser","running-sessions","@jupyterlab/toc:plugin","extensionmanager.main-view"]},"right":{"collapsed":false,"current":"jp-property-inspector","widgets":["jp-property-inspector"]}},"file-browser-filebrowser:cwd":{"path":"better-code-class"},"@jupyterlab/settingeditor-extension:plugin":{"sizes":[0.2387152777777778,0.7612847222222221],"container":{"plugin":"@jupyterlab/shortcuts-extension:shortcuts","sizes":[0.4674657534246575,0.5325342465753424]}},"notebook:notes/2020-02-19-blocking-get.ipynb":{"data":{"path":"notes/2020-02-19-blocking-get.ipynb","factory":"Notebook"}},"notebook:better-code-class/03-algorithms.ipynb":{"data":{"path":"better-code-class/03-algorithms.ipynb","factory":"Notebook"}},"notebook:better-code-class/04-data-structures.ipynb":{"data":{"path":"better-code-class/04-data-structures.ipynb","factory":"Notebook"}},"notebook:better-code-class/05-runtime-polymorphism.ipynb":{"data":{"path":"better-code-class/05-runtime-polymorphism.ipynb","factory":"Notebook"}},"notebook:better-code-class/06-concurrency.ipynb":{"data":{"path":"better-code-class/06-concurrency.ipynb","factory":"Notebook"}},"notebook:better-code-class/07-relationships.ipynb":{"data":{"path":"better-code-class/07-relationships.ipynb","factory":"Notebook"}},"notebook:better-code-class/08-epilogue.ipynb":{"data":{"path":"better-code-class/08-epilogue.ipynb","factory":"Notebook"}},"notebook:better-code-class/00-introduction.ipynb":{"data":{"path":"better-code-class/00-introduction.ipynb","factory":"Notebook"}},"notebook:better-code-class/01-preface.ipynb":{"data":{"path":"better-code-class/01-preface.ipynb","factory":"Notebook"}},"notebook:better-code-class/02-types.ipynb":{"data":{"path":"better-code-class/02-types.ipynb","factory":"Notebook"}}},"metadata":{"id":"default"}}
{"data":{"layout-restorer:data":{"main":{"dock":{"type":"tab-area","currentIndex":10,"widgets":["notebook:better-code-class/00-introduction.ipynb","notebook:better-code-class/01-preface.ipynb","notebook:better-code-class/02-types.ipynb","notebook:better-code-class/03-algorithms.ipynb","notebook:better-code-class/04-data-structures.ipynb","notebook:better-code-class/05-runtime-polymorphism.ipynb","notebook:notes/2019-09-15-code.ipynb","editor:stlab/libraries/stlab/concurrency/utility.hpp","notebook:better-code-class/06-concurrency.ipynb","notebook:better-code-class/07-relationships.ipynb","notebook:better-code-class/08-epilogue.ipynb"]},"current":"notebook:better-code-class/08-epilogue.ipynb"},"left":{"collapsed":false,"current":"filebrowser","widgets":["filebrowser","running-sessions","@jupyterlab/toc:plugin","extensionmanager.main-view"]},"right":{"collapsed":false,"current":"jp-property-inspector","widgets":["jp-property-inspector"]}},"file-browser-filebrowser:cwd":{"path":"better-code-class"},"@jupyterlab/settingeditor-extension:plugin":{"sizes":[0.2387152777777778,0.7612847222222221],"container":{"plugin":"@jupyterlab/shortcuts-extension:shortcuts","sizes":[0.4674657534246575,0.5325342465753424]}},"notebook:notes/2020-02-19-blocking-get.ipynb":{"data":{"path":"notes/2020-02-19-blocking-get.ipynb","factory":"Notebook"}},"notebook:better-code-class/03-algorithms.ipynb":{"data":{"path":"better-code-class/03-algorithms.ipynb","factory":"Notebook"}},"notebook:better-code-class/04-data-structures.ipynb":{"data":{"path":"better-code-class/04-data-structures.ipynb","factory":"Notebook"}},"notebook:better-code-class/05-runtime-polymorphism.ipynb":{"data":{"path":"better-code-class/05-runtime-polymorphism.ipynb","factory":"Notebook"}},"notebook:better-code-class/06-concurrency.ipynb":{"data":{"path":"better-code-class/06-concurrency.ipynb","factory":"Notebook"}},"notebook:better-code-class/07-relationships.ipynb":{"data":{"path":"better-code-class/07-relationships.ipynb","factory":"Notebook"}},"notebook:better-code-class/08-epilogue.ipynb":{"data":{"path":"better-code-class/08-epilogue.ipynb","factory":"Notebook"}},"notebook:better-code-class/00-introduction.ipynb":{"data":{"path":"better-code-class/00-introduction.ipynb","factory":"Notebook"}},"notebook:better-code-class/01-preface.ipynb":{"data":{"path":"better-code-class/01-preface.ipynb","factory":"Notebook"}},"notebook:better-code-class/02-types.ipynb":{"data":{"path":"better-code-class/02-types.ipynb","factory":"Notebook"}},"notebook:notes/2019-09-15-code.ipynb":{"data":{"path":"notes/2019-09-15-code.ipynb","factory":"Notebook"}},"editor:stlab/libraries/stlab/concurrency/utility.hpp":{"data":{"path":"stlab/libraries/stlab/concurrency/utility.hpp","factory":"Editor"}}},"metadata":{"id":"default"}}
4 changes: 3 additions & 1 deletion better-code-class/00-introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.10.0
jupytext_version: 1.11.2
kernelspec:
display_name: C++17
language: C++17
Expand Down Expand Up @@ -53,10 +53,12 @@ My hope is that this workshop is generally applicable, but my experience colors
- Epilogue
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} -->
## Materials

- Slides: https://sean-parent.stlab.cc/notebook
- Exercises: https://github.com/sean-parent/better-code-class
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} tags=[] -->
## Use of Jupyter w/Xeus-Cling
Expand Down
2 changes: 1 addition & 1 deletion better-code-class/01-preface.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.10.0
jupytext_version: 1.11.2
kernelspec:
display_name: C++17
language: C++17
Expand Down
38 changes: 24 additions & 14 deletions better-code-class/02-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.10.0
jupytext_version: 1.11.2
kernelspec:
display_name: C++17
language: C++17
Expand Down Expand Up @@ -546,24 +546,34 @@ The C++20 standard defines the _concept_ std::regular<T> to be copyable, equalit
<!-- #region slideshow={"slide_type": "slide"} -->
### Safety

- An object which represents an entity is _fully formed_.
- An object which does not represent an entity is _partially formed_.
- An object which represents an entity is _fully-formed_, or _well-formed_
- An object which does not represent an entity, but may be modified (i.e. through assignment) to establish a correspondence with an entity, or destroyed, is _partially-formed_.
- An object which does not represent an entity and cannot be safely modified to represent an entity, or destroyed, is _ill-formed_.
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "fragment"} -->
- Any operation which maintains the correspondence between an object and an entity it represents is _safe_
- Any operation which preserves the correspondence between an object and an entity it represents is _safe_
- An operation which loses the correspondence is _unsafe_
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "fragment"} -->
- There are different categories of safety
- i.e. _memory safety_
- Destroying the correspondence of unrelated objects to their respective entities by overlapping their representation
- There are different categories of safety:

- _memory safety_
- A memory safe operation preserves the correspondence of unrelated objects to their respective entities. For example, writing through a deleted pointer is a not a memory safe operation as it may leave an unrelated object ill-formed.

- _thread safety_
- A thread safe operation may be executed concurrently with other operations on the same object(s) without the possibility of a race condition (data or logical race) resulting an an object which is not full-formed.

- _exception safety_
- An exception safe operation is one which after an exception any objects being operated on are in a _fully-formed_ state. C++ refers to this as the _strong exception guarantee_.
- An operation satisfying the _basic exception guarantee_ ensures that after an exception any objects being operated on are partially-formed.
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} -->
- An operation is _operationally safe_ if, when the operation preconditions are satisfied, the operation results in objects which are fully formed
- An operation is _operationally unsafe_ if, when the operation preconditions are satisfied, the operation may result in an object which is not fully formed
- _operational safety_
- An operation is operationally safe if, when the operation preconditions are satisfied, the operation results in objects which are fully-formed
- An operation is operationally unsafe if, when the operation preconditions are satisfied, the operation may result in an object which is partially-formed
- From here on, when referring to a _safe_ operation we mean _operationally safe_
<!-- #endregion -->

Expand Down Expand Up @@ -729,7 +739,7 @@ bool operator==(const my_type& a, const my_type& b) {
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} -->
- There are many examples of unsafe operations with the built in types:
- There are many examples of unsafe operations with the built-in types:
<!-- #endregion -->

```c++ slideshow={"slide_type": "fragment"}
Expand Down Expand Up @@ -760,7 +770,7 @@ unique_ptr<int> y = move(x); // safe. x is guaranteed to be == nullptr
- After an unsafe operation where an object is left partially formed
- Subsequent operations are required to restore the fully formed state prior to use
- If the partially formed state is _explicit_ it may by used in subsequent operation but those operations must yield explicitly undefined values for later detection and handling
- i.e. NaN, expected, maybe-monad pattern
- i.e. NaN, [expected](https://wg21.link/P0323), maybe-monad pattern
- Or the object must be destroyed
<!-- #endregion -->

Expand Down Expand Up @@ -908,7 +918,7 @@ std::pair<std::string, std::string> get_pair() {
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "fragment"} -->
- Default-construction is only include in `std::regular<>` for historical reasons
- Default-construction is only included in `std::regular<>` for historical reasons
- The classical definition of regular predates `move` as a basis operation
- Instead, `move` was done with default-construction and swap
- Default construction is not required by any standard algorithm
Expand Down Expand Up @@ -1017,7 +1027,7 @@ if (a == b) some_operation();
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "fragment"} -->
- For the paranoid library write, the standard supplies `std::addressof()`.
- For the paranoid library writeer, the standard supplies `std::addressof()`.
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} -->
Expand All @@ -1027,7 +1037,7 @@ if (a == b) some_operation();
<!-- #region slideshow={"slide_type": "fragment"} -->
- Because every object exists in memory, it's representation can be hashed
- Representationally equal objects imply equal hashes, not the converse
- the standard allows you to specialize `std::hash<>` for your type
- The standard allows you to specialize `std::hash<>` for your type
- The standard does not provide a `hash_combine()` function or a tuple hash
- [Boost provides both](https://www.boost.org/doc/libs/1_75_0/doc/html/hash.html) which can be used with `std::tie()` to easily provide a hash function
<!-- #endregion -->
Expand Down
20 changes: 9 additions & 11 deletions better-code-class/03-algorithms.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.10.0
jupytext_version: 1.11.2
kernelspec:
display_name: C++17
language: C++17
Expand Down Expand Up @@ -82,8 +82,8 @@ The term _algorithm_ covers all code. If an algorithm does not require iteration
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} -->
- Limitations of half-open intevals
- If there is not _next element_ then a half open interval cannot express a single element
- Limitations of half-open intervals
- If there is not a _next element_ then a half open interval cannot express a single element
- If there is a finite number of elements, the last (or first) cannot be included
<!-- #endregion -->

Expand Down Expand Up @@ -403,7 +403,7 @@ What was part of the definition of concepts in general has been weakened to a re
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "fragment"} -->
- `std::fill`, `std::iota()` and `std::generate` would be better expressed with output iterators and sink function forms:
- `std::fill()`, `std::iota()` and `std::generate()` would be better expressed with output iterators and sink function forms:
<!-- #endregion -->

```c++ slideshow={"slide_type": "slide"}
Expand All @@ -421,16 +421,14 @@ constexpr void iota(T first, T last, F out) {
```c++ slideshow={"slide_type": "fragment"}
{
using namespace bcc;
vector<int> v;
bcc::iota(0, 10, [&](int n) { v.push_back(n); });
display(v);
}
```

<!-- #region slideshow={"slide_type": "fragment"} -->
- Every algorithm using a output iterator should have a corresponding form with a sink function
- Every algorithm using an output iterator should have a corresponding form with a sink function
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} -->
Expand Down Expand Up @@ -642,7 +640,7 @@ void swirl(I f, I l) {
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "fragment"} -->
- (Unfortunately, `std::reverse` throws it away!)
- (Unfortunately, `std::reverse()` throws it away!)
<!-- #endregion -->

```c++ slideshow={"slide_type": "fragment"}
Expand All @@ -652,7 +650,7 @@ template <class I>
I swirl(I f, I l) {
reverse(f, l);
auto m = next(f, distance(f, l) / 2);
if (m == l) return;
if (m == l) return m;
rotate(f, m, next(m));
return m;
}
Expand All @@ -673,7 +671,7 @@ I swirl(I f, I l) {
<!-- #endregion -->
<!-- #region slideshow={"slide_type": "fragment"} -->
_Predicate permutations_ use a predicate function to determine ordering. These algorithms partition the set into two sets. A _stable_partition_ algorithm preserves the relative order of the elements in each set.
_Predicate permutations_ use a predicate function to determine ordering. These algorithms partition the set into two sets. A _stable partition_ algorithm preserves the relative order of the elements in each set.
<!-- #endregion -->
<!-- #region slideshow={"slide_type": "slide"} -->
Expand Down Expand Up @@ -712,7 +710,7 @@ _Comparison permutations_ use a comparison function to map an ordering of the va
<!-- #endregion -->
<!-- #region slideshow={"slide_type": "slide"} -->
- The default is to user `operator<()`
- The default is to use `operator<()`
- On a type, the expectation is that `operator<()` is a _total ordering_
- Which is consistent with other operations on the type
Expand Down
14 changes: 10 additions & 4 deletions better-code-class/04-data-structures.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.10.0
jupytext_version: 1.11.2
kernelspec:
display_name: C++17
language: C++17
Expand Down Expand Up @@ -70,7 +70,7 @@ TLB is _Translation Look-aside Buffer_ - or _cache miss_

<!-- #region slideshow={"slide_type": "slide"} -->
- A data structure is created anytime a relationship is established between objects
- To avoid confusion we will reserve the term _data structure_ to refer to types with a set of invariants which insure a set of relationship are maintained. i.e. standard containers
- 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. i.e. standard containers
- More transient data structures will be referred to as _structured data_
<!-- #endregion -->

Expand All @@ -89,6 +89,12 @@ TLB is _Translation Look-aside Buffer_ - or _cache miss_



<!-- #region slideshow={"slide_type": "slide"} tags=[] -->
\[
Everything from here down is notes...
\]
<!-- #endregion -->

```c++
namespace bcc {

Expand Down Expand Up @@ -157,7 +163,7 @@ bcc::iota(0, 1'000'000, [&](int n){ _vector.push_back(n); });
- `std::list<>` only makes since when you are externally indexing and hence require iterator stability

<!-- #region slideshow={"slide_type": "skip"} -->
[
\[

Show performance difference with std::list.
Discuss how big O() advantages are frequently lost.
Expand All @@ -168,7 +174,7 @@ Almost every major application sits on just one, or a very small number of data-

include iota implementation in algorithm section

]
\]
<!-- #endregion -->

<!-- #region slideshow={"slide_type": "slide"} -->
Expand Down
Loading

0 comments on commit 32db9c6

Please sign in to comment.