Clark Kampfe - zeroclarkthirty.comhttps://zeroclarkthirty.comzeroclarkthirty.comSQLite: understanding and fixing "database is locked"https://zeroclarkthirty.com/2024-10-19-sqlite-database-is-locked.htmlSat, 19 Oct 2024 00:00:00 +0000SQLite has some surprising behavior regarding transactions that bites almost everyone who attempts to use SQLite with multiple concurrent connections.

the problem

If a connection is in an active write transaction, any other connection attempting to upgrade a read transaction to a write transaction will fail immediately with a surprising database is locked error. This happens regardless of what PRAGMA busy_timeout is set to!

understanding why

  1. In SQLite, all query interactions happen in transactions of some kind, whether in a read transaction (select) or a write transaction (insert|update|delete).

  2. SQLite allows for many concurrent readers but only 1 writer at a time. This invariant is enforced with locks, which connections must acquire to peform these reads and writes.

  3. By default, if a transaction starts with a read operation and only later later attempts a write (for example, a select followed by an insert), the default behavior of SQLite is to first start a read transaction by acquiring a read lock, and then lazily attempting to upgrade that read transaction to a write transaction only when the write statement occurs.

This may be surprising, especially the upgrade behavior, but it is all well documented.

(I am simplifying for ease of explanation. More detail about locking under the default rollback journal mode can be found here. This section in particular provides good detail about SQLite's locking strategy. Additionally, there is WAL mode, which has its own benefits and complications.)

how to fix it

The fix for this issue is twofold:

  1. For each connection to your SQLite database, set PRAGMA busy_timeout to a nonzero value when initializing the connection. busy_timeout is the amount of time in milliseconds that a connection will wait to acquire a write lock. Some SQLite clients like Python's set this value by default. Others do not, so I recommend you verify this in your client of choice.

  2. For any sequence of SQL statements run together in a transaction that includes at least one write, start the transaction with BEGIN IMMEDIATE rather than BEGIN. This instructs SQLite to immediately attempt to acquire a write lock rather than starting with a read lock and upgrading it to a write lock lazily. If the connection cannot immediately acquire the write lock because another connection has it, the connection attempting to acquire the write lock will busy wait for busy_timeout milliseconds before giving up and throwing the database is locked error.

Again, see SQLite's transaction documentation for more detail.

I am by no means claiming to have discovered or solved any of this on my own. Others have discussed this topic previously.

demonstration

I've provided a Python script at the end of this post that demonstrates both the error as it usually occurs as well as the fix.

To see the error, run: python lock.py

And to see the fix, run: python lock.py correct

The error looks like:

at [ 18:36:38 ] ➜ python lock.py
18:36:39: connection 1: thread started
18:36:39: connection 1: begin
18:36:39: connection 1: select
18:36:39: connection 1: inserted, sleeping
18:36:39: connection 2: thread started
18:36:39: connection 2: busy_timeout=0;
18:36:39: connection 2: attempting begin
18:36:39: connection 2: begin complete
18:36:39: connection 2: select
18:36:39: connection 2: trying to insert
Exception in thread Thread-2 (try_to_insert):
Traceback (most recent call last):
  File "/Users/clark/.asdf/installs/python/3.12.7/lib/python3.12/threading.py", line 1075, in _bootstrap_inner
    self.run()
  File "/Users/clark/.asdf/installs/python/3.12.7/lib/python3.12/threading.py", line 1012, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/clark/code/lock.py", line 80, in try_to_insert
    cur.execute("insert into people (id, name, address) values (1, 2, 3)")
sqlite3.OperationalError: database is locked
18:36:44: connection 1: sleeping over, committing

And with the fix, it looks like:

at [ 18:36:44 ] ➜ python lock.py correct
18:36:56: connection 1: thread started
18:36:56: connection 1: begin
18:36:56: connection 1: select
18:36:56: connection 1: inserted, sleeping
18:36:56: connection 2: thread started
18:36:56: connection 2: busy_timeout=5000
18:36:56: connection 2: attempting begin immediate
18:37:01: connection 1: sleeping over, committing
18:37:01: connection 2: begin immediate complete
18:37:01: connection 2: select
18:37:01: connection 2: trying to insert
18:37:01: connection 2: insert
]]>
Dynamic types are too powerfulhttps://zeroclarkthirty.com/2024-10-01-dynamic-types-are-too-powerful.htmlTue, 1 Oct 2024 00:00:00 +0000For a large portion of the software out there in the world, dynamic types are actually too powerful.

Take Ruby as an example. Ruby has a very powerful dynamic type system. You can define methods at runtime. You can define objects based on database tables at runtime. You can open up core classes and redefine their methods at runtime. You can ask objects what methods they have at runtime and branch on how they respond. This dynamism is amazing and enables a lot of the great libraries in the Ruby ecosystem, like Rails, ActiveRecord, etc.

The problem with power is, the more powerful things are, the worse they compose with each other.

And when it comes to dynamic languages like Ruby, you can't turn this power off. You get it whether you want it or not! To slightly repurpose a quote by Joe Armstrong: "You wanted a banana but what you got was a gorilla holding the banana and the entire jungle."

You go for Ruby because it's quick to write and it has these incredible libraries that let you write the first version of your app fast, but in exchange, you give up more or less all whole-program reasoning. You're writing the domain logic of your business application, and it's impossible to tell where things come from or what they do. Stuff just appears in scope without warning. Stuff just "happens" and it's not apparent from the text of the program where, when, or why.

That method, what object is it on? No idea, it's inherited from something, somewhere. Where is that variable defined? What touches it? Can I safely modify it? No idea, it just appears in scope because some parent class conjured it out of the ether. Did I fix up all the callsites after I modified that method definition? Some of the callsites might only exist at runtime via send or similar, so, no idea. Why is nil behaving weirdly? Oh, because someone opened up NilClass and modified it to make things "easier".

You go to grep for something, and grep fails you, because the name of thing you're grepping for was created with string concatenation at runtime. Am I upholding the invariants this API requires? No idea, we'll find out when we deploy it to production. Did I accidentally just make a breaking change to our library? No idea, I'm sure a user will file a bug report.

This is what it's like when a dynamic language is too powerful. It's using a jackhammer to hang a picture frame.

Again, some of the features that lead to these situations (like send or method_missing or duck typing) are useful and enable powerful stuff, but for normal, everyday, "grab this thing out of a database, munge it around a little, slam it into a template, and throw it on the wire" programming, they're actively harmful because they don't just inhibit local reasoning, they often make it impossible.

Knowing what a method returns is good. Knowing where an identifier comes from is good. This is low-level stuff you shouldn't have to think about. It doesn't make you a tough, big-boy programmer to be able to divine the arguments to a function, or track down where some magical thing was defined at runtime, or figure out how to work around your coworker's crappily monkey-patched String class. This kind of work is pure, 100% toil that wastes your time and adds no value for your users or your teammates.

I don't hate Ruby or dynamic languages generally and I don't want to ban powerful dynamic language features like Ruby has, but I think having these incredibly dynamic features readily available in line-of-business software is a mistake, just like C having unconstrained access to raw pointers has been a mistake.

I don't know how this would work, but it would be amazing if there were dynamic languages that took an approach similar to Rust's unsafe, where most of the language would be fairly vanilla, but you could have a delimited code block (or variety of different delimited code blocks) that clearly mark areas where you're opting-in to method_missing or send or class opening (or whatever else), so future readers can clearly see and audit those sections, lint them, grep for them, and build editor support for them. It would also be cool if the compiler was able to take this information into account, and offer better guarantees, optimizations, and error messages in the non-dynamic sections because it was able to better reason about the control flow of the less dynamic code.

]]>
For knives, worse is better, actuallyhttps://zeroclarkthirty.com/2024-09-25-worse-is-better-knives.htmlWed, 25 Sep 2024 00:00:00 +0000This post is another entry in the long and storied history of people misunderstanding and torturing Richard Gabriel's famous software design essay, The Rise of "Worse is Better".

This particular instance will apply to pocket knives. Yep, pocket knives!

See, I collect pocket knives. It's one of those irrational things I carry from my childhood. My grandpa always had a pocket knife, and I thought he was the coolest person ever, so it kind of stuck, and now I'm one of "those guys".

I have a few dozen at this point. Too many. Enough that my girlfriend laughs at me. I like to carry a different one every day. It's a dumb hobby, but I use them for all kinds of stuff, and I've used a ton of different knives over the years from many manufacturers. But let's get on with it. What does "worse is better" have to do with knives?

Well, knives are kind of like computer systems in certain respects. They're artifacts created by people for a particular use. They're a product of both industrial and bespoke, handmade processes. They require maintenance. They cost money. You get the idea.

Before we go any further, it'll be helpful for me to layout what I consider to be the functional tradeoffs inherent in knives:

Edge retention/Edgeholding

How much of something the knife will cut until the edge goes dull.

Price

How much does it cost.

Toughness

How well does a knife hold up to impact, bending, prying, throwing off a roof, getting pounded into a log, etc.

One illustrative scenario is to imagine you're opening up some packaged goods on a pallet and you hit a metal staple, a nail, etc. Does the knife's edge roll over? Does it break and chip? Is it damaged at all?

Maintainability

How easy or difficult is it to sharpen a knife. What kind of tools do you need to sharpen it. Are they expensive and complicated or simple and cheap?

Stainlessness

Knives are almost always made of steel, and all steel rusts (with the exception of some exotic materials I won't cover here), but at different rates. How well does the knife's steel resist corrosion? Stainlessnes is relevant in the real world, but I won't really discuss it in this essay.


With that out of the way, let's recall worse is better. "Worse is better" is Richard Gabriel's description of the differing design philosophies of the Lisp and C/UNIX camps. We don't need to get into the specifics of Lisp vs. C/UNIX but the general idea - which I must emphasize, Gabriel was criticizing! - is that in the real world, designs (and design philosophies) that sacrifice everything for simplicity of implementation often outcompete those that place more value on other particular traits like correctness, completeness, or consistency. It really isn't much more complicated than that.

So how does "worse is better" apply to knives?

The defining feature of a knife is that it cuts. There are other types of cutting tools like axes and saws, but knives are distinguished as being useful mainly to slice, push-cut, and/or perform light chopping. A knife's ability to cut is its feature set. In Gabriel's parlance, a knife's cutting ability is its "completeness".

Where this relates is, the community of "knife enthusiasts" (which is just as disgusting and pathetic as you imagine) goes through fads, and one of the fads over the last however many years has been for knives with greater and greater edge retention, which again is the ability to cut a lot of stuff without dulling.

And you might be saying, "well, isn't that good? I thought that was a knife's reason for existing."

And yes, in a vacuum, it is good!

But what has happened over this period of time is that a lot of knife manufacturers have been listening to the "knife enthusiasts", and increasingly making knives from relatively newer types of steel that maximize edge retention at the expense of price, toughness, and maintainability. Though not a complete list, some knife steels in this genre that have gained prevalence in recent years are M390, 20CV, S90V, and S30V. Knife people often refer to these as "super steels" because they can hold an edge so much longer than older, traditional steels.

These "super steels" are really good at what they're designed to do. I have some knives made from these steels in designs I love and they actually do hold an edge for a good long time, far longer than you might expect. It's a level of cutting performance that would be totally baffling to to somebody in the 1950s. They would be incredulous at how little you would have to sharpen these knives. Materials science and modern metallurgy is amazing!

The problem is, despite being great at cutting and holding an edge, they kinda suck at the rest of being a knife, which is being a thing that gets banged into nails, pries staples out of wooden boards, gets sharpened crappily and hastily on less than ideal tools, gets dropped on concrete, and just generally abused.

I have other knives, made in older, simpler, "crappier" steels like VG10, AUS-8, AUS-10, 420HC, 14C28N, 12C27, SK5, and AEB-L. These steels are simpler chemistries that have been around forever. Many are old enough so as to no longer be protected by intellectual property laws. These steels no longer excite "knife enthusiasts", who mostly consider these steels "worse".

And it's true. They are worse, objectively. Knives made in these steels dull faster than the same design made in the newer "super" steels mentioned above. They just won't cut for as long! Despite that, I find myself gravitating to knives made in these "worse" steels and using them more, because in real world use, they're often actually better to use than super-steel knives.

Blades made in these so-called "worse" steels have a lot going for them:

  • They're often tougher, meaning they better resist damage from nails, staples, and concrete. And when they do get damaged, that damage tends to simpler be more repairable. I have unintentionally damaged a number of knives through normal, non-extreme use, and knives made in these "worse" materials tend to damage less and less frequently. I wish I never damaged knives, but the simple fact is these knives get used in the real world and not in a lab in a test rig.

  • They require less skill to sharpen, they take less time to sharpen, and you can sharpen them with simpler, cheaper, more readily-available tools like simple bench stones or ceramics rather than diamond hones. As a result, I tend to view sharpening knives made of these steels as less of a chore, so I tend to do it more, so these knives tend to spend more of their lives in a state of decent repair. Furthermore, it's usually easier to get knives made in these steels to a truly scary level of scalpel-like sharpness rather than just "ehh it's sharp enough".

  • And finally, they're cheaper! While it's true that the prices of knives in the M390/20CV/S90V/S30V "super steel" family have come down in recent years, they're still more expensive, especially if you're interested in knives made by makers that aren't in China. As of this writing, you can pick up a Mora Eldris in 12C27 for $30, a Spyderco Endura for <$100 on sale, an ESEE Avispa in AUS-8 or SK5 for $35, as just a few examples. So you can buy 2 or 3 to keep a spare in your car or your bag. If you destroy one by dropping it off a roof or losing it on a camping trip, you're out tens of dollars instead of hundreds.

This particular line of thinking is new for me. When I first got into knives, I climbed the ladder (or fell into the trap, depending on your view) of ever more extravagent, "better" steels with ever better edge retention. I paid more for knives, I paid more for fancier sharpening tools, and I spent more sweat and time in sharpening those knives in the fancier steels. I was amazed at how long the edges lasted, but I dreaded sharpening them when they inevitably dulled or when I damaged them.

And over the years, I realized, I don't need the crazy edge retention offered by these steels. Not for what I'm doing with knives, which is your normal every-day stuff like opening bags of wood chips or soil or dogfood, breaking down cardboard so it fits in the recycle bin, making feathersticks for a bonfire, opening Amazon packages, or whatever else. Basically, my cutting needs are incidental and random, not constant. I'm not in a warehouse breaking down cardboard for 6 hours at a stretch.

These "better" steels have a place, but often like more powerful, "better" software frameworks or programming languages, that "better" often comes with a system-level cost. You're almost always giving something up to get it (except when you're not), whether that's more difficulty finding developers, or increased sharpening difficulty, or longer time to market, or lesser edge toughness.

These knives in these "worse" steels don't cut as long, which is ostensibly the point of a knife. They have to be sharpened more often, which is annoying. But that sharpening is easier! They're tougher, so when you actually use them to cut stuff, they tend to get damaged less and be repairable when they do!

So even though they appear to be worse knives, in the end, they're better tools.

]]>
Unsafety is really just imprecisionhttps://zeroclarkthirty.com/2024-09-04-unsafety-is-really-just-imprecision.htmlWed, 4 Sep 2024 00:00:00 +0000When a language is "unsafe" what we really mean is that the language is imprecise in a specific way.

When you write code in an imprecise language, the danger is that in the course of saying what you are trying to say, you inadvertently say things you did not mean to say, or you are unable to say exactly what you want to say.

For example, the C language lacks a way to talk about object lifetimes in a rigorous way. This leads to all kinds of bugs, security and otherwise.

But imprecision is not always unsafe, or even bad. Ruby also lacks a way to talk about object lifetimes (or even the underlying memory at all), but Ruby has a garbage collector that does, so this particular inarticulacy doesn't hamper it in the domains it was designed for.

In fact, Ruby's lack of ability to talk about memory actually helps it, as it is one less thing Ruby programmers need to think about!

Language design is (at least in part) the ability to know what your language should and should not be able to say.

]]>
jstream: a faster, extensible gronhttps://zeroclarkthirty.com/2024-04-29-jstream-a-faster-gron.htmlMon, 29 Apr 2024 00:00:00 +0000gron is a popular tool for viewing the structure of large JSON documents. It works by traversing the JSON document and outputting a combination of a given JSON value and the path in the document that points to that value.

From gron's readme:

▶ gron testdata/two.json 
json = {};
json.contact = {};
json.contact.email = "mail@tomnomnom.com";
json.contact.twitter = "@TomNomNom";
json.github = "https://github.com/tomnomnom/";
json.likes = [];
json.likes[0] = "code";
json.likes[1] = "cheese";
json.likes[2] = "meat";
json.name = "Tom";

gron is a great idea for a tool whose main implementation is lacking in a few respects, which I've tried to remedy a few times. My first attempt was jindex, which actually works fine, with the exception of two main flaws: it keeps the entire parsed JSON document in memory for the duration of the program, and it makes a ton of tiny allocations (on the order of 1 per path). This means jindex, when run on large documents, has a large memory overhead, and its propensity for allocation slows execution.

jstream is my attempt solve these issues, to improve on both gron and jindex.

jstream does the same as both, in this case emitting JSON paths rather than Javascript accessors:

$ echo '{
  "a": 1,
  "b": 2,
  "c": ["x", "y", "z"],
  "d": {"e": {"f": [{}, 9, "g"]}}
}' | jstream    
/a      1
/b      2
/c/0    "x"
/c/1    "y"
/c/2    "z"
/d/e/f/1        9
/d/e/f/2        "g"

jstream uses a different architecture than both gron and jindex. It uses a streaming JSON parser, namely the aws-smithy-json library. This addresses the deficiencies of jindex by reading the JSON document incrementally, and only loading and emitting paths as it traverses them. It also avoids allocating for every path by reusing a single Vec through the entire life of the program.

Because of this architecture, jstream has a dramatically lower memory overhead than jindex (I don't know about gron's memory usage; I have not benchmarked it for memory). On a ~180MB document (citylots.json), jstream uses only about 1.8MB more memory than the document itself (191,725,568 bytes maximum resident set size vs. 189,778,220 bytes document size). For comparison, jindex uses 1,139,638,272 bytes maximum resident set size, or ~1087MB.

jstream is also faster than both jindex and significantly faster than gron.

Running against another large-ish document (32MB) generated with the Python script here, the results look like this for gron (version 0.7.1 from homebrew, both sorted), jindex, and jstream:

$ hyperfine -w3 -r9 --output=null "gron big.json"
Benchmark 1: gron big.json
  Time (mean ± σ):      7.723 s ±  0.043 s    [User: 9.490 s, System: 1.437 s]
  Range (min … max):    7.663 s …  7.782 s    9 runs

$ hyperfine -w3 -r9 --output=null "gron --no-sort big.json"
Benchmark 1: gron --no-sort big.json
  Time (mean ± σ):      4.336 s ±  0.023 s    [User: 6.135 s, System: 1.427 s]
  Range (min … max):    4.301 s …  4.369 s    9 runs

$ hyperfine -w3 -r9 --output=null "jindex big.json"
Benchmark 1: jindex big.json
  Time (mean ± σ):     483.6 ms ±   4.4 ms    [User: 365.2 ms, System: 93.2 ms]
  Range (min … max):   477.9 ms … 489.9 ms    9 runs


$ hyperfine -w3 -r9 --output=null "jstream big.json"
Benchmark 1: jstream big.json
  Time (mean ± σ):     153.2 ms ±   0.5 ms    [User: 142.2 ms, System: 6.8 ms]
  Range (min … max):   152.5 ms … 154.1 ms    9 runs

jstream is also extensible. The current implementation outputs JSON paths by default (like the example above), but jstream can emit any path formatting you like, even like gron. You only have to implement one method on one trait to tell jstream how to print a given path and value combination:

pub trait PathValueWriter {
    fn write_path_and_value(&mut self, path: Path, value: JsonAtom) -> std::io::Result<()>;
}

You can get jstream here.

]]>
Rust has been too successfulhttps://zeroclarkthirty.com/2024-04-27-rust-has-been-too-successful.htmlSat, 27 Apr 2024 00:00:00 +0000As the years go on and more people use Rust, we're seeing more and more of these "Rust was a bad choice and here's what I don't like about it" posts, like this one. (Discussion here)

My goal with this post is not to discuss the above linked gamedev post directly. Rust should have a better gamedev story. My goal with this post is to try to understand a tiny bit about why so many people are publically expressing the feeling that Rust doesn't work for them.

One reason I think this is happening because Rust has actually been too successful at selling itself. How so? Rust has largely achieved what many people thought was impossible: it has supplanted a non-trivial amount of C/C++ code at places like Cloudflare, Amazon, Google, Microsoft, and others of similar caliber. The Linux kernel, not exactly a project known to live on the bleeding edge, is starting to evaluate and integrate Rust for drivers. This is great! A ton of low level infrastructure code in things like proxies, routers, SDKs, VMs, runtimes, languages, hypervisors, etc., is now arguably safer for end-users than if it were written in C or C++. It appears that Rust is here to stay at the highest (lowest?) levels of technology.

But too successful? Yes. Rust has overachieved. All of these stories of Rust's success in the holy halls of Big Tech have inundated us mere mortals with so much positivity that we're now witnessing that "if it worked for them it'll work for me" syndrome that we saw with so many other technologies over the years. Things like document databases, eventual consistency, Hadoop/"Big Data"/Spark/Kafka, object oriented programming, microservices, and more I'm forgetting. Things that most people didn't need but a lot of people tried, because they were popular, they had the hype, Big Tech people talked about them at conferences, they looked good on a resumé. Now, I'm not saying Rust is a fad, like some of those. I think the impact of Rust is quite a bit larger than microservices. But Rust is popular and hot like microservices were popular and hot.

This popularity has resulted in bringing a mass of new people in to Rust, people with all kinds of use cases, and some of those use cases are a poor fit for the tool. To those folks coming in evaluating Rust, I say this sincerely: if you need the simplest language to learn, or the fastest possible iteration times, or a great run-time reflection story, or the most straightforward migration from your existing tech stack, or the language with the largest-possible library coverage, or the language where you don't have to think about resource ownership at all, or the language with the shortest compile times, Rust might not be the best fit for your use case.

Rust is terrific in its niche, but like everything else, it has a niche. What we are witnessing now, in real-time, is people discovering the blurry edges of that niche through their pain. And in doing so, those edges are becoming slightly less blurry for all of us. And this is fine, actually. We're seeing where Rust works, and where it doesn't work well enough yet. This is how it goes when a technology is genuinely novel and you don't yet know where it's going.

(As an aside: I think that a great deal of people who have tried Rust and found it lacking, or hard, or a bad fit, or whatever else would be better served by either Elixir/Erlang or Go. There has been an enormous amount of criticism made (and frankly, hot air blown) against Rust's async story in particular, and while I think people's perceptions on async are valid, I often disagree with their conclusions. I think Rust's async is good. But most people and most companies would be better served by a more straightforward, conventional concurrency story, one that doesn't have strict ownership and zero-cost as goals, and for those use cases, Elixir and Go are great.)

]]>
Benchmarking Erlang 27.0's new JSON modulehttps://zeroclarkthirty.com/2024-04-21-benchmarking-erlangs-new-json.htmlSun, 21 Apr 2024 00:00:00 +0000Here are a few benchmarks comparing Elixir's Jason with the new :json module, which will ship in the standard library with Erlang 27.0. The usual caveats apply: I chose these example documents, this is my own hardware, etc. Always run these kind of benchmarks on your own hardware with your own workload.

inputs


$ ls -lah fixtures
Permissions Size User  Date Modified Name
.rw-r--r--  923k clark 21 Apr 13:23  big.json
.rw-r--r--  3.9k clark 21 Apr 13:21  github.json

decode results


at [ 14:06:31 ] ➜ mix run decode_bench.exs
Operating System: macOS
CPU Information: Apple M1 Max
Number of Available Cores: 10
Available memory: 64 GB
Elixir 1.16.2
Erlang 27.0-rc3
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 3 s
time: 5 s
memory time: 0 ns
reduction time: 0 ns
parallel: 1
inputs: big, github
Estimated total run time: 32 s

Benchmarking :json.decode/1 with input big ...
Benchmarking :json.decode/1 with input github ...
Benchmarking Jason.decode/1 with input big ...
Benchmarking Jason.decode/1 with input github ...
Calculating statistics...
Formatting results...

##### With input big #####
Name                     ips        average  deviation         median         99th %
:json.decode/1        184.17        5.43 ms     ±1.19%        5.42 ms        5.77 ms
Jason.decode/1        170.45        5.87 ms     ±7.24%        5.72 ms        6.65 ms

Comparison:
:json.decode/1        184.17
Jason.decode/1        170.45 - 1.08x slower +0.44 ms

##### With input github #####
Name                     ips        average  deviation         median         99th %
:json.decode/1       83.18 K       12.02 μs    ±18.69%       11.88 μs       14.54 μs
Jason.decode/1       61.64 K       16.22 μs    ±25.01%          16 μs       19.17 μs

Comparison:
:json.decode/1       83.18 K
Jason.decode/1       61.64 K - 1.35x slower +4.20 μs

decode source


~c"27" = :erlang.system_info(:otp_release)

github = File.read!("fixtures/github.json")
big = File.read!("fixtures/big.json")

# just assert that these actually work

{:ok, _} = Jason.decode(github)
{:ok, _} = Jason.decode(big)
# these throw, so no match
:json.decode(github)
:json.decode(big)

Benchee.run(
  %{
    "Jason.decode/1" => fn input -> Jason.decode(input) end,
    ":json.decode/1" => fn input -> :json.decode(input) end
  },
  inputs: %{
    "github" => github,
    "big" => big
  },
  warmup: 3
)

encode results


$ mix run encode_bench.exs
Operating System: macOS
CPU Information: Apple M1 Max
Number of Available Cores: 10
Available memory: 64 GB
Elixir 1.16.2
Erlang 27.0-rc3
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 3 s
time: 5 s
memory time: 0 ns
reduction time: 0 ns
parallel: 1
inputs: big, github
Estimated total run time: 32 s

Benchmarking :json.encode/1 with input big ...
Benchmarking :json.encode/1 with input github ...
Benchmarking Jason.encode_to_iodata/1 with input big ...
Benchmarking Jason.encode_to_iodata/1 with input github ...
Calculating statistics...
Formatting results...

##### With input big #####
Name                               ips        average  deviation         median         99th %
:json.encode/1                  439.97        2.27 ms    ±27.74%        2.09 ms        3.30 ms
Jason.encode_to_iodata/1        310.08        3.22 ms     ±4.10%        3.29 ms        3.55 ms

Comparison:
:json.encode/1                  439.97
Jason.encode_to_iodata/1        310.08 - 1.42x slower +0.95 ms

##### With input github #####
Name                               ips        average  deviation         median         99th %
:json.encode/1                246.56 K        4.06 μs   ±193.56%        3.96 μs        5.63 μs
Jason.encode_to_iodata/1      116.10 K        8.61 μs    ±26.61%        8.38 μs       11.17 μs

Comparison:
:json.encode/1                246.56 K
Jason.encode_to_iodata/1      116.10 K - 2.12x slower +4.56 μs

encode source


~c"27" = :erlang.system_info(:otp_release)

github = File.read!("fixtures/github.json")
big = File.read!("fixtures/big.json")

# just assert that these actually work

{:ok, github_term} = Jason.decode(github)
{:ok, big_term} = Jason.decode(big)
# these throw, so no match
:json.decode(github)
:json.decode(big)

{:ok, _} = Jason.encode_to_iodata(github_term)
{:ok, _} = Jason.encode_to_iodata(big_term)
:json.encode(github_term)
:json.encode(big_term)

Benchee.run(
  %{
    "Jason.encode_to_iodata/1" => fn input -> Jason.encode_to_iodata(input) end,
    ":json.encode/1" => fn input -> :json.encode(input) end
  },
  inputs: %{
    "github" => github_term,
    "big" => big_term
  },
  warmup: 3
)

conclusion

It looks like there are some respectable gains to be had here, especially for encoding. This :json module looks like a great addition, and it will be really nice to have it in the standard library. I wish it didn't handle errors with exceptions, and instead offered an {:ok, _} | {:error, _} API, but we can probably graft that on after the fact in Elixir without too much trouble.

I've seen talk that :json will be integrated into Jason version 2 at some point, so it's possible you won't have to change anything to realize these gains if you already use Jason.

]]>
Understanding GenServer startuphttps://zeroclarkthirty.com/2024-04-21-genserver-init.htmlSun, 21 Apr 2024 00:00:00 +0000In Elixir and Erlang, a GenServer is a way of defining a process that has a specific behavior, namely, it behaves as a server with typical "server and client" semantics. That is, you send some message to the server, and it responds. When I first encountered Erlang I remember being confused about GenServer startup. There is actually a fair amount of subtlety to how a GenServer starts, so let's look at a few modules to illustrate it.

First, this module, which I'll call the server module:

defmodule MyServer do
  use GenServer
  
  def start_link(args) do
    GenServer.start_link(__MODULE__, args, name: __MODULE__)
  end
  
  @impl GenServer
  def init(args) do
    {:ok, args}
  end
end

And this module, which I'll call the caller or client module:

defmodule Caller do
  def do_some_work() do
    {:ok, pid} = MyServer.start_link(%{})
    # further work intentionally omitted...
  end
end

When you work with the GenServer, like in our example caller module, by calling MyServer.start_link(%{}), this MyServer.start_link/1 call happens in whatever process you happen to be calling it in. We'll call this "the client process". This call blocks the client process until the GenServer is started. When MyServer.start_link/1 returns, the pid it return is considered started.

Going one layer deeper, the GenServer process itself is started in the MyServer.start_link/1 function, with the call to GenServer.start_link/3. This instructs the GenServer library in Elixir to start a new GenServer process defined from the current module (the first __MODULE__ arg), with an initial state of args, and with its name registered as the name of the current module (again, __MODULE__). While the GenServer has at this point been started, it is not considered fully booted, and it is not at this point ready to accept work.

The next step of the GenServer process startup happens when the GenServer library calls back into our code, specifically the init/1 function. This function is crucial. There are a few key facts to understand about init/1:

  1. Your GenServer process is not considered fully booted and cannot accept work until init/1 returns.
  2. init/1 runs synchronously, so any blocking setup work in init/1 blocks the start of the GenServer process, for example loading files from disk or making external network requests.
  3. Whatever you return as the 2nd argument of the return tuple in init/1 becomes the state of the newly started GenServer process.

Once init/1 returns, your GenServer is considered fully booted, and in turn each call further up the stack returns: first GenServer.start_link/3 and then MyServer.start_link/1.

At this point, the GenServer is running in its main loop and ready to accept new calls from clients.

But what if you want to perform some initialization work in your GenServer right after it is booted, or you want to perform some initialization work in your GenServer but want to do this in way that doesn't block its startup?

This is what handle_continue is for.

handle_continue

If we modify our init/1 slightly, we can instruct our GenServer to perform some work immediately after it has fully booted:

@impl GenServer
def init(args) do
  {:ok, args, {:continue, :do_some_post_boot_work}}
end

This {:continue, :do_some_post_boot_work} instructs the GenServer to run a handle_continue callback immediately after init/1 returns, which we define like this:

@impl GenServer
def handle_continue(:do_some_post_boot_work, state) do
  # do some post boot work here!
  {:noreply, state}
end

The :continue atom in init/1 is a GenServer-specific atom, and it says to run a handle_continue callback defined in your GenServer. The :do_some_post_boot_work atom is an atom we pick, and can be anything. It's not restricted to an atom necessarily, it can be anything as long as it can match the first argument to a handle_continue callback you define in your GenServer.

an example

Let's put it all together, add in some log lines and timers to show what happens when you actually run it:

defmodule MyServer do
  use GenServer
  require Logger

  def start_link(args) do
    GenServer.start_link(__MODULE__, args, name: __MODULE__)
  end

  @impl GenServer
  def init(args) do
    Logger.debug("GENSERVER init, before sleep")
    Process.sleep(:timer.seconds(2))
    Logger.debug("GENSERVER init, after sleep")
    {:ok, args, {:continue, :do_some_post_boot_work}}
  end

  @impl GenServer
  def handle_continue(:do_some_post_boot_work, state) do
    Logger.debug("GENSERVER handle_continue, before sleep, genserver is booted")
    Process.sleep(:timer.seconds(3))
    Logger.debug("GENSERVER handle_continue, after sleep, genserver is booted")
    {:noreply, state}
  end
end

defmodule Caller do
  require Logger

  def do_some_work() do
    Logger.debug("CLIENT do_some_work before start_link")
    {:ok, _pid} = MyServer.start_link(%{})
    Logger.debug("CLIENT do some work after start_link has returned")
    # further work intentionally omitted...

    Process.sleep(:timer.seconds(4))
  end
end

Caller.do_some_work()

And the resulting log lines, which show two important facts:

  1. MyServer.start_link/1 does not return until init/1 returns. This means the startup procedure is synchronous from the caller's/client's point of view.
  2. handle_continue runs after init/1 returns, meaning it runs after the GenServer has fully booted.
at [ 15:20:43 ] ➜ elixir genserver_startup.exs

15:21:03.376 [debug] CLIENT do_some_work before start_link

15:21:03.379 [debug] GENSERVER init, before sleep

15:21:05.380 [debug] GENSERVER init, after sleep

15:21:05.380 [debug] GENSERVER handle_continue, before sleep, genserver is booted

15:21:05.380 [debug] CLIENT do some work after start_link has returned

15:21:08.381 [debug] GENSERVER handle_continue, after sleep, genserver is booted

Note that GENSERVER handle_continue, before sleep, genserver is booted and CLIENT do some work after start_link has returned happened at the same time due to both log lines happening right as the GenServer was fully booted.

There is much more to how GenServer works, but I just wanted to explain how I understand the GenServer boot process. If you want to read more, there is extensive documentation.

]]>
Open source has a moral hazard problemhttps://zeroclarkthirty.com/2024-03-30-open-source-moral-hazard.htmlSat, 30 Mar 2024 00:00:00 +0000The cost society pays because of bad software is titanic. No matter how you measure it, in lost time, lost dollars, stolen identities, frustration, or whatever else, I don't think this point is controversial.

What may be controversial, though, is the realization that it is the users who pay most of these costs, not companies, and not developers of open source software. I think this is because open source software has a moral hazard problem:

Moral hazard can exist when a party to a contract can take risks without having to suffer consequences.

That open source software has a moral hazard problem should not be surprising, as the popular open source licenses all disclaim liability explicitly.

For example:

The 3-clause BSD license:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The GPLv3 license:

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

The Apache license:

  1. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

These licenses all say that as a condition of use, users of software cannot hold developers liable when that software causes them to have their bank details or identity stolen. I think this has an enormous effect on what tools developers choose to use, and how those tools shape the software ecosystem in aggregate. To make this interesting, let's flip things around and imagine a world where developers are open to liability when their software misbehaves and harms users. In this world, how would developers choose their tools and frameworks?

Take for example, the 800lbs gorilla in the room: the C language. Would anyone choose to continue write software in C? Would there be anywhere near as much new C code as there is today? Under an open liability regime, I think using C would be similar to building your home in California wildfire country: insurance companies would assess the risk, and the price of insurance would be far above what most people and organizations could pay. Only the richest organizations - those who know they need exactly what only C can provide, who can afford to spend the huge sums of money to make C safe - would choose C, like the rich choosing to build fireproof houses in lieu of homeowner's insurance. The average Joe open source developer (and every organization that isn't Apple/Google/Citadel) simply couldn't afford the liability exposure (and insurance premiums) that would come with using C.

Overnight, the demand for safer tools would explode. But crucially, this demand would be for tools that are not only safer in absolute terms, but tools that are also easier to use safely. That is a critical distinction, because in general, people are loath to give up productivity gains in the name of safety, often circumventing safety guards in order to regain lost productivity. I think this somewhat explains the rise of Rust and Go in the last 10 years, when Ada has already existed for decades. Rust and Go offer a developer experience better than Ada and C, are each substantially safer than C, while providing comparable performance.

While it is debatable whether the monetary cost of releasing unsafe software has gone up (maybe for companies, definitely not for developers), the social cost has definitely gone up. Developer culture has changed and continues to change such that releasing unsafe software using unsafe tools is more taboo than it used to be. Given the alternative of widespread litigation against individuals and teams of open source developers whose code is found to be insecure, the social taboo is probably the better approach. I'm a developer myself. I don't particularly like the idea of being personally liable for releasing code for free on the internet. But, at the same time, I also hate the idea of externalizing the costs of unsafe software onto users. Doing so seems unfair and irresponsible, and we have to fix that. Maybe Rust's biggest innovation has not been the Rust language itself - nice though it is - but its culture of attempting to mitigate the moral hazard of open source software development.

]]>
What I'm reading 10/1-10/8https://zeroclarkthirty.com/2023-10-01-what-im-reading.htmlSun, 8 Oct 2023 00:00:00 +0000Untold stories of football's Air Raid revolution

  • "How come they get to pretend they are soldiers?" Leach said. "The thing is, they aren't actually in the military. I ought to have Mike's Pirate School. The freshmen, all they get is the bandanna. When you're a senior, you get the sword and skull and crossbones. For homework, we'll work pirate maneuvers and stuff like that."

  • "Mike used to like to watch those simulcasts of Howard Stern. And those things would run till 4 in the morning. I'm in my bed trying to sleep. And here's Leach at 3 in the morning, he's laughing at Howard Stern, he's drinking a beer and he's having a good time."

Arizona to cancel leases allowing Saudi-owned farm access to state's groundwater

  • "Arizona governor Katie Hobbs said this week her administration is terminating state land leases that for years have given a Saudi-owned farm nearly unfettered access to pump groundwater in the dry southwestern state."

Among the Cabin Fanatics of Mississippi's Giant Houseparty

  • "At the fair, I was offered water, lemonade, iced tea, beer, Gatorade, a souvenir apron, boiled shrimp, homemade ice cream, a pork chop, a taco, a bed, a toilet, the remains of a funnel cake, a book about doughnuts, an introduction to 'some really obnoxious cousins,' two ibuprofens, two more ibuprofens, help 'fixing' a traffic ticket (offer declined), and numerous iterations of chicken."

  • The previous night, a visitor from Los Angeles had stumbled, drunk, into a cabin at the north end of the racetrack and commented on all the "pretty bitches" he had seen. One of the men in residence informed him, "Down here, we refer to them as 'ladies.'"

Two Families Got Fed Up With Their States’ Politics. So They Moved Out.

  • "Mr. Noble still seemed stunned that in America in 2023, politics would drive a family to seek refuge across state lines."

Rent Going Up? One Company's Algorithm Could Be Why.

  • "One of the algorithm's developers told ProPublica that leasing agents had 'too much empathy' compared to computer generated pricing."
]]>
What I'm reading 9/24-10/1https://zeroclarkthirty.com/2023-09-24-what-im-reading.htmlSun, 1 Oct 2023 00:00:00 +0000Not everyone who disagrees with you is a closet right-winger

  • "However, I have also become more estranged from what you might call the progressive political class over the past several years. One reason is that this class has rapidly become more left and less liberal — compare the Democratic presidential platforms of 2020, which began with a land acknowledgment, with Obama’s in 2012, which began by talking about the American Dream. I also strongly disagree with the left’s elevation of “misinformation” as a category of concern over free speech. There may also be some personality-driven dimensions to why I tend not get along with a certain type of of progressive personalty on social media, though Twitter rarely brings out the best in any of us."

Tech debt metaphor maximalism

  • "Tech debt, in its simplest form, is the time you didn't spend making tasks more efficient. When you think of it that way, it's obvious that zero tech debt is a silly choice."

How did "Defund the police" stop meaning "Defund the police"? - Why mainstream progressives have a strong incentive to 'sanewash' hard leftist positions

  • "The social weight of the subcultures I was involved in just clamped down on me."

  • "But the key thing about this is it's a social dynamic - that is, there's a strong social incentive to do this, because the pressure of guilt if you don't believe the right thing, or some version of it, is very strong, so you invent arguments for what other people believe, to explain why they're right, even though they don't seem to hold those positions themselves."

Why do we need modules at all?

  • "I am thinking more and more that if would be nice to have all functions in a key_value database with unique names."

Yamagami Tetsuya's Revenge

  • "Japan's peculiar arrangement was that of a powerful state run by an organizationally weak party that was heavily restricted by the postwar legal system. That arrangement meant that other powers had to be tapped by the LDP to get certain things done."

  • "When Yamagami's actions finally raised questions about LDP-Unification Church relations in 2022, half of the LDP members sitting in the House of Representatives turned out to have connections to the group."

YAML config file? Pain? Try Lua

  • "Also, you don't even have to mention you are using Lua as a configuration file—most likely, no one will really notice anyway."

Make systemd better for Podman with Quadlet

  • "Quadlet hid the complexity of running containers under systemd from users, making writing unit files from scratch much easier to maintain."
]]>
What I'm reading 9/17-9/24https://zeroclarkthirty.com/2023-09-21-what-im-reading.htmlSun, 24 Sep 2023 00:00:00 +0000The Stations of the Meritocrat Cross

  • "More, though, I just worry for these kids and for our future with them. We're winding our young people up so fucking tight... Sometimes I think the great American rite of passage is when you go from a youth full of Ritalin to an adulthood full of Xanax."

MPL-50

  • "It is sharpened on its working edge and often on one side, for use as an axe."

I rode with an ice road trucker to the Arctic Circle. Here’s what it was like

  • "This is the greatest trucking job in the world," Mustang told me. "No traffic, no stoplights, just trucking. You see bears and critters and water."

  • "Alaskan truck drivers call it 'the Dalton.' They also all know it is exactly 414 miles."

Journalism fails miserably at explaining what is really happening to America

  • "What we call the Republican Party is barely a political party in any sense of the word, but a dangerous antisocial movement that has embraced many of the tenets of fascism..."

64-Bit Bank Balances 'Ought to be Enough for Anybody'?

  • "We may not be able to intuit how big a 128-bit integer is. Not merely twice the 64-bit; it’s actually 2^64 times bigger!"

John McCarthy's collection of numerical facts for use in elisp programs

  • "This file was made for my own (John McCarthy, jmc@cs.stanford.edu) use, and I wasn't thinking of other people when I did it. Therefore, some of its feature may be obscure. It contains a lot of units conversions and also astronomical facts that I needed for some research on moving Mars to a more temperate location."
  • (setq J (* 1.0 kg (expt m 2) (expt sec -2)))

What Mitt Romney Saw in the Senate

  • "Shortly after moving into his Senate office, Romney had hung a large rectangular map on the wall. First printed in 1931 by Rand McNally, the 'histomap' attempted to chart the rise and fall of the world’s most powerful civilizations through 4,000 years of human history. When Romney first acquired the map, he saw it as a curiosity. After January 6, he became obsessed with it."
]]>
Elixir in shell pipelineshttps://zeroclarkthirty.com/2023-09-07-elixir-in-shell-pipelines.htmlThu, 7 Sep 2023 00:00:00 +0000When invoking elixir on the command line, you can pass the -e/--eval flag multiple times. This means you can define a shell alias where you use Elixir's new Mix.install functionality to preload dependencies, and then run quick one-liners in shell pipelines that have access to those dependencies.

First, in your shell profile define an alias like this:

alias ee='elixir -e "Mix.install([:csv, :easyhtml, :jason, :nimble_parsec, :req])"'

Now you can call your alias like you would normally call elixir, passing any code you want to execute to -e, and your Elixir dependencies will be available:

$ echo '{"a": 1, "b": 2}' | ee -e "IO.read(:stdio, :all) |> Jason.decode!() |> IO.inspect"
%{"a" => 1, "b" => 2}
]]>
Names are not enoughhttps://zeroclarkthirty.com/2023-06-01-names-are-not-enough.htmlThu, 1 Jun 2023 00:00:00 +0000When I was first learning programming - not counting TI BASIC when I was 13 - the more experienced developers I was learning from stressed the importance of good names for things like variables, methods, classes, and modules. I think they were right to an extent, but as I've built and maintained more systems, I've grown less and less enamored with the value of "good names" in software systems relative to other information channels.

For example, i and j and k say nothing about for loops, or indexes, or counters. They aren't actually "good names" in any way. They don't say anything about your intent when writing this code or the work your for loop happens to be doing. They're just the names we happened to give to that concept in that situation, and they stuck. Maybe they're derived from math in some way, but at this point, their origin matters less than their widespread use in the family of languages that have C-style loops.

For another example, when I was working with Ruby at my first real programming job, I remember being incredibly frustrated at how hard it was to tell what anything in our Ruby codebases was or did. Objects and values and classes and all had names, and they lived in modules that also had names, but I can still remember the daily frustration of trying to figure out what anything was, what it could do, or how it fit together with anything else in the system. The names just weren't sufficient to determine the capabilities of the objects without reading the various class and method implementations in full. (This was exacerbated by the predominant Ruby tooling at the time, which was almost always some combination of Sublime Text 2, Vim, and grep, but that's another blog post for another time.)

And maybe this is a sign of seniority (probably not) or burnt-out-ness (probably), but when I'm attempting to solve a specific problem, I don't want to read the class and method implementations of a bunch of unrelated features if I don't have to. In the systems that I have seen, the challenge to doing effective work is often not one of construction but reduction, i.e. the act of actually "writing" the code is less important than identifying and understanding the code that is relevant to you in a sea of code that isn't. The likelihood that any given module or function is relevant to the problem you happen to be working on decreases substantially with the size of the system, its longevity, and the number of people working on it.

And names just don't help that much with this kind of filtration! Names don't have anything to say about the importance of one module vs. another, or relationships between modules, or how to correctly use a subsystem. They often don't say anything about history, except in ad-hoc, useless ways like "LegacyQueue" or "APIv3". What a module does, and what it is related to, almost always matters more than what name its author has given it. That so many languages have such poor tools for identifying and presenting what code modules do does not refute this, and in fact confirms it, as in these languages you see programmers really leaning in to naming, as it is one of the few levers they can actually pull in lieu of having real tooling. You can't pull a lever you don't have, so you pull the ones you do, and unfortunately in many languages, names are all you've got.

One obvious mechanism to reach beyond names is types. Crucially, types aren't really syntax in the way that identifiers are. You can name a type, but in most languages that are worth a damn, types encode information at a deeper level than syntax. You can ask the compiler the type of something. You can ask the compiler what that type allows you to do, and how it interacts with other types. You can programmatically manipulate instances of that type. Types encode richer information than that which is conveyed by an a function paramter being called user. User of what? How? In what context? What can this user do?

Now, I'm not a types maximalist - though I do like them for some things and Rust is a favorite language of mine - but I think types are a really great tool in a lot of cases. I'm encouraged that the industry seems to agree with me, with the rising popularity of things like Typescript and mypy. But there are of course other ways to gain greater understanding of our systems, like debuggers, REPLs, live reloading, image environments like in Smalltalk, and many others. These are all good, but I don't think we're nearly advanced enough. Too many programmers still think programming is mostly naming things in text files, and we really have got to move beyond it if we hope to match the intelligibility and reliability of other, more mature disciplines.

]]>
Elixir and Erlang: whats so special?https://zeroclarkthirty.com/2023-05-18-elixir-and-erlang-whats-so-special.htmlThu, 18 May 2023 00:00:00 +0000(Note that in this post I use "Elixir" to refer to Elixir, Erlang, and OTP altogether. This is a deliberate choice to simplify things for those who are unfamiliar.)

A few days ago Erlang/OTP 26.0 was released, which lead to a lot of discussion on HN about Erlang and Elixir.

This post in particular asked, more or less, "what's the big deal?"

I actually think this is great that someone had the courage to write this out and ask this, as the Elixir marketing copy does not explain this well, Elixir people already think Elixir is special, and more people using Elixir is a good thing.

As it turns out though, the quality of the Elixir marketing copy cannot be fully explained by the writing talent of whoever wrote that copy, as articulating what makes Elixir special is actually quite difficult, in my opinion for one reason: Elixir is genuinely novel. It really is different enough from almost everything else that - in a rather circular way - comprehending its difference is difficult until you actually know it.

I consider Elixir to be novel because Elixir is actually a higher-level language than most other languages, and in a rather unique way.

I'll try to explain by way of a metaphor.

Java is a higher-level language than C, but Java was not universally hailed by C programmers on arrival. Of course some liked it, but many had reactions like this: "I am an expert C programmer. I have spent years of my career mastering the skill of manually managing memory. Why do I need slow, clunky Java?"

And people tend to react to Elixir similarly. My hypothetical Elixir equivalent goes like this: "I am an expert Ruby/Python/JS/etc. programmer. I know how to use the concurrency features - like threading and promises and callbacks - in my single-threaded language. Why do I need Elixir?"

Maybe now you can see where this is going.

On introduction, Java was not higher-level than C because it gave programmers new features. It was higher-level because it freed programmers from having to care about something of huge importance and difficulty, namely memory management.

Similarly, Elixir is higher-level than almost everything else not because Elixir gives programmers some incredible features (though it does! - but that's for another post), but because Elixir frees you from having to think about blocking IO and blocking computation and one thread of execution potentially stomping on another.

Just as how with Java the JVM manages memory for you, in Elixir, you write regular, boring, synchronous code that runs computations and does IO, and the Elixir VM (known as the BEAM) figures out how to properly schedule work so that multiple different threads of execution can run in a single instance concurrently, without blocking each other or crashing each other.

This is possible because the closest technical metaphor for Elixir that most people already know is actually that of the operating system itself. One of the main jobs of an operating system is to ensure that all running processes have fair access to the limited CPU, memory and IO of the system. This is exactly what Elixir's VM does, and other language VMs do not do. Elixir's VM observes all of the different pieces of code that it is running, and preempts them as necessary to ensure that all code running in the VM has fair access to resources like CPU and IO. There are a ton of benefits to this, but chief among them is that this is transparent to the programmer! The Elixir programmer does not have to write special code to say when something is preemptible, or when to take or release a mutex, or to annotate a function as being "async", or to note that this IO is blocking but this IO is not. Elixir handles this for you.

This is what makes Elixir special.

]]>
Mistake: too many choiceshttps://zeroclarkthirty.com/2022-07-30-mistake-circular-buffer-library.htmlSat, 30 Jul 2022 00:00:00 +0000A few years ago I wrote a library that provides a circular buffer (also known as a ring buffer) in Elixir.

I wanted one for something (I can't remember what!), didn't see one in Elixir, and wrote one. It works well enough, has decent test coverage, and is about as performant as you could expect from a pure Elixir implementation.

I made a big mistake in writing the library, though. I asked too much of users.

The library, cbuf, has not one but three different implementations of a circular buffer: one backed by Erlang's built-in queue, one by Elixir's Map, and one by Erlang's ets tables.

My thinking at the time was that, since it was possible to make the API of cbuf basically the same for all three variants, users could choose the backing datastructure that best fit their needs.

In theory, this sounds great. Who doesn't love choice? In reality, circular buffer performance is almost never a bottleneck at the application level, and so most users never actually need to be able to swap backing datastructures. Forcing users to know and choose which circular buffer implementation best fits their use case is unreasonable, both because users probably don't know the inherent performance tradeoffs between queue, Map, and ets, and because users likely don't know how the performance of cbuf will affect their program as a whole, so they have no basis against which to compare these different implementations.

This is not to say that there aren't performance differences between the three implementations. The main difference is that circular buffers backed by queue and Map are regular data structures in the Erlang/OTP runtime that use regular, in-process memory, whereas the ets implementation is backed by an off-heap ets table.

Where this can matter is that queue and Map are subject to the whims of process garbage collection, while in Erlang/OTP, ets tables occupy a separate region of memory that is not garbage collected in the same way as regular processes. In certain circumstances, it can make sense to put large or long-lived data in an ets table where accessing it will not interfere with (or be interfered with) normal process garbage collection. It also makes sense to use ets for data if you know that many processes are going to be accessing that data, as reading the data out of the ets table does not bottleneck any process other than the process doing the reading.

If I were to make cbuf again today, I would get rid of the option to have multiple kinds of backing storage and build a single implementation that uses queue. queue is built-in to Erlang, is very mature, and is fast enough for most use cases. I might consider writing the library in Erlang and providing an Elixir interface so it can be easily called from both Erlang and Elixir. If it became necessary in my application or in a user's, I would consider a separate library (rather than just a different module in the same library) backed by ets storage. Since I wrote cbuf, I've written a fair amount of Rust, as well as a few NIFs written in Rust, and feel confident that I could make a circular buffer NIF that takes advantage of one of Rust's main differences from Elixir/Erlang: mutable memory. This would be another option, but I wouldn't lead with this implementation, as it is probably more exotic than almost every Elixir/Erlang application would need.

My main takeaway is that forcing your users to make such a choice where the outcomes are only marginally differentiated is poor design. If the outcomes of various choices doesn't differ that much, then the freedom isn't worth the cost.

]]>
It's not about youhttps://zeroclarkthirty.com/2022-07-22-it's-not-about-you.htmlFri, 22 Jul 2022 00:00:00 +0000I just read this post and its HN thread. The post explores some of the things the Zig language does different than Rust, and how the appeal of Zig differs from that of Rust.

My issue isn't with the post itself, which explores the real differences and appeals of Rust and Zig well enough, but rather the HN comments, which are honestly pretty awful and indicative of what I find to be a corrosive mindset unfortunately too widespread among developers.

Let me explain. Among the class of chattering HN developers (the linked thread includes a representative sample but there have been many examples lately), we seem to have turned a corner from "Rust is very exciting! This is going to prevent so many bugs!" to "Rust is sooooo complex, it's basically worse than C++ at this point".

These "Rust sour Zig sweet" threads have almost universally devolved into developer navel-gazing about how a tool makes them feel. Common examples recently include things like these (I am paraphrasing rather than quoting directly):

- "Zig is so small that I can totally understand it, and I love that"
- "I am so much faster with Zig"
- "Rust just makes me feel dumb"
- "I spend so much time fighting the borrow checker and it slows me down"
- "Rust just so big"

Now, these claims aren't really provable in a real way, at least not in any way that I've seen. Sure you can count lines of code, or PR's closed, or contributors, or something else, but these comments are really just reports about how developers feel about using tools.

And these perceptions are valid! And they do matter. Everyone is entitled to their own perception about tools. We are entitled to use and discard tools as we see fit, to the extent that professional circumstances allow as much. And perception, insofar as it affects our ability to be motivated and continue to do productive work, does affect users. The Rust community certainly understands this, and works tirelessly to make Rust and its tool ecosystem more developer-friendly (see Cargo and Rust's continually improving error messages for evidence here).

But we, as a community, wildly overvalue these perceptions. Especially lately.

Most surprising to me, and the reason why I am writing this post, is that what I don't see in these threads - almost ever! - is anyone talking about the effects these tools have on users. You know, the people who actually use the software we write. About what it's like to be a user who gets owned by a memory corruption vulnerability. About what it's like to be a user of a product that crashes substantially less or runs much faster since it was rewritten from Python to Rust.

This sucks! The conversation sucks, the attitude sucks, all of it. We spend so much time talking about how our tools make us feel that we forget the reason we make software in the first place.

Maybe I'm old-fashioned or something but I think users should matter more than developers. Users shouldn't have to put up with slow software. When users use our software, they shouldn't be fearful that their private information is going to be stolen because our code got owned by a class of exploit that has been well-understood for more than 30 years. They shouldn't worry that the product is going to crash and lose their work. Users should have reasonable confidence that the developers of a piece of software have made significant effort to ensure their safety and productivity.

Rust may or may not be something you love or respect or use, but Rust is the first relatively-widely used language to achieve memory safety without garbage collection. Rust in 2022 is not Rust in 2014. It's no longer a hot new thing that might have legs someday. It's out there in the world. Real companies like Microsoft, Amazon, Mozilla, and many others are doing real things with Rust, because they believe it helps them write software that makes their users more secure and more productive. You're probably running Rust code right now, and that's not because of the "Rust Evangelism Strikeforce". I feel like I'm on pretty strong footing when I say that "Rust works".

I don't say all this to opaquely knock Zig by comparison, or something. I think Zig has a ton of interesting ideas and we would all be better learning from what the Zig community has accomplished so far. But let me reinforce my point: users don't care what language software is written in! If they get owned, users don't care that you could keep all of Zig (or C, or whatever) in your head, or that Zig felt fun and productive. Users don't care that memory-safety and data-race bugs in your language should be rare "in theory". Users care if someone walks away with their Social Security Number, credit card details, or personal medical history. Users care if the software does its job.

I am not saying that everyone should use Rust, but damn, I wish developers gave half as much of a shit about the security and productivity of their users as they did about whether or not they enjoyed writing the code that got their users owned.

]]>
Diffing CSV with SQLitehttps://zeroclarkthirty.com/2022-06-10-diffing-csv-with-sqlite.htmlFri, 10 Jun 2022 00:00:00 +0000Say you want to diff two CSV files, like these:

$ cat 1.csv 
id,name,fav_color
1,bill,blue
2,sue,red
3,abe,green

$ cat 2.csv
id,name,fav_color
1,bill,blue
2,sue,red
4,ali,orange

How do you do it? The most straightforward way would be to use diff, like this:

$ diff 1.csv 2.csv
4c4
< 3,abe,green
---
> 4,ali,orange

diff works great, especially in the simplest case.

You can also use SQLite, like this:

$ cat diff_csv.sql 
with left_diff as (
    select * from left except select * from right
), right_diff as (
    select * from right except select * from left
)
select *, 'left' as which from left_diff
union all
select *, 'right' as which from right_diff;

$ sqlite3 \
    -cmd ".mode csv" \
    -cmd ".headers on" \
    -cmd ".import 1.csv left" \
    -cmd ".import 2.csv right" < diff_csv.sql

id,name,fav_color,which
3,abe,green,left
4,ali,orange,right

This does a few things:

  1. Puts SQLite into CSV mode so it can load CSVs
  2. Turns on headers, so they show on output
  3. Creates the table left and imports the file 1.csv into it
  4. Creates the table right and imports the file 2.csv into it
  5. Runs diff_csv.sql

This might seem a bit more complicated than just running diff, but it gives you the entire power of SQL. You can decide which columns you want to diff on, or only diff certain subsets of each file, easily. You might add new rows inline. You can transform the diff'd results into something else, or summarize them. Maybe you want to diff 3 or more CSV files. No problem. There's a ton of power you get over doing it all in text, and using grep/sed/awk. You're only limited by your knowledge of SQL.

]]>
JSON diffing with SQLitehttps://zeroclarkthirty.com/2022-05-21-JSON-diffing-with-SQLite.htmlSat, 21 May 2022 00:00:00 +0000(Note: see the bottom of this post for the code and example data)

I wrote a small SQL script using SQLite that is capable of comparing a collection of JSON objects and rendering their differences as a SQL result set.

It is capable of detecting and reporting additions ({"a": 1} -> {"a": 1, "b": 2}), deletions ({"a": 1, "b": 2} -> {"a": 1}), and mutations ({"a": 1} -> {"a": 99}).

There are other ways to do this, but:

  1. I have a growing collection of JSON objects already in a SQLite database at work and wanted to see how they were changing over time
  2. I don't think the traditional UNIX diff-style textual diffing makes sense for structural/tree-style data like JSON
  3. Most of those solutions operate on diffing only 2 JSON objects instead of (potentially) a large series of JSON objects
  4. I haven't seen a JSON diff program that used SQL or SQLite and wanted to see if I could write one

It should be pretty easy to adapt this script into a CLI of some kind, as it's pretty easy to have SQLite run SQL on the command line.

Is it well tested? No. Is it production ready? Probably not. Are there bugs? Very likely.

But, it seems to work fine for simple objects and should serve as a decent jumping-off point for anyone looking to understand how a collection of JSON objects has evolved over time.

]]>
What Languages Taught Me: AWKhttps://zeroclarkthirty.com/2022-04-28-what-languages-taught-me-awk.htmlThu, 28 Apr 2022 00:00:00 +0000I didn't learn AWK (or, awk) until recently.

This past Decemeber, I decided to try the Advent of Code challenges in both Rust and awk. Rust I already know well enough to where solving word problems is not a task I would expect to learn much from, but awk I really didn't know at all.

I came away with the impression that awk is really an amazing, overlooked language.

Maybe the key thing about awk is just how little of it there is. Awk is a tiny language. If you're already a programmer, you can become useful with Awk in an hour or two.

The entire point is to process text streams by matching lines of text against patterns and taking actions based on what matches. That's basically it.

Awk is so devoted to this task that it does away with a traditional "main" function. Instead, code in awk is run through an implicit main loop, basically consisting of the following:

  1. Before processing any input, run any code in BEGIN statements.
  2. For every line of input in turn, attempt to match the line of input against each match expression in the awk program. If a match expression matches that line of input, run the statement corresponding to that match expression. Multiple expressions can match a given line of input, and matches happen one after another, in order.
  3. When the input is exhausted, run any code in END statements.

This loop isn't exposed to you explicitly, it's just the water you're swimming in. If you're coming from a traditional language, this seems restrictive, but really, it's freeing. This is just how awk is.

Awk can process any text, but it really shines on line-oriented, tabular, "record"-style data.

Assuming our data looks like the following tab-separated example:

1   "Bill"  20
2   "Steven" 3
3   "Hannah" 9
4   "Steven" 14
5   "Emily" 13

Our awk might look like this:

# This will run before any input is processed
BEGIN { print "Starting report!" }

# If the first column of input is digits,
# increment an entry in an array with those digits as its key.
# The array does not have to be declared, it is automatically created as
# it is used.
$1 ~ /\d+/ { numbers[$1] += 1 }

# If the text in the second column matches "Steven",
# add the contents of the third column to a new entry in the
# `stevens_payments` array.
# Again, the array and the `stevens_payments_len` variable are
# automatically initialized on use (numbers with a default value of 0),
# and do not have to be explicitly created.
$2 ~ "Steven" { stevens_payments[$1] = $3 }

# When there is no more input, this block will run.
END {
    print "Tallying complete!"
    print "Steven's payments:"
    for(payment_id in stevens_payments) {
        total += stevens_payments[payment_id]
        print payment_id, "\t", stevens_payments[payment_id]
    }
    print "Steven's total payments amount: ", total
}

and would print:

$ awk -f example.awk example.txt
Starting report!
Tallying complete!
Steven's payments:
2        3
4        14
Steven's total payments amount:  17

Notice how there is no main loop, no declarations, nothing. Notice how I'm not doing any string splitting to identify the fields within a line: awk takes care of that for you, automatically assigning each whitespace-delimited field to a corresponding $1-$N "magic" variable.

With awk, you just say what you're looking for in the input, and if it matches, the corresponding blocks get run. It's really amazingly ergonomic for blasting through a textfile, pulling out the stuff you care about, and transforming it or aggregating it in some way.

(I'm glossing over a lot, so if you want to actually learn awk, go here.)

Awk taught me that the space for specific languages for specific tasks is rich and unexplored. It seems like every language these days is a general purpose language on a general purpose virtual machine, with some tweaks to the typesystem or syntax. Awk never tried to be a language for everything, and here it is, 45 years later, still unsurpassed in its niche.

]]>
What Languages Taught Me: Rubyhttps://zeroclarkthirty.com/2022-04-23-what-languages-taught-me-ruby.htmlSat, 23 Apr 2022 00:00:00 +0000Ruby is a landmark in my programming languages journey because it is the first language I knew worth a damn. I had used other languages before, like TI-BASIC, HTML, Javascript, and a bit of Python, but only really to tinker with. It was the first language that I made money with and the first language I used to ship anything to real users, so in that way it really was among the first languages I used enough to understand in any depth.

The biggest ideas in Ruby, according to my own reading of the consensus of the Ruby community, are "programmer happiness" and pervasive object orientation. I saw something else, though.

I remember learning Ruby in 2013/2014 and being enthralled with a feature called "blocks". In almost every other language, they're known as "higher-order functions" or "closures", but Ruby did the characteristically Ruby thing and gave them a name only used in Ruby.

The idea of blocks is that you have a function that itself takes another function (a "block") as an argument. This allows callers of the function to vary its behavior by passing different blocks on each call.

For example, if we define a function map like this, that iterates over a given collection and yields each element of that array to a block, collecting and returning their results, we can pass different blocks to it, altering its behavior by doing nothing more than passing a different block each time we call it:

def map(list)
  results = []

  for element in list do
    new_element = yield element
    results << new_element
  end

  results
end

puts map([1,2,3]) { |el| el * 3.5 }.inspect
#=> [3.5, 7.0, 10.5]
puts map([1,2,3]) { |el| el.to_s }.inspect
#=> ["1", "2", "3"]

The definition of the map function stays the same, but we made it so each call does something different, with the first call multiplying each element by 3.5, and the second making each element into a string.

This is a powerful idea because it allows for the design of code that is wildly general. You can define a single function like the above map, deferring the details of "what it should actually do" until you know more about what you're trying to achieve in your program.

When I first learned Ruby, I was enthralled with this idea. Tons of functions in the standard library took blocks, like each, find, filter, reduce, and many others. This method of working with collections was so different from what I had seen before, in TI-BASIC or the kind of Javascript that was common at the time, where you typically traditional for or while loops that use indexes to access collections. You just say what you want to happen to each element in your block, and the rules of the host function define what happens with the result. It's really elegant.

I haven't used Ruby in years, but I've used first-class functions - as they're known in almost every other language - in probably a half-dozen or so more languages. They've become a foundational piece of how I think about programming. Due to the ubiquity of its blocks, Ruby really set me down the path toward functional programming - with Clojure and Scala - and profoundly influenced my taste in programming languages.

]]>
Faster Elixir map datastructure creationhttps://zeroclarkthirty.com/2021-11-29-elixir-maps.htmlMon, 29 Nov 2021 00:00:00 +0000UPDATE: Map.new is another great choice, as it also uses :maps.from_list internally, showing the same performance as Enum.into. Thanks, Shane for the tip!


Elixir and Erlang share a great map datastructure. It's an associative datastructure of keys and values. It looks like this:

%{a: 1, b: true, c: [821.99]}

Sometimes you'll want to create a map from another collection of things. One common way to do this would be like so, building up the map one key-value pair at a time, using Enum.reduce.

kvs = [{"a", 5}, {"x", 9194}, ...]
Enum.reduce(kvs, %{}, fn {k, v}, acc -> Map.put(acc, k, v) end)

There are other ways to do this in Elixir. Using the following code, we build a list of key value pairs, and then pass them to the Erlang function :maps.from_list, which converts the list to a map.

# imagine we didn't build this input list ourselves, as is possible in real-world code
kvs = [{"a", 5}, {"x", 9194}, ...]
Enum.reduce(kvs, [], fn pair, acc -> [pair | acc] end) |> :maps.from_list()

Another common way is to use Enum.into, which is designed specifically to convert one collection into another. It looks like this:

kvs = [{"a", 5}, {"x", 9194}, ...]
Enum.into(kvs, %{})

So which to use? I recommend using Enum.into, for a few reasons. The first of which is that, in its 2-arity form, it's less powerful. It does a collection to collection translation (say, list to map) and nothing else. There is also a 3-arity form that allows you to pass a function that serves as a mapper, transforming each input element before inserting it into the map, giving the same transformation power as both Enum.reduce versions above.

The second reason is performance. I did some simple benchmarking and found that on larger inputs (>=10,000 pairs), of the three variations (reduce/map, reduce/list, and Enum.into), reduce/list and Enum/into are between 2x and 2.5x faster than calling Map.put in a reduce loop.

Digging deeper, I checked out the Enum.into source code, and the reason Enum.into is faster is because it actually calls :maps.from_list if it can determine that the target collection is a map!

So, I recommend using Enum.into: its API is simpler for simple cases, powerful enough for those you need to transform, and automatically specializes to use fast Erlang built-in functions (written in C, rather than Erlang or Elixir) when it determines that it can.

]]>
Know your input - optimizing large JSON processinghttps://zeroclarkthirty.com/2021-11-24-jindex-allocation-sizes.htmlWed, 24 Nov 2021 00:00:00 +0000Recently, I was doing a little work on one of my programs, jindex, and learned a bit about properly sizing datastructures for the data they will actually hold.

A bit of background

jindex is a small library and binary that enumerates the possible paths through a JSON document. For example, given this JSON document:

{
  "a": 1,
  "b": 2,
  "c": ["x", "y", "z"],
  "d": {"e": {"f": [{}, 9, "g"]}}
}

jindex emits:

json = {};
json.d = {};
json.d.e = {};
json.d.e.f = [];
json.d.e.f[2] = "g";
json.d.e.f[1] = 9;
json.d.e.f[0] = {};
json.c = [];
json.c[2] = "z";
json.c[1] = "y";
json.c[0] = "x";
json.b = 2;
json.a = 1;

For any given value in a JSON document, jindex says "here is how you get to that value".

(You can also emit the paths as JSON pointers.)

I've been working on jindex for a couple years. It started in response to a problem I had at work - we were processing JSON payloads representing machine telemetry data that were so large that they were impossible to understand just by looking at them in an editor - and continued on as a project to better understand Rust, optimization, memory, etc.

A big theme of my work on jindex has been that it has to be fast, or it isn't useful to me (or anyone else), so to that end, I've spent a lot of time tinkering with its performance and trying to understand why it performs the way it does. It has gotten much faster over the years as I have learned more, and I continue to look for new ways to make it faster still.

A weird cliff

Recently I was tinkering with jindex, and I noticed a new quirk with the size of allocations. jindex calls the leaves of a JSON document "values" and calls the way you reach those values "paths". So the composite is called a "pathvalue". For example, json.b = 2 is a pathvalue, with b as the path and 2 as the value.

In Rust, it looks like this:

pub struct PathValue<'a> {
    pub value: &'a serde_json::Value,
    pub path_components: Vec<PathComponent<'a>>,
}

path_components is a vector that is dynamically sized. That is, we do not know its size in advance. Its size is linear with the depth of a given value inside the source JSON document. So, for the above example, json.b = 2, it would be a Vec of length 1, but if a value were 99 levels deep in a document, it would be a Vec of length 99.

I was messing around with preallocating the path_components vector by calling Vec::with_capacity rather than vec![] (which does not allocate until you push a value into it), and passing successively larger values to with_capacity, i.e.: starting capacities of 1, 2, 3, 4, 5, etc.

For my usual test input data (a ~200MB JSON document), I noticed a speedup when the starting vector size was set to 6. The runtime continued to be faster with size 7, 8, 9, and 10, before returning to the normal runtime with size 11.

As you can see below, it's a bit of a weird "cliff" type of behavior, taking only 84% of the normal runtime (about a 300-400ms speedup) when the starting vector size goes from 5 to 7.

Why

These results surprised me.

When your program runs in ~2 seconds on a ~200MB input, a 300-400ms speedup is pretty notable, so I wanted to dig further.

Why should it matter if the starting allocation size is 5 or 6 or 7? Why would that result in a faster runtime? So I measured the size of the paths throughout the input JSON, and found that any given value in the input is slightly more than 6 levels deep, on average. But Rust - the language jindex is written in - does not know this.

In Rust, vectors start with a size of zero, and their capacity doubles when they need to reallocate more space. Note that this strategy is not officially guaranteed, as Rust only guarantees that pushes to vectors take amortized O(1) time, but the strategy is known via the implementation itself.

So, because the average value depth is just slightly larger than 6 in this input document, and by starting the path_components with a size of between 6-10, jindex was able to avoid a ton of allocations by avoiding the need to resize vectors as they grew from 0 to 1 to 2 to 3 to 4 paths and so on.

This ended up being beneficial to runtime because allocating memory is not free in terms of wall-clock time, and can really add up if you do it a lot. It takes time for the language runtime and kernel to do their dance to find free space to claim for your requested memory allocation.

Resulting changes

The above result was a cool discovery, but it wasn't immediately generalizable. I can't set the starting capacity of the path_components vector to some magic number like 7 and call it good, because path_components depends on the path depth of the input! If we were given a JSON document that was just one huge, flat object with millions of keys that were all strings, numbers, booleans, or null, the average path depth would be 1, and jindex would give each of these paths a vector of size 7 only to use a single slot of that 7-length vector, wasting a ton of memory.

Conversely, if the document was a series of huge, nested objects 25 levels deep, then setting the starting capacity of path_components to 7 would leave us exactly back where we started, relying on Rust to adjust the allocated capacity of our vectors as they progressively overflowed as the objects got deeper.

So, what I ended up doing was to implement a dumb dynamic sizing strategy.

Instead of starting all path_components vectors at size 0 and letting Rust gradually resize them, causing reallocations, I had jindex keep a running average of the actual size of the path_components vectors it has already processed, and initialize vectors with a size of whatever that running average happens to be, rounded up to the next highest whole number.

So, over the runtime of a given invocation of jindex on a given input document, the starting capacity of all path_components vectors will trend toward whatever the actual average size of path_components vectors happens to be, meaning that jindex will progressively adjust the size of the initial path_components allocation in order to better match the size of the input data.

The overhead of this calculation is low, amounting to 3 integer additions and 1 integer division on machine-sized integers per PathValue, which is more than made up for by the number of memory allocations saved on large documents.

Takeaways

This was a fun one! I learned more about how knowing more about your input data can help guide your programs to make smarter, more mechanically-sympathetic assumptions about what kind of work is worth doing, and got a double-digit percentage speedup for jindex in the process.


Try jindex

If you want to try jindex yourself, you can install it like so:

Latest stable release from crates.io:

$ cargo install jindex

Latest unstable (HEAD) release from source:

$ cargo install --git https://github.com/ckampfe/jindex
]]>
Types are about whole-program informationhttps://zeroclarkthirty.com/2021-11-01-types.htmlMon, 1 Nov 2021 00:00:00 +0000The debate about types is kind-of played out, but I think that's mostly down to perspective, and the way we talk about types as tools. "Types help me make fewer mistakes!" or "Types get in my way!" Both of these sentiments are common and both are true in their own way, but they are looking at the problem from a localized "my workflow" view.

A typechecker is a collection of rules. You run your code through these rules, and it either conforms with the rules or not. You write code, annotating the "do real work" bits of your code with a sub-language ("types") that the typechecker understands, and when you do this, you get answers back about if your code abides by the typechecker rules, and if not, why not.

This has costs. You pay in time spent adding the type annotations. You pay in compile time. You pay in time spent trying to understand compiler errors, and trying to understand why something doesn't compile. As an organization, you pay in time spent training people on these tools, and time spent waiting for them to ramp up in productivity. You have to live under a cold, mechanical regime that doesn't care about your deadlines or how long you've been working on this piece of software or whatever else. You have to pay these costs in order to participate in the typechecker.

But in exchange for this cost, you get some benefits.

The typechecker doesn't just check your own code. It checks everyone's code. This is crucial: it is a global tool. In order to build and run your project, all of the code must typecheck successfully. This includes your code, your coworkers' code, and the code for all the dependencies you use in that project.

You and everyone on your team gets information about how their code fits together, whenever they want, as many times as they want, for any changes they make, and they get it globally, now and in the future, for all of your code and your dependencies' code.

You can think of the constraints a typechecker imposes as being like the rules of the road, in a way: you have to pay to build and maintain roads, and roads have certain laws to ensure their safety and continued operation, but once they are built, driving becomes much more predictable than attempting to drive across muddy, untamed countryside. You are giving up some local freedom (the freedom to drive with no rules at all) in exchange for a higher-order freedom (you can now drive and navigate much faster, easier, and more reliably).

As far as I can tell, Rúnar Bjarnason has the best talk on the subject that really digs in to the theory of this kind of composition tradeoff. This talk is one of my favorites and I think it should be required viewing for people in the industry.

Now, in fairness, typecheckers don't say anything about whether the types you've used to model your domain are any good, whether your typesystem itself is actually useful, whether you've solved the right problem, hired the right team, or anything else, but what does? On this point, I think static typing detractors usually undersell their usefulness, especially when it comes to the kind of programming people do in teams over longer periods of time, which is dominated by maintenance, tweaks, little feature additions, refactorings, security patches, and that kind of thing.

I do think that some of the criticism that dynamic typing proponents make of types hits home, though. Some communities - the functional programming communities, in particular - have really sold types poorly, presenting typed programming on the basis of correctness and proof, when the real wins to be had are about increasing our ability to understand our own systems. Proof and correctness are noble values and ought to be pursued, but not, I think, at the expense of a more general kind of engineering utility and intelligibility.

I'm still bullish, though, particularly when comparing typed vs. untyped programming on the axis of time: most load-bearing software in the world has been around for a while, and needs to be around for a while more, because people still depend on it! Most of the software doing useful stuff in the world cannot be called "greenfield". Everyone's experience will be different, but most of my career has been an exercise in "hey, modify this existing thing in some way".

I have worked on greenfield projects, but the actual greenfield phase of the project, where you're just slamming out code until the thing works at all, only lasts a few months at most. Once that's over, you have users, you have expectations, you have maintenance. At that point, what you want is to understand your system as holistically as possible. Your ability to write code as quickly as possible is no longer the thing holding back your organization. Your ability to understand how your system interacts with itself matters much more.

Personally, I'm not going to stop writing dynamically typed code. There are some really great, productive dynamic languages out there (I love Elixir in particular), but for code that has to last any length of time, I think that constraining ourselves to the subset of programs that can compile under a reasonable typechecker is a productive restriction, like an artist limiting their pallette to fewer colors intentionally, or an aircraft designer limiting themselves to the subset of aircraft designs that are aerodynamically stable. Not all constraints are actually limiting.

Of course, typed programming is just one way of understanding how a system interacts with itself. There are other ways to approach this question, but discussing those ways probably deserves its own post, and I wanted to write about types.

]]>
How to collapsehttps://zeroclarkthirty.com/2021-07-05-fukushima.htmlMon, 5 Jul 2021 00:00:00 +0000I just finished reading ON THE BRINK: The Inside Story of Fukushima Daiichi. Aside from being well-researched and technically interesting, it was also emotionally wrenching in a way I didn't expect. Many of the people involved in the operation to save the plant (and Japan itself) carried out their duties knowing that they could - and as the situation seemed to indicate at many points, likely would - be killed.

What happened at Fukushima Daiichi was a genuine disaster, with many killed and a great deal of devastation that remains to this day. And yet, it is a miracle that it was not even worse. Of course, miracle is not the right word. Humans managed the disaster from the beginning, with a huge amount of effort expended prior to, during, and after the disaster. It is only by their cleverness in planning and determination during the worst of things that Japan itself remains inhabitable.

Having read this book, and other writing about this and other disasters, it's difficult to come up with general axioms for avoiding catastrophes like what happened at Fukushima Daiichi.

Simply asking, "How can we avoid nuclear (and other) disasters?" is daunting. The failure modes are so many, so varied, and so interdependent, that it is hard to know where to start.

The universe does not know about us, does not care about us, and is sufficiently unpredictable that designing systems capable of thriving despite its volatility will remain difficult for as long as we humans exist.

However, taking a Mungeresque reverse perspective is one possible way to crawl in the right direction.

For example, based on some of the examples from the Fukushima Daiichi disaster, we can perform the thought experiment in reverse, by asking questions like, "How would you destroy a nuclear plant like Fukushima Daiichi?"

Contrary to asking directly how we might prevent a disaster in the abstract, this question is much easier. There are many, many things one could do to make operating a large-scale nuclear power generation facility more failure-prone, and many of them don't take much cleverness to come up with. By thinking of how to make something fail, we can start to imagine how we might make it more resilient.

The following list includes my layman's thoughts of how one would operate a nuclear plant if fragility was the goal, based on my reading of ON THE BRINK: The Inside Story of Fukushima Daiichi:

  • Assume the scale, frequency, and origin of future external threats (i.e., climate, geology, security, etc.) will remain the same as they were previously.
  • Ensure an unclear chain of command. Even better, negotiate the chain of command during the crisis itself.
  • Interrupt the work of frontline workers, as in the case of the Prime Minister visiting the site.
  • Assume regular control interfaces (monitoring, reactor control inputs, valves) will work as before.
  • Assume regular internal communication channels will be operational.
  • Assume you will not need external supplies, equipment, personnel, or capabilities generally. In other words, assume you will be able to maintain complete self-sufficiency.
  • Assume the relative importance of capabilities will remain the same as before the crisis. For example, assume that a typically unimportant portable diesel generator will remain unimportant in a crisis.
  • Design your systems such that they require positive control input to remain in a stable state, rather than self-stabilizing/shutting down if no input is received. See also dynamically unstable systems.
  • Keep frontline workers and managers in the dark: ensure that information only flows upward.
  • Assume crises will be shortlived. Stock only small numbers of consumables like radiation-proof suits, respirators, batteries, etc., in reserve.
  • Assume crises do not interact. For example, assume the failure of one nuclear power plant will not affect the operation of a separate nuclear power plant miles away.
  • Be optimistic and assume the best: trust and do not verify reports you hear about certain capabilities operating normally, i.e., diesel generators remaining operational, radiation levels remaining low, etc.
  • Count on the competence and heroism of single, isolated individuals. Assume they will not get hurt, lost, confused, tired, demoralized, panicked, and will always be able to perform their duties as before.
]]>
COVID-19 Log #8https://zeroclarkthirty.com/2021-01-19-covid-19-8.htmlTue, 19 Jan 2021 00:00:00 +0000
  • COVID-19 has killed nearly 400,000 people in the United States so far.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2021-01-19-potus-notes.htmlTue, 19 Jan 2021 00:00:00 +0000
  • Riotors, incited by President Trump, overran security and invaded the U.S. Capitol building.
  • ]]>
    Software Cost, Software Maintenancehttps://zeroclarkthirty.com/2020-11-08-cost.htmlSun, 8 Nov 2020 00:00:00 +0000Recently I read a post about Rust vs Go.

    I don't want to discuss the specific argument of Rust vs Go here as it's actually pretty boring, but one section - the section on correctness about 3/4 of the way through the article (especially the pullquote) - got me thinking on the topic of cost. This is the quote:

    "My take: Go for the code that has to ship tomorrow, Rust for the code that has to keep running untouched for the next five years."

    In my career so far, I've worked in three shops, all on different kinds of products and environments: one a loyalty program startup, one a "startup within a Fortune 500", and one a startup building an on-demand manufacturing platform.

    Across those jobs, I've written and maintained code that ran in production in Ruby, Elixir, Javascript, Scala, Clojure, Java, Rust, bash, SQL, Python, and probably more that I'm forgetting. I've worked on webapps, command line apps, "big data" batch-job programs, real-time telemetry ingestion, 3D geometry processing, and some higher-level firmware for embedded devices.

    At every shop, for all languages and domains, the majority of effort, money, and time was spent on maintenance.

    Put another way: the most costly part of the software has been changing the existing software to better reflect new or different demands or environmental constraints, not getting the initial version working.

    I am not talking here of what Rich Hickey might term "problems of misconception", where we didn't know what we were trying to do in the first place, but the more typical kind of maintenance work: that of adding an entirely new capability, adjusting an existing capability to meet a new constraint, fixing something that is either incorrect with regard to a specification, or fixing something that is incorrect with regard to some runtime characteristic. This kind of work dwarfed the cost of writing the stuff to begin with.

    Most problems I've seen or heard of at jobs didn't require code that "has to ship tomorrow", even at startups with time and capital pressure. These did exist and I won't pretend otherwise, but they weren't typical, and their scope is usually narrow. Most code is either written new with the expectation to stick around for some period of time as an integrated piece of some other system, or code to adjust the behavior of an existing system. Most of the code that I've seen and the programs I've used in a professional capacity seems to obey a kind of Lindy effect where things that have been around for a while have a propensity to stick around.

    Existing software and code I've seen also has tended to have its "low hanging fruit" picked early, as one might expect: things that are easy and cheap to change are changed, and bugs that are easy and cheap to fix are fixed, leaving only progressively more difficult and costly changes and fixes. One reason for this, in my experience, is that my confidence in being able to change some piece of the system while preserving the other existing characteristics of the system decreases as the system grows and ages. The typical word for attempting to change one thing and accidentally changing others is "regression".

    Another reason for the increase in cost/difficulty of changes/fixes over time is due to the difficulty of deciphering where one piece or layer or feature of the system ends and another begins. That is, things are intertwined, or tangled. Different pieces of functionality tend to bleed into each other, and it becomes difficult to individuate characteristics of the system. People usually call this "messy", "unclear", "muddy", or "spaghetti" code.

    For these reasons I don't buy in to the framing presented in the quote at the beginning of this post. I think it inaccurately portrays software as something which we must create as quickly as possible, or something we create and then leave untouched for years at a time with no upkeep. Obviously the quote author is exaggerating for effect, but this sentiment is not far off from real attitudes I've seen out in the wild.

    For example, for many projects I've worked on, as well as many friends have worked on and then told me about, the name of the game was "get the thing built as fast as possible, cut corners if you have to, maybe we'll come back to it some day". This is basically strip mall software. Built as quickly as possible, using low-quality construction, poorly integrated into its community, with little to no planning for its future upkeep. Basically, it works, albeit barely, but no one really likes it, and we only put up with it because of its convenience and the apparent cost of a suitable alternative.

    There is another, different class of projects that seem to mostly work fine, but the prospect of changing them or fixing them so they work better appears too difficult or costly. You might call them "working but Byzantine." Kind of like the wiring in some old houses. They are precariously balanced, and if something were to go wrong they might come crashing down. These projects are dangerous, as it is unsafe to depend on something that you can't readily maintain or replace.

    Neither of these are sustainable ways to build or live, be for code or community.

    All this isn't to say that Go isn't a great language for writing code that has to ship tomorrow, or that Rust isn't great for long-running systems. Maybe Go and Rust are fine for those purposes. Either way, I don't see either of the quoted rhetorical choices as a realistic conception of software as I've seen it practiced, or as I believe it ought to be practiced by professionals or viewed by the general public. Maintenance is deeply human. It's something we have always done and something we will always do.

    We should evaluate tools for their ability to help us create and maintain software sustainably over time, so that our users can thrive. There exists enough "strip mall software" and enough working-but-Byzantine software in the world, and we should be suspicious of tools, mindsets, and people that try to sell us speed-of-construction cons or maintenance-free magic.

    ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2020-11-07-potus-notes.htmlSat, 7 Nov 2020 00:00:00 +0000
  • The Associated Press declared Joe Biden the winner of the presidential election.
  • ]]>
    COVID-19 Log #7https://zeroclarkthirty.com/2020-10-03-covid-19-7.htmlSat, 3 Oct 2020 00:00:00 +0000
  • President Trump, Melania Trump, Trump advisor Hope Hicks, Utah Senator Mike Lee, North Carolina Senator Thom Tillis, Wisconsin Senator Ron Johnson, Trump advisor Kellyanne Conway, Trump campaign manager Bill Stepien, RNC chairwoman Ronna McDaniel, University of Notre Dame president John Jenkins, and former New Jersey governor Chris Christie test positive for coronavirus.
  • President Trump is hospitalized at Walter Reed National Military Medical Center.
  • ]]>
    COVID-19 Log #6https://zeroclarkthirty.com/2020-06-15-covid-19-6.htmlMon, 15 Jun 2020 00:00:00 +0000
  • The total number of confirmed deaths in the United States due to COVID-19 is more than 115,000.
  • The outbreak does not appear to have slowed, as many states are reporting increased infection rates after reopening weeks ago.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2020-06-15-potus-notes.htmlMon, 15 Jun 2020 00:00:00 +0000
  • Protests have roiled the country since the police killing of George Floyd, in Minneapolis.
  • The Supreme Court ruled that employers can not discriminate against employees on the basis of LGBTQ identity.
  • ]]>
    Always coming back home to you - 3 years laterhttps://zeroclarkthirty.com/2020-06-11-always-coming-back-home-to-you-2.htmlThu, 11 Jun 2020 00:00:00 +0000Three years ago I wrote a post how, despite loving Clojure, I felt tempted by Scala.

    I tried to understand some of the problems facing industry, and why I felt Scala - or Scala-like languages - was well-situated to address those problems.

    It has now been 3 years. In that time, the languages I have written Elixir and Rust almost exclusively, both for work and for fun. I've written a small amount of Clojure, and no Scala.

    In the previous piece, I wrote:

    if you gave me 2 weeks off I'd probably pour it into Rust

    It turns out I did pour two weeks into Rust, and then I poured two more, and then months, and then (as of writing) almost 2 years. Since late 2018 I've written quite a good amount of Rust, for things like graphics programs, high-performance parsers, command line utilities, Webassembly modules, and TUI applications, and read a good amount of other people's Rust.

    This is something of an experience report on Rust, and something of an experience report on how well my assumptions in the previous post held up.

    First, Rust.

    Rust has become my primary language. It is at this moment, the language I would prefer to write for the rest of my life if I had to pick one. It is that good. I feel confident in making this claim given the amount of time I have been exposed to Rust, and the amount of Rust I have written. I feel like I am beyond the honeymoon period, so to speak. Of course I hope Rust is not the last language I use, but I would not be unhappy if it was.

    I like many things about Rust, but most prominent theme of Rust's that I appreciate is the actual execution of its ideas, which is to say "how well things work in practice". I will contrast this with the idea of design, meaning the intended function of something. Very nearly everything in Rust feels well executed, down to little details, and the misfires (like mpsc) are rare.

    The implementations of structs and pattern matching feel great to use in practice. Core language identifiers and standard library functions feel intuitively named. Common names are short and easy to type. Returns are implicit, but can be explicit. It uses curly braces but this doesn't feel oppressive. Types come after identifiers. It is always clear when to use a semicolon. The syntax for important things like borrowing and mutability is consistent and pervasive. The trait system brings over the useful parts of object oriented programming but leaves behind the crap like inheritance and classes. There are real tuple types for passing around an unnamed grouping of values, and they are nice to use. Error handling has had an incredible amount of thought put into it, with the ? operator representing an amazing ergonomic advance that ensures errors are correctly handled while reducing the code necessary to do so. Type conversion with the From trait and .into() is useful and predictable (unlike Scala's implicit conversions). The standard library implementations of data structures like HashMaps, BTrees, Vectors, etc., are all incredibly well done, with great performance characteristics for common cases. I could go on.

    If you take away the main novel features of Rust (ownership/lifetimes), everything else feels great to use. I will contrast this with Clojure, where things are beautiful but sometimes a pain in the ass to actually use in practice. In this case I'm thinking of Clojure features like the sets API, futures (and errors in them), core.async (threadpools, dead goroutines), transducers (much fanfare, not much use), and lazy sequences (incredibly common pitfall for new and experienced users alike), the REPL (state management of a running app is hard, and startup times are still awful).

    Outside of the language itself, the tooling is the best I have used. The package manager, Cargo, and the package repository, Crates, seem to reflect a few things:

    1. The creators of Rust highly value the experience people have when using these tools
    2. The creators of Rust have had ample prior experience with other language tooling

    Regarding #1, the tooling ecosystem does not feel like an afterthought. It feels like a thing that the core members know about and value. Tooling is first class. Problems with tooling are acknowledge. Advances in tooling are met with much praise, and tool-improvement is prestigious work. Regarding #2, the tooling is clearly designed with the reflection of the shortcomings of other tooling. There is one ecosystem-wide build tool - Cargo - in contrast to the plethora of C/C++ build tooling. The compiler provides ample feedback about where an error is, and how you might fix it, in contrast to build systems like those found in the Javascript community, for example. Builds are reproducible, in contrast to early JS build tools. There is not an explosion of environment nonsense, like in Python. The tools are fast, unlike in Java.

    Anyway, the point of this entry isn't supposed to be about the features of Rust that feel well-executed, nice as they are. In the previous piece, I listed out a few characteristics of software construction that I feel should affect our behavior and tool choices. They were:

    - most projects don't ship
    - maintenance is expensive
    - maintenance is a second or even third-rate duty next to building and architecting
    - most projects are not meaningfully maintained (see above)
    

    Three years later, I stand by these points.

    • most projects don't ship

    A great deal of projects do not make it to production or ever serve customers. I have personally been involved with many and heard of many more. It is always demoralizing when this happens, but it is a reality, and so we should adapt accordingly. If we know that most projects will not ship, we should try to minimize the sunk cost of early stage projects. It should be trivial to start something. It should be trivial to deploy something so that a user can interact with it. It should be trivial to distribute, so we can gain momentum and feedback as quickly as possible. Reading Rust in this context, it fares well: Cargo provides templates to create a new binary or library with a single command. These are always the same commands, and they always produce the same thing. Linking against a library is as simple as adding that library's coordinates to the Cargo.toml file. Deploying Rust is pretty good as well, as it provides (mostly) straightforward features for cross compilation, and the result is either a shared library for linking or a binary that can be directly executed like any other binary on any architecture capable of running that binary. Dropping a binary on a system is an old, well-known mechanism, and can be shoehorned into any number of existing build processes with little fanfare. No JVMs to setup, no Rubies to version, nothing.

    • maintenance is expensive

    Maintenance is still expensive, as adapting software to a changing world and fixing defects dominates the cost of any non-trivial software over time. I think this is really where Rust shows its value. Rust is a language clearly built for systems that, as Bryan Cantrill says, are "load bearing". Systems that do real work. Systems that must last years. System on which people depend. There are no silver bullets, but types help with this. In Rust's case, I feel they do this in a few ways. The first is that they ensure that calling contracts hold. When you change code, the compiler tells you if you have inadvertently done something that, in a dynamic language, would result in a name resoultion error, or a type error, or an error when calling a function with too few or too many arguments. Of course, this is not semantic correctness, as testing provides, but it is not nothing. And on larger codebases, it is very much something. I think dynamic language advocates minimize the confidence that comes from this contractual coherence unjustly. Knowing that your functions, arguments, and types all line up is a significant kind of confidence, as it means that is one less class of behavior you have to test at build time or validate at run time. This frees us up to use our testing budget on other, more important things like business-logic validation. This confidence, along with the confidence from other tools and practices, contributes to our willingness to change software. And this willingness to change software as it ages is the essence of maintenance.

    Another useful maintenance-enabling thing Rust provides is extension, through traits. Traits allow the gradual introduction of new behavior to datatypes that were not originally designed to exhibit that behavior. The requirement that a piece of data now partcipate in new behavior is an incredibly common aspect of maintenance, and it becomes much more costly to undertake if that piece of data is widespread, as the maintainer has to account for all of the potential interactions of the new with the old. Traits provide a mechanism to safely introduce new behavior to a piece of data in a way such that it coheres with all of the mechanical checking provided by the compiler, without having to destructively change any of the existing uses of that data. That dynamic languages are open for extension is an oft-touted benefit, and for good reason. Traits allow Rust to have a great deal of that dynamic flexibility while still remaining type, memory, and resource safe.

    • maintenance is a second or even third-rate duty next to building and architecting

    I've seen nothing to diminish my perception of this. Everyone wants to build new things, very few want to be responsible for changing a system they neither built nor understand. The downsides of most maintenance work are much larger than the upsides. Often, maintainers and product owners perceive a change to be small and quick, but we have poor tools for identifying the existing interactions a given change has with the rest of the system. The upsides are often hard to quantity, and appear to be vague and somewhere in the future, so we may not get to experience them ourselves. It is hard to quantity "it just works and will continue to reliably, predictably serve traffic for the forseeable future" on a balance sheet, or to a CTO who doesn't plan to be around in 2 years. I'm not sure Rust has technical features that address this, but that doesn't matter, as Rust has arguably done something more important by increasing the social standing of maintenance work. Rust is on its way to mainstreaming the idea that software should work predictably and reliably for years. In some ways, the mainstream software development community has given up on this idea. Most software sinks to the bottom of the ocean when confronted with tiny waves, and only the application of massive amounts of time and money prevent it from doing so more regularly than it otherwise would. Rust is making the argument - and in my opinion, backing it up with real-world examples - that software can be reliable, and it can be cheaper to maintain over time. This is contributing to the idea that maintenance is something worth doing in service of long-term reliability and value. It's hard to overstate how desperately we, the software community, need this message.

    • most projects are not meaningfully maintained (see above)

    This continues to be the rule, as the cost of meaningful maintence remains high, and the prestige of meaningful maintenance remains low. As such, software is not meaningfully maintained insofar is there is an almost universally greater aggregate of issues with existing software than there is time, money, and will to deal with those issues. I need to do more thinking about this, but it seems that Rust's main advance in the art of software is that it lowers the cost of maintenance and correctness. It follows that more software could be meaningfully maintained if we could lower that cost.

    We humans have proven over and over again that we are well adapted to identifying and reacting to near-term high-downside risks, and terrible at identifying and reacting to long-term risks with almost any amount of downside.

    In the previous piece, I wrote:

    No one develops software with an ability to feel what the software will be like to maintain in 5 years, let alone 6 months.

    We simply cannot base the 5 year view of what the software should be like on what it feels like right now. What feels good now does not have any bearing on whether something will be successful in 5 years. If we want something to be around in 5 years, we have to think about that case, and design for that case, specifically. Rust may just be the vehicle that mainstreams that longer-term view of software. If we look back on Rust in 40 years and it has done this even partially it will have been a wild, screaming success, on the order of C or Lisp.

    On a personal note, I have to say that coming back to Rust software I wrote last week, last month, last year, is more enjoyable than coming back to old Clojure code. While it's true that the Clojure code likely hasn't changed, I now find myself asking, is that because the Clojure code is so well done and so stable and so complete, or is that because I don't want to touch it, for fear of breaking it? It makes me a little sad to write that, as I still love Clojure, and think is probably the most novel language of the last 20 years, but I stand by the closing I wrote 3 years ago:

    I love Clojure to bits, but coming back to a Clojure project after time away can be a bit like blindly reaching into a box I've just opened after moving apartments: there might be something sharp in there.

    ~~Scala~~Rust makes this a little less scary.

    Postscript

    I realize I have not said much about Scala in this post. This was not really intentional, but in a way feels correct. Writing this post mostly about Rust feels like a roundabout partial validation of Scala. Scala and Rust are similar. Strong typing, strong polymorphism, with a focus on extension over time. They diverge in that Rust also focuses on performance, low-level control, and developer experience while Scala focuses on Java compatibility and novel, PhD-worth language innovation. I still like Scala, but I think Scala is in the unfortunate position of having to maintain Java/JVM compatibility in a world where that compatibility promise appears as an instant downside to anyone who doesn't want to go near the JVM. Scala, unfortunately, also has managed to collect a fairly academic and contrarian community, that has over the years allowed it to absorb a somewhat unfriendly, academic reputation. Whether or not this is literally true does not matter as the image appears to have stuck regardless.

    ]]>
    COVID-19 Log #5https://zeroclarkthirty.com/2020-05-11-covid-19-5.htmlMon, 11 May 2020 00:00:00 +0000COVID-19 has now killed at least 80,000 in the United States. Many top health officials have gone into quarantine after learning they came into contact with White House staff who tested positive for the virus. US unemployment is at nearly 15%, with approximately 20.5 million jobs being eliminated in the month of April alone.

    ]]>
    jindex - enumerating paths in large JSON documentshttps://zeroclarkthirty.com/2020-04-08-jindex.htmlWed, 8 Apr 2020 00:00:00 +0000A while back (a year ago?) I was debugging an issue on embedded hardware that dealt with processing large (megabytes) JSON documents. I was using jq to format these blobs, but it was difficult knowing where anything was, as the documents were so large and complex. I was tracing paths by hand to try to figure out how to access specific values in these huge documents, and it got tedious. I had the idea that you could compute the pathwise index for every value in a JSON document. A JSON document is a tree, so this is basically a tree traversal that shows you how to get from the root to every leaf. You could then grep for the values you were interested in, and the traversal paths would be shown to you for those specific values.

    I tried and failed a few times to write this tool, but ultimately succeeded in writing jindex.

    Using it looks like this:

    $ echo '{
      "a": 1,
      "b": 2,
      "c": ["x", "y", "z"],
      "d": {"e": {"f": [{}, 9, "g"]}}
    }' | jindex
    
    ["a"]   1
    ["b"]   2
    ["c", 0]        "x"
    ["c", 1]        "y"
    ["c", 2]        "z"
    ["d", "e", "f", 0]      {}
    ["d", "e", "f", 1]      9
    ["d", "e", "f", 2]      "g"
    

    By default, the path (on the left) is separated from the value (on the right) by a tab character. This is configurable with a command line option. Each path/value combination is separated from subsequent pairs by a newline.

    You can see that it does a breadth-first traversal, showing values at each level before moving deeper in the document.

    Let's say I am only interested in accessing the value 9, deeply nested under the "d" key. Combining it with grep looks like this:

    $ echo '{
      "a": 1,
      "b": 2,
      "c": ["x", "y", "z"],
      "d": {"e": {"f": [{}, 9, "g"]}}
    }' | jindex | grep "9"
    ["d", "e", "f", 1]      9
    

    Now you know that to access 9, you need to lookup ["d", "e", "f", 1] from the root object.

    There are a few other options but that's basicallly all there is to it.

    Internally, it makes use of a queue (rather than recursion) to perform the tree traversal, and reference-counted pointers to do structural sharing to minimize memory copying.

    You can download and find the source here.

    ]]>
    COVID-19 Log #4https://zeroclarkthirty.com/2020-03-31-covid-19-4.htmlTue, 31 Mar 2020 00:00:00 +0000The last day of a hellish month.

    It's weird to witness something historical in real time. You think it'll be energizing or awe-inspiring, but mostly it's equal measures dull, foreboding, and helplessness-inducing. More than 4,000 people have died, which seems at once so many and so little. We haven't seen the worst of it. So many more will die. The Trump administration estimates more than 100,000.

    Who are we, that treat essential workers like delivery drivers and warehouse pickers and nurses with such disrespect? Who are we, that deny healthcare to those unable to convince someone to give them a salary? Who are we, that demand a nation where more than 3.5 million filed for unemployment benefits continue to pay rent to landlords? Who are we, who mocked this as the flu? Who are we, who let this happen?

    ]]>
    COVID-19 Log #3https://zeroclarkthirty.com/2020-03-29-covid-19-3.htmlSun, 29 Mar 2020 00:00:00 +0000
  • There are more COVID-19 cases in the United States than anywhere else, with NYT reporting at least 81,321 confirmed infections. There are, doubtless, more.
  • More than 1,000 people have died of COVID-19 in New York.
  • Trump extended social distancing guidelines until at least the end of April.
  • Chicago remains locked down until at least April 7. I went for a long bike ride yesterday, and the city is changed completely. Traffic is almost nonexistent, hardly anyone is out walking, parks are empty. It appears people are following the recommendations from what I am seeing, but we have not yet seen the worst of this thing here. Simulations are showing that we will see the worst of it some time around April 13.
  • Liberty University has decided to remain open despite all prevailing evidence.
  • Instacart shoppers will strike for better working conditions including hazard pay.
  • ]]>
    COVID-19 Log #2https://zeroclarkthirty.com/2020-03-20-covid-19-2.htmlFri, 20 Mar 2020 00:00:00 +0000Things are moving pretty fast.

    ]]>
    COVID-19 Log #1https://zeroclarkthirty.com/2020-03-15-covid-19-1.htmlSun, 15 Mar 2020 00:00:00 +0000And just like that, we went from "weird outbreak in China" to pandemic.

    • The first case was reported in Washington state.
    • At least 3,000 people in the United States are infected, with at least 68 deaths. Testing has been dangerously slow to ramp up, so those numbers are both likely higher.
    • As of writing, the CDC is recommending that for the next 8 weeks, people not gather at events of 50 or more.
    • Many companies are imposing mandatory work from home policies. My company is mandatory work from home for at least the next. We'll have to extend, though, as this is going to get much worse before it gets better. Our team in the software group is currently figuring out how to operate as a 100% remote team.
    • Stores across the country have seen empty shelves, as people panic-buy everything from toilet paper to peanut butter. I made a few large Amazon purchases before the panic hit, so I am in relatively good shape when it comes to staples. NYT is reporting that the food supply chain is strong, so I will likely go this week to see if I can get some more, like frozen vegetables, pizzas, cured meats, snacks, and milk.
    • Many conservatives have publicly expressed belief that the pandemic is either a hoax, or overblow, despite what has happened in Wuhan, Iran, and Italy.
    • There is a travel ban in effect for foreign nationals who have traveled in China, Iran, or the Schengen area. Beginning tomorrow (Marth 16), the United Kingdom and Ireland will also be included in the ban.
    • The Dow is down at least 18% YTD, with extreme volatility common.
    • Many conferences and trade shows have been cancelled. Meghan and I skipped the Every Time I Die concert we were planning on going to, for example.
    • The Fed cut the benchmark rate to nearly zero, and began a massive bond buyback program.
    ]]>
    How this site workshttps://zeroclarkthirty.com/2020-02-10-how-this-site-works.htmlMon, 10 Feb 2020 00:00:00 +0000The site has two main concepts, posts and pages. They are basically the same, with the exception of how they attach to the index page. Posts are listed chronologically by date, descending. Pages appear in the nav bar to the right of the title.

    Both pages and posts are written in Markdown and parsed with pulldown-cmark which works well. There is a custom, non-Markdown frontmatter on each document that describes the layout to render for the document, its title, and its date of creation. I wrote a little Nom parser to parse this frontmatter into a struct and strip it from the rendered HTML.

    HTML is rendered with Tera templates. These are not as nice as the Hiccup templates in the Clojure version, but nothing out there is.

    RSS for the blog is available at https://zeroclarkthirty.com/feed . This is rendered with the rss library.

    CSS is minified.

    There really isn't much to this process. The whole thing is just reading Markdown, parsing it, combining it, and rending it in templates.

    Outside of the above nuts-and-bolts, there are a few maybe interesting features of this site. There's no Javascript unless its necessary for a post-specific demo or embed. This blog is 99% text and Javascript doesn't add anything to it. I don't hate the features that Javascript can add to sites, but most sites don't need Javascript-powered navbars or inifinite scrolling or modals.

    All CSS is rendered inline, in the head element of every page and post. This may sound old fashioned, but it has the effect of cutting the number of external requests any document makes. Every page should have a minimum - and for 99% of documents, maximum - of two requests. The actual HTML and the favicon.

    There are no trackers or other crap like that. Maybe I'll put something like that in the future, but it's not likely. I write this site for myself, to externalize things, not to "build an audience" or run ads or some other crap. If you like or don't like something I'd much rather you just email me or tweet at me.

    If you'll permit a digression, I remember when single-page applications were on the uptake, there was - and still is - a lot of noise about full page reloads. I find this to be a poor framing of the real problem a lot of the time. What people really care about is speed and continuity. How long does it take to see the thing they want to see, and is it the logically correct continuation of what they told the site to load. There are many ways to get there. (DHH and his insistence on Rails + JS where necessary was proven right here)

    Who cares that the page doesn't refresh the page if it takes 1.5 seconds and 35 requests to go from one view to another? A post on the Gatsby JS blog itself makes 14 requests and loads 1MB of content and then spends quite a few words talking about the benefits of not reloading the whole page, preloads, smaller React runtimes, etc.

    Gatsby seems to have ~150,000 lines of Javascript, where my shitty little site has about 360 lines of Rust and HTML templates. For those counting, that's ~0.2%. These are not directly comparable but nevertheless it is a useful illustration. Gatsby offers much, much more, that many people find valuable. I say all this not to pick on Gatsby in particular, but more to ask, are we being honest about what we are and are not capable of understanding? Is it, long term, easier to use someone else's 150,000 lines than it is to write your own 360 lines?

    Sometimes it makes sense to take the 150,000. But just as important, sometimes it makes sense to write the 360.

    If you want to write something to take your thoughts and put them on the internet, you can do that. You can figure all of that out, and write it all yourself. It can take very few lines of code, every one sharp and understood.

    The cheapest way to solve a problem is to not create it in the first place.

    (But Clark don't you use libraries and compilers and operating systems and and and and.......Yes. Shut up.)

    History

    I've published this site since the end of 2012. I was overseas, depressed, and pretty unhappy with myself and my situation, so I decided to start a blog to distract myself.

    First, it was on Tumblr. Tumblr was great and its a damn shame what happened to that community. As I was entering Dev Bootcamp at the end of 2013, I migrated to Jekyll. Later I migrated to some guy's Elixir blog generator. I think it was called Obelisk. Obelisk was alright, but needed some help and did more than I wanted. At some point I forked Obelisk and removed a bunch of it.

    Later I wanted to get it out of Elixir, for whatever reason, and rewrote most of what I had previously in Clojure, and called that project Stanley.

    Stanley worked great for years. Clojure is lovely and I had that project hammered down to a fine edge. I was able to parallelize the parsing and rendering which sped up the generation of the site massively. The biggest annoyance was having to start the JVM and load Clojure to build the site. This could take seconds for a workload that seemed like it shouldn't take seconds.

    I was getting curious about Rust, and ported Stanley to Rust. The current version of this site is generated by Stanley. This was relatively easy even for someone who was new to Rust, and probably most surprisingly the length of the resulting code was about the same as the Clojure version.

    One benefit was the screaming fast runtime. No JVM startup and Clojure classloading brought the runtime down to milliseconds. Another benefit has been my confidence in maintenance. In developing the Clojure version, I routinely broke data contracts or forgot how something fit together. When I change the Rust version, I have more confidence that things cohere, even if they are not 100% correct. Correct is hard. Coherent is not as good but often easier, more readily automatable, and just as useful.

    ]]>
    Three themes for 2020https://zeroclarkthirty.com/2020-02-10-three-themes.htmlMon, 10 Feb 2020 00:00:00 +0000I have three themes I want to work on this year. This isn't a new year's resolution, because I don't really believe that those are sustainable. These are broader themes with less specific goals, which hopefully lend themselves easier to adaptation. These are self-improvement themes. There are other things I want to work on, like being a better teammate at work and being more on-top of my finances, but I'm not grouping those here.

    The first theme is art. I want to make more plotter drawings. I want to learn more about the GPU. I want to learn more graphics math, and work through https://thebookofshaders.com/

    The second theme is writing. I want to write more. I will consider myself successful at this theme if I can increase the volume of words on this blog materially. A corresponding increase in quality would be nice but I'll focus on volume and hope that quality follows. Longer pieces would be nice, but longer pieces have a tendency to drag out, and I'm more inclined to lower the barrier to publishing something than I am to raise it. I'm guessing a focus on writing will require a cofocus on better reading.

    The third theme is physical improvement. I don't have specific weight or strength or endurance goals. I want to ride my bike more, both for fun and to commute. I want to climb harder routes. I can climb most V4s and the occasional V5. I think more regular V5s, a V6 or two, and maybe even a V7 are attainable. I want to go from 6-7 hours of regular sleep to 7-8, and maybe 9 a few times a week. I am a person for whom sleep materially affects my mood and productivity, so this may turn out to be the biggest change, but I also like to stay up late, so it may also be the most difficult. I'd like to eat better. Right now I eat pretty ad hoc, so this goal is small rather than drastic like going vegetarian or something. I'll settle for less fried things, less soda, and more regular breakfasts even if I do nothing more.

    ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2020-02-05-potus-notes.htmlWed, 5 Feb 2020 00:00:00 +0000
  • The Senate acquitted President Trump.
  • The Iowa caucus imploded as an election app proved unreliable. Pete Buttigieg has a narrow lead over Bernie Sanders with all of the results still not in.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2020-01-18-potus-notes.htmlSat, 18 Jan 2020 00:00:00 +0000
  • Iran retaliated to the assassination of Qassem Soleimani by firing missles at airbases in Iraq.
  • In the confusion after the assassination of Qassem Soleimani, Iranian air defense shot down Ukraine International Airlines Flight 752 outbound from Tehran to Kiev.
  • ]]>
    Splitting Tweets with Rust and Yewhttps://zeroclarkthirty.com/2020-01-18-splitting-tweets-with-rust-and-yew.htmlSat, 18 Jan 2020 00:00:00 +0000I wrote a little tool that helps you split a larger body of text into tweet (or other) sized pieces.

    Input some text, and drag the slider to the maximum length each piece should be. The program will try to fill each piece as much as possible while only splitting on whitespace. That is, it should hopefully never split in the middle of anything that isn't a space or a line break.

    I think it's neat, and not just for what it does, but how it was made. First, I wrote a Rust library to split text on whitespace. This is a standard Rust library with a lib.rs file that exposes some functionality and a main.rs file that defines a simple CLI interface that looks like this:

    $ tweet_split -h
    ts 0.1.0
    
    USAGE:
        tweet_split [OPTIONS] [string]
    
    FLAGS:
        -h, --help       Prints help information
        -V, --version    Prints version information
    
    OPTIONS:
        -i, --input-path <input-path>                Location of text to tweetify
        -l, --max-tweet-length <max-tweet-length>    The maximum length of a tweet, in characters
    
    ARGS:
        <string>
    

    Then I used the Rust web framework Yew to make a simple web app that compiles the previously mentioned whitespace-splitting library to WASM and exposes it on the web with some simple form and slider controls.

    I didn't have to modify the splitting library at all in order for it to work on the web. I just included it in the web application, and used the Yew framework to handle the event-input and DOM rendering functionality. Overall this was incredibly pleasant. The compiler was a helpful tool along the way, and I knew that when things compiled my program would either handle inputs correctly or crash, rather than allow bad data.

    I think this kind of work is going to be big in the near future: porting existing, useful Rust code to web interfaces to expose it to new, non-technical audiences.

    The notion that WASM is useful only for high-performance contexts like graphics or scientific computing is incorrect. I see a few reasons why WASM will reach way beyond the high-performance domains.

    First, being able to use existing code in new contexts with minimal changes is the holy grail for many companies, and in the coming years we will start to see many companies and groups port their existing Rust (or C, C++, etc) code to WASM contexts with surprisingly little adaptation for huge wins. Rust is the clear leader in treating WASM as first class, and we will see much more WASM as Rust starts to make its way along the adoption curve into larger and more prolific shops.

    We are also going to see more Rust (and other non-JS) webapps become popular in domains where reliability and security are supreme, like banking or healthcare. It will perhaps take longer to write these frontend apps in Rust, but the total cost of ownership over the 5, 10, and 20 year timespans of banks and hospitals will be lower than those of Javascript by noticeable margins.

    Finally, all of this attention will contribute to WASM becoming much more stable and well supported by browsers, so the ecosystem of tools for profiling it and debugging it will mature, the sizes of produced binary will come down, and development will get easier as frameworks like Yew start to mature.

    This will push WASM's adoption downward from the high security, high reliability use cases to the more straightforward, lower-budget applications, and WASM will start to supplant many existing Javascript use cases, from internal tools to small/mid-market consumer facing services.

    This will be especially prevalent in small, highly-capable, tech-forward shops that would like to use something other than Javascript due to previous maintenance nightmares, but fear straying too far away from the mainstream path.

    Overall, WASM has a bright future, and while it will likely never supplant Javascript outright, it will maintain a significant minority position, especially as the costs of security and maintenance continue to increase.

    ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2020-01-02-potus-notes.htmlThu, 2 Jan 2020 00:00:00 +0000
  • President Trump directed the assassination of Qassem Soleimani, the leader of Iran's Quds Force
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-11-17-potus-notes.htmlSun, 17 Nov 2019 00:00:00 +0000
  • President Trump remains the subject of impeachment hearings.
  • "Mr. Stone, 67, was convicted in federal court of seven felonies for obstructing the congressional inquiry, lying to investigators under oath and trying to block the testimony of a witness whose account would have exposed his lies. Jurors deliberated for a little over seven hours before convicting him on all counts."
  • President Trump pardoned soldiers accused of war crimes.
  • ]]>
    A Clojure scratch REPLhttps://zeroclarkthirty.com/2019-10-21-clojure-scratch.htmlMon, 21 Oct 2019 00:00:00 +0000I had the idea recently that my one-off hacking would be greatly aided if I could hit a key in Emacs and immediately have a buffer connected to a running Clojure REPL session.

    This REPL session would come with a bunch of dependencies preloaded for things like local database access, JSON, HTTP, parsing, etc. All of those quick, scripty things.

    So I added created an Emacs lisp function to do it:

    (defun clj-scratch ()
      "Create a scratch clojure buffer and jack in with default deps"
      (interactive)
      ;; if there is a file that is TODAYS_DATE.clj,
      ;; open it, otherwise create it and open it
      (let* ((todays-date (insert-current-date-underscores))
             (buf (find-file (concat "~/code/dotfiles/scratch/src/ckampfe/" todays-date ".clj"))))
    
        (switch-to-buffer buf)
    
        ;; if the buffer is empty, insert the default imports
        (if (<= (buffer-size buf) 25)
            (insert-file-contents "~/code/dotfiles/scratch/default.clj" nil nil nil))
    
        ;; if the buffer is not connected to a cider session, start one
        (with-current-buffer buf
          (clojure-mode)
          (if (not (cider-connected-p))
              (cider-jack-in-clj '(:project-dir "~/code/dotfiles/scratch"))))))
    

    The function is set up to find or create a Clojure file with today's date if one doesn't exist. In this way, I get a new notebook-style file every day, rather than overwriting any previous day's work.

    The function also templates in the necessary require setup and database connection boilerplate that I always end up looking up.

    You can see the current version of this setup here, in .spacemacs and scratch: https://github.com/ckampfe/dotfiles

    ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-10-09-potus-notes.htmlWed, 9 Oct 2019 00:00:00 +0000
  • President Trump gave Turkey permission to invade Kurdish-controlled northern Syria, withdrawing U.S. troops from there.
  • Turkey attacked U.S.-allied Kurdish forces in northern Syria.
  • "[The Kurds] didn't help us with the second world war, they didn't help us with Normandy," President Trump said.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-10-03-potus-notes.htmlThu, 3 Oct 2019 00:00:00 +0000
  • President Trump called on China to investigate his political rival, Joe Biden.
  • President Trump ordered the removal of the U.S. ambassador to Ukraine for political reasons.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-09-26-potus-notes.htmlThu, 26 Sep 2019 00:00:00 +0000
  • A whistleblower alleges that President Trump attempted to lean on the president of Ukraine to investigate his political rival, Joe Biden.
  • House Speaker Nanci Pelosi is launching a formal impeachment inquiry.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-09-19-potus-notes.htmlThu, 19 Sep 2019 00:00:00 +0000
  • In trying to secure a peace agreement, President Trump nearly brought Taliban leadership to Camp David on the anniversary of September 11, 2001.
  • Oil facilities at Abqaiq, Saudi Arabia were attacked, cutting global oil production by about 5%.
  • President Trump fired national security advisor John Bolton.
  • The Fed cut the benchmark rate from 2.25% to 2%.
  • A whistleblower filed a formal complaint about President Trump's alleged promise to a foreign leader.
  • Air Force C-17 crews have been staying overnight at President Trump's Scottish resort.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-08-04-potus-notes.htmlSun, 4 Aug 2019 00:00:00 +0000
  • At least 20 people were killed in a mass shooting in El Paso, Texas.
  • At least 9 people were killed in a mass shooting in Dayton, Ohio.
  • At least 3 people were killed in a mass shooting in Gilroy, California.
  • The Fed cut the overnight lending rate from 2.25% to 2.00%.
  • President Trump announced another round of tariffs against $300B of Chinese imports.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-07-15-potus-notes.htmlMon, 15 Jul 2019 00:00:00 +0000
  • President Trump tweeted racist remarks at four minority congresswomen.
  • The Trump administration is publishing new regulation that will end asylum claims for those that pass from any third country through Mexico.
  • Labor Secretary Alex Acosta is out.
  • The department of Health and Human Services instructed taxpayer-funded family planning clinics that they may no longer refer women for abortions.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-05-12-potus-notes.htmlSun, 12 May 2019 00:00:00 +0000
  • President Trump asserted executive privilege on the full contents of the Mueller report.
  • The trade war worsened, with President Trump promising additional tariffs on Chinese goods as talks broke up.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2019-04-08-potus-notes.htmlMon, 8 Apr 2019 00:00:00 +0000
  • Special Counsel Robert Mueller finished his report. The whole report has not been released to the public.
  • DHS Secretary Kirstjen Nielsen resigns
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-12-22-potus-notes.htmlSat, 22 Dec 2018 00:00:00 +0000
  • The federal government shut down after Congress failed to agree on funding for President Trump's proposed $5B border wall.
  • The United States will withdraw military forces from Syria.
  • A seven year old girl died in the custody of United States Border Patrol.
  • Defense Secretary James Mattis resigned.
  • President Trump announced that Chief of Staff John Kelly will step down by the end of the year.
  • Interior Secretary Ryan Zinke resigned.
  • President Trump's former personal attorney Michael Cohen was setenced to 3 years in prison for lying to Congress, violating campaign finance laws, and tax evasion.
  • A federal judge chastised Michael Flynn, and then delayed his sentencing in lieu of further cooperation with the prosecution.
  • Brett McGurk, Presidential envoy to the coalition fighting ISIS, resigned.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-11-11-potus-notes.htmlSun, 11 Nov 2018 00:00:00 +0000
  • Democrats took the House of Representatives in the 2018 midterms. They also flipped a number of statehouses and governorships. Republicans picked up a few senate seats. Florida and Georgia still have not called senate and governor's races. Noted authoritarian toady Dana Rohrabacher was thrown out.
  • President Trump fired Attorney General Jeff Sessions.
  • Trump named Matthew Whitaker acting attorney general.
  • Complaining of rain, the president missed an Armistice Day memorial in France.
  • Fires burned northern and southern California, killing at least 23. President Trump blamed forest management and threatened to cut federal funding.
  • Another mass shooting, this time in Thousand Oaks, California, left at least a dozen dead. The city of Thousand Oaks is now facing evacuation orders due to advancing wildfires.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-10-27-potus-notes.htmlSat, 27 Oct 2018 00:00:00 +0000
  • A Trump supporter mailed bombs to Cory Booker, James Clapper, Kamala Harris, Tom Steyer, George Soros, Hillary Clinton, Barack Obama, John Brennan, Maxine Waters, Eric Holder, Joe Biden, and Robert De Niro.
  • Donald Trump declared himself a nationalist.
  • A man attacked a synagogue in Pittsburgh during Sabbath services, killing at least 8 people. The man allegedly yelled, "All Jews must die" as he began shooting.
  • A white man murdered two black people in a grocery store in Kentucky, after failing to gain entry to a mostly black church.
  • Poorly designed electronic voting machines are changing voters selections in Texas. Approximately 46% percent of registered voters in Texas use the machines in question.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-10-07-potus-notes.htmlSun, 7 Oct 2018 00:00:00 +0000
  • Donald Trump and his family evaded taxes and perpetrated financial fraud.
  • Amid accusations of sexual misconduct, The Senate confirmed Brett Kavanaugh to the Supreme Court to the Supreme Court by the smallest margin in 137 years.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-07-29-potus-notes.htmlSun, 29 Jul 2018 00:00:00 +0000
  • President Donald Trump threatened to shut down the government if Democrats in Congress do not give him the votes to fund his border wall.
  • Republican House Representatives Mark Meadows and Jim Jordan filed articles of impeachment against Deputy Attorney General Rod Rosenstein.
  • Farmers affected by the trade war with China will receive money from a $12B bailout fund.
  • Michael Cohen attests that Trump knew about the 2016 meeting where Russians offered dirt on Hillary Clinton.
  • The Trump administration will no longer publish readouts of the president's calls with foreign leaders.
  • President Trump tweeted a wild threat to the president of Iran.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-07-22-potus-notes.htmlSun, 22 Jul 2018 00:00:00 +0000
  • Special Counsel Robert Mueller indicted 12 Russian military officers for interfering in the 2016 U.S. presidential election.
  • Separately, Mariia Butina was charged with acting as a foreign agent. Butina sought to build ties with the NRA, senior GOP officials, and other American conservative organizations.
  • Donald Trump and Vladimir Putin held a joint press conference in Helsinki, Finland.
  • The Justice Department released its FISA wiretap application of former Trump aide Carter Page.
  • The FBI seized a recording of Donald Trump discussing made by his longtime personal lawyer Michael Cohen discussing paying off a woman who alleges she had an affair with Trump.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-07-10-potus-notes.htmlTue, 10 Jul 2018 00:00:00 +0000
  • Trump nominted Brett Kavanaugh to the Supreme Court.
  • Scott Pruitt resigned as administrator of the Environmental Protection Agency.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-06-28-potus-notes.htmlThu, 28 Jun 2018 00:00:00 +0000
  • The government of the United States has been separating children from their families at the border and imprisoning them.
  • Activists heckled Secretary of Homeland Security Kirstjen Nielsen at a Mexican restaurant.
  • A lawsuit alleges that migrant children were forcibly injected with psychiatric drugs.
  • Press Secretary Sarah Sanders was kicked out of a restaurant.
  • At least five people were shot and killed at the Capital Gazette in Annapolis, Maryland.
  • Supreme Court Justice Anthony Kennedy will retire this summer.
  • ]]>
    Useful Stuff in Clojure - Databases and Statehttps://zeroclarkthirty.com/2018-06-09-usic-database.htmlTue, 12 Jun 2018 00:00:00 +0000In the first piece in this series, we looked at how to turn your Clojure project into an artifact that you can deploy.

    Keeping things useful, we're going to take a look at the basis for many applications: databases.

    In this arena, Clojure is lucky. Being a hosted language on the JVM, Clojure inherits a ton of useful, mature database functionality that you and I get to use to do real stuff.

    Let's create another project:

    $ boot -d boot/new new -t app -n database
    

    This again creates a Clojure project with the Boot build tool, using the standard app template.

    Open up the build.boot file in your project's directory, and add the dependencies for java.jdbc, hikari-cp, sqlite-jdbc, and mount so the top part of your file looks like this:

    (boot.core/set-env! :resource-paths #{"resources" "src"}
                        :source-paths   #{"test"}
                        :dependencies   '[[org.clojure/clojure "1.9.0"]
                                          [org.clojure/java.jdbc "0.7.6"]
                                          [hikari-cp "2.4.0"]
                                          [org.xerial/sqlite-jdbc "3.23.1"]
                                          [mount "0.1.12"]
                                          [adzerk/boot-test "RELEASE" :scope "test"]])
    

    We're using Sqlite here, but everything we're doing works with Postres, Mysql, etc. java.jdbc is Clojure's interface to the Java database connection machinery. hikari is for database connection pooling and configuration. mount is for state management, which I'll get to after the next section.

    Pop open core.clj, and add the necessary requires to your namespace:

    (ns database.core
      (:require [clojure.java.jdbc :as jdbc]
                [hikari-cp.core :as h]
                [mount.core :refer [defstate]])
      (:gen-class))
    

    Managing State

    Ok so what's this mount thing?

    Mount is a library managing state. That's pretty ambiguous, so what does it really mean? Most applications out there aren't just doing math. They interact with the outside world, either through disk IO, network, the screen, or other peripherals.

    Often times, the way we interact with these services is stateful. That is, they maintain a persistent handle to the target service that is long-lived and changes over time.

    In our case (and in many database-backed applications) the application will set up a connection to the database that is active for the life of the application. The database may change over time with various inserts, updates, and table modifications, but the identity of the database - the connection - stays the same, or rarely changes. Other scenarios could be a connection to something like Redis, RabbitMQ, Kafka, etc. You want to be able to refer to these long-lived entities, and to be able to independently stop and start your application's connections to them.

    To contrast this with something that is not stateful, your application may have some domain logic that is "pure": it takes in a value, performs some calculations (for example, it may do some math), and then returns another value. There is no persistent handle, and the function will return the same value for the same arguments, every time.

    Mount is how our application is going to handle starting and stopping its connection to our Sqlite database. Do it like this:

    (def datasource-options {:jdbc-url "jdbc:sqlite:db/database.db"
                             :maximum-pool-size 1})
    
    (defstate datasource
      :start (h/make-datasource datasource-options)
      :stop (h/close-datasource datasource))
    

    Notice first that we defined some configuration in datasource-options that tells our application how to reach the database. In our case, this is Sqlite, so it's simple and just points to a file. This is pure data that could come from anywhere, like a config file. It is inlined here for convenience and clarity.

    Next is the interesting part. Mount gives us a lot of state management functionality. Among that functionality is the ability to stop and start our stateful components as we wish. To do that, we have to provide Mount with instructions for what it should do to start and stop those specific components.

    Here, we define out database connection as datasource using defstate. We tell mount how to start using :start and :stop key-value pairs, providing the "action" as the value to its respective key. When you tell Mount to start, it will run the :start action, and :stop when you tell it to stop. (Aside: the values you provide to defstate are raw expressions, because defstate wraps them in functions)

    You can use this pattern to manage connections to queues, start webservers, initialize job schedulers, etc. If you want to see how else you can use Mount, I recommend you check out the documentation. For now, let's continue on to using our database.

    clojure.java.jdbc

    Let's have a our database do some stuff. If you know SQL, or even if you don't this should be relatively straightforward. This is not a SQL tutorial, so this part does not focus on advanced SQL.

    Let's assume that our program receives events every so often, stores those events in the database, and compute some simple aggregates of the events and store those too.

    Now is where we break out the jdbc interface we pulled in at the beginning:

    (defn run-statement! [s]
      (jdbc/with-db-connection [conn {:datasource datasource}]
        (let [result (jdbc/execute! conn s)]
          result)))
    

    and

    (run-statement! [(str "CREATE TABLE IF NOT EXISTS events ("
                          "id INTEGER PRIMARY KEY,"
                          "number INTEGER,"
                          "timestamp TEXT DEFAULT CURRENT_TIMESTAMP"
                          ")")])
    

    With these two bits of code, we're defining first a function to take some DDL and run it, and secondly calling that function with our CREATE TABLE SQL.

    First, a short digression for a note about an important Clojure pattern: the function uses a common idiom, emdodied as with-db-connection, using it to check out a database connection, conn (described in {:datasource datasource}), using that conn in the body of the expression (for us, jdbc/execute!), returning a result, and then deallocating the conn that we acquired.

    When programming Clojure, it will be someone common to see various forms of with-* provided by the core language or various libraries. with-open is by far the most common, but others exist, like the ones in this article. The general pattern they take looks like this:

    (with-something [resource-name resource-initialization-expression]
      (do-stuff-with-resource resource-name))
    

    where the resource-initialization-expression will give us some resource that we bind to resource-name, which we then use in the body of the expression somehow.

    Back to the task at hand.

    We've created a table. Let's add some functions to insert data and query it.

    These aren't much different, they follow the same pattern, but use different functions from clojure.java.jdbc:

    (defn run-query! [q]
      (jdbc/with-db-connection [conn {:datasource datasource}]
        (let [rows (jdbc/query conn q)]
          rows)))
    
    (defn insert! [table-name rows]
      (jdbc/with-db-connection [conn {:datasource datasource}]
        (let [result (jdbc/insert-multi! conn table-name rows)]
          result)))
          
    (defn track-average! []
      (jdbc/with-db-transaction [conn {:datasource datasource}]
        (let [average (->> (jdbc/query conn ["SELECT AVG(events.number) as average FROM events"])
                           first
                           :average)]
          (->> (jdbc/insert! conn :events_averages {:average average})
               (map #(get % (keyword "last_insert_rowid()")))
               first))))
    
    (insert! :events [{:number 4820402}])
    ;; returns: ({:last_insert_rowid() 4})
          
    (run-query! ["SELECT * FROM events"])
    ;; returns: ({:id 1, :number 4820402})
    
    (track-average!)
    ;; returns: an integer representing the ID of the row it just inserted
    
    

    The last function is probably the least unlike the others. It explicitly creates a database transaction, and runs two queries within that transaction. The first is a read query which finds the average of the number field on the events table. It then inserts that average value into a different, new table, the events_averages table.

    The events_averages table doesn't exist, so let's create it.

    (run-statement! [(str "CREATE TABLE IF NOT EXISTS events_averages ("
                          "id INTEGER PRIMARY KEY,"
                          "average REAL,"
                          "timestamp TEXT DEFAULT CURRENT_TIMESTAMP"
                          ")")])
    

    No different than the other table, really. We could even reuse our our existing run-statement!.

    That's about it for this one. With the above, you can set up stateful components and use JDBC-compatible databases with clojure.java.jdbc. There isn't a whole lot more to it, honestly.

    Super party bonus time!

    Following are two functions that generate fake events and feeds them to the rest of the application. This isn't strictly related to using clojure.java.jdbc or mount, but it's a good example of a quasi-real use case for concurrency in Clojure. I've inlined comments with explanations for what each expression does.

    ;; given a function,
    ;; start a new thread running that function that
    ;; will not prevent the JVM from shutting down
    (defn start-daemon-thread [f]
      (doto (Thread. ^Runnable f)
        (.setDaemon true)
        (.start)))
    
    ;; our main function
    (defn -main
      "I don't do a whole lot ... yet."
      [& args]
    
      ;; start our stateful components,
      ;; which at this point is just the db connection
      (mount.core/start)
    
      ;; create a queue with a fixed size of 15.
      ;; threads will publish "log lines" to this queue,
      ;; and another thread will print those "log lines"
      (let [logging-queue (java.util.concurrent.ArrayBlockingQueue. 15)]
    
        ;; create the `events_averages` table, just like we did above
        (run-statement! [(str "CREATE TABLE IF NOT EXISTS events_averages ("
                              "id INTEGER PRIMARY KEY,"
                              "average REAL,"
                              "timestamp TEXT DEFAULT CURRENT_TIMESTAMP"
                              ")")])
    
        ;; create the `events` table, just like we did above
        (run-statement! [(str "CREATE TABLE IF NOT EXISTS events ("
                              "id INTEGER PRIMARY KEY,"
                              "number INTEGER,"
                              "timestamp TEXT DEFAULT CURRENT_TIMESTAMP"
                              ")")])
    
        ;; start a new thread
        ;; that will consume events from `logging-queue`,
        ;; and print those events preceded by a timestamp
        (start-daemon-thread
         (fn []
           (while true
             (println (str "[" (java.time.Instant/now) "]")
                      (.take logging-queue)))))
    
        ;; start a new thread,
        ;; that every 5 seconds will run the `track-average!` query,
        ;; printing the data it previously inserted
        (start-daemon-thread
         (fn []
           (while true
             (let [id (track-average!)]
               (doseq [row (query! ["SELECT * FROM events_averages WHERE id = ?" id])]
                 (.put logging-queue (str "AVERAGE EVENT NUMBER: " (:average row)))))
             (Thread/sleep 5000))))
    
        ;; start a new thread that will sleep a random amount of time
        ;; (between 1 and 5 seconds), inserting a random number to the `events` table,
        ;; sending that random number off to be logged
        (start-daemon-thread
         (fn []
           (while true
             (let [random-number (rand-int 60000)]
               (insert! :events [{:number random-number}])
               (.put logging-queue (str "received and inserted: " random-number)))
             (Thread/sleep (+ (rand-int 4000) 1000)))))
    
        ;; start a new thread that every 5 seconds will
        ;; count the number of rows in the `events` table,
        ;; and send that number off to be logged
        (start-daemon-thread
         (fn []
           (while true
             (doseq [row (query! ["SELECT COUNT(*) as count FROM events"])]
               (.put logging-queue (str "EVENTS COUNT: " (:count row))))
             (Thread/sleep 5000)))))
    
      ;; block the main thread for 30 seconds so we don't exit after starting the other threads
      (Thread/sleep 30000))
    

    Running it looks like this:

    clark$> java -jar target/database-0.1.0-SNAPSHOT-standalone.jar 
    [2018-06-12T22:14:43.046Z] received and inserted: 39884
    [2018-06-12T22:14:43.074Z] EVENTS COUNT: 12
    [2018-06-12T22:14:43.075Z] AVERAGE EVENT NUMBER: 29521.5
    [2018-06-12T22:14:43.079Z] received and inserted: 50832
    [2018-06-12T22:14:47.592Z] EVENTS COUNT: 13
    [2018-06-12T22:14:48.081Z] AVERAGE EVENT NUMBER: 31160.76923076923
    [2018-06-12T22:14:48.084Z] received and inserted: 57947
    [2018-06-12T22:14:52.522Z] EVENTS COUNT: 14
    [2018-06-12T22:14:53.082Z] AVERAGE EVENT NUMBER: 33074.07142857143
    [2018-06-12T22:14:53.092Z] received and inserted: 32677
    [2018-06-12T22:14:56.197Z] EVENTS COUNT: 15
    [2018-06-12T22:14:58.085Z] AVERAGE EVENT NUMBER: 33047.6
    [2018-06-12T22:14:58.100Z] received and inserted: 41916
    [2018-06-12T22:15:01.074Z] EVENTS COUNT: 16
    [2018-06-12T22:15:03.088Z] AVERAGE EVENT NUMBER: 33601.875
    [2018-06-12T22:15:03.107Z] received and inserted: 40567
    [2018-06-12T22:15:04.161Z] received and inserted: 33285
    [2018-06-12T22:15:05.472Z] received and inserted: 33913
    [2018-06-12T22:15:06.915Z] EVENTS COUNT: 19
    [2018-06-12T22:15:08.091Z] AVERAGE EVENT NUMBER: 33968.15789473684
    [2018-06-12T22:15:08.115Z] received and inserted: 58119
    
    ]]>
    Useful Stuff in Clojure - Deployable Artifacthttps://zeroclarkthirty.com/2018-06-07-usic-deployable-app.htmlThu, 7 Jun 2018 00:00:00 +0000Let's do some useful stuff in Clojure. A lot of tutorials focus on things like why lazy sequences are great or what you can do with transducers.

    These are both cool things, but Clojure is, I think, at a singular sweet-spot of utility and clarity.

    Let's get started.

    The quickest useful thing we can do is share our work with someone. Regardless of what our work is, it's useful to be able to share it, and Clojure makes this pretty easy to do.

    For this series we're going to use Boot, which is a comparatively new-ish build tool in the Clojure ecosystem. Leiningen is the other build tool in Clojure, and most of what I talk about will apply to both.

    First, you're going to need to install Boot. If you're on Mac, you can brew install boot-clj. Linux should be similar.

    Then, we're going to create a new Clojure project with Boot:

    $ boot -d boot/new new -t app -n deployable
    

    This says "make a new project called deployable, with the app template."

    Templates are a feature of Boot and Leiningen that allow you to quickly create new Clojure projects in a way that is similar to how you use something like Rails generators to quickly create a new controller or model. You can create your own templates, and we might explore that in a future tutorial, but for now, you'll have a new directory in your working directory called deployable containing your project.

    It will look like this:

    clark$> tree
    .
    ├── CHANGELOG.md
    ├── LICENSE
    ├── README.md
    ├── build.boot
    ├── doc
    │   └── intro.md
    ├── resources
    ├── src
    │   └── deployable
    │       └── core.clj
    └── test
        └── deployable
            └── core_test.clj
    

    The only two we really care about at this point are build.boot and core.clj. build.boot is the file that describes your project and how to build it, similar to a Makefile or a combination Gemfile/Rakefile.

    I'll explain it more in a sec, but first let's build and run the project:

    $ boot build
    

    If you ls the target directory, you should see a few things, among them a file named deployable-0.1.0-SNAPSHOT-standalone.jar.

    This is the artifact of your project that you can share with other people or run on a server somewhere. The only caveat is that they need to have a JVM compatible with the version of the JVM with which you compiled the project.

    Run the project like:

    $ java -jar target/deployable-0.1.0-SNAPSHOT-standalone.jar
    

    If you see "Hello, World!", you did everything right!

    Back to the details of what we just did.

    core.clj is the entrypoint of your project. If you open it up, and you'll see the main function of your project.

    (ns deployable.core
      (:gen-class))
    
    (defn -main
      "I don't do a whole lot ... yet."
      [& args]
      (println "Hello, World!"))
    

    This function, -main, which takes a variable number of args, ([& args]), is what will receive any args you pass to your program when you invoke it on the command line.

    The -main function generated by Boot prints "Hello, World!"`, but we could make ours do anything.

    If we wanted to make it print the first argument, we could add this snippet:

    (when (first args)
      (println (first args)))
    

    Now we can do:

    clark$> java -jar target/deployable-0.1.0-SNAPSHOT-standalone.jar hi
    Hello, World!
    hi
    

    Back to the build.boot file, you'll see a few things. Only a few are relevant right now. Those are deftask build and the section of task-options! next to jar.

    The build task is what will take our program and emit what in Clojure is known as an "uberjar". This file, with the .jar extension, is the executable format of the JVM landscape. The "uber" in the name refers to the fact that it will include all of our project's dependencies (if it has any), rather than relying on them being somewhere else on our machine's filesystem, like you would in Ruby or Python.

    We don't have to get super into detail, but the build task composes a few other sub-tasks to ultimately produce our jarfile into our project's target directory, while the jar subsection of task-options! tells the build process what our project's entrypoint is, and what the jarfile should be called.

    In our case, you see that our jar file will have the name of the result of this expression: (str "deployable-" version "-standalone.jar"), and the entrypoint will be deployable.core. In Java or other OOP terms, you can think of deployable.core as the "main class".

    To drive this post a little further into useful territory, let's learn how to add dependencies to our project. This will clarify the "uber" bit of uberjar, as the build step will remain the same, and the target, whether it's our friend's computer or a server, will not have to adjust to the presence of a dependency at all.

    Take a look at the section of the build.boot that looks like this:

    (set-env! :resource-paths #{"resources" "src"}
              :source-paths   #{"test"}
              :dependencies   '[[org.clojure/clojure "RELEASE"]
                                [adzerk/boot-test "RELEASE" :scope "test"]])
    

    Notice how it is a series of key-value pairs? THe keys are the keywords :resource-paths, :source-paths, and :dependencies. The values are the terms that follow each respective key. Right now, we care about the one following :dependencies.

    We're going to make our program do something with JSON, so we're going to add the Cheshire dependency.

    To do that, change the :dependencies value from:

    '[[org.clojure/clojure "RELEASE"]
      [adzerk/boot-test "RELEASE" :scope "test"]]
    

    to:

    '[[org.clojure/clojure "RELEASE"]
      [cheshire "5.8.0"]
      [adzerk/boot-test "RELEASE" :scope "test"]]
    

    Notice how we added [cheshire "5.8.0"].

    Now you can turn back to core.clj, where we're going to pull in the functionality from Cheshire that we need, and hook it into our program:

    (ns deployable.core
      (:require [cheshire.core :as json])
      (:gen-class))
    
    (defn -main
      "I don't do a whole lot ... yet."
      [& args]
      (println "Hello, World!")
      (when (first args)
        (println (json/decode (first args)))))
    

    After rebuilding ($ boot build), we see the result of our changes:

    clark$> java -jar target/deployable-0.1.0-SNAPSHOT-standalone.jar '{"hi":"folks"}'
    Hello, World!
    {hi folks}
    

    That's it! Now you can tell all of your Golang friends that your language builds static binaries too!

    ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-05-10-potus-notes.htmlThu, 10 May 2018 00:00:00 +0000
  • President Trump withdrew the United States from the Iran Deal.
  • Michael Cohen took payments from a company linked to a Russian oligarch, as well as from companies attempting to sway the administration, like AT&T and Novartis.
  • ZTE, a major Chinese maker of mobile phones, shutdown its main operations after the Department of Commerce ruled that the company could no longer use American products after for violating American sanctions on Iran and North Korea.
  • For the first time, Iran attacked Israel directly, and Israel retaliated by striking a large number of sites in Syria.
  • North Korea released three American prisoners.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-05-03-potus-notes.htmlThu, 3 May 2018 00:00:00 +0000
  • Rudy Giuliani admitted that President Trump knew of, and reimbursed his Michael Cohen for his payoff to Stormy Daniels.
  • Ty Cobb is leaving the president's legal team.
  • The government of Morocco hired a lobbyist linked to Scott Pruitt who helped plan the EPA administrator's trip to the country.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-04-14-potus-notes.htmlSat, 14 Apr 2018 00:00:00 +0000
  • The United States attacked Syria in response to the Syrian government's chemical weapons attack on its own citizens a few days ago.
  • Elliott Broidy resigned from the Republican National Committee in response to the news that he paid hush money to a woman with whom he had an affair and impregnated. Broidy was vice chairman of President Trump's inaugural committee.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-04-09-potus-notes.htmlMon, 9 Apr 2018 00:00:00 +0000
  • The FBI raided President Trump's personal lawyer, Michael Cohen.
  • The CBO released projections showing the federal deficit rising past $1 trillion by 2020.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-04-02-potus-notes.htmlMon, 2 Apr 2018 00:00:00 +0000
  • President Trump fired national security adviser H.R. McMaster and appointed John Bolton to the position.
  • President Trump fired VA secretary David Shulkin and appointed the White House physician Ronny L. Jackson to the position.
  • Stocks plunged as Chinese tariff retaliation and Facebook's privacy woes rattled investors.
  • The Environmental Protection Agency approved a project by Enbridge, Inc., while E.P.A. Administrator Scott Pruitt was renting a condo from the wife of a member of Enbridge's lobbying firm.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-03-18-potus-notes.htmlSun, 18 Mar 2018 00:00:00 +0000
  • The attorney general fired FBI second-in-command Andrew McCabe, days before he was set to retire. Like dismissed FBI director James Comey, McCabe kept memos on his dealings with the president.
  • Facebook kicked the data analysis firm that helped Donald Trump win the presidency off their service. Facebook alleges that the firm, Cambridge Analytica, improperly obtained the personal information of more than 50 million people.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-03-14-potus-notes.htmlWed, 14 Mar 2018 00:00:00 +0000
  • Lawyers employed by companies owned by Donald Trump worked to silence Stormy Daniels, a porn star who alleges she had an affair with Trump in 2006.
  • President Trump has agreed to meet with North Korean leader Kim Jong-un directly.
  • The President misspelled Marine Corps as "Marine Core" in a tweet.
  • Donald Trump fired secretary of state Rex Tillerson, replacing him with Mike Pompeo, the director of the CIA.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2018-01-31-potus-notes.htmlWed, 31 Jan 2018 00:00:00 +0000
  • The state of Hawaii descended into panic after an erroneous emergency broadcast that a ballistic missle was heading for the islands.
  • Deputy Director of the FBI Andrew McCabe resigned amid criticism from Congressional Republicans and President Trump. McCabe was appointed by former Director of the FBI James Comey.
  • The House of Representatives voted to reauthorize a law that grants intelligence agencies the ability to surveil American citizens communicating with foreigners abroad without obtaining a warrant. The name of the law, Section 702, refers to its membership in the FISA Amendments Act.
  • A lawyer for Donald Trump paid hush money to a pornstar with whom Mr. Trump was allegedly sexually involved.
  • President Trump delivered the State of the Union address.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-12-14-potus-notes.htmlThu, 14 Dec 2017 00:00:00 +0000
  • Lead by chairman Ajit Pai, the FCC today repealed net neutrality regulation.
  • In Alabama, longshot Democrat Doug Jones defeated Roy Moore in the special election to fill Jeff Sessions' senate seat.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-12-02-potus-notes.htmlSat, 2 Dec 2017 00:00:00 +0000
  • Michael Flynn pleads guilty to lying to the FBI, takes deal, agrees to cooperate with special counsel investigation.
  • The Senate passes a massive tax bill in the dead of night, with no chance for anyone to read the nearly 500-page bill. The bill passed on party lines, with only one Republican senator defecting: Bob Corker of Tennessee.
  • The tax bill will add $1.4 trillion to the deficit over the next 10 years. The bill overwhelmingly benefits corporations and the rich.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-08-27-potus-notes.htmlSun, 27 Aug 2017 00:00:00 +0000
  • Hurricane Harvey ravaged Houston and the Texas gulf coast.
  • Trump pardoned political ally Joe Arpaio, who was convicted of contempt of court for refusing to stop detaining people he suspected of being undocumented immigrants.
  • Nationalist-linked Sebastian Gorka forced out at the White House
  • President Trump ordered that transgender people shall no longer serve in the military. The order notably prohibits federal dollars from being spent on sex-reassignment treatment.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-08-21-potus-notes.htmlMon, 21 Aug 2017 00:00:00 +0000
  • President Donald Trump announced a new strategy for Afghanistan, purportedly increasing the troop count by 4,000.
  • Steve Bannon is out as Chief White House strategist.
  • A US Navy warship, the USS John S. McCain, collided with a cargo ship in the Strait of Malacca. 10 sailors are missing. This collision is the second by a US Naval warship in as many months.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-08-14-potus-notes.htmlMon, 14 Aug 2017 00:00:00 +0000
  • Neo-Nazis protested in Charlottesville, VA, on Saturday, murdering one counter-protestor.
  • Donald Trump took over 48 hours to issue a denunciation of the events, previously condemning hate "on many sides"
  • In reponse to the events in Charlottesville, protestors in North Carolina ripped down a Confederate memorial statue
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-07-30-potus-notes.htmlSun, 30 Jul 2017 00:00:00 +0000
  • Reince Priebus resigned as White House Chief of Staff
  • Lisa Murkowski, Susan Collins, and John McCain led a rebellion in the Senate that defeated the GOP's most recent attempt to destroy the Affordable Care Act.
  • White House Communications Director Anthony Scaramucci talked shit about Reince Priebus, Steve Bannon, and everyone else, hilariously saying, "I'm not Steve Bannon, I'm not trying to suck my own cock."
  • Reversing Obama administration policy, President Trump announced ban on transgender people serving in the military
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-07-26-potus-notes.htmlWed, 26 Jul 2017 00:00:00 +0000
  • President Trump asserted the power to pardon anyone, including himself
  • Intelligence intercepts indicated Attorney General Jeff Sessions talked to Russian ambassador
  • Sean Spicer quit the Trump administration after Trump named Anthony Scaramucci as White House Communications director
  • President Trump addressed the National Scout Jamboree, with former acting CIA Director John McLaughlin noting his speech "had the feel of a third world authoritarian's youth rally."
  • ]]>
    Your own Elixir shellhttps://zeroclarkthirty.com/2017-06-24-your-own-elixir-shell.htmlSat, 24 Jun 2017 00:00:00 +0000

    A question I see often in the Elixir community is "how do I do the equivalent of gem install so it's available globally?"

    Folks typically do this because they want to be able to boot up their REPL (previously irb, now iex) and pull in an HTTP client, JSON parser, etc., and fire off some quick commands without having to got through the hassle of making a new project every time.

    The usual answer I've seen has been to create a dummy project that you then load with your chosen dependencies and iex preloads and call it a day. This sounds tedious, but it's not all bad. It localizes your "global" dependencies to a specific place, and, even better, it's just a normal project that you can check into git and push somewhere. git clone and you have it on your new machine.

    Setting up the dummy project

    Create your project using Mix, like this:

    
    $ cd ~/code/dotfiles
    $ mix new exshell --sup

    I use --sup to make this project a supervision tree, because my past Clojure experience leads me to leave REPLs open for long periods of time. And when you leave things running for a while, you usually need to restart them or reload them after putting your machine to sleep, having a job time out, etc. This is much easier to do it Elixir/Erlang than Clojure, so why not?

    I added these dependencies to my project's mix.exs:

    
    defp deps do
    [{:httpoison, "~> 0.11.1"},
    {:poison, "~> 3.1"},
    {:strand, "~> 0.5"},
    {:array_vector, "~> 0.2"},
    {:prolly, "~> 0.2"}]
    end

    This is basically all you have to do.

    After running a quick mix deps.get, you can now just cd ~/code/dotfiles/exshell and iex -S mix, and you're cooking. Granted, you can't open iex from anywhere and magically have your dependencies available.

    But what if you could?

    As with most things, our global Elixir REPL project can be improved with a sprinkle of UNIX.

    I added this function to my .zshrc:

    
    function siex() {
    pushd $HOME/code/dotfiles/exshell \ && iex "$@" -S mix \ && popd }

    pushd with a directory as an argument changes to that directory, but not before first putting your current working directory on the directory stack.

    popd changes to the top item on the directory stack.

    So, when I start off in ~, and run siex, and Ctrl-C the REPL, this is what happens:

    
    [~]
    clark$> siex
    ~/code/dotfiles/exshell ~ ~/code/dotfiles
    Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

    Interactive Elixir (1.4.5) - press Ctrl+C to exit (type h() ENTER for help)
    iex(1)> pwd()
    /Users/clark/code/dotfiles/exshell
    iex(2)>
    BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
    (v)ersion (k)ill (D)b-tables (d)istribution \^C~ ~/code/dotfiles
    [~]
    clark$>

    We went from ~ to /Users/clark/code/dotfiles/exshell in order to run the project and back to ~ without having to manage that ourselves. Nice!

    Now we're free to just start using those "global" dependencies we pulled in earlier, Ruby-style:

    
    $ siex
    iex(1)> HTTPoison.get("yahoo.com")
    {:ok,
    %HTTPoison.Response{body: "<HTML>\n<HEAD>\n<TITLE>Document Has Moved</TITLE>\n</HEAD>\n\n<BODY BGCOLOR=\"white\" FGCOLOR=\"black\">\n<H1>Document Has Moved</H1>\n<HR>\n\n<FONT FACE=\"Helvetica,Arial\"><B>\nDescription: The document you requested has moved to a new location. The new location is \"https://www.yahoo.com/\".\n</B></FONT>\n<HR>\n</BODY>\n",
    headers: [{"Date", "Sat, 24 Jun 2017 05:38:38 GMT"},
    {"Via", "https/1.1 ir15.fp.gq1.yahoo.com (ApacheTrafficServer)"},
    {"Server", "ATS"}, {"Location", "https://www.yahoo.com/"},
    {"Content-Type", "text/html"}, {"Content-Language", "en"},
    {"Cache-Control", "no-store, no-cache"}, {"Connection", "keep-alive"},
    {"Content-Length", "304"}], status_code: 301}}
    iex(2)> Poison.encode!(["isn't", "this", "great?"])
    "[\"isn't\",\"this\",\"great?\"]"

    Also, notice that the actual iex invocation looks like iex "$@" -S mix. The "$@" lets you pass your own arguments in to the VM, so you can even run a few shells locally and communicate between them, like this:

    
    # in shell 1
    $ siex --sname joe
    iex(joe@clark)1>
    
    
    # in shell 2
    $ siex --sname mike
    iex(mike@clark)1> Node.connect(:"joe@clark")
    true
    iex(mike@clark)2> Node.spawn_link(:"joe@clark", fn -> IO.puts("Hello, Joe"); IO.puts(Node.self) end)
    Hello, Joe
    #PID<15384.205.0>
    joe@clark
    
    
    # back in shell 1
    iex(joe@clark)1> Node.spawn_link(:"mike@clark", fn -> IO.puts("Hello, Mike"); IO.puts(Node.self) end)
    Hello, Mike
    #PID<15429.205.0>
    mike@clark
    

    Fun, huh?

    ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-07-13-potus-notes.htmlTue, 13 Jun 2017 00:00:00 +0000
  • Donald Trump Jr., Jared Kushner, and Paul Manafort met with a Russian attorney promising compromising information on Hillary Clinton
  • Inexplicably, Donald Trump Jr. posted the email chain in which he set up a meeting with an attorney linked the Russian government
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-06-07-potus-notes.htmlWed, 7 Jun 2017 00:00:00 +0000
  • President Trump withdrew the United States from the Paris agreement on climate change
  • Former FBI Director James Comey released his prepared remarks in anticipation of his testimony tomorrow before the Senate Intelligence Committee
  • Trump's reelection campaign sent out an Infowars article
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-05-29-potus-notes.htmlMon, 29 May 2017 00:00:00 +0000
  • Jared Kushner attempted to set up a secret, unofficial line of communication with the Russian government prior to Donald Trump taking office
  • Donald Trump took his inaugural international trip, first visiting Saudi Arabia to sign off on a $110 billion arms deal, among other things
  • Trump also stopped off in Israel to leave a bizarre message at Yad Vashem
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-05-17-potus-notes.htmlWed, 17 May 2017 00:00:00 +0000
  • Justice Department appoints Robert Mueller as Special Counsel to execute investigation of Trump/Russia collusion.
  • House Majority Leader Kevin McCarthy: "I think Putin pays Trump"
  • Donald Trump revealed highly classified intelligence to the Russian foreign minister and ambassador
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-05-10-potus-notes.htmlWed, 10 May 2017 00:00:00 +0000
  • President Trump Fired FBI Director James Comey 4 years in to his 10-year term.
  • Comey had requested more resources for the counterintelligence investigation into Russian meddling in the US Presidential election.
  • Trump met with the Russian foreign minister and the Russian ambassador hours after firing FBI Directory James Comey.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-03-11-potus-notes.htmlSat, 11 Mar 2017 00:00:00 +0000
  • Attorney General Jeff Sessions recused himself from the federal government's investigation into Russian interference after reports emerged that he met with the Russian ambassador during the campaign, contradicting his earlier sworn testimony.
  • Former National Security Adviser Michael Flynn was a paid agent of the Turkish government during the presidential campaign and failed to disclose as much until filing the necessary paperwork this week.
  • President Trump signed a new executive order prohibiting the issue of visas to citizens of Syria, Iran, Libya, Somalia, Sudan, and Yemen for 90 days.
  • Trump gave an address to a joint session of Congress that was largely overshadowed by a stream of leaks and bad press surrounding his current and former senior staff and cabinet appointees.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-02-19-potus-notes.htmlSun, 19 Feb 2017 00:00:00 +0000
  • Shepard Smith goes off on Trump's media-hating nonsense.
  • Trump holds a campaign-style rally in Melbourne, Florida.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-02-13-potus-notes.htmlMon, 13 Feb 2017 00:00:00 +0000
  • Michael Flynn resigned his post of national security adviser facing allegations he lied about the extent of his interactions with the Russian ambassador to the United States in the wake of Donald Trump's election victory. Flynn held the job for only 24 days.
  • The Senate confirmed former Goldman Sachs banker Steven Mnuchin as Treasury Secretary by a margin of 53-47.
  • President Trump convened an ad hoc, unsecured national security meeting with Japanese Prime Minister Shinzo Abe at a public dinner table at his Mar-a-Lago club in response to North Korea's test-firing a ballistic missile.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-02-09-potus-notes.htmlThu, 9 Feb 2017 00:00:00 +0000
  • The 9th Circuit Court of Appeals unanimously upheld the order made last Friday by U.S. District Court Judge James Robart blocking President Trump's executive order that barred residents of 7 Muslim-majority countries -- as well as refugees -- from entering the United States.
  • Trump's nominee to the Supreme Court, Neil Gorsuch, expressed dismay at Trump's attack on the judiciary.
  • The Senate confirmed Jeff Sessions as Attorney General by a vote of 52-47.
  • Kellyanne Conway -- a top adviser to President Trump -- likely violated federal ethics rules when she went on Fox News and told viewers to purchase products from Ivanka Trump's fashion line.
  • The Senate confirmed Betsy DeVos as Secretary of Education, with Vice President Mike Pence casting the tie-breaking vote 51-50. Republicans Susan Collins and Lisa Murkowski joined the Democrats to vote in opposition.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-02-02-potus-notes.htmlThu, 2 Feb 2017 00:00:00 +0000
  • In a call with Mexican President Enrique Pena Nieto, President Trump threatened to invade Mexico unless the country does more to control its criminal drug cartels.
  • The White House issued a statement marking Holocaust Remembrance Day that failed to mention the suffering of the Jewish people in the Holocaust.
  • "This is what Holocaust denial is," Senator Tim Kaine (D-Virginia) said.
  • CIA Director Mike Pompeo announced the appointment of Gina Haspel as deputy CIA Director. Haspel was in charge of a CIA black site called "Cat's Eye" in Thailand in the early 2000s.
  • The President berated the Prime Minister of Australia in a phone call about immigration, then ended the call 35 minutes early.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-01-30-potus-notes.htmlMon, 30 Jan 2017 00:00:00 +0000
  • Donald Trump fired acting Attorney General Sally Yates after she directed Department of Justice lawyers not to defend Trump's executive order barring immigrants from seven mostly Muslim countries.
  • The White House statement announcing her dismissal claims she "betrayed the Department of Justice by refusing to enforce a legal order designed to protect the citizens of the United States."
  • Trump replacement Dana J. Boente immediately reversed Ms Yates' directive.
  • David Frum extrapolates now to nightmare in How to Build an Autocracy.
  • House Judiciary aides helped draft Trump's executive order banning Muslim immigrants -- in secret, without consulting congressional leadership.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-01-29-potus-notes.htmlSun, 29 Jan 2017 00:00:00 +0000
  • Trump adds White House strategist Steve Bannon to National Security Council, weakens role of Joint Chiefs.
  • Trump issues executive order barring immigrants from Iran, Iraq, Libya, Somalia, Sudan, Syria and Yemen.
  • Protests spring up across the country against the immigration ban.
  • ]]>
    POTUS Noteshttps://zeroclarkthirty.com/2017-01-24-potus-notes.htmlTue, 24 Jan 2017 00:00:00 +0000
  • Journalists at inauguration day charged with felony rioting
  • House prohibits federal dollars from funding insurance that funds abortions
  • Trump to sign executive orders cracking down on sanctuary cities; build a wall along US-Mexico border
  • Trump enraged by media reports that Women's March crowds were much bigger than those for his inauguration
  • Many federal departments directed to significantly curtail communication with the public
  • Refugees from Syria and other Middle Eastern countries banned from entering United States
  • Press Secretary Sean Spicer lies about size of inauguration
  • ]]>
    Our Credohttps://zeroclarkthirty.com/2017-01-19-our-credo.htmlThu, 19 Jan 2017 00:00:00 +0000"Our credo must be the exposure of the plunderers, the steerers, the wirepullers, the bosses, the brokers, the campaign givers and takers," Mr. Barrett once said, accepting an award at Columbia Journalism School. "So I say: Stew, percolate, pester, track, burrow, besiege, confront, damage, level, care."

    Wayne Barrett died today. He was 71.

    ]]>
    Graph of stateshttps://zeroclarkthirty.com/2017-01-08-states-graph.htmlSun, 8 Jan 2017 00:00:00 +0000Today, I sketched out the borders of the 50 states as nodes and edges. It looks pretty cool. Graph and code below.

    ]]>
    Always coming back home to youhttps://zeroclarkthirty.com/2017-01-02-always-coming-back-home-to-you.htmlMon, 2 Jan 2017 00:00:00 +0000I love Clojure. I've written its praises many times, sold it to many people, and I am currently trying to introduce it at work.

    Beyond of Clojure The Language (which is phenomenal), the ideas in the language will live on, and it's likely that in 20 years we'll all be writing in something that has at least some of Clojure's wisdom concerning state and time.

    Despite this, I keep coming back to Scala and other MLish things (if you gave me 2 weeks off I'd probably pour it into Rust).

    This really shouldn't be happening to me. Clojure is -- at this point, almost objectively -- genius on a symphonic level.

    By comparison Scala looks like the Firefly-class transport ship Serenity: useful and attracting a colorful crowd, but you need a genius mechanic to keep it from falling out of the sky.

    So why does a bucket of bolts like Scala keep on enticing me in the presence of Clojure's sleek simplicity?

    Languages with ML-style static typing have been gaining momentum in the last few years on the promise that they make certain kinds of errors impossible, provide expressive types to aid in the design process, and help ensure refactorings maintain their contracts, while keeping the brevity of dynamic languages by inferring most types.

    It's a subjective question as to whether these languages fulfill their charters, but for the one I know decently well, they do. At least enough to not be laughed out of the room.

    What I wrote above reads like a list of features on a car. It doesn't say anything about the problem of trying to get from one place to another given the constraints of time, cost, safety, or fun.

    So what are the problems? Why do I keep coming back?

    our problems

    At the risk of alienating any Federalists currenlty reading, bear with me on a slight tangent where I say that there are a number of essential problems to the software development domain that the people in our industry do not enumerate explicitly enough. The following list is not definitive but is relevant to my argument as to why I keep coming back ML-ish languages despite their flaws:

    • most projects don't ship
    • maintenance is expensive
    • maintenance is a second or even third-rate duty next to building and architecting
    • most projects are not meainingfully maintained (see above)

    Though the above may sound like evidence-free truisms (that's because they are), I challenge any reader who has built or worked on any non-toy app to tell me I'm wrong.

    Now, attempt to claw back some 8th grade alegebra, because these relationships can be explained with some simple logarithms and exponentiation.

    On a graph with time on the x-axis and cost of maintenance on the y-axis, most projects resemble y = x^n. That is, they rapidly become more and more costly to maintain as they age. For this function, think "SAP installation".

    On a similar graph with y-axis now representing probability, the liklihood of throwing away/rewriting a mature project probably resembles something like y = -log_n(x), ie, projects are most likely to be thrown away early in their life but marginally increase their staying power each day they entrench themselves in an organization's communication structure and business model. For this function, think "Rails MVP app that sticks around".

    This function also applies to the liklihood of a project shipping at all given its time in initial development: every day of development without shipping slightly weakens a project's prospects to ship at all. Think "The Big Rewrite".

    Taking these together we see projects that ship end up sticking around, end up not being maintained, and never get rewritten because the complexity they accrue over time takes eons to reimplement, putting the rewrites at risk of never completing.

    Ok...so?

    Imagine each of the above equations has a coefficient that modifies the amplitude of the function while retaining its behavior space.

    When we develop software, this coefficient is where we spend our day. No one develops software with an ability to feel what the software will be like to maintain in 5 years, let alone 6 months. No one feels y = -log_n(x) or y = x^n at a personal level. We develop in the here and now, paying the price for every null, every botched config, every broken API, every slow ramp up after being away from the code for a year, every unintelligible abstraction.

    And the impersonal area-under-the-curve cost (ie, real $$$ cost) of maintenance from time now - 1 to now is so much larger than from now - 101 to now - 100 that this coefficient begins to matter. If an ML-inspired typesystem can offer even a modest improvement for things like refactoring, or error reduction, or durability of design, this is real money and time that can be allocated elsewhere.

    I find that Scala does this. It's easier to read, I have less fear changing it, bumping dependencies, or making significant cleanups. The compiler informs me of my idiocy if I botch an API contract. It's true there are costs, like learning some of the more theoretical abstractions inherent in this programming style (hello Monad, Applicative, Functor, etc.), but this cost is amortized quickly, and you get to keep the knowledge forever.

    I'm not going to stop writing Clojure, or sellings its benefits to others -- its treatment of state and time is just too good. I just might be doing some of the more long-lived work in Scala.

    I love Clojure to bits, but coming back to a Clojure project after time away can be a bit like blindly reaching into a box I've just opened after moving apartments: there might be something sharp in there.

    Scala makes this a little less scary.

    ]]>
    Folksy programming wisdomhttps://zeroclarkthirty.com/2016-11-13-folksy-programming-wisdom.htmlSun, 13 Nov 2016 00:00:00 +0000Too often we programmers get carried away in what is essentially unsubstantiated bullshit. This is nothing unusual: we're prone to following the herd and repeating crap because evolution made us that way. Also not unusual is that we need to debunk this bullshit from time to time to make room for tomorrow's bullshit. So here we are.



    getting up and going fast is incredibly important

    • getting up and going quickly "feels good"
    • we have disproportionately prioritized "feeling good" over outcomes
    • what is 1 week vs. 1 month if the timeframe is 2 years?
    • symbolize a disdain of learning: if it takes you 1 week to learn, how much did you really learn?

    automatic measures of code like "cyclomatic complexity" and "coverage" are acceptable indicators of quality

    • often latched on to, because they have numbers, which facilitate measurement
    • like story points: meaningless but trackable
    • the reality is that we have no idea if these mean anything at all or materially affect outcomes

    technology (documentation/tests/etc) can make up for a team that doesn't care about nurturing new developers and new team members

    • nothing will ever replace teaching
    • ever
    • but seriously your documentation is probably some horrific out of date vomit in a JIRA/Confluence somewhere.

    unit tests will save us

    • too often they end up being yet another, especially rigid dependency
    • are almost impossible to write in a non-brittle fashion, even for experts
    • are made especially useless by the prevalence of stateful programming practices, necessitating Sisyphean amounts of mocking and stubbing makework

    languages that look like human languages are ipso facto better (ie "Ruby looks like English")

    • say nothing about the reliability or fitness for purpose of the software
    • say nothing about the semantics of the language
    • show the fallacy of familiarity epitomized in the "simple vs. easy" argument
    ]]>
    Analysis of What I'm Reading serieshttps://zeroclarkthirty.com/2016-09-01-analysis-what-im-reading.htmlThu, 1 Sep 2016 00:00:00 +0000From July/2015 to July/2016 I wrote one post a week, collecting various links I had been reading, and pulling out relevant passages from the articles into quotes.

    You can see an example here.

    I thought it would be cool to do a little trend analysis of these of these 52 posts, to see if any interesting trends appear.

    You can see my analysis here.

    To accomplish this, I wrote a parser using Instaparse to extract semantic information from the posts (links, quotes, dates, titles, etc.), and pulled this information into Gorilla-REPL where I could simply plot it.

    This represents maybe 6 hours of work: 2 for the parser, 2 for figuring out the Gorilla-REPL API, and another 2 for playing around with the math and figuring out what I wanted to graph.

    You can find the source code here.

    ]]>
    Enjoy scripting with Clojurehttps://zeroclarkthirty.com/2016-08-01-enjoy-scripting-clojure.htmlMon, 1 Aug 2016 00:00:00 +0000

    Every day we write crappy little scripts to shuffle files between directories, download/upload something from an API, generate PDFs, and other miscellanea.

    Most folks I know usually reach for Ruby or Python for this kind of thing.

    Me? I like Clojure.

    Why? Aside from the usual reasons ("robust, practical, and fast") and Just Really Liking Clojure, Boot has made this kind of "shitty little scripting" really pleasant.

    Getting boot is just brew install boot-clj.

    Here's how I do it:

    $ clj\-new\-script a\_great\_script
    
    $ cat a\_great\_script
    
    \#!/usr/bin/env boot
    
    (set-env! :dependencies '[[org.clojure/data.csv "0.1.3"]
                                  [me.raynes/fs "1.4.6"]
                                  [instaparse "1.4.2"]])
    
    (require '[clojure.spec :as s]
                 '[clojure.java.io :as io]
                 '[clojure.java.shell :as sh]
                 '[clojure.data.csv :as csv]
                 '[me.raynes.fs :as fs]
                 '[instaparse.core :as insta])
    (import '[java.time Instant])

    (defn -main [& args]
    (println "hello, world"))

    This is 16 tiny lines, but let's break it down anyway.

    First, we declare a shebang that calls boot:

    #!/usr/bin/env boot

    This, plus chmod +x scriptname is all it takes to run a valid Clojure script in the familiar ./scriptname style.

    Next, we declare the external libraries our script depends on.

    In this case I pull in Clojure Contrib's data.csv for CSV parsing/generating, Raynes' fs for handy filesystem interaction, and Engelberg's awesome instaparse library for parsing context-free grammars:

    (set-env! :dependencies '[[org.clojure/data.csv "0.1.3"]
                                  [me.raynes/fs "1.4.6"]
                                  [instaparse "1.4.2"]])
    

    Boot will resolve these dependencies the first time we run the script and cache them from then on.

    Next, we link our script against some namespaces and Java classes:

    (require '[clojure.spec :as s]
                 '[clojure.java.io :as io]
                 '[clojure.java.shell :as sh]
                 '[clojure.data.csv :as csv]
                 '[me.raynes.fs :as fs]
                 '[instaparse.core :as insta])
    (import '[java.time Instant])
    

    The -main fn accepts args as you think it would:

    (defn -main [& args] 
    (println "hello, world"))

    This -main fn is sparse, but it would be easy enough to add in validation with clojure.spec.

    It really is this simple: declare a shebang, some dependencies, links, a main fn, and you're on your way.

    I would put this scripting workflow up against Ruby/Python/Bash any day for its brevity, simplicity, functionality (automatic inline dependency resolution!), and speed.

    Notes

    • The Boot Scripting guide can be found here. It outlines a few additional scripting features Boot provides.

    • For those who would rather do their scripting with Clojurescript via Node or JavaScriptCore over the JVM, there is the phenomenal Planck which is similarly straightforward to the approach outlined above.

    • For those partial to Scala, I have used Li Haoyi's Ammonite in production, and it is unparalleled for this kind of work. Highly recommended.

    • The source for clj-new-script is here.

    ]]>
    What I'm reading 7/18-7/25https://zeroclarkthirty.com/2016-07-25-what-im-reading.htmlMon, 25 Jul 2016 00:00:00 +0000How to Reformat Reality - akira

    1. "'Change the world,' the Bay choir sings, 'by increasing advertising impressions.'"

    2. "The Agency betrayed the trust of Americans, so Ed simply returned the favor."

    3. "The Church could not send a cloud of drones to the Middle East. The Pope did not have eyes on every street, nor ears in every pocket."

    The Bandwagon - Claude E. Shannon

    1. "Seldom do more than a few of nature's secrets give way at one time."

    2. "It will be all too easy for our somewhat artificial prosperity to collapse overnight when it is realized that the use of a few exciting words like information, entropy, redundancy, do not solve all our problems."

    Pinboard Turns Seven - Maciej Cegłowski

    1. "I've added revenue this year because I'm no longer afraid of competitors, and I'd like to encourage people who are considering doing their own one- or zero-person business."
    ]]>
    What I'm reading 7/11-7/18https://zeroclarkthirty.com/2016-07-18-what-im-reading.htmlMon, 18 Jul 2016 00:00:00 +0000The Fact of Sisyphus - Barrett Brown

    1. "Not that I do [burpies] anyway, or any other exercise, and I've never approved of excessive sleeping, either, for life is not meant to be spent in rest, but rather in conflict or preparation for future conflict."

    2. "The chief thing to keep in mind is that dungeons vary."

    3. "It's rather dehumanizing, this matter of having to drink milk out of bags like a common Canadian, but getting breakfast in bed every day makes up for it."

    Announcing GenStage - José Valim

    1. "Developers who use GenStage only need to worry about how the data is produced, manipulated and consumed. The act of dispatching the data and providing back-pressure is completely abstracted away from the developers."

    2. "For the word counting problem with a fixed data, early experiments show a linear increase in performance with a fixed overhead of 20%. In other words, a dataset that takes 60s with a single core, takes 36s on a machine with 2 cores and 18s in one with four cores."

    3. "Developers who maintain libraries that integrate with external data sources, be it a RabbitMQ, Redis or Apacha Kafka, can explore GenStage as an abstraction for consuming data from those sources."

    Erlang's iolist - Mathieu Lecarme

    1. "Everything is message, everything can go through a wire."

    2. "Copy each items from the first list, then each items from the second one. But when you concatenate inside a loop, the amount of copies becomes huge, and first items are copied again and again."

    Poll Results: Erlang & Maintenance - Fred Hébert

    1. "This shows that when people know OTP very well (and see it as essential), they tend to estimate that they need less time to adapt to a project."

    2. "This might not be too surprising, but I still found this one funny. The more Erlang you know, the less you tend to rely on comments. They can even end up being seen negatively!"

    What do the Erlang emulator info statements mean? - Stu Thompson and Warren Young

    1. "[Async threads, or +A] refers to the number of threads in the Erlang emulator's async thread pool, which more or less tells you how many blocked system calls can be spun off into background threads before the emulator stalls."
    ]]>
    What I'm reading 7/4-7/11https://zeroclarkthirty.com/2016-07-11-what-im-reading.htmlMon, 11 Jul 2016 00:00:00 +0000[How Complex Systems Fail - Richard I. Cook](http://web.mit.edu/2.75/resources/random/How Complex Systems Fail.pdf)

    1. "All ambiguity is resolved by actions of practitioners at the sharp end of the system."

    2. "The complexity of these systems makes it impossible for them to run without multiple flaws being present."

    3. "The system continues to function because it contains so many redundancies and because people can make it function, despite the presence of many flaws."

    4. "All of the interesting systems (e.g. transportation, healthcare, power generation) are inherently and unavoidably hazardous by the own nature."

    What If We Admitted to Children That Sex Is Primarily About Pleasure? - Alice Dreger

    1. "Our son asked why they didn't tell him this stuff at school. The mate explained that adults stupidly think that if you tell children the truth about sex, they'll have sex earlier than they really should. He added that the evidence indicates otherwise."

    Parsing: The Solved Problem That Isn't - Laurence Tratt

    1. "After the creation of programming languages themselves, parsing was one of the first major areas tackled by theoretical computer science and, in many peoples eyes, one of its greatest successes."

    2. "PEGs are interesting because, unlike LL and LR, they're closed under composition: in other words, if you have two PEGs and compose them, you have a valid PEG."

    3. "To discover whether a given CFG is ambiguous or not we have to try every possible input: if no input triggers an ambiguous parse, the CFG is not ambiguous."

    Mutable Value Chains - Joe Armstrong

    1. "The solution is blindingly simple (once you see it) - we represent the sequence as a set Key-Value pairs where the Keys are taken from an iterated sequence of SHA1 checksums."

    On Technical Debt: Shoveling forward - Fred Hébert

    1. "The problem becomes that sooner or later, people start misinterpreting the original intent and thinking of technical debt the same way you could think about financial debt: a lever to use in order to get something now and then pay the accrued cost progressively over time."

    2. "The only way to fix it is by attacking whatever snow we have pushed ahead of us and getting rid of it, or working in another direction entirely, abandonning the halfway dug path we've made for ourselves and working another way."

    ]]>
    What I'm reading 6/27-7/4https://zeroclarkthirty.com/2016-07-04-what-im-reading.htmlMon, 4 Jul 2016 00:00:00 +0000The Moral Economy of Tech - Maciej Cegłowski

    1. "I am very suspicious of attempts to change the world that can't first work on a local scale."

    2. "But opting out of surveillance capitalism is like opting out of electricity, or cooked foods—you are free to do it in theory. In practice, it will upend your life."

    3. "Machine learning is like money laundering for bias."

    4. "We pretend that by maximizing our convenience and productivity, we're hastening the day when we finally make life better for all those other people."

    Zero Tolerance: Censored by the Left - Alice Dreger

    1. "This "zero tolerance" approach on the left is like some kind of Monty Python satire of activism. It would be funny if it did not lead to the right pointing out how the left isn't actually thinking, it's just playing a game of identity politics go fish. Who has the most oppression cards? They win!"

    Waiting for Gödel - Siobahn Roberts

    1. "'A set is a Many that allows itself to be thought of as a One,' Cantor said."

    The Hunt for the Death Valley Germans - Tom Mahood

    1. "I believe there are sometimes situations in which individuals can end up finding themselves in great peril without making grossly bad decisions. Fortunately it doesn't happen often, but I think it does happen."

    2. "Les had put on an RMRU tee shirt and I had put on an RMRU cap in an attempt to show were weren't just your average wankers coming out of the desert (even though, in fact, we were)."

    3. "At this point they entered into a survival situation, but may not have fully appreciated that fact."

    The Tyranny of the Clock - Ivan Sutherland

    1. "Each increase in the relative cost of communication over logic brings us closer to the fundamental physical truth that 'simultaneous' lacks meaning."

    2. "As transistors and wires get smaller, the area over which one can deliver a clock signal 'simultaneously' becomes smaller and thus the number of "clock zones" must increase."

    3. "Like all tyranny, the tyranny of the clock stems from the range over which we choose to subject ourselves to the tyrantʼs authority."

    Process registry in Elixir: A practical example - Brian Thomas Storti

    1. "Be careful when dealing with pids directly, as they will change when a process is restarted and you may be holding a dead one;"

    2. "Solving this issue should not be too hard, though. We will make our registry monitor all the processes it is taking care of, and when one of them crashes, we can safely remove it from our Map."

    Why OO Sucks - Joe Armstrong

    1. "If a language technology is so bad that it creates a new industry to solve problems of its own making then it must be a good idea for the guys who want to make money."

    2. "In an OOPL data type definitions belong to objects. So I can't find all the data type definition in one place. In Erlang or C I can define all my data types in a single include file or data dictionary. In an OOPL I can't - the data type definitions are spread out all over the place."

    Healthcare.gov and the Gulf Between Planning and Reality - Clay Shirky

    1. "The mismatch between technical competence and executive authority is at least as bad in government now as it was in media companies in the 1990s, but with much more at stake."

    2. "If there is no room for learning by doing, early mistakes will resist correction. If the people with real technical knowledge can't deliver bad news up the chain, potential failures get embedded rather than uprooted as the work goes on."

    3. "Every time there was a chance to create some sort of public experimentation, or even just some clarity about its methods and goals, the imperative was to avoid giving the opposition anything to criticize."

    ]]>
    What I'm reading 6/20-6/27https://zeroclarkthirty.com/2016-06-27-what-im-reading.htmlMon, 27 Jun 2016 00:00:00 +0000Brexit Is Only the Latest Proof of the Insularity and Failure of Western Establishment Institutions - Glenn Greenwald

    1. "Elite denunciations of the right-wing parties of Europe fall on deaf ears. Elites can't stop, or even affect, any of these movements because they are, at bottom, revolts against their wisdom, authority, and virtue."

    2. "The solution is not to subserviently cling to corrupt elite institutions out of fear of the alternatives. It is, instead, to help bury those institutions and their elite mavens and then fight for superior replacements."

    3. "Even more important, the mechanism that Western citizens are expected to use to express and rectify dissatisfaction — elections — has largely ceased to serve any corrective function."

    G.L.O.S.S.' New Record, 'Trans Day of Revenge,' Is a Case for Righteous Queer Rage - Kelton Sears

    1. "Rather than trying to prove their humanity to those who won't accept or even try to understand it, in the face of repeated violence, they wield a knife and say "Try me." Rather than ask for a safe space, they demand it, and make space unsafe for those who would dare harm the community."

    2. "On a cultural level, toxic masculinity has poisoned our nation's men, conditioning them to dominate and destroy everything considered feminine."

    Don't scar on the first cut - Jason Fried

    1. "No one sets out to create a bureaucracy. They sneak up on companies slowly."

    Gareth McConnell: Towing the Slow boat to Thasos - Brad Feuerhelm

    1. "Great things would be expected of him."

    2. "He noticed a young couple in the water below. They seemed oblivious to his presence. He watched them embrace in the cool waters below, their silhouetted shapes difficult to see in the haze of the bright sun."

    No one asked me, but here are my thoughts on the tragedy of the Brexit vote - Vincent Bevins

    1. "If we want to move forward productively from these historical shocks (and please, let's try to do that), rich world urban dickheads (like me) need to recognize that they are not the only people on the planet with views worth listening to."

    2. "Can we really sustainably create a media structure that only hires kids from top universities (and, moreover, those prick graduates that can basically afford to work for free for the first 5-10 years) who are totally ignorant of regular people, if not outright disdainful of them?"

    What ORMs have taught me: just learn SQL - Geoff Wozniak

    1. "By moving away from thinking of the objects in my application as something to be stored in a database (the raison d'être for ORMs) and instead thinking of the database as a (large and complex) data type, I've found working with a database from an application to be much simpler."

    2. "My contention with ORMs is that, if you need to know SQL, just use SQL since it prevents the need to know how non-SQL gets translated to SQL."

    ]]>
    What I'm reading 6/13-6/20https://zeroclarkthirty.com/2016-06-20-what-im-reading.htmlMon, 20 Jun 2016 00:00:00 +0000Facebook is wrong, text is deathless - Tim Carmody

    1. "Bet for better video, bet for better speech, bet for better things we can't imagine – but if you bet against text, you will lose."

    2. "Text is surprisingly resilient. It's cheap, it's flexible, it's discreet. Human brains process it absurdly well considering there's nothing really built-in for it."

    The Nigel Farage Show - Bagehot

    1. "The referendum has been marked by a pin-striped nihilism dressed up as common sense."

    2. "To some extent the referendum has revealed things that were already present: the growing void between cosmopolitan and nativist parts of the country, the diminishing faith in politics, the rise of populism, the inadequacy of the left-right partisan spectrum in an age when open-closed is a more salient divide."

    The Forest for the Trees - isis agora lovecruft

    1. "Personally, I would be completely ecstatic if Jake decided to move to Alaska."

    2. "Additionally, we would likely have had more diverse contributors to Tor, if we had dealt with Jake sooner, since, for years, many people have been warned about Jake through a whisper network and disuaded from becoming involved."

    3. "I have spoken personally with every person whose story was published in the original set on the anonymous site. I am convinced beyond reasonable doubt that each of them is true."

    Evil tip: avoid "easy" things - Yossi Kreinin

    1. "Failing at easy things is shameful; succeeding is unremarkable."

    The German School of Lisp - Fogus

    1. "Fluchtpunkt Lisps skirt the vanishing point between theory, practicality, and art."

    2. "I suppose the fundamental philosophy of newLISP is to not necessarily provide everything, but to make everything possible."

    3. "The core types provided by Pico Lisp are numbers, symbols, and lists."

    Living with yaks - Chas Emerick

    1. "We all struggle with whether we did good work yesterday, whether what we're working on now is what we want to be working on, and whether it's a stop on our path to something else, or a place where we might rest for a while."

    2. "All of this was done in order to do other things."

    3. "These computers we pound and tap on are things of our own creation: we choose our own legacy through our use and abuse of them."

    All the lonely people - André Picard

    1. "Being lonely also has stigma attached to it: it's often associated with having poor social skills or being odd. We look upon those who are reaching out to make a connection with suspicion. How often have you heard: "How can I meet people?" For most, the answer to that question is not Tinder or Grindr."

    2. "Yet, we underfund and devalue places that bring us together like libraries, parks, recreation centres and community gardens."

    The Story of Haskell at IMVU - Chad Austin

    1. "In fact, one weekend, Andy went home with the explicit goal of proving that Haskell was stupid and not good for writing production software. He came back on Monday glowing."

    2. "We learned two things: teaching Haskell was a nontrivial problem. BUT, Haskell newcomers hacking on the codebase only caused one regression, and that regression actually exposed a bug in some of our infrastructure."

    3. "From my perspective it was kind of a weird experience. Highly-skilled people that I respect just got really angry and irrational and basically refused to even try to learn Haskell, which resulted in a culture divide in the company."

    ]]>
    What I'm reading 6/6-6/13https://zeroclarkthirty.com/2016-06-13-what-im-reading.htmlMon, 13 Jun 2016 00:00:00 +0000You and Your Research - Richard Hamming

    1. "I have to get you to drop modesty and say to yourself, 'Yes, I would like to do first-class work.'"

    2. "And after some more time I came in one day and said, 'If what you are doing is not important, and if you don't think it is going to lead to something important, why are you at Bell Labs working on it?'"

    3. "You have to learn to write clearly and well so that people will read it, you must learn to give reasonably formal talks, and you also must learn to give informal talks."

    4. "You have to neglect things if you intend to get what you want done. There's no question about this."

    5. "When you find apparent flaws you've got to be sensitive and keep track of those things, and keep an eye out for how they can be explained or how the theory can be changed to fit them."

    6. "By changing a problem slightly you can often do great work rather than merely good work."

    Five or Sex Questions for BP Laval - Brad Feuerhelm

    1. "I live with a sexy, strong, beautiful woman who turns my crank."

    2. "I think a metaphor for this time in our society would be a tree that's under stress. When that happens the tree puts out a lot of seed."

    Anywhere but Medium - Dave Winer

    1. "Look at how slowly Twitter has improved their platform, and all the new features are for advertisers, not for writers. I suspect Medium will go down a similar path."

    2. "Is it necessary that a Silicon Valley tech company own every media type?"

    3. "I don't see a statement of principles, tech startups usually don't have them. They're here to dominate and make money off the dominance."

    Too Many Knobs - Greg Wilson

    1. "Only a small percentage (6.1%-16.7%) of configuration parameters are set by the majority of users; a significant percentage (up to 54.1%) of parameters are rarely set by any user."

    What's Worse Than Crashing? - Jeff Atwood

    1. "Unfortunately, attempting to help the user by fixing the error could make things worse by leading to subtle and catastrophic failures down the road."

    2. "If you can't safely fix the problem, always err on the side of protecting the user's data. Protecting the user's data is a sacred trust."

    The Fucking Open Web - Eran Hammer

    1. "Aren't you glad everyone is using fucking OAuth now?"

    2. "Do I miss IE6? As a CEO, actually yes."

    3. "Yes, you can build 2007 websites much better now. They will be consistent across platforms and perform great. But my 12 year olds don't want 2007 websites. They want 2016 apps."

    4. "We have more amazing technology than ever before but we also have so much diversity of platforms, browsers, and screen types, that building a consistent experience pretty much means using almost none of it."

    Inside the bitter last days of Bernie's revolution - Edward-Isaac Dovere and Gabriel Debenedetti

    1. "Every time Sanders got into a knife fight, aides say, they ended up losing."

    2. "Aides think Democrats should be grateful that he's increased voter turnout and registration."

    Why you shouldn't share links on Facebook - Inti De Ceukelaire

    1. "Friendly and descriptive as always, they told me this would be deemed a won't-fix and is actually intentional behavior. I was puzzled: how can Facebook let this happen?"
    ]]>
    What I'm reading 5/30-6/6https://zeroclarkthirty.com/2016-06-06-what-im-reading.htmlMon, 6 Jun 2016 00:00:00 +0000On #Tronc, Journalism, and Its Value - Allison Hantschel

    1. "Nobody checking Facebook on an iPhone made the Tribune a national joke today, and if there was no internet at all in the world, newspaper companies would still be imploding because stupidity is a constant, whereas technology changes with the times."

    2. "I saw the strings that held us up, and I saw how thin they were, how frayed."

    3. "They spent so much time, in fact, telling people about the name they ran out of time to tell people how to advertise in it or where to pick it up."

    The Big Uneasy - Nathan Heller

    1. "At some point, it seemed, the American left on campus stopped being able to hear itself think."

    2. "...a student wanted trigger warnings on 'Antigone.'"

    3. "'They do not make eye contact! They do not look into your motherfucking eyes!'"

    4. "Marc Blecher, an Oberlin professor of politics, had problems with the program at the time, in part, he said, because thinking in terms of cultural identities often leaves out a critical factor: class."

    A Tool For Thought - David Nolen

    1. "I think it's no small part of the attraction of Lisps that the use/mention distinction becomes at least slightly blurred."

    2. "By casting validation as fundamentally a parsing problem (computer science!), we get a wonderfully expressive language for crisply describing our Clojure programs without changing how we joyfully write them."

    3. "So I think clojure.spec gives us a pretty damn nice hammock away from the hammock and I look forward to hearing more about it from the larger community."

    Canada's $6.9 Billion Wildfire Is the Size of Delaware—and Still Out of Control - Charles Graeber

    1. "Most wildfire policy involves stepping on fires close to inhabited areas as quickly as possible, resulting in an increasing number of mature-growth trees and an accumulation of tinder."

    2. "Experts consider those above 4,000 kilowatts per meter to be too dangerous to be worked by fire crews on the ground, and water bomber aircraft are futile at 10,000 kW/m. By the time Tiedemann heard the evacuation order, the heart of the fire near her home was estimated to be raging at 100,000 kW/m.

    Constraints - Cristina Videira Lopes

    1. "If we want enforcement, constraints need to be included in the design of the language itself."

    Gunfire Is Reversing the Great Migration in Chicago - Alex P. Kellogg

    1. "Census data released in late March showed that Cook County, which includes Chicago, experienced the greatest population loss of any major U.S. region in 2015, topping even Michigan's Wayne County, home of Detroit, which for decades has been the fastest shrinking big city in the nation. "

    Changelog for Elixir v1.3 - Jose Valim and contributors

    1. "Elixir will now warn if constructs like if, case and friends assign to a variable that is accessed in an outer scope."

    2. "Note describe blocks cannot be nested. Instead of relying on hierarchy for composition, we want developers to build on top of named setups."

    Sisyphus on Fire: The Coming Agile Dystopia - Marc Phillips

    1. "This is project management theater."

    2. "A world of ash and soot. Bodies and brains toiling day after day, pushing boulders up steep mountainsides."

    ]]>
    What I'm reading 5/23-5/30https://zeroclarkthirty.com/2016-05-30-what-im-reading.htmlMon, 30 May 2016 00:00:00 +0000Unnecessariat - Anne Amnesia

    1. "What does it mean, to see the world's narrative retreat into the distance? To know that nothing more is expected of you, or your children, or of your children's children, than to fade away quietly and let some other heroes take their place?"

    2. "Before it was heroin it was oxycontin, and before it was oxycontin it was meth. Death, and overdose death in particular, are how things go here."

    3. "The money has gone to the top. The wages have gone to the top. The recovery has gone to the top. And what's worst of all, everybody who matters seems basically pretty okay with that."

    4. "And yet this isn't seen as a crisis, except by statisticians and public health workers. Unlike the AIDS crisis, there's no sense of oppressive doom over everyone. There is no overdose-death art. There are no musicals. There's no community, rising up in anger, demanding someone bear witness to their grief. There's no sympathy at all."

    Tornado Town, USA - Maggie Koerth-Baker

    1. "This is a part of the country where little kids dream about growing up to be storm chasers."

    2. "One town. Sixteen years. Four big, powerful tornadoes. It's a hell of a coincidence."

    3. "Devastating EF4s made up 1.37 percent of all the tornadoes that hit the U.S. from 1994 to 2012. Just 0.14 percent were incredible EF5s."

    Is Free Speech Under Fire on Campus? - Sarah Breger, Anna Isaacs, Sala Levin, et al.

    1. "It doesn't make any allowance for the possibility that someone could erroneously diagnose racism or sexism or some other form of bigotry in another person's ideas. The only real way to resolve the dispute, once the callout has been made, is through an apology or a confession."

    2. "What is college about if not the opportunity to explore new ideas and consider new ways of thinking about the world? These actions are contrary to the entire notion of higher education."

    3. "The premise of the modern American university is that no one should be protected from ideas. Some ideas may be wrong, but we can't tell that they're wrong unless we are free to debate them."

    This is how fascism comes to America - Robert Kagan

    1. "If someone criticizes or opposes the leader, it doesn't matter how popular or admired that person has been."

    2. "What these people do not or will not see is that, once in power, Trump will owe them and their party nothing. He will have ridden to power despite the party, catapulted into the White House by a mass following devoted only to him."

    3. "In such an environment, every political figure confronts a stark choice: Get right with the leader and his mass following or get run over."

    Chicago's Murder Problem - Ford Fessenden and Haeyoun Park

    1. "In Chicago, homicide rates correspond with segregation. While many areas have few or no killings, the South and West Sides are on par with the world's most dangerous countries, like Brazil and Venezuela, and have been for many years."

    2. "The homicide rate in Chicago is just a little higher than in New York when guns aren't involved. But when it comes to shootings, both fatal and not, Chicago stands out, suggesting a level of armed interaction that isn't happening in New York."

    Cats Documentation - Traverse - Adelbert Chang and contributors

    1. "Note the return type List[Future[Profile]]. This makes sense given the type signatures, but seems unwieldy. We now have a list of asynchronous values, and to work with those values we must then use the combinators on Future for every single one. It would be nicer instead if we could get the aggregate result in a single Future, say a Future[List[Profile]]."

    spec Guide - Alex Miller

    1. "Any existing Clojure function that takes a single argument and returns a truthy value is a valid predicate spec."

    2. "A key design constraint of spec is that all specs are also designed to act as generators of sample data that conforms to the spec (a critical requirement for property-based testing)."

    Anti-Choice Groups Use Smartphone Surveillance to Target 'Abortion-Minded Women' During Clinic Visits - Sharona Coutts

    1. "While theoretically anonymous, these marketing personas are surprisingly accurate. Marketers likely know your age, gender, occupation, education level, marital status, and—if you have GPS enabled on your phone and are logged into apps that track you—where you live, work, and travel."

    The artist calling BS on your 'motivational' Instagram feeds - lone Gamble

    1. "Like any organic movement it's only a matter of time before it is gussied up, stripped of political meaning and sold back to us."

    2. "It's now possible to edit out the shit and difficult parts of life and leave in those posts about success and happiness."

    Monotonic Versioning Manifesto 1.2 - orbitz

    1. "The only number which the release engineer has control over is COMPATIBILITY, which needs to be incremented if a new line of compatibility is added. The RELEASE number is incremented for every release."
    ]]>
    What I'm reading 5/16-5/23https://zeroclarkthirty.com/2016-05-23-what-im-reading.htmlMon, 23 May 2016 00:00:00 +0000The Fierce Triumph of Loneliness - Helena Fitzgerald

    1. "My unmitigated joy at the simple fact of being left alone was perfect in a way that very few larger, adult joys have ever been able to recreate since."

    2. "It is becoming the witch in the forest, powerful and watchful and silent, setting visitors on edge."

    3. "I moved through these scenes like a ghost yet felt astoundingly whole."

    4. Thanks to Jacob Lundborg for the article

    The Security Mindset - Bruce Schneier

    1. "They can't walk into a store without noticing how they might shoplift. They can't use a computer without wondering about the security vulnerabilities. They can't vote without trying to figure out how to vote twice. They just can't help it."

    2. "If I wanted to evade this particular security device, how would I do it? Could I follow the letter of this law but get around the spirit? If the person who wrote this advertisement, essay, article or television documentary were unscrupulous, what could he have done? And then, how can I protect myself from these attacks?"

    Arbitrage Discovered - Matt Levine

    1. "But this contract was not typical: prices for the funds were published each Friday, and clients were allowed to switch funds at those prices anytime before the next price was published, even if markets moved in the meantime."

    2. "Well, how much is his claim worth? Conservatively, I would ballpark it at an infinite amount of money."

    My time with Rails is up - Piotr Solnica

    1. "Rails has been built with the ease of use in mind. Do not confuse this with simplicity."

    2. "As everything with Rails, it was 'nice and easy in the beginning' and then it would turn into unmaintainable crap."

    3. "Competition fosters progress and innovation, competition creates a healthier ecosystem, it allows people to collaborate more, to share what's common, to build better foundations. This is not what's happening in the Ruby community."

    4. "Breaking through with new ideas is hard, to say the least, as every time you come up with something, people just want it to be Rails-like and work well with Rails."

    At the UN, new global fault-lines over moral matters are emerging - Erasmus

    1. "The United States, the European Union and Canada are appalled by the fact that 11 gay and transgender groups have been barred from the gathering under pressure from the Organisation of Islamic Cooperation (OIC), which groups 57 mainly Muslim lands."

    Functional Programming, Abstraction, and Naming Things - Stephen Diehl

    1. "The argument that Monoid should be called something else (maybe Appendable) is about as convincing as the proposition that a Group should be Clock."

    2. "Groups, like many concepts in functional programming, are often some of the first concepts that we encounter that defy a reduction down to our everyday experience; and are a constant point of confusion because of it."

    Understanding Transducers - Elben Shira

    1. "One important property of transducers is that they should employ only one collection regardless of the number of transformations."
    ]]>
    What I'm reading 5/9-5/16https://zeroclarkthirty.com/2016-05-16-what-im-reading.htmlMon, 16 May 2016 00:00:00 +0000Douglas Adams' speech at Digital Biota 2 Cambridge U.K., September 1998

    1. "The fact that we live at the bottom of a deep gravity well, on the surface of a gas covered planet going around a nuclear fireball 90 million miles away and think this to be normal is obviously some indication of how skewed our perspective tends to be, but we have done various things over intellectual history to slowly correct some of our misapprehensions."

    2. "Tools have enabled us to think intentionally, to make things and to do things to create a world that fits us better."

    3. "If you're doing handwriting recognition, what you are trying to do is not to assess the relative degrees of A-ness or B-ness of the letter, but trying to define the intention of the person who wrote it."

    4. "The other thing that comes out of that vision of the Universe is that it turns out to be composed almost entirely and rather worryingly, of nothing."

    Algorithmic Compositions - isis agora lovecruft

    1. "[Twitter] seems convenient for posting links to the physics and cryptography whitepapers I read, and then receiving the internet standard — inane feedback from people I've never even heard of."

    Updating a classic - Charlie Stross

    1. "It's often hard to know where incompetence ends and malice begins: the beauty of organizations is that most of them have no effective immune systems against such deliberate excesses of incompetence."

    2. "To ensure that everybody has their say everybody will be allocated exactly the same amount of time to speak. If they don't have anything to fill the silence with, we will wait it out, to encourage slow thinkers to keep up."

    Oil at $45 a Barrel Proving No Savior as Bankruptcies Pile Up - Asjylyn Loder and Erik Schatzker

    1. "Since the start of 2015, 130 North American oil and gas producers and service companies have filed for bankruptcy owing almost $44 billion, according to law firm Haynes & Boone."

    2. "While some of the best operators in the most prolific acreage may boast well break-evens of $35 a barrel, that only includes the cost of drilling, said Spencer Cutter, a credit analyst with Bloomberg Intelligence."

    Multiversal Equality for Scala - Martin Odersky

    1. "Comparisons with = and ! are universal. They compare any two values, no matter what their types are. This causes real problems for writing code and more problems for refactoring it."

    2. "The best known way to characterize such relationships is with type classes. Implicit values of a trait `Eq[T, U]` can capture the property that values of type `T` can be compared to values of type `U`."

    Everything Is Selling - Alex Balk

    1. "We've all gotten so used to the simultaneous tweets from the happy campers at this company or that who are part of a coordinated effort to sell you on a particular story that we no longer even distinguish between an attempt to push content and an attempt to push product."

    2. "We're so far along in our acceptance of this idea that acting as if there is something off-putting or untoward about it marks you out as naive or deluded."

    3. "Anyway, this post was brought to you by whatever product pops up adjacent to it, so I hope you have an improved association with it by virtue of my candor."

    Why OpenBSD Is Important To Me - Scott Bonds

    1. "The freedom to speak in private is essential to democracy."

    2. "Instead of respecting our wishes, or reopening the debate to see if we would change our minds in light of 9/11 or other physical attacks, the US govenment chose to spy on us in secret and then lie about it."

    3. "Thought and private speech are the breeding ground for new, sometimes controversial ideas. They are how we prototype, think new ideas through, refine them, and get them ready for wider distribution and discussion."

    4. "Our freedom requires fighting, struggling, working. OpenBSD is on our side, and its volunteers are fighting for us."

    Erlang/OTP 19.0.rc1 - Kenneth Lundin

    1. "gen_statem a new state machine behavior"

    2. "dialyzer: the support for maps is very much extended both the type specification syntax and the type analysis."

    3. "erts: erlang:open_port(spawn, ...) 3-5 times faster"

    ]]>
    What I'm reading 5/2-5/9https://zeroclarkthirty.com/2016-05-09-what-im-reading.htmlMon, 9 May 2016 00:00:00 +0000Richard Pevear and Larissa Volokhonsky, The Art of Translation No. 4 - Interviewed by Susannah Hunnewell

    1. "I love words. I love my dictionaries. I literally love what I am doing. And there is this feeling of having a mission. I cherish the thought that we supply something that has not been done."

    2. "And I taught myself Italian in order to read Dante."

    3. "And I said, Smooth translations slide smoothly into oblivion."

    4. "Machines don't have a worldview."

    FBI Harassment - isis agora lovecruft

    1. "If you're going to get arrested, you might as well look good and smile your brightest while doing so."

    Exploring the Wasteland with Fine Artist V Holeček - Elizabeth Hobson

    1. "They all want a lot of the same things; which is to be able to tell you what you're allowed to say, do, or enjoy. The person who wants to rule the world and the person who wants to save it are all too often one-in-the-same."

    2. "They're not buying what they think will go with the drapes. They are all over the board. This has taught me never to presume too much about a person."

    Why Spinoza still matters - Steven Nadler

    1. "Spinoza's philosophy is founded upon a rejection of the God that informs the Abrahamic religions."

    2. "In Spinoza we can find inspiration for resistance to oppressive authority and a role model for intellectual opposition to those who, through the encouragement of irrational beliefs and the maintenance of ignorance, try to get citizens to act contrary to their own best interests."

    'I Just Don't Find American Literature Interesting': Lit-Blog Pioneer Jessa Crispin Closes Bookslut, Does Not Bite Tongue - Boris Kachka

    1. "There's always space to do whatever you want. You won't get as much attention, but fuck attention. Fight for integrity."

    Dead-Simple Dependency Injection - Rúnar Óli Bjarnason

    1. "Inversion of control is really just a pretentious way of saying 'Taking an argument.'"

    The Fall of Hacker Groups - Strauss

    1. "We are tormented by a relentless flow of information as well as the daily worries of an eternally insecure, unwarranted life. Furthermore, we dread the thought of being alike, of sharing multiple views and opinions. As such, we are turning progressively judgemental of who we should be partnering with, on the basis that 'they do not understand'."

    2. "Communities, rather than individuals, should be more intellectually empowered to create, but lately we have been watching the force of the solo, the age of the ego."

    ScalaZ - Getting to grips with the Free Monad - Rob Povey

    1. "The idea of the Free Monad is simple enough, you build an AST, and provide one or more interpreters over the AST, so lets start with some code, I figured a basic stack based language was a good place to start."

    WhatsApp, Used by 100 Million Brazilians, Was Shut Down Nationwide by a Single Judge - Glenn Greenwald, Andrew Fishman

    1. "An estimated 91 percent of Brazilian mobile users nationwide — more than 100 million individuals — use WhatsApp to communicate with one another for free (it has 900 million active daily users around the world)."

    IO List - Andy Till

    1. "Use deeply nested lists of integers and binaries to represent IO data to avoid copying when concatenating strings or binaries."

    2. "They are efficient even when combining large amounts of data."

    ]]>
    What I'm reading 4/25-5/2https://zeroclarkthirty.com/2016-05-02-what-im-reading.htmlMon, 2 May 2016 00:00:00 +0000Satire Is Satire Even When People Fall For It, Mr. Jarvis - Ken White

    1. "Again, the joke is not only at the expense of Jeff Jarvis. The joke is, in part, at the expense of people who read carelessly."

    2. "I don't think ethics require satirists to pitch to the lowest possible common denominator, to make their satire ABC-at-8:00-PM obvious."

    3. "For years I've been trying to figure out who made this point: all satire is a shared joke between the writer and the reader at the expense of a hypothetical third person — the dupe — who takes it literally."

    4. "Remember: only things that could reasonably be understood as provably false statements of fact can be defamatory. Satire is not a statement of fact."

    Decline of the English Murder - George Orwell

    1. "Jones and Hulten committed their murder to the tune of V1, and were convicted to the tune of V2."

    2. "The murderer should be a little man of the professional class — a dentist or a solicitor, say — living an intensely respectable life somewhere in the suburbs, and preferably in a semi-detached house, which will allow the neighbours to hear suspicious sounds through the wall."

    Pop Goes the Digital Media Bubble - Monika Bauerlein and Clara Jeffery

    1. "If we're going to have a functioning democracy, we'll need a press that can turn over rocks, and the days of that being financed by deep-pocketed media companies are drawing to a close."

    2. "A whole class of future-of-news pundits made a living pontificating about how 'legacy media' were getting their lunch eaten by digital-native startups."

    3. "What keeps them from making money now is that online advertising pays pennies."

    Elixir RAM and the Template of Doom - Evan Miller

    1. "That is, the first template is delivered to the client in tiny 410 byte chunks — but when the empty string is included, the second template (along with the HTTP response headers) is flattened into one big 410 kilobyte string instead. Verrrrrrrry interesting."

    2. "But the Erlang VM, clever as it is, does produce some oddities. From my highly informal testing, it looks like ERL_SMALL_IO_BIN_LIMIT in particular should be cranked up a bit, perhaps to 512 bytes"

    Traffic to Wikipedia terrorism entries plunged after Snowden revelations, study finds - Joseph Menn

    1. "Internet traffic to Wikipedia pages summarizing knowledge about terror groups and their tools plunged nearly 30 percent after revelations of widespread Web monitoring by the U.S. National Security Agency, suggesting that concerns about government snooping are hurting the ordinary pursuit of information."

    Unmasking the Men Behind Zero Hedge, Wall Street's Renegade Blog - Tracy Alloway and Luke Kawa

    1. "With that in mind, the website has argued that 'pseudonymous speech' is necessary amid an atmosphere of stifled public dissent—hence the 'Tyler Durden' alias was born."

    2. "'What you are reading at Zero Hedge is nonsense. And you shouldn't support it,' Lokey wrote in an e-mail. 'Two guys who live a lifestyle you only dream of are pretending to speak for you.'"

    Kinds and some type-foo - Eugene Yokota

    1. "In other words, (Functor) is a type constructor that accepts another type constructor. This is analogous to a higher-order function, and thus called higher-kinded type."

    The MakerBot Obituary - Brian Benchoff

    1. "Including the 2015 yearly report, Stratasys has taken a total goodwill impairment charge of nearly one Billion dollars for MakerBot. Keep in mind Stratasys acquired MakerBot for $403 Million in stock. Stratasys has written off nearly double the value it paid through the failures of the MakerBot brand."

    2. "Throw money at anything, and the vultures will start circling."

    Segfaults are our friends and teachers - Kamal Marhubi

    1. "I vaguely remembered that stacks on Linux default to 8MB. Could the segfault be from going past the stack limit?"

    2. "Segmentation faults are raised by the memory management unit (MMU), which is a piece of hardware!"

    ]]>
    What I'm reading 4/18-4/25https://zeroclarkthirty.com/2016-04-25-what-im-reading.htmlMon, 25 Apr 2016 00:00:00 +0000Against Blacklists - Andrea Shepard

    1. "Instead, we must fight for the establishment of norms which allow peaceful coexistence and free association – and thus, against the authoritarian, universalizing tendencies within every cultural-ideological tribe – and for the possibility of pluralistic technical spaces with norms that protect the purpose they serve for technologists regardless of tribal affiliation, and resist being transformed into a no man's land in between red and blue tribe trenches."

    System Overload - James Surowiecki

    1. "This is the heart of our problem: infrastructure policy has become a matter of lurching from crisis to crisis, solving problems after the fact rather than preventing them from happening."

    2. "Today, the Metro is in such a state that fixing it may require shutting whole lines for months at a time. It's yet again an example for the nation, but now it's an example of how underinvestment and political dysfunction have left America with infrastructure that's failing and often downright dangerous."

    3. "As the economist Larry Summers has pointed out, once you adjust for depreciation, the U.S. makes no net investment in public infrastructure."

    False Plagiarism Accusation Against Shaun King Shows Dangers of Online Mob Journalism - Glenn Greenwald

    1. "They evidently had no compunction about publicly accusing someone of a reputation-destroying transgression without first contacting the accused and, worse, without making any effort to gather the elementary facts."

    A Protocol for Dying - Pieter Hintjens

    1. "In time it became the basis, and then the goal of my work: to go to strange places and meet new people."

    2. "I am so grateful not to have died suddenly. I'm so grateful I won't lose my mind."

    What convolutional neural networks look at when they see nudity - Ryan Compton

    1. "However, since deep learning researchers don't specify exactly how the network should behave on a given input, a new problem arises: How can one understand what the convolutional networks are activating on?"

    2. "This highlights a fundamental difference between training rule-based classifiers and modern A.I. research. Rather than redesigning features by hand, we redesign our training data until the discovered features are improved."

    Introduction to Scala Macros - Sturm Mabie

    1. "In Scala, as in Lisp, macros are not merely transformations that operate on a set of strings, but rather, are functions that map from a given AST to another AST."

    Implementers, Solvers, and Finders - Randall Koutnik

    1. "How could this be? A group of people, granted the ability to do what they love for great pay & perks, all wanting to move on?"

    2. "If we're to escape this situation where fantastic fanatic programmers can't see themselves programming in three years, we need to couple our words to real world meaning."

    ]]>
    Not argumentshttps://zeroclarkthirty.com/2016-04-24-not-arguments.htmlSun, 24 Apr 2016 00:00:00 +0000"you can write shitty code in any language"

    "it's about tradeoffs"

    "the best tool for the job"

    "you just aren't doing $PROCESS right"

    Programming is the manipulation of symbolic language. Other professions share this purpose – law and journalism among them – with varying emphasis on the "symbolic". Programmers use computers as our vehicle, which makes us so special we've given ourselves pass to perpetrate language genocide in our debates and and on our mailing lists.

    Attempting to inject nuance into every damn thing services no one, and instead comes across as obfuscatory ass-covering, hedging against any potential refutation.

    The above phrases are not arguments. They do not mean anything. They do not make you sound smarter. Stop using them.

    ]]>
    What I'm reading 4/11-4/18https://zeroclarkthirty.com/2016-04-18-what-im-reading.htmlMon, 18 Apr 2016 00:00:00 +0000I wrote an essay about working overnights. - Peter Nickeas

    1. "There isn't a relationship in my life that is stronger now than it was five years ago. I've lost touch with friends, I've flaked on personal engagements, I've lost energy."

    2. "I went probably a solid 12 months past what should have been my end point, and during that period I stopped remembering uneventful nights. Guys tell me things, I have no memory of those things."

    3. "I want to live, again. I miss living."

    Compliance with Court Orders Act of 2016 - Richard Burr, Diane Feinstein

    1. "(5) to uphold both the rule of law and protect the interests and security of the United States, all persons receiving an authorized judicial order for information or data must provide, in a timely manner, responsive, intelligible information or data, or appropriate technical assistance to obtain such information or data;"

    An MIT Underwear Exposé (and Sorting Hat) - Lydia K.

    1. "There is a sad, persistent decrease in multicolored underwear, ending with none by senior year."

    2. "Bayes' Theorem allows us to calculate what we don't know from what we do."

    Tim Hecker: 'I make pagan music that dances on the ashes of a burnt church' - Bella Todd

    1. "'I need a little bit of threat, menace, confusion about what I'm making.'"

    2. "'You take home your Apple Store computer with your Apple Store keyboard and you make music you're told by Apple to make.'"

    3. "He began work on Love Streams by illegally downloading a bunch of choral works by Josquin des Prez, a 15th- and 16th-century Franco-Flemish composer who left little of himself to history beyond graffitiing his name in the Sistine Chapel."

    4. "'I found myself questioning my work. Like, in 2016, is music better than it was in 1547? Probably not, right?'"

    Keeping secrecy the exception, not the rule: An issue for both consumers and businesses - Brad Smith

    1. "Notably and even surprisingly, 1,752 of these secrecy orders, or 68 percent of the total, contained no fixed end date at all. This means that we effectively are prohibited forever from telling our customers that the government has obtained their data."

    2. "Ultimately, we view this case as similar to the other three that we have filed. It involves the fundamental right of people and businesses to know when the government is accessing their content and our right to share this information with them."

    The usefulness of Clojure's cond-> - Jake McCrary

    1. "Looking through the codebases I work on, I almost primarily see cond-> being used with the initial expression being a hash-map."
    ]]>
    What I'm reading 4/4-4/11https://zeroclarkthirty.com/2016-04-11-what-im-reading.htmlMon, 11 Apr 2016 00:00:00 +0000The Blue State Model - Thomas Frank

    1. "A thousand dollars a pill, 30 grand a semester: the debts that are gradually choking the life out of people where you live are what has made this city so very rich."

    2. "The ideology of educational achievement conveniently negates any esteem we might feel for the poorly graduated."

    3. "Once the visitor leaves the brainy bustle of Boston, he discovers that this state is filled with wreckage – with former manufacturing towns in which workers watch their way of life draining away, and with cities that are little more than warehouses for people on Medicare."

    4. "Most of the old factories are boarded up, unmistakable emblems of hopelessness right up to the roof. But the ones that have been successfully repurposed are in some ways even worse, filled as they often are with enterprises offering cheap suits or help with drug addiction."

    What happened with my Security BSides talk - Violet Blue

    1. "This could have been solved in a positive way if the people making the complaints had simply talked to me."

    2. "I have presented talks about sexuality at tech conferences all over the world, and I make it clear each time that my talks are not technical and that they are about issues that affect the culture to which I am presenting."

    3. "'No, they're here and they're not leaving. They told me they'll make it into a bigger problem if you do your talk.'"

    The resource leak bug of our civilization - viznut

    1. "Nearly every methodology, language and tool used in the virtual world focuses on cumulative growth while neglecting many other aspects."

    2. "Tell a bunch of average software developers to design a sailship. They will do a web search for available modules. They will pick a wind power module and an electric engine module, which will be attached to some kind of a floating module. When someone mentions aero- or hydrodynamics, the group will respond by saying that elementary physics is a far too specialized area, and it is cheaper and more straight-forward to just combine pre-existing modules and pray that the combination will work sufficiently well."

    3. "The mainstream of open source / free software, for example, is a copycat culture, despite its strong ideological dimension. It does not actively question the philosophies and methodologies of the growth-obsessed industry but actually embraces them when creating duplicate implementations of growth-obsessed software ideas."

    Clojure Compilation: Parenthetical Prose to Bewildering Bytecode - Nicholas Kariniemi

    1. "Clojure uses an extra level of indirection for calling the print function. Java fetches java.lang.System.out and calls invokevirtual to print. Clojure loads the var pointing to the function, calls invokevirtual to get the function value, casts it to a function, and calls invokeinterface to print."

    2. "According to Clojure.org documentation, for each namespace a loader class with an _init suffix is created."

    Managing two million web servers - Joe Armstrong

    1. "There are some things we explain because we know other people don't understand them and there are some things we don't explain because we assume that everybody else knows them."

    2. "If we want to pack sand in barrels it's easy. The grains of sand are so small that it's easy to completely fill the barrels. Packing huge boulders is difficult, they don't pack well and much space is wasted."

    American Big Brother: A Century of Political Surveillance and Repression

    1. "Whether protesting the march to war, federal policy on AIDS research, civil rights violations, or simply enjoying the Nevada desert at a 'Burning Man' gathering, the common theme that emerges is that simply publicly expressing strong political views that run counter to the prevailing government political paradigm is often enough to trigger federal government surveillance."

    2. "The FBI conducted sureillance and informant/penetration operations against the ACLU which stretched over at least a 56-year period."

    3. "The FBI's surveillance of and subversive actions against the Socialist Party of America effectively politically destroyed the organization for decades."

    Does Elixir have a life outside of the Phoenix framework? - iszlail

    1. "'Absolutely it does, and we are seeing a diverse, and thriving ecosystem around Elixir. The thing that excites me the most outside of Web is the Nerves project and Elixir eating the world on embedded devices.'" - Chris McCord

    Layoffs - Keith Gregory

    1. "Strategic work is for the future: shaping your next product or next release. Tactical work is about now: operations, bugfixes, responding to immediate customer desires. When a company is forced to choose, they'll value tactics above strategy every time."

    Thread pools! How do I use them? - Julia Evans

    1. "In my case, I was reading a bunch of data off disk. maybe 10GB of data. And I was submitting all of that data into the ExecutorService work queue. Unsurprisingly, the queue exploded and crashed my program."

    2. "When working with these concurrency abstractions I end up having to worry almost immediately about what's underneath because the underlying queue has filled up and crashed my program."

    Erlang 19.0 Garbage Collector - Lukas Larsson

    1. "Generational garbage collection aims to increase performance at the expense of memory. This is achieved because only the young, smaller, heap is considered in most garbage collections."

    2. "The generational hypothesis predicts that most terms tend to die young, and for an immutable language such as Erlang, young terms die even faster than in other languages. So for most usage patterns the data in the new heap will die very soon after it is allocated."

    ]]>
    What I'm reading 3/28-4/4https://zeroclarkthirty.com/2016-04-04-what-im-reading.htmlMon, 4 Apr 2016 00:00:00 +0000The Origins of Pattern Theory the Future of the Theory, And The Generation of a Living World - Christopher Alexander

    1. "If life is to be created, these processes must change."

    2. "I don't really see discussion about What, collectively, are computer scientists supposed to be doing with all these programs."

    3. "So, I have no idea whether the search for something that helps human life is a formal part of what you are searching for. Or are you primarily searching for - what should I call it - good technical performance? This seems to me a very, very vital issue."

    4. "Have you done that in software pattern theory? Have you asked whether a particular system of patterns, taken as a system, will generate a coherent computer program?"

    5. "I began getting calls from computer people."

    6. "Architects themselves build a very, very small part of the world. Most of the physical world is built by just all kinds of people."

    Three Generations of a Hackneyed Apologia for Censorship Are Enough - Ken White

    1. "If you have a pertinent case showing that particular speech falls outside the First Amendment, you don't have to rely on a 90-year-old rhetorical flourish to support your argument."

    2. "After Holmes' opinions in the Schenck trilogy, the law of the United States was this: you could be convicted and sentenced to prison under the Espionage Act if you criticized the war, or conscription, in a way that 'obstructed' conscription, which might mean as little as convincing people to write and march and petition against it. This is the context of the 'fire in a theater' quote that people so love to brandish to justify censorship."

    3. "Deference from the judiciary is a good thing when it comes to interference in general policy. It's a dangerous thing when it comes to interpretation of the state's power over the individual."

    Those Entry-Level Startup Jobs? They're Now Mostly Dead Ends in the Boondocks - Lauren Smiley

    1. "Once they clamored into the lunchroom, they were handed packets hyping the low cost of living in Nashville."

    Too much of a good thing - The Economist

    1. "If markets are truly competitive, why do so many companies now claim they can retain the cost synergies that big deals create, not pass them on to consumers? Why do investors believe them? Why have returns on capital risen almost everywhere?"

    2. "In a market the size of America's prices should be lower than in other industrialised economies. By and large, they are not."

    3. "Concentration is contagious."

    4. "Much of health-care purchasing in America is ultimately controlled by insurance firms. Four of the largest, Anthem, Cigna, Aetna and Humana, are planning to merge into two larger firms."

    5. "[DoJ and FTC]'s purpose is to police illegal conduct, not reimagine the world. They lack scope."

    The Right to Privacy - Samuel D. Warren and Louis D. Brandeis

    1. "The intense intellectual and emotional life, and the heightening of sensations which came with the advance of civilization, made it clear to men that only a part of the pain, pleasure, and profit of life lay in physical things."

    2. "The common law secures to each individual the right of determining, ordinarily, to what extent his thoughts, sentiments, and emotions shall be communicated to others."

    3. "The principle which protects personal writings and all other personal productions, not against theft and physical appropriation, but against publication in any form, is in reality not the principle of private property, but that of an inviolate personality."

    4. "When personal gossip attains the dignity of print, and crowds the space available for matters of real interest to the community, what wonder that the ignorant and thoughtless mistake its relative importance."

    5. "Triviality destroys at once robustness of thought and delicacy of feeling. No enthusiasm can flourish, no generous impulse can survive under its blighting influence."

    Reclaiming Design Patterns (20 Years Later) - Ted Neward

    1. "One guy with whom I taught at DevelopMentor called Design Patterns '23 ways to use a pointer'."

    2. "If suddenly we can start calling local variables a 'pattern', then the whole point of designing a higher-level toolbox of terms becomes lost."

    On the Phenomenon of Bullshit Jobs - David Graeber

    1. "It's as if someone were out there making up pointless jobs just for the sake of keeping us all working. And here, precisely, lies the mystery. In capitalism, this is exactly what is not supposed to happen."

    2. "Hell is a collection of individuals who are spending the bulk of their time working on a task they don't like and are not especially good at."

    3. "Huge swathes of people, in Europe and North America in particular, spend their entire working lives performing tasks they secretly believe do not really need to be performed."

    4. "Over the course of the last century, the number of workers employed as domestic servants, in industry, and in the farm sector has collapsed dramatically. At the same time, 'professional, managerial, clerical, sales, and service workers' tripled, growing 'from one-quarter to three-quarters of total employment.'"

    Mass surveillance silences minority opinions, according to study - Karen Turner

    1. "The majority of those primed with surveillance information were less likely to speak out about their more nonconformist ideas, including those assessed as less likely to self-censor based on their psychological profile."

    2. "[Elizabeth Stoycheff, lead researcher of the study and assistant professor at Wayne State University] said that participants who shared the 'nothing to hide' belief, those who tended to support mass surveillance as necessary for national security, were the most likely to silence their minority opinions."

    Micropackages and Open Source Trust Scaling

    1. "Afterwards I end up with 165MB in node_modules."

    2. "Those dependencies can easily end up being high value targets because of how few people know about them. juliangruber's 'isarray' has 15 stars on github and only two people watch the repository. It's downloaded 18 million times a month."

    ]]>
    What I'm reading 3/21-3/28https://zeroclarkthirty.com/2016-03-28-what-im-reading.htmlMon, 28 Mar 2016 00:00:00 +0000How America Can Create Jobs - Andy Grove

    1. "But what kind of a society are we going to have if it consists of highly paid people doing high-value-added work—and masses of unemployed?"

    2. "American companies discovered that they could have their manufacturing and even their engineering done more cheaply overseas. When they did so, margins improved. Management was happy, and so were stockholders. Growth continued, even more profitably. But the job machine began sputtering."

    An Interview with Emmet Gowin (1998) - ASX

    1. "What we really need, we can't write the prescription for. You can't predict what it is you need to do. You just see each other, and you're interested. That's all."

    2. "The fact that something is unsayable, that you are emotionally restricted from saying or even recognizing consciously what your own spirit is struggling with, energizes one's work. That is exactly where good work comes from. And that's why you can't ask somebody to find out what it is they need to do."

    My Year in Startup Hell at Hubspot - Dan Lyons

    1. "Arriving here feels like landing on some remote island where a bunch of people have been living for years, in isolation, making up their own rules and rituals and religion and language—even, to some extent, inventing their own reality."

    2. "How can you get hundreds of people to work in sales and marketing for the lowest possible wages? One way is to hire people who are right out of college and make work seem fun."

    How to Get Out of Bed - Sadie Stein

    1. "The words danced before my eyes and I felt more alone than ever."

    An Interview with Enrique Metinides: Death, Gore and Crying at Night - ASX

    1. "I laugh as he shows me a series of photographs of a beautiful young lady with long hair, dark eye makeup, and a go-go miniskirt and tall boots, first giving testimony to an investigator and then posing for Metinides' camera on top of a desk."

    Why Markdown Sucks - Joe Armstrong

    1. "I am reluctant to say this, but there is a future proof way of making markdown - that's to write documents directly in XML with a strict DTD and then generate markdown from the XML - that way whatever incompatibilities the latest markdown de jour has to offer can be accommodated with a tweak to the code generator."

    My dad killed himself when I was 13. He hid his depression. I won't hide mine. - Amy Marlow

    1. "So when I struggled with the wet-blanket sadness and gripping fear that characterize my depression and anxiety, I didn't tell my colleagues. I pushed myself harder and smiled even bigger. Like so many people who live with mental illness, you never would have known."

    Insta-Declarative DSLs! - Ryan Brush

    1. "We need a simple way to write simple rules."

    On the Perils of Dynamic Scope - Stuart Sierra

    1. "Remember that dynamic scope in Clojure is really thread-local binding."

    2. "Say goodbye to Agents, Futures, thread pools, non-blocking I/O, or any other kind of asynchrony. The resource is only valid on the current thread."

    ]]>
    What I'm reading 3/14-3/21https://zeroclarkthirty.com/2016-03-21-what-im-reading.htmlMon, 21 Mar 2016 00:00:00 +0000Why do we work so hard? - Ryan Avent

    1. "The problem is not that overworked professionals are all miserable. The problem is that they are not."

    2. "One of the facts of modern life is that a relatively small class of people works very long hours and earns good money for its efforts."

    3. "Willingly or unwillingly, those lower down the ladder worked fewer and fewer hours. Those at the top, meanwhile, worked longer and longer."

    4. "At the end of the day we can sit back and admire our work – the completed article, the sealed deal, the functioning app – in the way that artisans once did, and those earning a middling wage in the sprawling service-sector no longer do."

    5. Thanks to Brandon Hirdler for the article

    Photographer Philip-Lorca diCorcia Talks - ASX

    1. "There is nothing that is being said by any photojournalist that hasn't been said a million times before."

    Donald Trump is American journalism's great failure - Gregory J. Wallance

    1. "The problem is that they don't make them like [Edward R. Murrow] anymore."

    Programming and Scaling - Alan Kay

    1. "About 80% of the cost of all software that is deployed in industry comes after the software has been successfully put out the first time."

    2. "Why did the internet turn out so well, and why can't we do regular software that way?"

    Boot: Build it like a Pro(grammer)! - Anatoly Polinsky

    1. "Boot tasks are functions. boot.build is Clojure code. Customizing/fixing/understanding a task is no different than doing it for any other Clojure library. There is no mental gap of decyphering someone's DSL."
    ]]>
    What I'm reading 3/7-3/14https://zeroclarkthirty.com/2016-03-14-what-im-reading.htmlMon, 14 Mar 2016 00:00:00 +0000Data Is a Toxic Asset - Bruce Schneier

    1. "Saving it is dangerous because it's highly personal. Location data reveals where we live, where we work, and how we spend our time. If we all have a location tracker like a smartphone, correlating data reveals who we spend our time with­ – including who we spend the night with."

    2. "Always it's personal information about us, information that we shared with the expectation that the recipients would keep it secret. And in every case, they did not."

    3. "The phrase "big data" refers to the idea that large databases of seemingly random data about people is valuable."

    JOHN BANASIAK: "GEORGE BROWN'S BAR" (1970-71) - ASX

    1. "From 1971-1981, John Banasiak photographed Chicago and surrounding areas at night."

    Presser in FL: Donald Trump Is Not A Leader - Marco Rubio

    1. "And I get it: people are frustrated at the direction of our country. But leaders cannot say whatever they want, because words have consequences. They lead to actions that others take."

    2. "And when the person you're supporting for president is going around saying things like, 'go ahead and slap 'em around, I'll pay your legal fees', what do you think is going to happen next?"

    3. "This boiling point that we have now reached has been fed largely by the fact that we have a front runner in my party who has fed into language that basically justifies physically assaulting people that disagree with you."

    4. "We are being ripped apart at the seams now."

    Instaparse - Mark Englelberg

    1. I used Instaparse to write a log parser in an afternoon. It was an enjoyable experience and ended up being less than 100 lines of code.

    2. "What if context-free grammars were as easy to use as regular expressions?"

    Trackers - Jacques Mattheij

    1. "Some of the more enterprising trackers took down the stuff the newspaper guy told them about me in their own little black books and soon were auctioning that information off to other trackers and in fact to anybody that was willing to part with some money."

    Why Are We Fighting the Crypto Wars Again? - Steven Levy

    1. "Through a 227-year-old statute called the All Writs Act, the US essentially is demanding that Apple write new software that will make it easier for the government to break the code."
    ]]>
    What I'm reading 2/29-3/7https://zeroclarkthirty.com/2016-03-07-what-im-reading.htmlMon, 7 Mar 2016 00:00:00 +0000Disneyland with the Death Penalty - William Gibson

    1. "I didn't see a single 'bad' girl in Singapore. And I missed her."

    2. "But where else in the world today is the adjoining sleazy bordertown Islamic?"

    3. "Singapore is curiously, indeed gratifyingly devoid of certain aspects of creativity. I say gratifyingly because I soon found myself taking a rather desperate satisfaction in any evidence that such a very tightly-run ship would lack innovative elan."

    4. "And you come to suspect that the reason you see so few actual police is that people here all have, to quote William Burroughs, 'the policeman inside.'"

    5. "Put on a white shirt laundered so perfectly the cuffs could slit your wrists."

    6. "And I must've been starting to lose it, because I saw a crumpled piece of paper on the spotless floor and started snapping pictures of it. They really didn't like that."

    ARTHUR TRESS: 'PHOTOGRAPHS' - ASX

    1. "Dissatisfied with his experience, he soon dropped out and until 1966 he spent time in Europe, Mexico, India, Japan, Egypt, and other countries in Africa."

    Travis County GOP Apoplectic Over New Chairman - Jordan Rudner

    1. "'Tell them they can go fuck themselves,' Morrow told the Tribune."

    2. "Last week, he tweeted that the Republican National Committee was just a 'gay foam party.'"

    We Should All Have Something To Hide - Moxie Marlinspike

    1. "You probably do have something to hide, you just don't know it yet."

    2. "Imagine if there were an alternate dystopian reality where law enforcement was 100% effective, such that any potential law offenders knew they would be immediately identified, apprehended, and jailed."

    3. "How could people have decided that marijuana should be legal, if nobody had ever used it? How could states decide that same sex marriage should be permitted, if nobody had ever seen or participated in a same sex relationship?"

    The GOP's Super Tuesday bloodbath: Dick Nixon counts the bodies - @DICK_NIXON

    1. "My God, did you see Christie when he stood behind Trump tonight? I've seen happier men go to the gas chamber."

    2. "To call it Rubio's failure would give him too much credit. Failure connotes competition in strength, character, or ideas; Rubio has none of those things."

    3. "There couldn't be a worse outcome for McConnell, Priebus, and all the bastards who sat on their fat butts while Trump poked open wounds in every factory town from here to the Gulf."

    Cryptography Pioneers Win Turing Award - John Markoff

    1. "Public-key cryptography is a method for scrambling data in which each party has a pair of keys, one which can be publicly shared and the other which is known only to the intended recipient of a message."

    There are no acceptable ads - FiveFilters

    1. "Why should any of us put up with being advertised to when we have no interest in giving our attention to advertisers? Advertising is not some noble industry that deserves our attention."
    ]]>
    What I'm reading 2/22-2/29https://zeroclarkthirty.com/2016-02-29-what-im-reading.htmlMon, 29 Feb 2016 00:00:00 +0000Why This Radical Leftist is Disillusioned by Leftist Culture - Bailey Lamon

    1. "While many of these folks are directly impacted by class inequality and do realize it, they are likely not spending their days and nights reading Karl Marx, educating themselves on the intricacies of capitalism. They do not sit around pondering the effects of 'problematic behaviours' in radical communities. They are not concerned with checking their privilege. No. They are busy trying to survive."

    2. "But I would go as far as saying that the politically correct mafia on the left perpetuates a form of bigotry on its own because it alienates and 'otherizes' those who do not share their ways of thinking and speaking about the world."

    3. "Speaking of Fascism, there is also a disturbing trend on the left nowadays that involves rejecting free speech/freedom of expression as a core value, because that speech could possibly be hurtful to someone, somewhere."

    4. "Folks, do the world a favour…stop with the safe spaces and trigger warnings, and get serious about changing the world."

    Kissinger to the Argentine generals in 1976: "If there are things that have to be done, you should do them quickly" - Edited by Carlos Osorio and Kathleen Costar

    1. "The Secretary: '...If there are things that have to be done, you should do them quickly. But you must get back quickly to normal procedures.'"

    Confirmed: Carnegie Mellon University Attacked Tor, Was Subpoenaed By Feds - Joseph Cox

    1. "Between January and July 2014, a large number of malicious nodes operated on the Tor network, with the purpose, according to the Tor Project, of deanonymising dark web sites and their users."

    2. "[CMU Software Engineering Institute] researchers Alexander Volynkin and Michael McCord were due to present research at the Black Hat hacking conference in August 2014 on how to unmask the IP addresses of Tor hidden services and their users, before the talk was suddenly canceled without explanation."

    Dynamic Languages Strike Back - Steve Yegge

    1. "This is 80% politics and 20% technology."

    Cryptome's searing critique of Snowden Inc. - Tim Shorrock

    1. "Natsios: It's a serious conflict of interest. They've written themselves into the story as heroes, co-heroes of the story. It's a conflict of interest. They're not at a distance from their source. They've embedded themselves in the narrative, and therefore all decisions are highly suspect because they benefit from the outcome of the narrative in every sense."

    Why Clojure's a Great Next Language for Rubyists - Daniel Higginbotham

    1. "In Clojure, you primarily care about two things: data and functions. You pass data to functions and get new data back."

    2. "'But wait a minute,' you might be thinking, 'You can't just pass data around like that. Haven't you read POODR? What about encapsulation? What if those functions mutate your data?'"

    Why is Intersectionality so Dehumanizing? - Rachel Haywire

    1. "At first I refused to look up the term intersectionality. It seemed like one of those terms reserved for wealthy college types with zero real life experience."

    2. "Who would be selfish enough to consider their individual experiences... individual experiences?"

    3. "Your direct experiences are merely a social construct."

    Jetbrains: The unicorn Silicon Valley doesn't like to talk about - Prashant Deva

    1. "It is not endorsed by Paul Graham, isn't backed by Andreesen Horowitz, doesn't have a profitless business model, doesn't throw decadent $7m holiday parties, and its formed by a bunch of intellectuals, not people who wrestle over drinks in a steakhouse."

    2. "Jetbrains core tech comprises of incremental parsers and lexers written in Java rendered on a desktop using Swing APIs. There is no Big Data, Hadoop, Kafka, NodeJS or any other 'sexy' technologies in use."

    The US Government has no credibility to compel anybody to weaken security - Mark Jeftovic

    1. "Since the State won't do what's right by it's citizens (and no, squashing their civil liberties into dust and telling them it's for their own good isn't what's right), citizens and private enterprise (while it still exists) will react to these realities in their own way. As they should."

    Concurrency is not a language thing anymore - Jay Kreps

    1. "Distributed system development is not going to become a part of every application developers daily life because it is a massive pain in the ass."

    2. "MapReduce programming is almost always single-threaded. Concurrency is managed by the framework. The last thing that would help you write good MapReduce programs is more user-level concurrency primitives."

    Motivational Startup Taglines You Can Print Out And Stick On The Exposed Brick In Your Office - Amanda Rosenberg

    1. "FAIL AT FAILING."
    ]]>
    What I'm reading 2/15-2/22https://zeroclarkthirty.com/2016-02-22-what-im-reading.htmlMon, 22 Feb 2016 00:00:00 +0000Sex & Startups - Jennifer Brandel and Mara Zepeda

    1. "Startups, like the male anatomy, are designed for liquidity events."

    2. "But the model for startup venture financing, and the system of rewards driving this supposed innovation, isn't creative — it's masturbatory."

    3. "In private, we squirm over how raising money requires faking it. But we don't get off on that, and that means we don't get off the ground."

    4. "And we return to 'mundane' ideals born of this world, with an emphasis on repairing, cultivating, and connecting rather than 'disrupting,' 'crushing,' 'owning,' or 'killing' it."

    Too many people have peed in the pool - Stephen Fry

    1. "It's quite simple really: the room had started to smell. Really quite bad."

    2. "To leave that metaphor, let us grieve at what twitter has become. A stalking ground for the sanctimoniously self-righteous who love to second-guess, to leap to conclusions and be offended – worse, to be offended on behalf of others they do not even know."

    Erlang Garbage Collection Details and Why It Matters - Hamidreza Soleimani

    1. "No GC occurs in a short-lived process which doesn't use heap more that min_heap_size and then terminates. This way the whole memory used by process is collected."

    How Zenefits Crashed Back Down To Earth - William Alden

    1. "Soon after [Conrad's firing], the California insurance commissioner announced that he was investigating whether Zenefits complied with laws and regulations in the state, its biggest market."

    2. "As of the end of September, the mutual fund giant Fidelity, which bought Zenefits shares in May, marked down the value of its stake by 48%."

    3. "But a running joke among the Zenefits sales staff was that anyone who scored significantly above 60% was a nerd who had studied too hard, former employees said."

    ]]>
    What I'm reading 2/8-2/15https://zeroclarkthirty.com/2016-02-15-what-im-reading.htmlMon, 15 Feb 2016 00:00:00 +0000Maybe you should just be single - Laurie Penny

    1. "Nothing frustrates me so much as watching young women at the start of their lives wasting years in succession on lacklustre, unappreciative, boring child-men who were only ever looking for a magic girl to show off to their friends, a girl who would in private be both surrogate mother and sex partner."

    2. "It's just that I think compulsory heterosexual monogamy is the least romantic idea since standardised testing, and I don't see why our best ideals of love and lust and passion and dedication need to be boxed into it."

    3. "Today, whatever else we are, women are still taught that we have failed if we are not loved by men."

    4. "We take care of people, soothe hurt feelings, organise chaotic lives and care for men who never learned to care for themselves, regardless of whether or not we're constitutionally suited for such work."

    Raymond Pettibon: "I DON'T LOVE YOU ANYMORE"

    1. "One can't stay on the straight and narrow path forever."

    How to build stable systems — An incomplete opinionated guide - Jesper L. Andersen

    1. "It is better to solve a minuscule subset of the full problem space first and get that deployed to production than it is to have a large project die."

    2. "There are a few people on a project, no more than 6. A project is never longer than 2.5 months of time. Every project has a win condition."

    3. "Every project starts with a list of 'things we don't solve in this project'."

    4. "You will only pick the parts of Agile/XP/SCRUM/Kanban/ThisYearsFad which works for the team. You will kill everything else."

    5. "Unless you have a dataset above 10 Terabytes, you pick postgresql."

    6. "The system must avoid waking people up in the middle of the night at all costs."

    Rich Hickey Q&A - Michael Fogus

    1. "Fogus: Favorite tools? Editor? Version control? Debugger? Drawing tool? IDE? Hickey: Circus Ponies NoteBook, OmniGraffle, hammock."

    2. "I'm more interested in reducing complexity than I am in concision."

    3. "Looking at Python and Ruby left me resolute that I didn't want to create yet another syntax and yet another object system."

    4. "Prior to starting work on Clojure, he made four attempts to combine Lisp with either Java or Microsoft's Common Language Runtime: jfli, Foil, Lisplets, and DotLisp but Clojure was the first to draw significant attention."

    5. "I don't do any programming not directed at making the computer do something useful, so I don't do any exercises. I try to spend more time thinking about the problem than I do typing it in."

    Why the Assholes are Winning: Money Trumps All - Jeffrey Pfeffer

    1. "A fifth mechanism also operates from the consistency principle: people infer traits of social actors from the outcomes those actors have obtained. Thus, great results cause attributions of positive traits and behaviours."

    The Zen of Erlang - Fred Hebert

    1. "The idea is not to have uncontrolled failures everywhere, it's to instead transform failures, exceptions, and crashes into tools we can use."

    2. "Heisenbugs by contrast, have unreliable behaviour that manifests itself under certain conditions, and which may possibly be hidden by the simple act of trying to observe them."

    3. "A once in a billion issue requires quite a lot of tests and validation to uncover, and chances are that if you've seen it, you won't be able to generate it again just by luck."

    Antonin Scalia, Justice on the Supreme Court, Dies at 79 - Adam Liptak

    1. "He seldom agreed with Justice Ruth Bader Ginsburg on the important questions that reached the court, but the two for years celebrated New Year's Eve together. Not long after Justice Elena Kagan, another liberal, joined the court, Justice Scalia took her skeet shooting."

    Erlang Scheduler Details and Why It Matters - Hamidreza Soleimani

    1. "Cooperative Scheduling system cannot satisfy a real-time system because a running task in such system might never return control back or returns late after a deadline. So real-time systems commonly use Preemptive Scheduling."

    Planning for Disaster - John Regehr

    1. "Markets (and the humans that make them up) are not very good at analyzing low-probability risks."
    ]]>
    What I'm reading 2/1-2/8https://zeroclarkthirty.com/2016-02-08-what-im-reading.htmlMon, 8 Feb 2016 00:00:00 +0000Snowden's Chronicler Reveals Her Own Life Under Surveillance - Andy Greenberg

    1. "'I haven't written in over a year for fear these words are not private,' are the journal's first words. 'That nothing in my life can be kept private.'"

    2. "The stress becomes visceral: She writes that she feels like she's 'underwater' and that she can hear the blood rushing through her body. 'I am battling with my nervous system,' she writes. 'It doesn't let me rest or sleep. Eye twitches, clenched throat, and now literally waiting to be raided.'"

    Warning: A Column on Butt Play - Maureen O'Connor

    1. "When a man puts the most delicate part of his body (penis) between the sharpest parts of mine (teeth), he maintains the belief that he is dominant—even though I'm the one who could, with a few purposeful chomps, remove him from the gene pool."

    2. Thanks to Brandon Hirdler for the article

    Henry Rollins: Fuck Suicide

    1. "I have life by the neck and drag it along. Rarely does it move fast enough. Raw Power forever."

    A Badass Way to Connect Programs Together - Joe Armstrong

    1. "Session based TCP programs are trivial to write in Erlang but a bugger in any sequential language."

    2. "[UDP] is wonderful news for systems like Node.js whose concurrency model is non-existent and whose idea of having a fun time is throwing promises into the future and hoping that nobody breaks them."

    The Beggar CEO and Sucker Culture - Erik Dietrich

    1. "Sucker culture is the race to the bottom that's created where advancement within the company is predicated upon offering free labor."

    2. "She looks at Amazon's tough culture, movies and shows about startups, and her own, over-glorified past, and thinks that she's no longer one of the cool kids where people live to work."

    3. "The real problem isn't Victoria, and it isn't sucker culture itself — it's the fact that going home after 8 hours is the new original sin."

    Bored People Quit - Rands

    1. "Boredom is easier to fix than an absence of belief."
    ]]>
    What I'm reading 1/25-2/1https://zeroclarkthirty.com/2016-02-01-what-im-reading.htmlMon, 1 Feb 2016 00:00:00 +0000Making Peace With Violence: Camus in Algeria - Robert Zaretsky

    1. "Camus would immediately recognize the Islamic State as an enemy as loathsome and nihilistic as Nazism, and one that we must combat with violence. But at the same time, he would warn us not to lose recognition of who we are and why we are fighting."

    2. "For Camus, true rebellion entails great tension. It holds fast to the moral center, resisting those who seek to oppress oneself all the while resisting one's own tendency to oppress in turn."

    Ricky Gervais does not get enough credit for being offensive - Grace Dent

    1. "'Better get dressed and offend some humourless cunts I suppose,' Gervais tweeted before donning his suit for the ceremony. I was one of these humourless cunts once, I thought."

    2. "Possibly the only thing the internet relishes more than being offended – wringing the jollity out of one-liners, demanding comedians apologise – is being bereaved."

    3. "None of us, not even celebrities, has the right to sail through life unoffended."

    As Zika virus spreads, El Salvador asks women not to get pregnant until 2018 - Joshua Partlow

    1. "'Morality says that people shouldn't have that control' over procreation, Figueroa said. 'But the church also isn't going to say something that runs contrary to life and health.'"

    The Unintentional side-effects of a bad concurrency model - Joe Armstrong

    1. "I was initially confused when I learned about the software architecture of the AXE system since it appeared to be very similar to the organizational structure of a large part of the company."

    2. "Concurrency has been forgotten in most programming languages, and when it has been added it seems like a afterthought, not as an act of conscious design."

    3. "Concentrating on the communication provides a higher level of abstraction than concentrating on the function APIs used within the system."

    Dorothea Lange: The Internment of Japanese American Citizens - ASX

    1. "'This is what we did. How did it happen? How could we?'"

    Debt Dodgers: Meet the Americans Who Moved to Europe and Went AWOL on Their Student Loans - Alexander Coggin

    1. "The amount of money adults in the US owe due to educations is over $1.3 trillion and jumps up by more than $2,000 every second."

    2. "Sure, I realize the responsibility I took on when I signed the papers and agreed to take out the loans, but I should have never had to do it in the first place. I feel some sort of civic duty not to pay them back, as if my small protest will make any kind of difference."

    3. "Our mentors and teachers told us that we would pay this education off for a long time, but everyone in America is doing it so it's almost like eating breakfast. That's how Americans are raised."

    4. Thanks to Brandon Hirdler for the article

    Erlang Question mailing list: Why Erlang looks like it does - Robert Virding

    1. "Again our goal was to solve the problem, not design a language with a predefined set of primitives."

    2. "Everything was very problem oriented and we did not have as goals that Erlang should be a functional language or that we should implement the actor model."

    3. "IMAO one reason that Erlang/OTP has taken a long time to become adopted is that in many cases it took designers of these other systems a long to realise that they actually did have these requirements and that Erlang was a good way of meeting them."

    Ian Murdock In His Own Words: What Made Debian Such A Community Project - Gabriella Coleman

    1. "'And my final test as to whether or not Debian succeeded was: could the founder step away from the project and could the project keep going because that is the only point at which you know that the project has basically taken a life of its own.'"

    Why programming is a good medium for expressing poorly understood and sloppily­formulated ideas - Marvin Minsky

    1. "A computer is like a violin. You can imagine a novice trying first a phonograph and then a violin. The latter, he says, sounds terrible."

    2. "To begin, I want to warn against the pitfall of accepting the apparently 'moderate' positions taken by many people who believe they understand the situation."

    ]]>
    Sketch &#35;5https://zeroclarkthirty.com/2016-01-30-sketch-5.htmlSat, 30 Jan 2016 00:00:00 +0000
  • From a little sketch series I'm doing.
  • ]]>
    What I'm reading 1/18-1/25https://zeroclarkthirty.com/2016-01-25-what-im-reading.htmlMon, 25 Jan 2016 00:00:00 +0000Clojure is for type B personalities - Zach Oakes

    1. "When looking at languages through this lens, it becomes obvious that a lot of internet flamewars are predicated not on objective disagreements, but subjective personality differences."

    2. "This may be pop psychology stuff, but it's convenient for my point so in the spirit of American politics I will treat it as fact."

    3. "It's been said that Shaq played basketball to do all the things he really wanted to do: making terrible movies, rapping about Kobe eating his ass, and holding things."

    4. "Paul Simon didn't come up with The Sound of Silence from a list of requirements. He sat in his bathroom with the lights off and riffed on his guitar until genius poured out."

    Jim Harbaugh's Guide to Dating - Spencer Hall

    1. "Milk. Babies grow from it. Men remain strong with it. Even dogs crave it, but do not let them have it! The farts are just too tremendous for words."

    2. "The only bad idea is to date someone who DOESN'T work with you. That person is not on your team. They're on team Meijer or team H&R Block or team County Land Appraiser's Office."

    3. "Trips right, leave a tight end in to block, and line her up way out wide on the left. If she can't find a soft spot in the defense you're better off without her anyways."

    The Last Days of Target - Joe Castaldo

    1. "The investigating team went to Fisher and John Morioka, the senior vice-president of merchandising, with a drastic proposal: Shut down the entire merchandising division so everyone could comb through and verify every single piece of data in the system — manually."

    2. "Ironically, even as consumers encountered barely stocked stores, Target's distribution centres were bursting with products. Target Canada had ordered way more stock than it could actually sell."

    3. "But by flipping the auto-replenishment switch off, the system wouldn't report an item as out of stock, so the analyst's numbers would look good on paper. 'They figured out how to game the system,' says a former employee."

    The aliens are silent because they are extinct - ANU Canberra

    1. "A plausible solution to Fermi's paradox, say the researchers, is near universal early extinction, which they have named the Gaian Bottleneck."

    The Fallacy of Premature Optimization - Randall Hyde

    1. "What Hoare and Knuth are really saying is that software engineers should worry about other issues (such as good algorithm design and good implementations of those algorithms) before they worry about micro-optimizations such as how many CPU cycles a particular statement consumes."

    2. "Premature optimization may lead to code that is difficult to modify, maintain, and read. Improper design and implementation, on the other hand, often necessitate a complete rewrite."

    Alec Baldwin with Peter Beard: The Elephant Attack - ASX

    1. "Well, you can't escape an elephant."

    2. "The elephants went back up the hill so to speak and we just stood there. The sons of bitch, this matriarch came again. So then she starts coming, we start running again, make it feel happy. But it wasn't stopping."

    ]]>
    What I'm reading 1/11-1/18https://zeroclarkthirty.com/2016-01-18-what-im-reading.htmlMon, 18 Jan 2016 00:00:00 +0000Political Correctness is a More Dangerous Form of Totalitarianism - Slavoj Žižek

    1. "I hate this politically correct respect, oh, what is your food, what are your cultural forms. No, I tell them tell me a dirty joke about yourself and we will be friends and so on. It works."

    2. "The only thing I know is that when I was in Missoula, Montana, I got engaged in a very friendly conversation with some Native Americans. They hate the term and they gave me a wonderful reason. They told me Native American and you are a cultural American so what, we are part of nature. They told me we much preferred to be called Indians. At least our name is a monument to white men's stupidity who thought they are in India when they come here."

    Harold Brodkey, The Art of Fiction No. 126 - James Linville

    1. "Ideals are for greeting cards. I am trying to change consciousness, change language in such a way that the modes of behavior I am opposed to become unpopular, absurd, unlikely. You try to work toward a culture that takes time and conscience seriously in a real way and not as part of a tidal flow of hype."

    2. "You really spend an awful lot of your time in New York just being confused about how to act."

    3. "I stopped trying, because I got this sense, you see, that there was this trap, that you had to merchandise yourself, be cute on cue. And then you'd be stuck with producing that effect, that personality, all your life; you'd never escape."

    4. "It was something about being a young man and being part of the society of the time. I wasn't prepared to assert myself as an independent voice arguing and howling."

    5. "But the cruelest to bear is the beginning, the confrontation with the blank sheet of paper, where you have the chance to get up and turn your back on being a writer. You think, 'I'll quit, I'll live a real life as a citizen; I'll belong to the PTA and love my children. And have a country house.'"

    6. "There is a movement away from ordinary life, from statistically normal life, the kind of life that most people of your class lead, into this other specialization that is really only bearable at the beginning."

    Private messages at work can be read by European employers - Kevin Rawlinson, BBC News

    1. "The worker, an engineer in Romania, had hoped the court would rule that his employer had breached his right to confidential correspondence when it accessed his messages and subsequently sacked him in 2007."

    The Reductive Seduction of Other People's Problems - Courtney Martin

    1. "While thousands of the country's best and brightest flock to far-flung places to ease unfamiliar suffering and tackle foreign dysfunction, we've got plenty of domestic need."

    2. "There's a social dimension to this: the 'likes' one gets for being an international do-gooder might be greater than for, say, working on homelessness in Indianapolis."

    3. "They drop technology without having a training or maintenance plan in place, or try to shift cultural norms without culturally appropriate educational materials or trusted messengers."

    4. Thanks to Brandon Hirdler for the link

    People call me Aaron - Noah Swartz

    1. "I watched as he was turned into a figurehead for American injustice and the open access movement, as every nuanced part of him — the parts that I loved to chat about with the people close to him — were stripped away and he was made a banner of the exceptional being crushed by dumb laws like the CFAA."

    2. "I started being unable to control when I cried. Tears would stream from my eyes if I stayed up too late, or if I was feeling especially socially anxious or rejected."

    Requiem For a Trijet Masterpiece – The Lockheed L-1011 - Peter J.M. Harrington-Cressman

    1. "History has often dictated that airlines don't purchase the aircraft; they purchase the manufacturer."

    2. "Whereas the DC-10 had a rather simple interior design, the TriStar had its entire interior concept conceived by the industrial design firm of Sundberg-Ferrar."

    What I Believe - E.M. Forster

    1. "No, I distrust Great Men. They produce a desert of uniformity around them and often a pool of blood too, and I always feel a little man's pleasure when they come a cropper."

    2. "Love and loyalty to an individual can run counter to the claims of the State. When they do - down with the State, say I, which means that the State would down me."

    3. "The evidence of history shows us that men have always insisted on behaving creatively under the shadow of the sword; that they have done their artistic and scien- tific and domestic stuff for the sake of doing it, and that we had better follow their example under the shadow of the aeroplanes."

    ]]>
    What I'm reading 1/4-1/11https://zeroclarkthirty.com/2016-01-11-what-im-reading.htmlMon, 11 Jan 2016 00:00:00 +0000The internet has made defensive writers of us all - Paul Chiusano

    1. "I love this notion of relying on 'the common sense and ordinary charity of readers'. What a wonderful, inspiring idea."

    2. "I've also taken to toning down any rhetorical flourishes that could be interpreted uncharitably in a way that annoys some people. The result: boring writing stripped of a lot of my own personal style."

    3. "It encourages a tendency to be attached to ideas and defend them against attackers, rather than letting ideas exist separate from ourselves as they should."

    William Klein's Tokyo Pop - Marlaine Glicksman

    1. "Klein, however, declared 'this Moriyama guy' not only as derivative but, he said, a 'rip-off.'"

    DNC Chair, Fueled by Booze PACs, Blasts Legal Pot - Zaid Jilani

    1. "The fifth-largest pool of money the congresswoman has collected for her re-election campaign has been from the beer, wine, and liquor industry."

    The sad graph of software death - Gregory Brown

    1. "The business side of the house may blame developers for not moving fast enough, while the developers blame the business for piling work on too quickly and not leaving time for cleanup, testing, and long-term investments. Typically, both sides have valid concerns, but they don't do an especially good job of communicating with one another."

    Don't fear the Monad - Brian Beckman

    1. "If you know a function, you know everything you need to know to understand monads."

    2. "Everyone knows that one of the biggest problems in software today is controlling complexity."

    3. "We're out of control in the complexity space."

    4. "The way to control complexity is compositionality."

    Yes, Give It Away - Richard Stallman

    1. "One of the important reasons for giving software away free is to enable the users to change it."

    2. "Furthermore, they develop self-reliance, confidence, and a sense of responsibility."

    Paul Graham is Still Asking to be Eaten - Holly Wood

    1. "Most of us outside of Palo Alto have no idea how a product as fucking stupid as Peeple gets valued at $7.6 million while a 4th grade teacher can't pay off her student loans and pay rent at the same time."

    2. "But what the market deems valuable is not necessarily aligned with what is ultimately good for us as a society or even what we want. Because under conditions of extreme inequality, the market is biased towards people who have lots of money, at the expense of virtually everyone else."

    Assassins Were Paid Less Than $30,000 to Kill Mexican Mayor - Ryan Devereaux

    1. "According to reports, sometime shortly after 7 a.m. on Saturday morning, intruders entered Mota's home, tied her up, beat her, and shot her in the head."

    2. "According to the United Nations, from December 2006, when the Mexican government first sent the military into the streets to take on the nation's drug cartels (eventually securing extensive U.S. support), to November 2012, a total of roughly 2 percent of 102,696 reported homicides led to prosecutions."

    Type classes - Cats project contributors

    1. "The type class pattern is a ubiquitous pattern in Scala, its function is to provide a behavior for some type. You think of it as an "interface" in the Java sense."

    2. "We use this pattern to retrofit existing types with new behaviors. This is usually referred to as 'ad-hoc polymorphism'."

    When anger turns to ink: A coming-of-age memoir by an artist enraged - The Economist

    1. "She burned to put her nib to political and social issues."
    ]]>
    What I'm reading 12/28-1/4https://zeroclarkthirty.com/2016-01-04-what-im-reading.htmlMon, 4 Jan 2016 00:00:00 +0000The Website Obesity Crisis - Maciej Cegłowski

    1. "Remember when Google Maps, the most sophisticated web app of its day, was thirty-five times smaller than a modern news article?"

    2. "I began by replacing the image carousels with pictures of William Howard Taft, America's greatest president by volume."

    3. "In conversations with web performance advocates, I sometimes feel like a hippie talking to SUV owners about fuel economy."

    4. "The designers of pointless wank like that Facebook page deserve the ultimate penalty. They should be forced to use the Apple hockey puck mouse for the remainder of their professional lives."

    5. "These comically huge homepages for projects designed to make the web faster are the equivalent of watching a fitness video where the presenter is just standing there, eating pizza and cookies."

    6. "Advertisers will tell you it has to be this way, but in dealing with advertisers you must remember they are professional liars."

    The scurrilous lies written about Charlie Hebdo - Robert McLiam Wilson

    1. "When the politically or religiously dismayed decide it's time to wade, guns blazing, into the supergeek underworld of leftwing satirical weeklies, that's something that changes the very laws of physics."

    2. "[Charlie Hebdo staff] look like kittens in a bunker. I'm tempted to say that this is now the world they live in. But that's not what is interesting. The point is that this is now the world you live in."

    3. "Only two days after the murders, the New Yorker published a riotously ignorant article that took Charlie to task for its evident Nazi-standard racism. It was in the New Yorker so it must have been true. It was a filthy and stupid libel."

    Spain 1937 - W.H. Auden

    1. "O no, I am not the Mover, Not today, not to you."

    How Completely Messed Up Practices Become Normal - Dan Luu

    1. "The data are clear that humans are really bad at taking the time to do things that are well understood to incontrovertibly reduce the risk of rare but catastrophic events. We will rationalize that taking shortcuts is the right, reasonable thing to do. There's a term for this: the normalization of deviance."

    2. "As an industry, we spend a lot of time thinking about how to incentivize consumers into doing what we want. But then we set up incentive systems that are generally agreed upon as incentivizing us to do the wrong things, and we do so via a combination of a game of telephone and cargo cult diffusion."

    3. "Turning off or ignoring notifications because there are too many of them and they're too annoying? An erroneous manual operation? This could be straight out of the post-mortem of more than a few companies I can think of, except that the result was a tragic death instead of the loss of millions of dollars."

    4. "Humans are bad at reasoning about how failures cascade, so we implement bright line rules about when it's safe to deploy. But the same thing that makes it hard for us to reason about when it's safe to deploy makes the rules seem stupid and inefficient!"

    5. "In most company cultures, people feel weird about giving feedback. Everyone has stories about a project that lingered on for months after it should have been terminated because no one was willing to offer explicit feedback."

    Truffles, Caviar, and Cristal: A Tale from the Mythic Days of Magazine Expense Accounts - Robert Hughes

    1. "To put it bluntly, she gorged as though she had skipped lunch, but came out of it looking like the Sugar Plum Fairy, albeit one with truly wonderful breasts."

    Why We Can't Solve Big Problems - Jason Pontin

    1. "Since Apollo 17's flight in 1972, no humans have been back to the moon, or gone anywhere beyond low Earth orbit. No one has traveled faster than the crew of Apollo 10. (Since the last flight of the supersonic Concorde in 2003, civilian travel has become slower.)"

    2. "With the exception of Google (which wants to "organize the world's information and make it universally accessible and useful"), the ambitions of startups founded in the last 15 years do seem derisory compared with those of companies like Intel, Apple, and Microsoft, founded from the 1960s to the late 1970s."

    FUCK THE CLOUD - Jason Scott

    1. "By the cloud, of course, I mean this idea that you have a local machine, a box running some OS, and a vital, distinct part of what you do and what you're about or what you consider important to you is on other machines that you don't run, don't control, don't buy, don't administrate, and don't really understand."

    2. "If you lose your shit, the technogeeks will not help you. They will giggle at you and make fun of your not understanding the fundamental principles and engineering of client-server models."

    3. "Insult, berate and make fun of any company that offers you something like a 'sharing' site that makes you push stuff in that you can't make copies out of or which you can't export stuff out of. They will burble about technology issues. They are fucking lying."

    Entire US voter registration record leaks (191 million) - Chris Vickery

    1. "I have recently downloaded voter registration records for 191 million Americans from a leaky database. I believe this is every registered voter in the entire country. To be very clear, this was not a hack."

    2. "The mysterious, insecure database is currently configured for public access. No password or other authentication is required at all. Anyone with an internet connection can grab all 300+ gigabytes."

    Peter Doig Discussing Sigmar Polke - The ASX Team

    1. "They were more quirky, idiosyncratic things that he discovered for himself and that he seemed to find personally amusing."

    Silicon Valley is confusing pseudo-science with innovation - Ben Popper and Elizabeth Lopatto

    1. "On the surface everything about Theranos looked good, right? It wasn't until after The Wall Street Journal dug in that all the irregularities in partnerships, relationships with regulators, and general fuckery began to surface."

    2. "'Ask forgiveness, not permission' works fine in software. The medical field doesn't move as fast as the software industry because moving fast and breaking things is fine for things but not for people."

    2015: Another Bad Year for Blasphemers - Sarah McLaughlin

    1. "In February, a man was sentenced to death (likely beheading, as is the Saudi Arabian way) for cursing God and Muhammad and hitting a Koran with a shoe."

    2. "This fall, Iranian courts decided that activist Soheil Arabi will spend 7 years in prison as punishment for "insulting the Prophet" on Facebook, and must prove his faith and knowledge of Islam in monthly meetings. This is actually an improvement over his earlier sentence: death."

    3. "Specifically, they beat [Farkhunda Malikzada], ran over her body with a car and dragged her down the street, stoned her, and then lit her on fire. She received essentially no help from the police during the attack."

    4. "In February, Al Qaeda members 'taught a lesson to blasphemers' by hacking atheist Bangladeshi blogger Avijit Roy to death with machetes."

    5. "Amos Yee Pang Sang, a 16-year-old blogger in Singapore was sentenced to a 4 week prison term in July for insulting Christianity, and he 'admitted to his guilt and promised not to reoffend, as he realised his actions were against the law and could disrupt social harmony' after he was required to go to counseling."

    Interview with Jesper Louis Andersen about Erlang, Haskell, OCaml, Go, Idris, the JVM, software and protocol design  —  PART I - Federico Carrone

    1. "In biology, it has been observed solutions are usually not rewriting code, but rather patching code. Imagine a world where we are more inclined to build on top of what we already have rather than go down and rewrite older parts."

    2. "If the waterfall model risks not building the right product, then agile risks not building the product right."

    3. "If you reject an old idea, you need to explain why. If you reinvent an old idea, you need to know you reinvented it and what happened historically for that idea not to catch on."

    Interview with Jesper Louis Andersen about Erlang, Haskell, OCaml, Go, Idris, the JVM, software and protocol design  —  PART II - Federico Carrone

    1. "Many of the problems in the design space requires a different approach than sheer execution brute force, especially in a multicore world. Had fast execution been important, it would have been addressed a long time ago."

    2. "If you introduce many abstractions, you are also introducing the need for readers to have that knowledge. It is possible to go overboard here, and end up with code which only a few people in the world can read and understand."

    Spying on Congress and Israel: NSA Cheerleaders Discover Value of Privacy Only When Their Own Is Violated - Glenn Greenwald

    1. "All sorts of people who spent many years cheering for and defending the NSA and its programs of mass surveillance are suddenly indignant now that they know the eavesdropping included them and their American and Israeli friends rather than just ordinary people."

    2. "What happened to all the dismissive lectures about how if you've done nothing wrong, then you have nothing to hide? Is that still applicable? Or is it that these members of the U.S. Congress who conspired with Netanyahu and AIPAC over how to sabotage the U.S. government's Iran Deal feel they did do something wrong and are angry about having been monitored for that reason?"

    Garbage Collection in Erlang - James Hague

    1. "The key is that garbage collection in Erlang is per process."

    2. "A system may have tens of thousands of processes, using a gigabyte of memory overall, but if GC occurs in a process with a 20K heap, then the collector only touches that 20K and collection time is imperceptible."

    ]]>
    Sketch &#35;2https://zeroclarkthirty.com/2016-01-01-sketch-2.htmlFri, 1 Jan 2016 00:00:00 +0000#2

    ]]>
    What I'm reading 12/21-12/28https://zeroclarkthirty.com/2015-12-28-what-im-reading.htmlMon, 28 Dec 2015 00:00:00 +0000ISIS is a revolution - Scott Atran

    1. "What inspires the most lethal assailants in the world today is not so much the Quran or religious teachings but rather a thrilling cause and a call to action that promises glory and esteem in the eyes of friends."

    2. "The Caliphate is an attractor to all of these young people, providing purpose and freedom from what they have come to see as the vice of a meaningless, material world."

    3. "Besides, brutal terror scares the hell out of enemies and fence-sitters."

    4. "Asymmetric operations involving spectacular killings to destabilise the social order is a tactic that has been around as long as recorded history."

    5. "Without an overarching national identity and the liberal values and institutions to sustain it, popular choice and elections lead only to a tyranny of the majority, as both ancient Athens and post-Saddam Iraq confirm."

    The Great Republican Revolt - David Frum

    1. "You can measure their pessimism in polls that ask about their expectations for their lives—and for those of their children. On both counts, whites without a college degree express the bleakest view."

    2. "The country has recovered from the worst economic disaster since the Great Depression. Most of its people have not. Many Republicans haven’t shared in the recovery and continued upward flight of their more affluent fellow partisans."

    3. "Trump Republicans were not ideologically militant. Just 13 percent said they were very conservative; 19 percent described themselves as moderate. Nor were they highly religious by Republican standards."

    The Drake Effect Is Real, But The Nicki Effect Is Bigger - Allison McCann

    1. "For songs in the top quartile of streams, a Nicki feature was streamed 46 percent more often, on average, compared with 25 percent more often for Drake."

    how to make the internet not suck (as much) - Dan Pollock

    1. "Use this file to prevent your computer from connecting to selectedinternet hosts."

    Did Apple Just Give Up? - Sean Geraghty

    1. "Apple's emphasis of making things minimal and unobtrusive is actually having the opposite effect to what they're after. Instead of increasing the beauty and simplicity of their products, they're instead leading people to have to search for ways around things."

    GPL enforcement is a social good - Matthew Garrett

    1. "Toys that have a 'Guaranteed to work until' date, and then suddenly Barbie goes dead and you're forced to have an unexpected conversation about API mortality with your 5-year old child."

    Santa Claus confirms NSA attack on naughty or nice database - Joe McNamee

    1. "The NSA further pointed out that Mr Claus set up the database without any authorisation and, crucially, chose to avoid providing either encryption keys or an encryption backdoor to the United States or any of its five-eyes allies."

    Landmark Algorithm Breaks 30-Year Impasse - Erica Klarreich

    1. "Babai's new algorithm starts by taking a small set of nodes in the first graph and virtually 'painting' each one a different color. Then it begins to look for an isomorphism by making an initial guess about which nodes in the second graph might correspond to these nodes, and it paints those nodes the same colors as their corresponding nodes in the first graph. The algorithm eventually cycles through all possible guesses."

    The Rise And Fall Of Venture-Backed News Readers In One Chart

    1. "Specifically, we looked at the wave of venture financing deals into the news reader space since January 2010 – and the subsequent rash of acquisitions or shutdowns that began in 2013."

    A Scala Writer Monad - Alex Baranosky

    1. "In essence Writer Monad is a sort of immutable, functional Builder pattern."
    ]]>
    What I'm reading 12/14-12/21https://zeroclarkthirty.com/2015-12-21-what-im-reading.htmlMon, 21 Dec 2015 00:00:00 +0000Eric Posner: The First Amendment's Nemesis - Ken White

    1. "Eric Posner is well-cast as the First Amendment's nemesis: he represents everything it stands against. He represents obeisance to passing tastes about what is couth, clenched fists of power disguised as helping hands, suppression dressed up as order. He is the Foe."

    It's OK not to use tools - Jonas Downey

    1. "As builders, we like tools and tech because they're interesting and new, and we enjoy mastering them. But when you think about the people we're building for, the reality is usually the opposite. They need simple designs, clear writing, less tech, and fewer abstractions."

    How Rogue Techies Armed the Predator, Almost Stopped 9/11, and Accidentally Invented Remote War - Arthur Holland Michel

    1. "'The Icelandic women were amazing' is about as much as he'll volunteer."

    2. "The team framed a copy of a 2000 Defense Department report that had declared the Predator a failure and hung it on a wall next to a list of what Marshall called their greatest hits."

    Congress vs. the Internet - Shari Steele

    1. "Just as we don't want the phone company censoring our telephone calls, we should be very troubled by any copyright law interpretation that would assign liability to those who provide Internet service."

    Free Concurrency with GNU Parallel - Philipe Fatio

    1. "By making sure that our script has a simple, yet functional interface and by printing to standard output, we were able to run it with GNU Parallel, achieving the desired goals of running the simulation with all possible combinations of parameters and making use of all CPU cores."

    How To Predict Bad Cops In Chicago - Rob Arthur

    1. "Even laying aside the moral imperative to prevent abuse, the financial cost of police misconduct to the cash-strapped city is immense. Direct costs, in terms of legal fees and the funds disbursed in settlements, exceeded $500 million over 10 years, according to a Better Government Association study."

    2. "Repeaters only make up a small fraction of the more than 12,000 officers on Chicago's force — perhaps 1 percent to 10 percent of the officers in the database, depending on where you draw the line — but are responsible for a huge fraction of the complaints: 10 percent of the officers who had received complaints generated 30 percent of the total departmental complaints since 2011."

    Python Is Not C: Take Two - Jean Francois Puget

    1. "When it is compiled with Numba, our native Manhattan distance code using loops over Numpy arrays is about 10,000 times faster than the code we started with 6 months ago."

    Introducing new open-source tools for the Elixir community - Steve Cohen

    1. "The system that manages rate limits for both the Pinterest API and Ads API is built in Elixir. Its 50 percent response time is around 500 microseconds with a 90 percent response time of 800 microseconds. Yes, microseconds."

    2. "The Java version used an Actor system and weighed in at around 10,000 lines of code. The new Elixir system has shrunk this to around 1000 lines."

    Too many open files: Tracking down a bug in production - Paul Bostrom

    1. "We use a Clojure agent as a queue to store the set of HTTP clients that were marked, and then call `close' on each one. With logging turned up for this namespace, I could see that clients were being queued up, but never closed."

    2. "We issue about 2 to 3 million requests per day to these APIs and we would see the problem occur every three to four days, so roughly one in 10 million API requests returned a problematic response."

    ]]>
    What I'm reading 12/7-12/14https://zeroclarkthirty.com/2015-12-14-what-im-reading.htmlMon, 14 Dec 2015 00:00:00 +0000The Lessons of Bygone Free-Speech Fights - Conor Friedersdorf

    1. "The same laws or regulations used to silence bigots can be used to silence you."

    2. "20 years ago, opponents of speech codes warned that those with the impulse to suppress any speech were putting us on a slippery slope, that core, protected speech would inevitably be punished or chilled. Today's campus-speech battles suggest they were correct."

    Romain Slocombe: City of Broken Dolls - ASX

    1. "'My work's not only about my obsession with Japanese women, it's about medical fetishism and my fascination with accidents.'"

    Bret Easton Ellis on Living in the Cult of Likability - Bret Easton Ellis

    1. "That's the real crime being perpetrated by the reputation culture: stamping out passion; stamping out the individual."

    2. "Ultimately, the reputation economy is about making money. It urges us to conform to the blandness of corporate culture and makes us react defensively by varnishing our imperfect self so we can sell and be sold things."

    Jacob Appelbaum at Aaron Swartz Day 2015 - Lisa Rein

    1. "Part of what Aaron carried was an understanding that it wasn't just that something needed to be done. He carried with him the idea that very specific things needed to happen, and for very good reasons, to benefit all of those alive and all of those yet to live."

    2. "Today, he would’ve been 29. Use your time wisely. May you have more time than him, and may you use it as wisely as he did."

    Brassai Interviews Pablo Picasso: An excerpt from 'Conversations with Picasso' - ASX

    1. "If I were to sign it now, I'd be committing forgery. I’d be putting my 1943 signature on a canvas painted in 1922. No, I cannot sign it, madam, I'm sorry."

    2. "And the name a person bears or adopts has its importance."

    3. "That was a good idea of yours to chop up the female body that way. The details are always exciting."

    4. "Venus is replaced by the Virgin, but the same life goes on."

    Michigan State's harrowing, Himalayan journey to the top of the Big Ten's last undefeated summit - Spencer Hall

    1. "On day three, Young Connor threw the minifridge several thousand feet off the south face of the mountain. I hailed this as a great display of leadership. The men agreed."

    Dash Snow: Polaroids - ASX

    1. "Dash Snow originally started taking photos when he was a teenager."

    The Ultimate Trip: 100 rare behind-the-scenes photos from Stanley Kubrick's '2001: A Space Odyssey' - One Perfect Shot

    1. "I always counter this notion with the fact that 2001 looks way better than the crappy moon landing footage; if Kubrick had directed that shit, it would be beautiful."

    DevOps and the Myth of Efficiency, Part I - Christian Posta

    1. "Bad behavior arises when you abstract people away from the consequences of their actions."

    National Front Gets a Boost in French Regional Elections - Alissa J. Rubin

    1. "The National Front not only came in first in the popular vote on Sunday with 28 percent of votes cast nationwide, it was leading races to govern six of France’s 13 regions, decisively in at least two."

    MIT Sophomore Arrested at Logan For Wearing LED Device - Angeline Wang

    1. "She 'said it was a piece of art,' Margolis said, and 'refused to answer any more questions.'"
    ]]>
    What I'm reading 11/30-12/7https://zeroclarkthirty.com/2015-12-07-what-im-reading.htmlMon, 7 Dec 2015 00:00:00 +0000CINDY SHERMAN: “Untitled Film Stills” (1977-1980) - ASX

    RECRUITMENT 2016 - Victoria Valentine

    1. Credit: https://vimeo.com/user27228255

    Discipline: Stomp Out Cynicism - Chad Fowler

    1. "Cynicism is born of laziness and fear: It's easy to complain about something."

    Watch a VC use my name to sell a con. - Jamie Zawinski

    1. "Follow the fucking money. When a VC tells you what's good for you, check your wallet, then count your fingers."

    Dating Without Kundera - Maciej Cegłowski

    1. "Milan Kundera is the Dave Matthews of Slavic letters, a talented hack, certainly a hack who's paid his dues, but a hack nonetheless."

    Clojure: State Management - Jay Fields

    1. "I think state shapes Clojure more than any other influence; it's the core of the language."

    I Turned Off JavaScript for a Whole Week and It Was Glorious - Klint Finley

    1. "But the most surprising thing is that most things just worked. And in many cases, worked better."

    If you keep saying Saudi Arabia is like ISIS, you might get sued - Adam Taylor

    1. "According to a report in pro-government newspaper Al Riyadh, the Saudi justice ministry is planning to sue a Twitter user who suggested that a death sentence recently handed out to a Palestinian artist for apostasy was 'ISIS-like.'"

    The Lisp Curse - Rudolf Winestock

    1. "The moral of this story is that secondary and tertiary effects matter. Technology not only affects what we can do with respect to technological issues, it also affects our social behavior. This social behavior can loop back and affect the original technological issues under consideration."

    2. "Since making Scheme object-oriented is so easy, many Scheme hackers have done so. More to the point, many individual Scheme hackers have done so."

    3. "Programs written by individual hackers tend to follow the scratch-an-itch model. These programs will solve the problem that the hacker, himself, is having without necessarily handling related parts of the problem which would make the program more useful to others."

    Ex Machina - Alex Garland

    1. "Caleb: Did you program her to flirt with me? Nathan: If I did, would that be cheating?"

    A Decade-Old Gag Order, Lifted - Jameel Jaffer

    1. "According to the Justice Department's inspector general, the FBI issued a staggering 143,074 NSLs between 2003 and 2005. And every NSL was accompanied by a categorical and permanent gag order."

    2. "This kind of secrecy prevents the public from learning how the government's surveillance authorities are used, distorts public debate, shields policymakers from accountability for their decisions, and insulates surveillance powers from judicial review."

    Fail at Scale & Controlling Queue Delay - Adrian Colyer

    1. "Good queues convert bursty arrivals into smooth, steady departures (and reduce in length when the arrival rate drops back down below the departure rate). Bad queues (standing queues) serve no useful purpose and simply create excess delay."
    ]]>
    What I'm reading 11/23-11/30https://zeroclarkthirty.com/2015-11-29-what-im-reading.htmlMon, 30 Nov 2015 00:00:00 +0000Career Advice - Moxie Marlinspike

    1. "They are the future you. Do not think that you will be substantially different. Look carefully at how they spend their time at work and outside of work, because this is also almost certainly how your life will look."

    2. "I know that by making choices designed to land me in the first class cabin, it would be difficult to avoid also inheriting the dreariness associated with its current occupants."

    3. "I try to remind myself that if leaving prison is scary, the same is likely true for any genuine process of discovery."

    Alex Majoli and the Creators of "Another Congo" Bare All - Paul Loomis

    1. "When do this I go and set up my lights without saying anything to anyone. So they feel like 'oh, we are on a stage.'"

    Your Pipeline Argument Is Bullshit - Anonymous

    1. "When you talk only (or mostly) about the 'pipeline', I hear someone who doesn't want to work on hard problems. You don't have a 'women in tech' problem. You have a 'senior women in tech' problem."

    Max Headroom broadcast signal intrusion - Wikipedia

    1. "An unidentified female accomplice wearing a French maid outfit said to him, 'Bend over, bitch!'. The accomplice then started to spank the man with a flyswatter as the man screamed loudly."

    2. The video: https://www.youtube.com/watch?v=tWdgAMYjYSs

    Primer - directed by Shane Carruth

    1. "Maybe it was the dramamine kicking in, but I remember this moment in the dark with the reverberation of the machine. It was maybe the most content I've ever been."

    English is not normal - John McWhorter

    1. "But our monolingual tendency leaves us like the proverbial fish not knowing that it is wet. Our language feels 'normal' only until you get a sense of what normal really is."

    2. "We think it's a nuisance that so many European languages assign gender to nouns for no reason, with French having female moons and male boats and such."

    The Advertising Bubble - Maciej Cegłowski

    1. "The problem is not that these companies will fail (may they all die in agony), but that the survivors will take desperate measures to stay alive as the failure spiral tightens."

    Excerpt from "Surely you're joking, Mr. Feynman" - Richard Feynman

    1. "Now that I am burned out and I'll never accomplish anything, I've got this nice position at the university teaching classes which I rather enjoy, and just like I read the Arabian Nights for pleasure, I'm going to play with physics, whenever I want to, without worrying about any importance whatsoever."

    The Yale Problem Begins in High School - Jonathan Haidt

    1. "'So let me get this straight. You were unanimous in saying that you want your school to be a place where people feel free to speak up, even if you strongly dislike their views. But you don’t have such a school.'"

    2. "After the first dozen questions I noticed that not a single questioner was male."

    Refs and Transactions (Clojure) - Rich Hickey

    1. "Refs are bound to a single storage location for their lifetime, and only allow mutation of that location to occur within a transaction."

    Atoms (Clojure) - Rich Hickey

    1. "Atoms are an efficient way to represent some state that will never need to be coordinated with any other, and for which you wish to make synchronous changes."

    How I get ready: Karl Pilkington - Rosanna Greenstreet

    1. "There is no point me having a great dinner if my feet aren't happy."

    Optimizing Hash-Array Mapped Tries for Fast and Lean Immutable JVM Collections - Adrian Colyer

    1. "Both Scala and Clojure use a Hash-Array Mapped Trie (HAMT) data structure for immutable collections. The HAMT data structure was originally developed by Bagwell in C/C++. It becomes less efficient when ported to the JVM due to the lack of control over memory layout and the extra indirection caused by arrays also being objects."
    ]]>
    What I'm reading 11/16-11/23https://zeroclarkthirty.com/2015-11-23-what-im-reading.htmlMon, 23 Nov 2015 00:00:00 +0000Uncertain Journeys - Ashley Gilbertson

    1. "We should not let that terrible night in Paris diminish our sense of humanity and responsibility."

    'Normal' Considered Harmful - Alan Kay

    1. "The problem is: we don't understand what the problem is."

    CNN Punished Its Own Journalist for Fulfilling a Core Duty of Journalism - Glenn Greenwald

    1. "As Murrow said in justifying his opposition to the Wisconsin Senator and his allies: 'there is no way for a citizen of a republic to abdicate his [sic] responsibilities.'"

    Director Lexi Alexander explains why she sides with pirates - Cory Doctorow

    1. "I used to get frustrated about my peers’ lack of courage, but lately I feel only empathy. I don’t like seeing talented storytellers ruled by fear."

    Perl 6 Release Talk - Larry Wall

    1. "Pretty much everything is a reference… if you scratch it."

    2. "What would it actually take to make a 100-year language?"

    3. "We'd just as soon have slow, stable - but sustainable - growth."

    The Doomsday Scam - C.J. Chivers

    1. "In meetings with smugglers in several towns along the border, red mercury inhabited the fertile mental terrain where fear and distrust of authority meet superstitious folklore."

    Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I - John McCarthy

    1. "The class of functions which can be formed in this way is quite limited and not very interesting."

    Refugee Vote a Failure for Obama - Elizabeth Williamson

    1. "Stopping refugees at the border will have little to no impact on the movement of terrorists, who generally either enter illegally or are born here."
    ]]>
    What I'm reading 11/09-11/16https://zeroclarkthirty.com/2015-11-16-what-im-reading.htmlMon, 16 Nov 2015 00:00:00 +0000Joseph Rodriguez on Desperation, Being an 'Outsider' and Stories inside the Head (2011)

    1. "My work is very subjective, I don’t believe in that objective stuff."

    Be the friction - Our Response to the New Lords of the Ring - Shoshana Zuboff

    1. "The indifference of the Lords of Silicon Valley is not a harbinger of the end times, but rather a wake up call to remind us that we must undertake the work of every age."

    2. "No longer exalted end users, we were demoted to data entry clerks, delivering content for them to hawk."

    3. "And most important to us now, the third law: In the absence of countervailing restrictions and sanctions, every digital application that can be used for surveillance and control will be used for surveillance and control, irrespective of its originating intention."

    4. "The challenge for the overseers had shifted from the architecture of buildings or the tedious labor of administrative records to that of information systems designed to produce automated, continuous, frictionless, perfect accounts available for zoom-in detail and zoom-out patterns any time, all the time, everywhere."

    5. "Our responses must summon political solutions that insist on democratic oversight of surveillance procedures, commercial solutions in which we reject companies that externalize responsibility for the consequences of their activities, and individuals who are willing to make a stand on what is right and what is wrong."

    6. "[The companies] had debased their most essential value — the sanctity of the user experience, the notion that they were, at bottom, on our side."

    Edward Snowden Explains How To Reclaim Your Privacy - Micah Lee

    1. "Snowden: I can neither confirm nor deny the existence of other Twitter accounts."

    Academic assholes and the circle of niceness - Inger Mewburn

    1. "Put simply, the nice clever people leave."

    2. "If performing like an asshole in a public forum creates the perverse impression that you are more clever than others who do not, there is a clear incentive to behave this way."

    3. "As time goes on the culture progressively becomes more poisonous and gets transmitted to the students."

    No One Minding the Store - Michael Tsai

    1. "In short, the system is broken on multiple levels, and there is no evidence to suggest that things will get better."

    We're Doing It All Wrong - Paul Phillips

    1. "To have to defend against all outcomes at all times is to abandon any hope of progress."

    The Physics of Why Airplane Wings Oscillate in Turbulence - Rhett Allain

    1. "Really all materials act like a spring. When you push on them, they bend—even if it’s just a little bit."
    ]]>
    What I'm reading 11/02-11/09https://zeroclarkthirty.com/2015-11-09-what-im-reading.htmlMon, 9 Nov 2015 00:00:00 +0000Ad Blockers and the Next Chapter of the Internet - Doc Searls

    1. "This is exactly what Shoshana Zuboff's three laws (first issued in the 1980s) predicted: First, that everything that can be automated will be automated. Second, that everything that can be informated will be informated. And most important to us now, the third law: In the absence of countervailing restrictions and sanctions, every digital application that can be used for surveillance and control will be used for surveillance and control, irrespective of its originating intention."

    2. "…because one thing you're not looking for is to be marked and tracked like an animal when you leave the site. But that's what you get when you visit most advertising-supported commercial websites, whether you want it or not."

    3. "Ad blocking at this stage is mostly prophylaxis. But it is also a demonstration of unprecedented individual agency in the online world, and a shift in power dynamics, from the supply side to the demand side."

    4. "If this be a boycott, it's surely the largest in human history."

    Lake Street Dive - "Rich Girl" (FUV Live at Clearwater)

    1. You're a rich girl

    The Sad and Beautiful World of Sparklehorse's Mark Linkous - Max Blau

    1. "'I was lucky enough to have been told how much my music meant to people,' Linkous said in 2001. 'Maybe something about my music will inspire one person to tell another person how much they mean to them today before it's [too] late.'"

    RECONSIDER - DHH

    1. "Angels? Really? You've plucked your self-serving moniker from the parables of a religion that specifically and explicitly had its head honcho throw the money men out of the temple and proclaim a rich man less likely to make it into heaven than a camel through a needle's eye."

    2. "Well, the reason I'm here is to remind you that maybe, just maybe, you too have a nagging, gagging sense that the current atmosphere of disrupt-o-mania isn't the only air a startup can breathe."

    3. "A whole generation of people working with and for the internet enthralled by the prospect of being transformed into a mythical creature."

    4. "Independence isn't missed until its gone. And when it's gone, in the sense of having money masters dictate YOUR INCREDIBLE JOURNEY, it's gone in the vast majority of cases."

    Full text of "Guerilla Open Access Manifesto" - Aaron Swartz

    1. "But sharing isn't immoral — it's a moral imperative. Only those blinded by greed would refuse to let a friend make a copy."

    2. "The world's entire scientific and cultural heritage, published over centuries in books and journals, is increasingly being digitized and locked up by a handful of private corporations."

    The Decay of Twitter - Robinson Meyer

    1. "Or maybe nothing can be done. No one promises growth forever. Communities and companies of all sizes fall apart. And some institutions that thrive on their tensions for many years can one day find them exhausted, worn out, limp, their continued use driven more by convenience and habit than by vibrancy and vigor."

    2. "…on Twitter, people say things that they think of as ephemeral and chatty. Their utterances are then treated as unequivocal political statements by people outside the conversation."

    3. "'Now, it's just Twitter. It's a space where all contexts are collapsed and all ideas can be mob-amplified or end up pulled for a Buzzfeed article.'"

    Avijit Roy's publisher, 2 bloggers hacked in Dhaka

    1. "Saturday's attack comes amid fears about the rise of extremism in Bangladesh. At least four atheist bloggers have been murdered in the country earlier this year."

    Executing Software Engineers for Bugs - Harlan Lieberman-Berg

    1. "Do we, as software engineers, have the same kind of moral responsibility as our fellow engineers in other disciplines? Should we refuse to build systems which can be turned against users, even if it means our jobs? How do we, as a profession and as a community, balance our responsibilities to our employers and to the general public?"

    Erdogan's Party in Turkey Regains Parliamentary Majority - Tim Arango and Ceylan Yeginsu

    1. "With 99 percent of the votes counted, according to the state broadcaster TRT, the Justice and Development Party, or A.K.P., captured 49.3 percent of the popular vote, giving it a solid majority of 316 seats in Parliament."

    Corporations and OSS Do Not Mix - Ian Cordasco

    1. "That said, when there's a bug introduced in the package, those companies email me, ping me relentlessly in IRC, create duplicate issues, and do everything they can to (perhaps unintentionally) overload me. As soon as a bug affects them, they want it fixed immediately. If you don't fix it in 24 hours (because maybe you have a real life or a family or you're sick or any number of other very valid reasons) then the threats start."

    Programmers: Stop Calling Yourselves Engineers - Ian Bogost

    1. "…software development has become institutionally hermetic. And that's the opposite of what 'engineering' ought to mean: a collaboration with the world, rather than a separate domain bent on overtaking it."

    2. "Engineering has always been a well-paid profession, but computing is turning it into a type of speculative finance rather than a calling."

    3. "Computing has become infrastructure, but it doesn't work like infrastructure."

    4. "Engineering claims an explicit responsibility to public safety and reliability, even if it doesn't always deliver."

    TDD is dead. Long live testing. - DHH

    1. "It was yoyo cycle of pride, when I was able to adhere to the literal letter of the teachings, and a crash of despair, when I wasn't. It felt like falling off the wagon."

    The forgotten history of Tumblr - Fernando Alfonso III

    1. "I tried all of the great tools that were around at the time - WordPress, Blogger - and obviously all the specialized tools - Flickr for photos and YouTube for videos - and I kept falling down."
    ]]>
    Elixir is not Rubyhttps://zeroclarkthirty.com/2015-11-01-elixir-is-not-ruby.htmlSun, 1 Nov 2015 00:00:00 +0000With Elixir's recent rise from "totally unknown" to "still definitely unknown but mentioned in hushed tones", I've noticed the more-common-than-it-should-be assertion that Elixir is - or basically is - Ruby.

    Despite resemblance on the initial pass, the languages, environments, and programming idioms are stark in their differences.

    Model - the how

    The differences start at the execution model.

    In Ruby, one moves through a monolithic call stack, manipulating objects. One can grab more call stacks with threads or fibers, with all threads/fibers sharing the same heap. Nearly every programming language or virtual machine in existence uses this model.

    Elixir (and every other language on the BEAM virutal machine) is built around processes. A process is a goofy, unfortunately loaded name for an independent unit of execution. It is not an OS process, and it is not an OS thread.

    The defining features of a process are its memory independence and the asynchronicity of its execution.

    Processes have their own heaps, and the VM collects process' garbage independently of each other. One process does not know about and cannot manipulate the memory owned by another process: they communicate by a message passing mechanism that copies data from the sender's heap to the receiver's.

    Processes are scheduled and executed concurrently by the VM, and up to a certain point the BEAM will be able to take advantage of as many cores as you allocate to it to execute code in parallel.

    Idiom - the what

    To program Elixir is to program in a functional style. Other articles bear this out in more detail, but the quick and dirty involves a few fairly straightforward ideas that have profound effects on how one programs computers:

    • the function as the primary abstraction -- including as data itself
    • immutability of data -- data is mapped from one value to a new value, rather than mutating it in place
    • a basis in expressions rather than statements, where all or nearly all code returns a value
    • referential transparency -- the same value input to a function will return the same output value every time

    Elixir is not a pure functional language: one can and must interact with the outside world. Functional programming in Elixir is not a theoretical dream. Elixir is functional because of practical benefits it confers to the programmer who is busy building concurrent systems.

    (You could say it was born this way: Erlang and the BEAM were invented to ensure the profitability of Ericsson by guaranteeing the reliability of its flagship telephone switches, rather than to prove the soundness of a typesystem.)

    Ruby has a few functional features, notably its module of higher-order methods like map and reduce, and its procs/blocks/lambdas. Ruby does not, however, do anything to mandate -- or even encourage -- immutability of data.

    This leads to practices -- perfectly idiomatic Ruby -- like using the << method inside of an #each higher-order function to side-effect an object, or using getters and setters to mutate object state rather than operate on values.

    The idiom in Ruby is overwhelmingly to mutate state.

    The amount of Ruby code I have seen that is concurrent at the application level is vanishingly small, and given the prominence of the above patterns and others, it isn't difficult to see why.

    With a few exceptions, the community seems to have abandoned this point, and despite Rails' threadsafety, web applications mostly rely on app servers that fork N application instance processes, proxing requests between them at the expense of memory economy.

    (further information as to why Ruby concurrency is so difficult)

    In Elixir, computation is concurrent from the start, whether you like it or not, and the emergent behaviors and idioms in the code reflect this. Even many simple programs take advantage of concurrency because, well, why not? It just isn't that much more difficult in Elixir.

    To paraphrase a quote I can't remember from an author I can't recall, programming languages aren't useful for their features list, they are useful for the behaviors and idioms they encourage. Ruby and Elixir encourage behaviors as different as prank calls and ballet.

    Philosophy - the why

    Elixir and Ruby are coming from two headspaces that overlap in sections, but with different heritages and different design goals.

    Both languages place value on what is known in the Ruby community as "programmer happiness". You can see this in their surface level aesthetic appearance, their succintness, their general lack of ceremony, expressiveness, etc. It appears in the efforts both communities devote to documentation, with the great Rails Guides paving the way for the excellent Elixir language documentation. It comes through in their courting of the beginner as a valued member of the community rather than a timesink to be scorned. None of this is surprising, as Elixir brings with it a number of former prominent Ruby programmers with an obvious talent for user experience.

    (As an aside, there is a divergence in tooling, where my experience has been better -- significantly so -- with Elixir's Mix and Hex tools than Ruby's combo of Rubygems, RVM/Rbenv, Bundler, and Rake)

    The cracks form when you look at Elixir as "an Erlang".

    As an Erlang, Elixir and its runtime come from a family whose main concerns are reliability, consistency, and concurrency. It is a community that is obsessed with failure: understanding it, preparing for it, and embracing it. Things fall apart.

    All aspects of the language and the environment revel in failure. From the concept of processes, to the supervisors and genservers that give them legs, to the code patterns that emphasize early failure, Elixir is a language and an environment built for systems that must run for months, years, or decades without maintenance.

    (I recommend Joe Armstrong's thesis for those who are curious on this point)

    Where Erlang itself has traditionally won traction among telecom, industrial, embedded, gaming, and low-latency/high-io applications due to this reliability bent, Ruby justifiably has other concerns, and has found adoption accordingly: Ruby is hugely popular among solo developers, consultancies, startups and beginners. That is, programmers who are generally concerned more with time-to-market and short-term ROI rather than maintenance.

    Elixir is poised to walk off with Ruby's bacon, as it fuses these two mentalities: systems that run for years should be as enjoyable to build as a NetHack clone.

    Further reading

    If something in the above has rustled you, I highly recommend Fred Hebert's Learn You Some Erlang for Great Good. It is the best text to understand what makes the Erlang environment distinct from whatever you're doing now. If you have no experience in Elixir/Erlang, I promise Fred's book to be as profound an experience as learning a Lisp or Haskell, and probably more practical.

    The book is in Erlang, so the language and tools in the book are not those you'll find in Elixir, but as Elixir is "an Erlang", there is almost no friction between taking your understanding of things like processes and OTP from Learn You Some Erlang and applying them in an Elixir context. One can absolutely learn Elixir through a combination of Fred's book and the Elixir guides/documentation/source code.

    ]]>
    What I'm reading 10/26-11/02https://zeroclarkthirty.com/2015-11-01-what-im-reading.htmlSun, 1 Nov 2015 00:00:00 +0000Librarian of Congress grants limited DRM-breaking rights for cars, games, phones, tablets, and remixers - Cory Doctorow

    1. "Section 1201 of the Digital Millennium Copyright Act prohibits tampering with, weakening or removing digital locks, even when you're doing so for a lawful purpose. But every three years, the Copyright Office lets individuals and nonprofits square off against some of the best-funded companies in the world in order to argue that you should be able to do lawful things with your lawful property."

    On Tinder, Off Sex - Ali Rachel Pearl

    1. From Tory Clark

    2. "Except we never have sex. And we never fall in love. We fall into almost love and then life takes us away from each other."

    The Emma Goldman Papers

    1. "On August 13, 1915, the Portland case against EG (for speaking about birth control) was dismissed in court by Circuit Judge Gatens, quoted as saying, 'There is too much tendency to prudery nowadays. We are shocked to hear things uttered that we are familiar with in our everyday life.'"

    Vintage East Village - Ken Schles

    1. "A couple kissing on 14th Street, November 1983."

    Why Middle-Class Americans Can't Afford to Live in Liberal Cities - Derek Thompson

    1. From Brandon Hirdler

    2. "There is a deep literature tying liberal residents to illiberal housing policies that create affordability crunches for the middle class."

    Do one thing… - Mike Loukides

    1. "Whether it's Skype, Twitter, Google Docs, Flickr, or something else, everything seems to be converging into a single application that doesn't do anything well, but does everything poorly."

    2. "I don't want anyone's walled garden. I've seen what's inside the walls, and it isn't a palace; it's a tenement."

    The Dream Of Being Better - Alex Balk

    1. "Eventually the dawn breaks, you haven't slept in hours, and you understand the only way to have kept yourself from all the heartless, hurtful acts you've spent your selfish life committing would be to have never been born in the first place."
    ]]>
    What I'm reading 10/19-10/26https://zeroclarkthirty.com/2015-10-25-what-im-reading.htmlSun, 25 Oct 2015 00:00:00 +0000Oklahoma Earthquakes Are a National Security Threat - Matthew Philips

    1. "Since 2008, Oklahoma has gone from averaging fewer than two earthquakes per year that measure at least 3.0 in magnitude to surpassing California as the most seismically active state in the continental U.S. This year, Oklahoma is on pace to endure close to 1,000 earthquakes."

    Let's Applaud Wesleyan's Student Censors For Honesty - Ken White

    1. "People who respond to student paper content they don't like by trashing the paper to suppress it are thug trash, and it's nice of them to sign a self-identifying petition."

    2. "I like the petition. I like it because the students aren't pretending to be anything but censorious: it's honest."

    Gustavus student newspaper's 'Case Day' story gets papers trashed - Kate Maternowski

    1. Related to the above, this shit happened at Gustavus just as I was joining the Weekly.

    The Assassination Complex - Jeremy Scahill

    1. "Drones are a tool, not a policy. The policy is assassination."

    2. "During one five-month period of the operation, according to the documents, nearly 90 percent of the people killed in airstrikes were not the intended targets."

    Whale Song Explained - David Rothenberg and Mike Deal

    1. "Extraordinarily, while the whales in each population have distinctly different dialects of song, all the whales within a population change their song together synchronously."

    Homan Square revealed: how Chicago police 'disappeared' 7,000 people - Spencer Ackerman

    1. "According to an analysis of data disclosed to the Guardian in late September, police allowed lawyers access to Homan Square for only 0.94% of the 7,185 arrests logged over nearly 11 years."

    2. "No contemporaneous public record of someone’s presence at Homan Square is known to exist."

    3. "The warehouse is also unique in not generating public records of someone’s detention there, permitting police to effectively hide detainees from their attorneys."

    America's biggest economic dilemma: private affluence amid public squalor - @KStreetHipster and Matthew Yglesias

    1. "'There's a whole society to improve. Crime and inequality and poverty and on and on, but (most of) our jobs aren't for improving society. Instead out jobs are (typically) for enriching someone. Not a societal good in and of itself, but a private good.'"

    Getting a full PDF from a DRM-encumbered online textbook - Jonathon Vogel

    1. "Several coffee/tea/tinder breaks later, broken up by restarting the scraping process where it broke for some reason, and all the pages are living on my hard drive. Nice!"

    The Hostile Email Landscape - Jody Ribton

    1. "In the end, I gave up and switched back to Google Apps. It felt like defeat. This isn't how the internet is supposed to work."
    ]]>
    What I'm reading 10/12-10/19https://zeroclarkthirty.com/2015-10-19-what-im-reading.htmlSun, 18 Oct 2015 00:00:00 +0000Out of the Darkness - ACLU

    1. "In between the sessions, the conditions designed to assault Abu Zubaydah's senses persisted. He remained in solitary confinement throughout the period, naked, hooded, on a liquid diet, and chained in varying stress positions designed to cause him pain and deprive him of sleep. Loud rock music blared constantly in his blinding white-lit cell."

    Slide-Show Poetry: Closing Down the Bungalow - Andy Friedman

    1. "We never swam in the lake. My mother cut her toe on something in it one day, in the summer of 1956."

    Who's the alpha male now, bitches? - Andrew O'Hagan

    1. "There has been an epidemic in gun violence since 2000, and mass shootings in public places are clearly on the increase. According to the FBI, there have been close to two hundred such incidents in the last 15 years, resulting in the murder of 486 people and the wounding of 557 as of September last year."

    2. "Someone, perhaps not a million miles from you, whose name we don't yet know but whose face is camera-ready, whose conscience is clearing before the fact, is preparing a biography of his mentality in advance of a shooting massacre."

    Should bike helmets be compulsory? Lessons from Seattle and Amsterdam - Renate van der Zee

    1. "In Amsterdam, adults don't wear helmets while riding city bikes – they don't even consider it an option. Helmets are mainly worn by tourists and expats, whom the Dutch regard with bemusement, even ridicule."

    Convicted by Code - Rebecca Wexler

    1. "Today, closed, proprietary software can put you in prison or even on death row. And in most U.S. jurisdictions you still wouldn’t have the right to inspect it."

    2. "Because eliminating errors from code is so hard, experts have endorsed openness to public scrutiny as the surest way to keep software secure."

    Meetings Are Toxic - Getting Real, 37signals

    1. "Every minute you avoid spending in a meeting is a minute you can get real work done instead."

    Programmer Burn-in - Anonymous

    1. "Last year I had trouble enjoying things I had enjoyed my whole life. I felt that I had this "burned-in" addiction to complexity that made it very difficult to talk about normal human being things, or spend time on things that didn't seem very complex or mentally challenging."

    "A marvelous mind" Hannah Arendt's FBI file - Conor Skelding

    1. "'She is a small, rotund, stoop shouldered woman with a crew-like haircut, masculine voice and a marvelous mind. She is described as being very positive, dominating, enthusiastic, and an eloquent speaker, and as being about fifty years of age.'"

    VW - Robert C. Martin

    1. "I think that argument is even more asinine than Michael Horn's. They knew. And if they didn't know, they should have known. They had a responsibility to know."

    If You’re Not Paranoid, You’re Crazy - Walter Kirn

    1. "Its employees dealt with us in an upbeat, tightly scripted manner that appeared to stem from their awareness of several cameras angled toward the service counter. The situation reminded me that the ferreting-out of secrets is merely one purpose of surveillance; it also disciplines, inhibits, robbing interactions of spontaneity and turning them into self-conscious performances."

    2. "Evidently, some callous algorithm was betting against my pending marriage and offering me an early exit."

    The Price Is Right - Emily Nussbaum

    1. "And yet there's something in Trow's manifesto that I find myself craving these days: that rude resistance to being sold to, the insistence that there is, after all, such a thing as selling out."

    Not a Perfect Fit syndrome and Poisonous Internal Solutions - Matt Freeman

    1. "You return to work on Monday and realized that time and space is not yet truly understood, your nightmares actually did happen, you wonder if this is related to watching the new Interstellar film."

    Living in the Age of Software Fuckery - Bryan Edds

    1. "But in all seriousness, we can start by telling the truth about the situation, to others and especially ourselves. At the very least, it should help to lessen the shock of the reality to people entering our field. The people most affected by this shock are the honest young people who are least suspicious of this type of chicanery. In other words, the people we lose the earliest are the people we may need the most."

    Kill Our Meeting Culture - Sebastian Thrun

    1. "The fix is: abandon all recurring meetings. I am serious. All!"

    The self is moral - Nina Strohminger

    1. "However, new research by myself and the psychologists Larisa Heiphetz and Liane Young at Boston College has found that the single most important mental trait in judging self-identity is one's deeply held moral convictions. We are not only concerned with moral character when constructing an identity for others, but when doing so for ourselves."

    2. "People are not so much concerned with memory as with memory's ability to connect us to others and our capacity for social action."

    ]]>
    What I'm reading 10/5-10/12https://zeroclarkthirty.com/2015-10-11-what-im-reading.htmlSun, 11 Oct 2015 00:00:00 +0000Anarchism Triumphant: Free Software and the Death of Copyright - Eben Moglen

    1. "It's an emergent property of connected human minds that they create things for one another's pleasure and to conquer their uneasy sense of being too alone."

    2. "It turns out that treating software as property makes bad software."

    3. "Aristocracy looks hard to beat, but that's how it looked in 1788 and 1913 too. It is, as Chou En-Lai said about the meaning of the French Revolution, too soon to tell."

    4. "In most programming languages, far more space is spent in telling people what the program does than in telling the computer how to do it."

    5. "'Expressivity' became a property of programming languages, not because it facilitated computation, but because it facilitated the collaborative creation and maintenance of increasingly complex software systems."

    6. "But the most significant difference between political thought inside the digirati and outside it is that in the network society, anarchism (or more properly, anti-possessive individualism) is a viable political philosophy."

    Computer Applications: A Dynamic Medium for Creative Thought - Alan Kay

    1. "A large enough quantitative change introduces a qualitative change."

    Queues Don't Fix Overload - Fred Hebert

    1. "You look at your stack traces, at your queue, at your DB slow queries, at the APIs you call. You spend weeks at a time optimizing every component, making sure it's always going to be good and solid. Things keeps crashing, but you hit the point where every time, it takes 2-3 days more."

    The economics of software correctness - David R. MacIver

    1. "Bugs found by users are more expensive than bugs found before a user sees them. Bugs found by users may result in lost users, lost time and theft. These all hurt the bottom line."

    The most wanted man in the world - James Bamford

    1. "'The question for us is not what new story will come out next. The question is, what are we going to do about it?'"

    2. "Another troubling discovery was a document from NSA director Keith Alexander that showed the NSA was spying on the pornography-viewing habits of political radicals. The memo suggested that the agency could use these 'personal vulnerabilities' to destroy the reputations of government critics who were not in fact accused of plotting terrorism."

    ]]>
    What I'm reading 9/28-10/4https://zeroclarkthirty.com/2015-10-04-what-im-reading.htmlSun, 4 Oct 2015 00:00:00 +0000Haunted By Data - Maciej Cegłowski

    1. These data pipelines take on an institutional life of their own, and it doesn't help that people speak of the 'data driven organization' with the same religious fervor as a 'Christ-centered life'."

    'We Have Passed the Stage of Amateur Evil' - Scientists respond to the Atomic Bomb, August 6, 1945 - Andrew Lipsett

    1. "This morning I opened my eyes about 4 a.m. and found myself wide awake for no apparent reason. An odd feeling overcame me that something terrible had happened, and yet it seemed foolish to think so."

    2. "[Eugene Cotton] saw the events of that morning as the worst possible outcome of science: destruction in the place of progress, hubris over morality, technology as God."

    Volkswagen’s Diesel Fraud Makes Critic of Secret Code a Prophet - Jim Dwyer

    1. "'If Volkswagen knew that every customer who buys a vehicle would have a right to read the source code of all the software in the vehicle, they would never even consider the cheat, because the certainty of getting caught would terrify them.'"

    Sorry Ello, the Real Anti-Facebook Is Good Old Email - Klint Finley

    1. "Secondly, you don't have to convince people to install yet another app in order to build an audience. Anyone with an email address—which is pretty much everyone, despite many efforts to kill email—can subscribe to your newsletter."

    2. "For many users, social media has become impersonal. Facebook algorithmically curates what we see, while Twitter overwhelms us with a firehose of fast-moving content, and LinkedIn is, well, LinkedIn."

    3. "Mailchimp doesn't even get much, if any, data out of running TinyLetter—Lee says that TinyLetter's data doesn't feed into Mailchimp’s analytics at all. Nor is advertising in the cards, she says. 'It's important to all of us that people feel like TinyLetter is a safe place,' she says."

    Adblockers: The Only Way Out - Frédéric Filloux

    1. "By the way, users do not feel guilty of using adblockers or anti-tracking systems. According to the aforementioned The Information survey, less than 9% of users who deploy blocking tools experience some kind of guilt feeling."

    Learning to code is overrated: An accomplished programmer would rather his kids learn to read and reason - Jeff Atwood

    1. "I've known so many programmers who would have been much more successful in their careers if they had only been better writers, better critical thinkers, better back-of-the-envelope estimators, better communicators. And aside from success in careers, we have to ask the broader question: What kinds of people do we want children to grow up to be?"

    Full Reddit Submission Corpus now available (2006 thru August 2015)

    1. http://reddit-data.s3.amazonaws.com/RS_full_corpus.bz2 (42,674,151,378 bytes compressed)

    2. sha256sum: 91a3547555288ab53649d2115a3850b956bcc99bf3ab2fefeda18c590cc8b276

    The Measured Worker - Tyler Cowen

    1. "Insofar as workers type at a computer, everything they do is logged, recorded, and measured. Surveillance of workers continues to increase, and statistical analysis of large data sets makes it increasingly easy to evaluate individual productivity, even if the employer has a fairly noisy data set about what is going on in the workplace."

    Whence function notation? - Stuart Shieber

    Selling Out and the Death of Hacker Culture - Rodney Folz

    1. "There is a clear contractual transaction of goods and supply: your time, your résumés, and your intellectual labor in return for their dinner, their cheap sunglasses, and their shirts emblazoned with corporate logos."

    2. "Large corporations don't care about community. They look for ROI and large reserves of semi-skilled laborers. They're finding that in droves."

    est, Werner Erhard, and the corporatization of self-help - Suzanne Snider

    1. "At least est-ies were reaching their arms out into the dark, truly lost, unlike those who are “found,” relatively speaking, but want to finesse their interpersonal skills for the purpose of increasing sales. est was absurd enough to take a stand and make strong friends and enemies. The Forum is practically mainstream; it points to our most cowardly moderate tendencies and our current priority—to be productive."

    2. "Anyone who learned the hard way knows it’s a non-punchline, and the non-joke proved that if people were determined to 'get it,' they would, even if there was nothing to get."

    ]]>
    What I'm reading 9/20-9/27https://zeroclarkthirty.com/2015-09-27-what-im-reading.htmlSun, 27 Sep 2015 00:00:00 +0000Have You Encountered the Softboy? - Alan Hanson

    1. "The Softboy doesn't want to talk to you about The Wire. He concedes that it is 'objectively good television' yet 'ultimately problematic' and 'undeserving of its lionization.' Obviously, he is an Ally."

    The Death of the Party - Teddy Wayne

    1. "Except for a few years, the number of homebodies who never attended parties as high school seniors has steadily increased, to 41.3 percent in 2014 from 11.6 percent in 1987, and it's accelerated in the new millennium, more than doubling since 2001."

    Infrastructure as code would be easy if we cared - No Fun Allowed

    1. "We need to be realistic about how much we care about correctness."

    The Bipolar Lisp Programmer - Mark Tarver

    1. "Now the other aspect of the [brilliant bipolar mind] that I remarked on is his sensitivity to artifice. To put it in plain American, he knows bullshit when he smells it. Most of us do. However the BBM has much lower tolerance of it than others. He can often see the absurdity of the way things are, and has the intelligence to see how they should be. And he is, unlike the rank and file, unprepared to compromise. And this leads to many things."

    Fuccbois, Beta Bros, Softboys, Man-Children - Emily Rappaport

    1. "It’s a commodification of the avant-garde wherein people’s understanding of themselves as countercultural is rooted not in their beliefs or in how they treat people, but in what they choose to consume. These guys use art as a kind of reflective armor that protects them from having to engage intellectually or intimately in ways that make themselves vulnerable, and also from having to look critically at their own behaviors."

    2. "So it’s probably not surprising that these artists often make work that is neither freaky nor prophetic nor beautiful, but derivate, bland, or even non-existent."

    Who Wants to Be a Legionnaire? - Margaret Talbot

    1. "The other [leading cause for the waning of civic engagement] is television, the heavy watching of which, Putnam says, is 'the single most consistent predictor' of low civic engagement. TV not only 'steals time,' it breeds 'lethargy and passivity.'"

    2. "In the late 70's, for instance, the average American entertained friends at home about 14 times a year; now it's more like 8."

    A user’s manual - The Economist

    1. "Conservative attitudes or a religious family background may be the factors that increase the likelihood of reporting problematic use of pornography, she says. 'With porn, people say they are addicted when they just like it.'"

    The sad state of web app development - Eevee

    1. "My experience is admittedly limited here, but as far as I can tell, installing a Rails app is impossible."

    'I Was There': On Kurt Vonnegut - William Deresiewicz

    1. "Beneath the anger, though, the sense of desperation is profound. Vonnegut had always been a bitter and resentful man, uncomfortable with intimacy, a heavy drinker, the lonely little boy who could never make up for the love he didn't get. Now he had broken up his marriage and plunged into the maelstrom of celebrity."

    2. "The book is so jumbled, Vonnegut explains in the opening chapter, 'because there is nothing intelligent to say about a massacre.'"

    ]]>
    What I'm reading 9/12-9/19https://zeroclarkthirty.com/2015-09-19-what-im-reading.htmlSat, 19 Sep 2015 00:00:00 +0000Welcome to the Block Party - Casey Johnston

    1. I included this piece to show how morally timid all of these advertising arguments have become. Online advertisements are not like print ads where you can flip the page or TV ads where you can change the channel. They are code that is executed on your computer. They track your movement across the site and the web, reporting your clicks and views to a host of third parties bent on selling your demographic information to the highest bidder. People and companies who build a business model on the assumption of your consent to execute arbitrary code on your computer do not have my sympathy, and they should not have yours.

    New Rose Hotel - William Gibson

    1. "Once you left me, ran back to that beach saying you'd forgotten our key. I found it in the door and went after you, to find you ankle-deep in surf, your smooth back rigid, trembling; your eyes far away. You couldn't talk. Shivering. Gone. Shaking for different futures and better pasts. Sandii, you left me here. You left me all your things."

    2. "The zaibatsus, Fox said, the multinationals. The blood of a zaibatsu is information, not people. The structure is independent of the individual lives that comprise it. Corporation as life form."

    3. "It lay there in the palm of my hand, all that death."

    New Laws Explain Why Fast-Growing Networks Break - Jennifer Ouellette

    1. "Phase transitions are ubiquitous in nature, and they also provide a handy model for how individual nodes in a random network gradually link together, one by one, via short-range connections over time."

    2. "Once a large cluster has formed, it dominates the system, absorbing any smaller clusters that might otherwise merge and grow."

    3. "Disruptions can occur even in the most robust networks, whether these are power grids, global financial markets, or your favorite social network."

    4. "Yet acting to avoid any outage whatsoever can inadvertently lead to very large outages that are far more costly. Thus, encouraging small cascading “failures” can dissipate energy imbalances that would otherwise have caused massive failures later on, a potentially smart strategy even though it eats into profit margins."

    lib/eex/lib/eex.ex

    1. Did a good bit of work on a side project to parallelize template rendering. Speedup was proportional to the number of logical cores.

    A millisecond isn't fast (and how we made it 100x faster) - Julia Evans

    1. "I used to think a millisecond was fast. At work, I have code that runs some VERYLARGENUMBER of times. It’s distributed and split up into tasks, and an individual task runs the code more than 6 million times."

    Reflection - TypeTags and Manifests

    Data is not an asset, it’s a liability - Marko Karppinen

    1. "Here’s a hard truth: regardless of the boilerplate in your privacy policy, none of your users have given informed consent to being tracked. Every tracker and beacon script on your web site increases the privacy cost they pay for transacting with you, chipping away at the trust in the relationship."

    2. "And unlike code, data seems almost free: user activity generates an essentially endless amount of it. You just need to write it down on a disk somewhere."

    3. "You can’t expect the value of data to just appear out of thin air. Data isn’t fissile material. It doesn’t spontaneously reach critical mass and start producing insights."

    4. "You don’t start with the raw data. You start with the questions you want answered. Then you collect the data you need (and just the data you need) to answer those questions. Think this way for a while, and you notice a key factor: old data usually isn’t very interesting."

    Earley Parsing Explained - Loup Vaillant

    1. "The biggest advantage of Earley Parsing is its accessibility. Most other tools such as parser generators, parsing expression grammars, or combinator libraries feature restrictions that often make them hard to use."

    count_min_sketch.ex

    1. A little Count Min Sketch implementation I hacked out. It still needs some help with hashing algorithms.
    ]]>
    What I'm reading 9/4-9/11https://zeroclarkthirty.com/2015-09-11-what-im-reading.htmlSun, 13 Sep 2015 00:00:00 +0000Syria's Climate Conflict - Audrey Quinn and Jackie Roche

    Peopleware - Tom DeMarco and Timothy Lister

    1. "If you participate in or manage a team of people who need to use their brains during the day, then workplace environment is your business. "

    2. "A disturbing possibility is that overtime is not so much a means to increase the quantity of work time as to improve its average quality. Everyone knows that you get more work done after office hours than during, its a damning indictment of the office environment. The amazing thing is not that it's so often impossible to work in the workplace, but that everyone knows it and nobody ever does anything about it."

    3. "A California company that Tom DeMarco consulted for conducted a survey and recognized that the noisy environment was the worst problem workers faced, but decided that they couldn't do anything about it. This is a policy of total default."

    4. "Entropy is levelness or sameness. The more it increases, the less potential there is to generate energy or do work. In companies, entropy can be thought of as uniformity of attitude, appearance and thought process. Just as thermodynamic entropy is always increasing in the universe, so too corporate entropy is on the rise. 2nd Thermodynamic Law of Management: 'Entropy is always increasing in the organization'. That's why young companies are more fun to work for. The successful manager brings in the right people and lets them be themselves even though they may deviate from the corporate norm."

    5. "Allowing the standard of quality to be set by buyer instead of builder is termed flight from excellence. It makes good sense only if you ignore the effect on the builder's attitude and effectiveness, it costs more in the long run."

    6. "Turnover engenders turnover. Poeple leave quickly so nothing is spent on training. Since the company does not invest in the individual, the individual thinks of nothing but moving on."

    7. "On February 3, 1984, in a study of 32,346 companies worldwide, the authors confirmed a virtually perfect inverse relationship between people density and dedicated floor space per person. If you're having trouble seeing why this matters, you're not thinking about noise."

    8. "In Australia, there's a charming form of strike called work to rule where worker will follow every stupid detail of regulations such that work almost grinds to a halt."

    9. "Variation on a Theme by Parkinson - A company exhibits Parkinsonian behaviour if it is drowning in bureaucracy: 'Organizational busy work tends to expand to fill the working day.'"

    10. "People who wouldn't consider living in a home without windows end up spending most of their daylight time in a windowless workplace."

    Rethinking Work - Barry Schwartz

    1. "You enter an occupation with a variety of aspirations aside from receiving your pay. But then you discover that your work is structured so that most of those aspirations will be unmet. Maybe you're a call center employee who wants to help customers solve their problems — but you find out that all that matters is how quickly you terminate each call. Or you're a teacher who wants to educate kids — but you discover that only their test scores matter. Or you're a corporate lawyer who wants to serve his client with care and professionalism — but you learn that racking up billable hours is all that really counts. Pretty soon, you lose your lofty aspirations. And over time, later generations don't even develop the lofty aspirations in the first place. Compensation becomes the measure of all that is possible from work. When employees negotiate, they negotiate for improved compensation, since nothing else is on the table. And when this goes on long enough, we become just the kind of creatures that Adam Smith thought we always were."

    2. "We want work that is challenging and engaging, that enables us to exercise some discretion and control over what we do, and that provides us opportunities to learn and grow. We want to work with colleagues we respect and with supervisors who respect us. Most of all, we want work that is meaningful — that makes a difference to other people and thus ennobles us in at least some small way."

    3. "Gallup regularly polls workers around the world to find out. Its survey last year found that almost 90 percent of workers were either 'not engaged' with or 'actively disengaged' from their jobs."

    4. "In the face of longstanding evidence that routinization and an overemphasis on pay lead to worse performance in the workplace, why have we continued to tolerate and even embrace that approach to work?"

    A Field Guide to Developers - Joel Spolsky

    1. "By the way, the original hiring rule for Fog Creek, stolen from Microsoft, was 'Smart, and Gets Things Done.' Even before we started the company, we realized that we should add a third rule: 'Not a jerk.'"

    2. "When a programmer complains about 'politics,' they mean—very precisely—any situation in which personal considerations outweigh technical considerations. Nothing is more infuriating than when a developer is told to use a certain programming language, not the best one for the task at hand, because the boss likes it. Nothing is more maddening than when people are promoted because of their ability to network rather than being promoted strictly on merit. Nothing is more aggravating to a developer than being forced to do something that is technically inferior because someone higher than them in the organization, or someone better-connected, insists on it."

    3. "Anyway, I don't want to revisit the discussion of why private offices are more productive for software developers, or why just putting on headphones to drown out the ambient noise has been shown to reduce the quality of work that programmers produce, and why it doesn't really cost that much more in the scheme of things to have private offices for developers. I've talked about that already."

    Friends at Work? Not So Much - Adam Grant

    1. "The economic explanation is that long-term employment has essentially vanished: Instead of spending our careers at one organization, we expect to jump ship every few years. Since we don't plan to stick around, we don't invest in the same way."

    2. "Focusing our friendship efforts outside work isn't the norm around the world."

    3. "What will make workplaces less transactional? Research suggests that social events aren't always effective: People don’t mix much at mixers, and at company parties, they mostly bond with similar colleagues."

    Parsex - Clark Kampfe

    1. A little parser combinator library I wrote in a weekend.

    "Silence is for the weak" - Paul Biggar

    1. "Why does this happen? Because of a belief that 'silence is for the weak'. You should just suck it up and get back to your desk. Put on your headphones and write me some code!"

    2. "My favorite example of this sort of insanity is the office in which each time any developer deployed to production, the speaker system automatically played 6 seconds of their favorite song across the entire office. You could actually watch productivity go out the window as dozens of developers fell out of the zone."

    3. "Its lunacy! Everyone tries to attract the best engineers with top-of-the-line Macbooks, expensive coffee grinders, catered lunches, and fridges full of expensive smoothies and beer. Why not attract them by giving them a great working environment, where they can spend their time deeply engrossed in their passion: writing code and building systems?"

    Elixir Process Architecture or: How I Learned to Stop Worrying and Love to Crash - John Bohn

    1. "With multiple third party APIs in play, there is a lot that can go wrong. One of the services could have an outage, an API may change, the service may start timing out, and so many more things can go wrong. How can you possibly account for everything? I recently had a system that I was interacting with that started concatenating Java errors, formatted as XML, onto the end of a valid JSON response, about 25% of the time. Am I supposed to write code to handle that specific situation? I don't think so. Even if you did account for everything, my code would be 75% error handling, 25% actual feature code."
    ]]>
    What I'm reading 8/27-9/3https://zeroclarkthirty.com/2015-09-05-what-im-reading.htmlSat, 5 Sep 2015 00:00:00 +0000A Short Lesson in Perspective - Linds Redding

    1. "It turns out I didn't actually like my old life nearly as much as I thought I did. I know this now because I occasionally catch up with my old colleagues and work-mates. They fall over each other to enthusiastically show me the latest project they’re working on. Ask my opinion. Proudly show off their technical prowess (which is not inconsiderable.) I find myself glazing over but politely listen as they brag about who's had the least sleep and the most takaway food. 'I haven't seen my wife since January, I can't feel my legs any more and I think I have scurvy but another three weeks and we'll be done. It's got to be done by then The client's going on holiday. What do I think?'"

    2. "What do I think? I think you're all fucking mad. Deranged. So disengaged from reality it’s not even funny. It's a fucking TV commercial. Nobody give a shit. This has come as quite a shock I can tell you. I think, I've come to the conclusion that the whole thing was a bit of a con. A scam. An elaborate hoax."

    3. "The other consequence, with the benefit of hindsight, is that we became more conservative. Less likely to take creative risks and rely on the tried and trusted. The familiar is always going to research better than the truly novel. An research was the new god."

    4. "Our technology whizzes along at the velocity of a speeding electron, and our poor overtaxed neurons struggle to keep up. Everything has become a split-second decision. Find something you like. Share it. Have a half-baked thought. Tweet it. Don’t wait. Don’t hesitate. Seize the moment. Keep up. There will be plenty of time to repent later. Oh, and just to cover your ass, don’t forget to stick a smiley :) on the end just in case you’ve overstepped the mark."

    5. "Ideas themselves have become just another disposable commodity to be supplied to order by the lowest bidder."

    6. "I've seen quite a few creative drones fall by the wayside over the years. Booze mostly. Drugs occasionally. Anxiety. Stress. Broken marriages. Lots of those. Even a couple of suicides. But mostly just people temperamentally and emotionally ill-equipped for such a hostile and toxic environment."

    7. "But what I didn’t do, with the benefit of perspective, is anything of any lasting importance. At least creatively speaking. Economically I probably helped shift some merchandise. Enhanced a few companies bottom lines. Helped make one or two wealthy men a bit wealthier than they already were."

    The Humane Representation of Thought - Bret Victor

    Taco Bell Programming - Ted Dziuba

    1. "The cool-kids answer is to write a distributed crawler in Clojure and run it on EC2, handing out jobs with a message queue like SQS or ZeroMQ."

    2. "I could have done the whole thing Taco Bell style if I had only manned up and broken out sed, but I pussied out and wrote some Python."

    Was Banning Tyler, the Creator, the Victory International Feminism Needed? - Julianne Escobedo Shepherd

    1. "For United States feminists like Nadine Strossen, a professor at New York Law School and the first woman President of the ACLU from 1991 to 2008, it doesn’t matter how 'offensive, how vile' Tyler’s lyrics or persona might be—under the Constitution, it’s protected speech. 'Censorship always does more harm than good, including and especially to the groups that are supposedly benefiting from it,' she said, referring to the premise of her 2000 book Defending Pornography: Free Speech, Sex, and the Fight for Women’s Rights."

    2. "She continued: 'Historically, every censorship law that was supposedly passed for the benefit of women, starting with Anthony Comstock in the late 19th Century, has been used systemically, through the so-called feminist anti-pornography laws in the US and Canada, has been used disproportionately but not exclusively against feminist expression.'"

    The Arab Spring was a revolution of the hungry - Thanassis Cambanis

    1. "The basic equation is stark: The Arab world cannot feed itself. Rulers obsessed with security have created a twisted web of importers and bakeries whose aim is not to feed the population efficiently or nutritiously but simply to maintain the regime and stave off that much feared revolution of the hungry."

    2. "Saudi Arabia’s ultrarich monarchy calculated that it could survive any challenge from political dissidents critical of the country’s lack of rights and freedoms — as long as it could keep its citizens in material comfort. The king quickly increased handouts to citizens, and after a brief rumble, Saudi Arabians sat out the regional wave of protests that swept through nearly every other Arab state."

    Is Our General Internet Experience Getting Worse? - Joe Fallon

    1. "Browsers are crazy fast at rendering plain HTML. Web servers are crazy good at compressing and serving plain HTML. Can anyone explain this insanity? Why do I need another rendering engine built in JavaScript?"

    2. "After the page is fully loaded, several modal pop-ups, pop-overs, and sliders appear. Those usually take another 2 seconds to dismiss, if I can even dismiss them at all. Some of them can’t be dismissed, or are broken on certain devices, and actually cover main content. It reminds of all of the porn pop-ups from the nineties. Why would anyone do that to their users?"

    From REPL to Playgrounds - Manuel Chakravarty

    1. "Neither REPLs nor modern IDEs with integrated source-code debuggers are exposing the insides of programs in a manner that is easy to comprehend by the standards set in Bret Victor's essay and his talk 'Inventing on Principle'."

    Why I Didn't Answer Your Email

    1. "If it was actually important that I read and respond to your email, and I couldn't tell that from the subject, what the hell is wrong with your writing?"

    We Convinced Underrated Power Pop Punkers To Finally Release Their 2000 Album For Free

    Creating Domain Specific Languages with Scala - Part 1

    1. "Although it might look hard at first look, defining your own (basic) DSL is very often quite easy. One thing to notice is that the only Scala features that we used here are o overloaded operators and implicits."

    Born to Run and the Decline of the American Dream

    1. "'I don’t think the American Dream was that everyone was going to make it or that everyone was going to make a billion dollars,' he later said (as captured in the anthology, Bruce Springsteen Talking). 'But it was that everyone was going to have an opportunity and the chance to live a life with some decency and a chance for some self-respect.'"

    2. "Between 1967 and 1977 the average number of workers on strike climbed by 30 percent and the number of work days lost to stoppages by 40 percent. 'At the heart of the new mood,' argued The New York Times, 'there is a challenge to management's authority to run its plants.'"

    Uber TLC FOIL Response

    1. "This directory contains data on over 4.5 million Uber pickups in New York City from April to September 2014."

    Awk in 20 Minutes - Fred Hebert

    Is Silicon Valley in Another Bubble…and What Could Burst It? - Nick Bilton

    1. "All of this exuberance is magnetizing the same diaspora of Wall Street bankers, models, college dropouts, and anyone else with a start-up idea who came to Silicon Valley in the mid-90s."

    2. "You know there’s a bubble," the saying goes, "when the pretty people show up."

    3. "All across the Valley, the majority of big start-ups are actually glorified distribution companies that are trying, in some sense, to copy what Domino’s Pizza mastered in the 1980s when it delivered a hot pie to your door in 30 minutes or less."

    4. "As the British economist John Maynard Keynes is said to have observed, the market can stay irrational longer than you can stay solvent."

    5. "Now countless people from all over want this to be a bubble and they want it to burst. There are the taxi drivers who have lost their jobs to Uber; hotel owners who have seen their rooms sit vacant as people sleep in Airbnbs; newspapers that are at the mercy of Facebook’s algorithms; booksellers and retailers who have been in an unrelenting war with Amazon; the elderly, who can’t keep up; the music industry; television producers; and, perhaps most of all, San Franciscans, who would rejoice in the streets if their rents fell from totally insane to merely overpriced, or if they could get into a decent restaurant on a Monday night."

    Don Knuth and the Art of Computer Programming: The Interview - Richard Morris

    1. "I often tear up the first draft or two, after I see how things are going, because algorithms tend to be full of surprises."
    ]]>
    What I'm reading 8/19-8/26https://zeroclarkthirty.com/2015-08-27-what-im-reading.htmlThu, 27 Aug 2015 00:00:00 +0000Tehran’s Promise - Robin Wright

    1. "But America has crept back in, shaping everything from Iran’s self-perception to its cultural appetites and fast-food cravings."

    2. "'The Americans are much better carpet merchants than any Iranian could dream of!' the Iranian Foreign Minister, Mohammad Javad Zarif, told me, during a troubled period in the final weeks."

    3. "At one point, Zarif got up, walked around the room, and announced, 'I have to leave.' He then sat on a chair against a wall and put his head in his hands."

    4. "Kerry, known for being unflappable, lost it, too. Toward the end of six difficult hours, he slammed his hand down on the conference table so hard that his pen flew across the table and hit one of the Iranians."

    5. "'It’s such a complex set of relationships,' the State Department official said. 'We know each other. All of the mistrust that has been there for these decades remains. It's not gone. It's incredibly present all the time. But it fights against the fact that we've spent two years getting to know each other.'"

    You Really Don’t Need To Work So Much - DHH

    1. "It’s completely unrealistic to expect someone five levels deep in the bowels of the organization to reach out to the fifth-richest man in the world and trouble him with his or her toils."

    2. "'But that’s not what I meant' is an adequate, if somewhat naive, excuse the first time you see the consequences of your actions. The second, third, or fifth time, it's a lot less so. At some point 'unintended side effects' becomes 'predictable outcomes'."

    Get me off Your Fucking Mailing List - David Mazieres and Eddie Kohler

    1. http://scholarlyoa.com/2014/11/20/bogus-journal-accepts-profanity-laced-anti-spam-paper/

    NSA Spying Relies on AT&T's 'Extreme Willingness to Help' - Julia Angwin, Jeff Larson, Charlie Savage, James Risen, Henrik Moltke, Laura Poitras

    1. "AT&T began turning over emails and phone calls 'within days' after the warrantless surveillance began in October 2001, the report indicated."

    2. "Targeting someone on American soil requires a court order under the Foreign Intelligence Surveillance Act. When a foreigner abroad is communicating with an American, that law permits the government to target that foreigner without a warrant. And when foreigners are messaging other foreigners, that law does not apply and the government can collect such emails in bulk without targeting anyone."

    We Are Not Thinking Big Enough - Lawrence Lessig

    1. "I fear we are not thinking big enough. So used are we to getting crumbs, we can't imagine an actual meal."

    Don't Settle: The Journalist in the Shadow of the Commercial Web - Guy Patrick Cunningham

    1. "Or, as Adler puts it in After the Tall Timber: 'Independent journalists have obligations of their own.'"

    2. "But, for most users and nearly all working journalists, the online experience takes place entirely on the commercial web — an explicitly commercial space dominated by a very small number of companies, such as Facebook and Google. Those companies make decisions based on their own interests, and those of their shareholders."

    3. "A journalist that doesn’t know their subject down cold ends up with a monologue: they have just enough information to make their own judgment about what happened, but cannot make the kind of argument that might convince the reader this judgment is correct."

    4. "Skepticism is the first step to being a good journalist. And the first step to good writing. But it’s worth pausing to note that real skepticism — as opposed to showy faux contrarianism — takes time."

    5. "...I certainly believe that bad journalism ultimately serves the powerful"

    6. "But it’s another, more subtle habit that strikes me as especially pertinent in today’s professional environment: the risks of settling down."

    7. "Serious publications ... tend from time to time to hire talented people, educated, usually young, devoted to the craft of criticism, at least as it entails fidelity to an art and to a text under review. What usually happens is that such a critic writes for some time at his highest level: reporting and characterizing accurately; incorporating in whatever is judgmental evidence for what he’s saying (a sign of integrity in a critic, as opposed to an opinion monger, is that he tries for evidence; in reviewing prose forms, for example, he will quote); and producing insights, and allusions, which, if they are not downright brilliant, are apposite. What happens after a longer time is that he settles down."

    The Creative Apocalypse That Wasn't - Steven Johnson

    1. "As file-sharing and iTunes and Spotify have driven down the price of music, they have also made it far easier to envelop your life with a kind of permanent soundtrack, all of which drives awareness of the musicians and encourages fans to check them out in concert."

    2. "Why have the more pessimistic predictions not come to pass? One incontrovertible reason is that — contrary to the justifiable fears of a decade ago — people will still pay for creative works."

    The Ketamine Cure - Caroline Winter

    1. "'It's settled—to my mind beyond a shadow of a doubt—that ketamine has a powerful antidepressant effect for as many as 50 percent of people where other medications haven’t been helpful,' says Michael Thase, a professor of psychiatry at the University of Pennsylvania who's consulted for various drug companies developing ketamine-like products."

    2. "Hartman tried more than 15 antidepressants, none of which worked. He never married and mostly kept to himself. 'When I would get social invitations, I would say, 'Thanks, but I'm already busy,'' he says. 'Really I was hiding at home because I needed to repair myself so I could get out of bed the next morning.' Eventually, Hartman decided that ending his life was the most humane option. Hoping to mitigate the trauma for his family, he set the date a couple of months into the future so a young relative could finish the school year."

    Lessig on Equal Citizens

    Anatomy of a runaway IT project - Bruce F. Webster

    1. "Builds take all night."

    2. "Developers check in files that won’t even compile."

    3. "The FUBAR project keeps being touted as a world-class development team, but it is not producing world-class, or even minimally-professional, results."

    4. "Two consultants rewrote the 140,000 lines of [original obscure language] into 4200 lines of Java. The Java version runs as fast on a laptop PC as the original version runs on a high-powered UNIX server."

    5. "The fallacy that software is somehow different is just that — a fallacy, and one that costs corporations millions (if not billions) of dollars a year in missed schedules and failed projects. When it comes to engineering, sincerity and commitment, while important, can never substitute for expertise and quality of work."

    6. "There isn’t enough intellectual honesty within the FUBAR project. Managers reject or explain away bad news and real problems, looking instead for people who will tell them what they want to hear."

    The Wetware Crisis: the Thermocline of Truth - Bruce F. Webster

    1. "...we tend to rely on seat-of-the-pants (or, less politely, out-of-one’s-butt) estimations by IT engineers or managers that a given subsystem or application is “80% done”. This, in turn, leads to the old saw that the first 90% of a software project takes 90% of the time, and the last 10% of a software projects takes the other 90% of the time."

    Project from Hell

    1. "55 people in the team: 20 developers, 35 managers."

    2. "Doing a first checkout requires taking an appointment with the version control team, usually granted a week later."

    3. "Build takes 48 hours on 32 parallel machines."

    4. "No dynamic library linking: executable sizes in the range of several hundred megabytes."

    The Downfall of Imperative Programming - Bartosz Milewski

    1. "Originally there wasn't much interest in FP outside of academic circles because there was no functional killer app. Now we know that this killer app is concurrency."

    2. "Programmers are scared of concurrency, and rightly so. Managers are scared of concurrency even more."

    Rust Inside Other Languages - Ruby

    1. "Whoa, that was fast! On my system, this took 0.086 seconds, rather than the two seconds the pure Ruby version took."

    You Really Don’t Need To Work So Much - Tim Wu

    1. "in white-collar jobs, the amount of work can expand infinitely through the generation of false necessities—that is, reasons for driving people as hard as possible that have nothing to do with real social or economic needs."

    The Factory of Ideas: Working at Bell Labs - Computerphile - Brian Kernighan

    ]]>
    What I'm reading 8/11-8/18https://zeroclarkthirty.com/2015-08-18-what-im-reading.htmlTue, 18 Aug 2015 00:00:00 +0000The hacker hacked - Brett Scott

    1. "Your curiosity takes you to places where you don’t belong. It thus becomes an assertion of individual defiance of social norms. The byproduct of such exploration is pragmatic knowledge, the disruption of standard patterns of thought, and also dealienation – you see what’s behind the interfaces that surround us, coming closer to the reality of our social world."

    2. "I'm going to stake a claim on the word though, and state that the true hacker spirit does not reside at Google, guided by profit targets. The hacker impulse should not just be about redesigning products, or creating 'solutions' A hack stripped of anti-conventional intent is not a hack at all. It's just a piece of business innovation."

    3. "Unlike the open uprising of the liberation leader, the hacker impulse expresses itself via a constellation of minor acts of insurrection, often undertaken by individuals, creatively disguised to deprive authorities of the opportunity to retaliate."

    4. "The association of the hacker ethic with startups might have started with an authentic counter-cultural impulse on the part of outsider nerds tinkering away on websites. But, like all gentrification, the influx into the scene of successive waves of ever less disaffected individuals results in a growing emphasis on the unthreatening elements of hacking over the subversive ones.

    5. "Through the lens of moral panic, a narrative emerges of hackers as a class of computer attack-dogs. Their primary characteristics become aggression and amorality. How to guard against them? How, indeed, to round out the traditional good-versus-evil narrative?

    Keep the Aspidistra Flying - George Orwell

    1. "The sky was leaden..."

    2. "They were the kind of people who in every conceivable activity, even if it is only getting on to a bus, are automatically elbowed away from the heart of things."

    3. "...with patent-leather hair..."

    4. "Twopence halfpenny and a Joey - twopence halfpenny."

    5. "The kind of girl who goes in for Plenty of Clean Fun."

    6. "He was forever snubbing friendly advances."

    7. "This tea-making was the major household offense, next to bringing a woman in."

    Up or Out: Solving the IT Turnover Crisis - Alex Papadimoulis

    1. "Let's not ignore the elephant in the room: employees will quit. No matter what you say, no matter what cushiony benefits you give, no matter how hard you try, they will leave you. It’s just a matter of 'when'.

    2. "...instead of fighting to retain top talent, we need to make top talent."

    3. "What was once 'fresh new ideas that we can't implement today' become 'the same old boring suggestions that we’re never going to do'."

    4. "I need you to document this process in detail so that any yahoo can understand it a year from now after you’ve left."

    Miscomputation: Learning to live with errors - Tomas Petricek

    1. "Computer programs do not always work as expected."

    2. "It is important to understand that in the Erlang philosophy, having crashing processes is a perfectly normal thing and there is nothing wrong with it. So, miscomputation becomes not a thing to be avoided; not a thing integrated into the development process, but something that we can deliberately introduce into programs to deal with unexpected conditions."

    3. "Programming [in Smalltalk] was not thought of as the task of constructing a linguistic entity, but rather as a process of working interactively with the semantic representation of the program, using text simply as one possible interface." - Mark Priestley, Science of Operations (2011)

    Looking Past Our Racist Assumptions To See Africa - Quinn Norton

    1. "...I came to hate the term 'First world problems.' Most Africans I've met on either end of the continent, if I complained about cell phone battery life or social media or dealing with overbearing neighbors or whatever, would chime in with sympathy and understanding."

    Beyond Bash - Shell Scripting in a typed, OO language - Li Haoyi

    1. "How can we stop using the worst languages in the world to build our most important infrastructure?"

    2. "Everything is global…Everything is spooky!"

    3. Non-Goals!

      1. "Monadic pure dependent-typed safety"

      2. "Reactive manifesto accreditation"

      3. "50-year enterprise maintainability"

    Building an Elixir Mascot - Augie De Blieck Jr.

    Rust in 2016 - Nicholas Matsakis and Aaron Turon

    1. "Don’t know the difference between the stack and the heap? Don’t worry, Rust is a great way to learn about it, and I’d love to show you how."

    Who actually reads the code? - Ole Tange

    1. "The comment was put in a section of the code that no one would look to fix or improve the software – so, the source code equivalent to a dusty corner. To make sure the comment would not show up if some one just grepped through the source code I rot13'ed the source code."

    Problems with Computer Science Education

    1. "People are graduating without any notion of how to use a version control system like Git! I've seen teachers advocate having multiple copies of code in different folders as 'backups'."

    shapeless/examples/monoids.scala

    {% highlight scala %} { val f = Foo(13, "foo") |+| Foo(23, "bar") assert(f == Foo(36, "foobar")) } {% endhighlight %}

    Inside Amazon: Wrestling Big Ideas in a Bruising Workplace - Jodi Kantor and David Streitfeld

    1. "In Amazon warehouses, employees are monitored by sophisticated electronic systems to ensure they are packing enough boxes every hour."

    2. "Noelle Barnes, who worked in marketing for Amazon for nine years, repeated a saying around campus: 'Amazon is where overachievers go to feel bad about themselves.'"

    3. "For years, he and his team devoted themselves to improving the search capabilities of Amazon's website — only to discover that Mr. Bezos had greenlighted a secret competing effort to build an alternate technology. 'I'm not going to be the kind of person who can work in this environment,' he said he concluded. He went on to become a director of engineering at Twitter."

    4. https://twitter.com/MazMHussain/status/632955792556212229

    Ammonite - A Modernized Scala REPL

    1. "Ammonite is a cleanroom re-implementation of the Scala REPL from first principles. It is much more featureful than the default REPL and comes with a lot of ergonomic improvements and configurability that may be familiar topeople coming from IDEs or other REPLs such as IPython or Zsh."
    ]]>
    What I'm reading 8/3-8/10https://zeroclarkthirty.com/2015-08-10-what-im-reading.htmlMon, 10 Aug 2015 00:00:00 +0000The Web We Have to Save - Hossein Derakhshan

    1. "In the past, the web was powerful and serious enough to land me in jail. Today it feels like little more than entertainment."

    2. "Ironically enough, states that cooperate with Facebook and Twitter know much more about their citizens than those, like Iran, where the state has a tight grip on the Internet but does not have legal access to social media companies."

    3. "The web was not envisioned as a form of television when it was invented. But, like it or not, it is rapidly resembling TV: linear, passive, programmed and inward-looking."

    Why Offices Are Where Work Goes to Die

    1. "Did you notice? Every conversation in my example started with somebody not remembering the details of a previous conversation."

    2. "I'm an introvert and being forced to spend 8+ hours a day surrounded by people leaves me feeling like a wet rag. When I come home, I can't get back to important work. I can't write. I can't do anything. All I want is just to be alone."

    3. "You see, when people write, they think. They weigh what they’re saying, they consider how it comes across, they go back and edit and change what they said."

    Let's stop kidding ourselves about APIs

    1. "Programmers typically don't like politics and tend to argue using technical language. But that doesn't make politics go away, it just makes it subconscious."

    Scripting with Scala - eed3si9n

    {% highlight scala %} #!/usr/bin/env scalas

    /*** scalaVersion := "2.11.7"

    libraryDependencies ++= Seq( "com.amazonaws" % "aws-java-sdk" % "1.9.34" ) */

    import scala.collection.JavaConverters._ import scala.io.Source

    val formatToKV = (k: String, v: String) => s"${k}: ${v}" val filterLongKeys = (k: String, v: String) => k.length > 20 val attachLength = (k: String, v: String) => (k, v + " " + s"(key length: ${k.length})") val addNewLine = (str: String) => str + "\n"

    println(util.Properties.versionString) println println System.getenv.asScala .filter(filterLongKeys.tupled) .map(attachLength.tupled andThen formatToKV.tupled andThen addNewLine) .foreach(println)

    val ten = Source.fromURL("http://zeroclarkthirty.com") .mkString .split("\n") .toVector .take(10)

    ten.foreach(println) {% endhighlight %}

    Understanding implicit in Scala

    1. "The final parameter list on a method can be marked implicit, which means the values will be taken from the context in which they are called."

    shapeless/sized.scala

    Hadley Wickham, the Man Who Revolutionized R

    1. "The analyses that get me excited are not Google crunching a terabyte of web ad data in order to optimize revenue... [but rather] the biologists who are absolutely passionate about this one swampfly and now they can use R and they can understand it."

    2. "One of the attributes that has made me successful," he says, "is that I am exquisitely sensitive to frustration."

    3. "I've always been very certain that I could come up with a good way of doing things," he explained, "and that that way would actually help people."

    4. "The fact that data science exists as a field is a colossal failure of statistics. To me, that is what statistics is all about. It is gaining insight from data using modelling and visualization. Data munging and manipulation is hard and statistics has just said that's not our domain."

    Scripts, REPL, and Dependencies - sbt

    1. "The script runner can run a standard Scala script, but with the additional ability to configure sbt. sbt settings may be embedded in the script in a comment block that opens with /***."
    ]]>
    What I'm reading 7/26-8/2https://zeroclarkthirty.com/2015-08-02-what-im-reading.htmlSun, 2 Aug 2015 00:00:00 +0000API Overview - Incanter 1.5.4 (stable)

    1. "Incanter is a Clojure-based, R-like statistical computing and graphics environment for the JVM."

    In Defense Of Inclusionism - gwern

    1. "Participation matters because it drives quality. People come and go naturally, and that means we need to continually bring in and successfully orient new people. If we don’t, the community will shrink over time and quality will suffer. That’s why participation is our top priority right now."

    2. "Regaining our sense of openness will be hard work: it flies in the face of some of our strongest and least healthy instincts as human beings. People find it difficult to assume good faith and to devolve power. We naturally put up walls and our brains fall into us-versus-them patterns. That’s normal. But we need to resist it."

    Burmese Days - George Orwell

    1. "How's the British Empire? Sick of the palsy as usual?"

    Sleeping Through a Revolution - Letter to the millennials 2 - Jonathan Taplin

    1. "If the best and the brightest of you are drawn to building addictive apps rather than making great journalism, important films, or literature that survives the test of time, will we as a society be ultimately impoverished?"

    2. "I cannot imagine that your parents spent $40,000 a year at this university to prepare you to be part of the new 'sharing economy.'"

    runit - a UNIX init scheme with service supervision

    1. "runit is a cross-platform Unix init scheme with service supervision, a replacement for sysvinit, and other init schemes."

    Data Focused - Dmitri Sotnikov

    1. "When a function is called its output can be used in a new context without any additional ceremony."

    The adblocking revolution is months away (with iOS 9) – with trouble for advertisers, publishers and Google - Charles Arthur

    1. "Why should web advertisers be immune from evolutionary or revolutionary change in user habits?"

    Warren Buffett’s Family Secretly Funded a Birth Control Revolution - Karen Weise

    1. "The teen birthrate dropped 40 percent from 2009 to 2013, and the teen abortion rate was down by more than a third."

    2. "This spring, when the legislature debated taking over the funding after the Buffett donation ran out, conservative legislators voted against providing support, saying the efforts amounted to mini abortions."

    A Map of Akka - Heiko Seeberger

    1. "Failure is compartmentalized, which means that only a part of the system is affected instead of the whole one."

    The Neophyte's Guide to Scala Part 12: Type Classes - Daniel Westheide

    1. "Scala type classes allow you to develop your Scala code in such a way that it’s open for retroactive extension while retaining as much concrete type information as possible."

    Growing a Language - Guy Steele

    1. "We should now think of a language design as a pattern for language designs."

    2. "A language design can no longer be a thing. It must be a pattern."

    ]]>
    What I'm reading 7/18-7/25https://zeroclarkthirty.com/2015-07-26-what-im-reading.htmlSun, 26 Jul 2015 00:00:00 +0000Things Will Not Change

    • "As you might have guessed from the lines above, I’m not particular happy with the current way our industry is working. I know that I’m not alone with this opinion, but this article is about bringing my frustration to an end. I accept that I cannot change anything with complaints."
    • "Stop talking about tools, stop being a smart ass about why something should have been done differently. We are all responsible for making it a place for happiness and creation again."

    We are data: the future of machine intelligence

    • "What they never could have told you 20 years ago, though, is how boring and intense and unrelenting this sort of capitalist micro-assault is, from all directions at all waking moments, and how, 20 years later, it only shows signs of getting much more intense, focused, targeted, unyielding and galactically more boring."

    WHY IS THERE NO ADVERTISING ON TEXTFILES.COM?

    • "They look at every spare moment of life as a potential to sell you a product. Every square inch of unused space is a place where an ad should be. Every last bit of meaning in the world should be "presented by" a corporate entity."

    Technology is run by the wrong people

    • "In 2015, we live in a time of broad-based and pervasive organizational decline. While Silicon Valley champions all that is “startup”, another way to perceive the accelerated birth-and-death cycle of organizations is that they’ve become shorter-lived and more disposable in general."

    Bret Victor - The Future of Programming

    • "The real tragedy would be if people forgot you could have new ideas about programming models in the first place."

    Functional XML editing using zippers in Clojure

    How Sushi Are You: 2015

    • "And #UGH! do these pics get a ton of cheap LIKES…#JEAL"

    Mesh - Responsive Grid & Typography in Clojurescript

    • "Web Design is 95% Typography"

    Tesser - Clojure reducers, but for parallel execution: locally and on distributed systems.

    Is Advertising Morally Justifiable? The Importance of Protecting Our Attention

    • "The result is not only that it has become morally acceptable to sell off other people's attention without their consent in the name of free market economics. But, in addition, anyone who refuses to do so is considered an economic idiot - someone who leaves money on the table."

    William Gass, The Art of Fiction No. 65

    • "Type has no drawl."

    • "These beliefs and these forms have to do with the security and insecurity of going forward into the void."

    ]]>