Skip to content

Commit

Permalink
Fix issues from @amyrbrown's amazing proofread.
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelDiBernardo committed Jun 27, 2016
1 parent f10008f commit 1693048
Show file tree
Hide file tree
Showing 14 changed files with 45 additions and 41 deletions.
6 changes: 2 additions & 4 deletions contingent/contingent.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -1155,17 +1155,15 @@ The wrapper can access the original version of the function
via the name `function`,
calling it at the appropriate time.
The body of the Contingent wrapper
runs something like this: \newpage
runs something like this:

```python
def task(function):
@wraps(function)
def wrapper(*args):
task = Task(wrapper, args)

if self.task_stack:
self._graph.add_edge(task, self.task_stack[-1])

self._graph.clear_inputs_of(task)
self._task_stack.append(task)
try:
Expand Down Expand Up @@ -1347,7 +1345,7 @@ under the name `_` for use in the subsequent expression.)
This recursive task of looking repeatedly for immediate consequences
and only stopping when we arrive at tasks with no further consequences
is a basic enough graph operation that it is supported directly
by a method on the `Graph` class: \newpage
by a method on the `Graph` class:

```python
>>> # Secretly adjust pprint to a narrower-than-usual width:
Expand Down
4 changes: 2 additions & 2 deletions crawler/crawler.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,6 @@ The `foo` function loads `bar` onto its stack and calls it, then pops its return

When `PyEval_EvalFrameEx` encounters the `CALL_FUNCTION` bytecode, it creates a new Python stack frame and recurses: that is, it calls `PyEval_EvalFrameEx` recursively with the new frame, which is used to execute `bar`.

\aosafigure[240pt]{crawler-images/function-calls.png}{Function Calls}{500l.crawler.functioncalls}

It is crucial to understand that Python stack frames are allocated in heap memory! The Python interpreter is a normal C program, so its stack frames are normal stack frames. But the *Python* stack frames it manipulates are on the heap. Among other surprises, this means a Python stack frame can outlive its function call. To see this interactively, save the current frame from within `bar`:

```python
Expand All @@ -366,6 +364,8 @@ It is crucial to understand that Python stack frames are allocated in heap memor
'foo'
```

\aosafigure[240pt]{crawler-images/function-calls.png}{Function Calls}{500l.crawler.functioncalls}

The stage is now set for Python generators, which use the same building blocks—code objects and stack frames—to marvelous effect.

This is a generator function:
Expand Down
23 changes: 14 additions & 9 deletions dagoba/dagoba.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ _[Dann](https://twitter.com/dann) enjoys building things, like programming langu
> "What went forth to the ends of the world to traverse not itself, God, the sun, Shakespeare, a commercial traveller, having itself traversed in reality itself becomes that self."
> —James Joyce
A long time ago, when the world was still young, all data walked happily in single file. If you wanted your data to jump over a fence, you just set the fence down in its path and each datum jumped it in turn. Punch cards in, punch cards out. Life was easy and programming was a breeze.
\noindent A long time ago, when the world was still young, all data walked happily in single file. If you wanted your data to jump over a fence, you just set the fence down in its path and each datum jumped it in turn. Punch cards in, punch cards out. Life was easy and programming was a breeze.

Then came the random access revolution, and data grazed freely across the hillside. Herding data became a serious concern: if you can access any piece of data at any time, how do you know which one to pick next? Techniques were developed for corralling the data by forming links between items [^items], marshaling groups of units into formation through their linking assemblage. Questioning data meant picking a sheep and pulling along everything connected to it.
Then came the random access revolution, and data grazed freely across the hillside. Herding data became a serious concern: if you can access any piece of data at any time, how do you know which one to pick next? Techniques were developed for corralling the data by forming links between items[^items], marshaling groups of units into formation through their linking assemblage. Questioning data meant picking a sheep and pulling along everything connected to it.

Later programmers departed from this tradition, imposing a set of rules on how data would be aggregated[^relationaltheory]. Rather than tying disparate data directly together they would cluster by content, decomposing data into bite-sized pieces, collected in pens and collared with name tags. Questions were posed declaratively, resulting in accumulating pieces of partially decomposed data (a state the relationalists refer to as "normal") into a frankencollection returned to the programmer.

Expand All @@ -28,7 +28,7 @@ The distributed revolution changed everything, again. Data broke free of spacial

## Take One

Within this chapter we're going to build a graph database[^dagoba]. As we build it we're going to explore the problem space, generate multiple solutions for our design decisions, compare those solutions to understand the tradeoffs between them, and finally choose the right solution for our system. A higher-than-usual precedence is put on code compactness, but the process will otherwise mirror that used by software professionals since time immemorial. The purpose of this chapter is to teach this process. And to build a graph database.[^purpose]
Within this chapter we're going to build a graph database[^dagoba]. As we build it we're going to explore the problem space, generate multiple solutions for our design decisions, compare those solutions to understand the tradeoffs between them, and finally choose the right solution for our system. A higher-than-usual precedence is put on code compactness, but the process will otherwise mirror that used by software professionals since time immemorial. The purpose of this chapter is to teach this process. And to build a graph database[^purpose].

[^dagoba]: This database started life as a library for managing Directed Acyclic Graphs, or DAGs. Its name "Dagoba" was originally intended to come with a silent 'h' at the end, an homage to the swampy fictional planet, but reading the back of a chocolate bar one day we discovered the sans-h version refers to a place for silently contemplating the connections between things, which seems even more fitting.

Expand Down Expand Up @@ -105,7 +105,7 @@ We're treating the edges as a global variable, which means we can only ever have

We're also not using the vertices at all. What does that tell us? It implies that everything we need is in the edges array, which in this case is true: the vertex values are scalars, so they exist independently in the edges array. If we want to answer questions like "What is Freyja's connection to the Valkyries?" we'll need to add more data to the vertices, which means making them compound values, which means the edges array should reference vertices instead of copying their value.

The same holds true for our edges: they contain an "in" vertex and an "out" vertex [^vertexnote], but no elegant way to incorporate additional information. We'll need that to answer questions like "How many stepparents did Loki have?" or "How many children did Odin have before Thor was born?"
The same holds true for our edges: they contain an "in" vertex and an "out" vertex[^vertexnote], but no elegant way to incorporate additional information. We'll need that to answer questions like "How many stepparents did Loki have?" or "How many children did Odin have before Thor was born?"

You don't have to squint very hard to tell that the code for our two selectors looks very similar, which suggests there may be a deeper abstraction from which they spring.

Expand Down Expand Up @@ -145,7 +145,7 @@ Dagoba.graph = function(V, E) { // the factory
}
```

We'll accept two optional arguments: a list of vertices and a list of edges. JavaScript is rather lax about parameters, so all named parameters are optional and default to `undefined` if not supplied [^optionalparams]. We will often have the vertices and edges before building the graph and use the V and E parameters, but it's also common to not have those at creation time and to build the graph up programmatically [^graphbuilding].
We'll accept two optional arguments: a list of vertices and a list of edges. JavaScript is rather lax about parameters, so all named parameters are optional and default to `undefined` if not supplied[^optionalparams]. We will often have the vertices and edges before building the graph and use the V and E parameters, but it's also common to not have those at creation time and to build the graph up programmatically[^graphbuilding].

[^optionalparams]: It's also lax in the other direction: all functions are variadic, and all arguments are available by position via the `arguments` object, which is almost like an array but not quite. ("Variadic" is a fancy way of saying a function has indefinite arity. "A function has indefinite arity" is a fancy way of saying it takes a variable number of variables.)

Expand Down Expand Up @@ -176,7 +176,7 @@ Dagoba.G.addVertex = function(vertex) { // accepts a vertex-like object
}
```

If the vertex doesn't already have an `_id` property we assign it one using our autoid. [^autoid] If the `_id` already exists on a vertex in our graph then we reject the new vertex. Wait, when would that happen? And what exactly is a vertex?
If the vertex doesn't already have an `_id` property we assign it one using our autoid.[^autoid] If the `_id` already exists on a vertex in our graph then we reject the new vertex. Wait, when would that happen? And what exactly is a vertex?

[^autoid]: Why can't we just use `this.vertices.length` here?

Expand Down Expand Up @@ -414,13 +414,15 @@ There are a couple of common ways of determining this: in a statically typed sys

[^referencecounter]: Most modern JS runtimes employ generational garbage collectors, and the language is intentionally kept at arm's length from the engine's memory management to curtail a source of programmatic non-determinism.

JavaScript doesn't have either of these facilities, but we can get almost the same effect if we're really, really disciplined. Which we will be. For now. \newpage
JavaScript doesn't have either of these facilities, but we can get almost the same effect if we're really, really disciplined. Which we will be. For now.


#### In-N-Out

Walking the graph is as easy as ordering a burger. These two lines set up the `in` and `out` pipetypes for us.

\newpage

```javascript
Dagoba.addPipetype('out', Dagoba.simpleTraversal('out'))
Dagoba.addPipetype('in', Dagoba.simpleTraversal('in'))
Expand Down Expand Up @@ -467,11 +469,14 @@ In this case, with a dozen or so pipetypes, the right choice seems to be to styl

#### Property

Let's pause for a moment to consider an example query based on the three pipetypes we've seen. We can ask for Thor's grandparents like this: `g.v('Thor').out('parent').out('parent').run()` [^runnote]. But what if we wanted their names?
Let's pause for a moment to consider an example query based on the three pipetypes we've seen. We can ask for Thor's grandparents like this[^runnote]:

[^runnote]: The `run()` at the end of the query invokes the interpreter and returns results.

We could put a map on the end of that:
```javascript
g.v('Thor').out('parent').out('parent').run()
```
But what if we wanted their names? We could put a map on the end of that:

```javascript
g.v('Thor').out('parent').out('parent').run()
Expand Down
2 changes: 1 addition & 1 deletion functionalDB/functionalDB.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ We will access the storage via a simple _protocol_, which will make it possible
(drop-entity [storage entity]))
```

And here's our in-memory implementation of the protocol, which uses a map as the store:
\noindent And here's our in-memory implementation of the protocol, which uses a map as the store:

```clojure
(defrecord InMemory [] Storage
Expand Down
4 changes: 2 additions & 2 deletions minutiae/colophon.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
Heros, both by Bogus\l{}aw Jackowski and Janusz M. Nowacki. The code font is
Inconsolata by Raph Levien.

The front cover photo is composed of 23 separate stack focused images of watch
gear assemblies. The picture was taken by Kellar Wilson.
The front cover photo is composed of twenty-three separate focus-stacked images
of watch gear assemblies. The picture was taken by Kellar Wilson.
(\url{http://kellarwilson.smugmug.com/})

This book was built with open source software (with the exception of the
Expand Down
6 changes: 3 additions & 3 deletions minutiae/frontmatter.tex
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

\small
\noindent \textbf{500 Lines or Less} \\
Edited by Michael DiBernardo and Amy Brown
Edited by Michael DiBernardo

\vspace{0.15cm}

Expand Down Expand Up @@ -115,13 +115,13 @@
\vspace{0.15cm}

\noindent Front cover photo \copyright Kellar Wilson \\
\noindent Copyediting, cover design, and publishing support by Amy Brown: www.amyrbrown.ca
\noindent Copyediting, cover design, and publishing support by Amy Brown: \url{http://amyrbrown.ca}

\vspace{1cm}

\noindent Revision Date: \today \\

\noindent ISBN: 978-1-304-48878-7
\noindent ISBN: 978-1-329-87127-4
\normalsize

\newpage
Expand Down
4 changes: 2 additions & 2 deletions minutiae/intro.tex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
\begin{aosachapter}{Introduction}{s:intro}{Michael DiBernardo}

This is the fourth volume in the \emph{Architecture of Open Source Applications}
series, and the first to not feature the words `open source applications' anywhere in the
series, and the first to not feature the words ``open source applications'' anywhere in the
title.

The first three volumes in the series were about big problems that big programs
Expand Down Expand Up @@ -61,7 +61,7 @@ \section*{Contributors}

\emph{Taavi Burns (DBDB)}: As the newest bass (and sometimes tenor) in Countermeasure, Taavi strives to break the mould\ldots sometimes just by ignoring its existence. This is certainly true through the diversity of workplaces in his career: IBM (doing C and Perl), FreshBooks (all the things), Points.com (doing Python), and now at PagerDuty (doing Scala). Aside from that—when not gliding along on his Brompton folding bike—you might find him playing Minecraft with his son or engaging in parkour (or rock climbing, or other adventures) with his wife. He knits continental.

\emph{Leo Zovic}: Leo (better known online as inaimathi) is a recovering Graphic Designer who has professionally written Scheme, Common Lisp, Erlang, Javascript, Haskell, Clojure, Go, Python, PHP and C. He currently blogs about programming, plays board games and works at a Ruby-based startup in Toronto, Ontario.
\emph{Leo Zovic}: Leo (better known online as inaimathi) is a recovering graphic designer who has professionally written Scheme, Common Lisp, Erlang, Javascript, Haskell, Clojure, Go, Python, PHP and C. He currently blogs about programming, plays board games and works at a Ruby-based startup in Toronto, Ontario.

\emph{Dr.\@ Christian Muise (Flow shop)}: Dr.\@ Muise is a Research Fellow with the Model-based Embedded and Robotic Systems group at MIT's Computer Science and Artificial Intelligence Laboratory. He is interested in a variety of topics including AI, data-driven projects, mapping, graph theory, and data visualization, as well as Celtic music, carving, soccer, and coffee.

Expand Down
2 changes: 1 addition & 1 deletion ocr/ocr.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ the digit predicted by the ANN.
Many resources are available online that go into greater detail on the
implementation of backpropagation. One good resource is from a [course by the
University of
Williamette](http://www.willamette.edu/~gorr/classes/cs449/backprop.html). It
Willamette](http://www.willamette.edu/~gorr/classes/cs449/backprop.html). It
goes over the steps of backpropagation and then explains how it can be
translated into matrix form. While the amount of computation using matrices is
the same as using loops, the benefit is that the code is simpler and easier to
Expand Down
2 changes: 1 addition & 1 deletion pedometer/pedometer.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ When bumpiness occurs at our threshold, we can mistakenly count too many steps f

\aosafigure[333pt]{pedometer-images/acceleration-filtered.png}{Tweaked peaks}{500l.pedometer.accelerationfiltered}

In accounting for these four scenarios, we've managed to bring our messy $a(t)$ fairly close to our ideal sine wave (\aosafigref{500l.pedometer.accelerationfiltered}), allowing us to count steps.
\noindent In accounting for these four scenarios, we've managed to bring our messy $a(t)$ fairly close to our ideal sine wave (\aosafigref{500l.pedometer.accelerationfiltered}), allowing us to count steps.

### Recap

Expand Down
4 changes: 2 additions & 2 deletions same-origin-policy/same-origin-policy.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,7 @@ and it is the responsibility of the receiving document to
_additionally_ check the `srcOrigin` parameter to ensure that the
message is coming from a trustworthy document. Unfortunately, in
practice, many sites omit this check, enabling a malicious document to
inject bad content as part of a `PostMessage` [^postMessageStudy].
inject bad content as part of a `PostMessage`[^postMessageStudy].

However, the omission of the origin check may not simply be the result
of programmer ignorance. Implementing an appropriate check on an incoming
Expand Down Expand Up @@ -1301,7 +1301,7 @@ resource on the server. This access pattern is appropriate if the
resource is considered public and accessible to anyone. However, it
turns out that many sites use "\*" as the default value even for
private resources, inadvertently allowing malicious scripts to access
them through CORS requests [^corsStudy].
them through CORS requests[^corsStudy].

Why would a developer ever use the wildcard? It turns out that
specifying the allowed origins can be tricky, since it may not be
Expand Down
10 changes: 5 additions & 5 deletions sampler/sampler.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ as well).
Before we get into the rest of the class, let's go over
two points related to the constructor.

#### Descriptive vs. Mathematic Variable Names
#### Descriptive versus Mathematic Variable Names

Usually, programmers are encouraged to use descriptive variable names:
for example, it would be considered better practice to use the names
Expand Down Expand Up @@ -333,10 +333,10 @@ numbers come from. We create it as follows:
>>> rso = np.random.RandomState(230489)
```

where the number passed to the `RandomState` constructor is the *seed*
for the random number generator. As long as we instantiate it with the
same seed, a `RandomState` object will produce the same "random"
numbers in the same order, thus ensuring replicability:
\noindent where the number passed to the `RandomState` constructor is the
*seed* for the random number generator. As long as we instantiate it with the
same seed, a `RandomState` object will produce the same "random" numbers in the
same order, thus ensuring replicability:

```python
>>> rso.rand()
Expand Down
4 changes: 2 additions & 2 deletions spreadsheet/spreadsheet.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ input:focus + div { white-space: nowrap; }
## Conclusion
Since this book is _500 Lines or Less_, a web spreadsheet in 99 lines is a minimal exampleplease feel free to experiment and extend it in any direction you’d like.
Since this book is _500 Lines or Less_, a web spreadsheet in 99 lines is a minimal example—please feel free to experiment and extend it in any direction you’d like.
Here are some ideas, all easily reachable in the remaining space of 401 lines:
Expand All @@ -563,4 +563,4 @@ For people preferring a cleaner syntax, the [as-livescript-1.3.0](https://audrey
Building on the LiveScript language, the [as-react-livescript](https://audreyt.github.io/500lines/spreadsheet/as-react-livescript/) directory uses the [ReactJS](https://facebook.github.io/react/) framework; [it is 10 lines more longer](https://github.com/audreyt/500lines/tree/master/spreadsheet/as-react-livescript) than the AngularJS equivalent, but runs considerably faster.
If you are interested in translating this example to alternate JS languages, send a [pull request](https://github.com/audreyt/500lines/pulls)I’d love to hear about it!
If you are interested in translating this example to alternate JS languages, send a [pull request](https://github.com/audreyt/500lines/pulls)—I’d love to hear about it!
Loading

0 comments on commit 1693048

Please sign in to comment.