869 private links
What tests you shouldn’t write for your software -- An essay on negative tests · Endless Parentheses
Interesting insight: A false failure is one that you fix by editing the test, while a real failure is one you fix by editing the code. Some tests virtually never have real failures, so it's better to avoid them. One principle is to test function, not code.
A clever way to implement a htmx-like mechanism of substituting the content of a node with the response of a request.
It works like this. Have a hidden iframe whose onload callback sets the target node (specified by hash) with the iframe's body content. Then use an a
element to trigger the iframe load: <a target=_the_iframe href="/req-url#target-element">
.
TIL: a[target]
, iframe[hidden]
, contentWindow
, contentDocument
, <base target=X>
This article talks about PGA (projective geometric algebra), an alternative approach to do geometric transformation that is not using matrix.
This video specifically talked about the real difference in biological neurons and its artificial counterpart. I found the part is on how to represent information and training "artificial biological neuron networks" interesting. Notes (terms: neuron := biological neuron):
- neurons accumulates the incoming charge (stateful), with charge leakage
- three ways to encode information: frequency, timing, and parallelism
- backprop breaks down on discrete signals
- the only known mechanism for neuron weight update is "neurons that fires together wires together". but it's not very useful to developing a way to train it.
- it's likely neurons interpret its input as binary.
- the firing rate limit of neurons is only around 4 ms/spike (very slow)
- directional hearing requires distinguishing 1/2 ms delay of signals. how is it possible given the maximum firing rate? answer: create a group of neurons each detecting different delay and ordering in input signal.
- neuron components:
- loopback neuron can store a bit of signal that can be set and reset. (like an SR latch)
- mpsc (read-write) buffer
- mechanism that repetitively reading refreshes the memory (like DRAM)
- power efficiency. (12W for the brain) calculated result: neocortex only fires every two seconds (Wow!)
I enjoyed the puns, for example, PageRank - Larry Page, erlang - Agner Erlang, Price Club - Sol Price
xDCI is a specification that includes features to allow programming a USB port to emulate a USB device. This article talks about kernel hardware support, BIOS flashing, PCH (Platform Controller Hub), PMC (Power Management Controller), NVRAM, efivars, and finally how to use the author's Raw Gadget tools to emulate USB devices.
In this article Josh Comeau went in depth on why it matters to think of CSS as the parameter to the layout algorithms. This means for any layout problem, you must think of which layout algorithm you're using before deciding.
For example, z-index
is not functioning by default. To use it you must set position: relative | relative
. This is because the flow algorithm (think about Word) doesn't know about z-index. It only makes sense in the "Positioned" layout algorithm. And the position
attribute is used to switch the positioned algorithm. Instead of saying z-index
depends on the position
attribute, it's better understood that it depends on the layout algorithm.
Another evidence is that properties are interpreted differently in different layouts. For example, width
is hard-restriction for flow layout, but more fluid in a flexbox layout.
It's possible to declare conflicting layouts on the same element. But then there is a priority in which algorithm takes precedence. Two algorithms are never used simultaneously on the same element.
Identifying the algorithm:
- flow (the default)
- the core of flow layout are inline blocks and blocks.
- positioned (when
position
is set), four variants: relative, absolute, fixed, sticky - float (when
float
is set) - table
- flexbox (parent is
display: flex
) - grid (parent is
display: grid
)
There are quirks which are result of different layout algorithms. For example, when putting an img inside a box, it gets a little whitespace below it that are not padding/margin/border of either parent box or the image. This is because inline elements are aligned by baseline. And the flow algorithm adds a bit of vertical space below the baseline of inline element to ensure the bottom part of "g", "j", etc are visible. img
by default is inline-block and its baseline is at its bottom edge (0). Now the problem is understood one can solve it in different ways.
Josh Comeau writes one of the best interactive css tutorial out there! I learned so much in this article. A few notes:
margin: auto
makes the child take as much margin as possible.width: fit-content
uses all available space, but within the intrinsic sizemargin-inline: auto
is a shorthand formargin-left: auto; margin-right auto;
place-content: center
is a shorthand foralign-content: center; justify-content: center
- difference between
place-content
andplace-items
in grid layout - the latter aligns items relative to the cell - the insight that css attributes are merely inputs to the underlying layout algorithm
An article on how Rust can benefit from an effect system.
The information advantage over your competitor is something you can choose to cultivate. In journalism, one can avoid large topic on key persons that everyone went about, instead focus people with just as much insight and far less attention.
This article explores how we can separate the lifetime of values in a container from the lifetime of the container structure. The author approach the problem by issuing a token (zero-sized type) with an invariant lifetime. TIL ghost token. I think the type AppendOnlyVec (Vec<Box<T>>) could make a more straightforward example.
Nice write up. Aside from these mentioned, I also wanted to point out a few problems about Protocols.
- the implementation on struct is fine, but implementations on primitive types are very different and sometimes awkward
- the first argument is forced to be the type that implements the protocol, making it difficult to define abstract methods on, for example, a set of values
- there is no concept of associated type, associated constant,
- the role of protocols mostly overlaps with a
@behaviour
but a behaviour is more flexible
And here are more places I'd like to see improvements (some pointed out in the article, too):
- the lack of simpler struct construction/deconstruction syntax sugar, forcing everyone to write code like
%{a_long_property: a_long_property}
repeatedly - the lack of early return. the design of
with
discards the information about the mismatching branch. Ecto.Multi
is not composable (I tried to fix it via https://github.com/shouya/ecto-tx)
A concise and complete cheatsheet for the format!
macro.
This article talks about the default value for DefaultRestartSec is not sensible for use cases where you expect the service to restart indefinitely. Under the default setting, if your service could crash in 100ms, then it will only be restarted for around 1 second before systemd gives up.
It's a pleasurable and informative read. The nature of algebraic effect was accurately and concisely pointed out. This has been one of the best write-up on algebraic effects implementation in Rust I've read so far.
Quick explainer for ZFS caching mechanisms: ARC, L2ARC, TXG, ZIL, and SLOG.
A detailed description on the hardware architecture of Game Boy console.
TIL A* with fixed iteration depth.
All look like interesting concepts to toy with!
- Text editor
- 2D game - Space Invaders
- Compiler - Tiny BASIC
- Mini operating system
- Spreadsheet (hard!)
- Video game console emulator (hard!)
- Ray tracer
- Key-value store web API
- Web browser
- Stock trading bot
Also see Challenging algorithms and data structures every programmer should try.
This article talked about three data structures for efficient text editing (a.k.a. text buffer data structure): Rope, Gap Buffer, and Piece Table. It's first time I learned about Piece Table, it works like this:
- Store the text in an append-only fashion in two buffers known as original file and add file
- Store the information about segments of the files as a list of reference to the slices into the two buffers (known as "piece table")
The inserting/deleting in this data structure would simply need to breaking up items in the piece table. It seems like a good candidate as a basis to implement CRDT in a collaborative editor.
From my preliminary understanding of the nature of this data structure, it doesn't seem necessary to have two buffers, a single append-only buffer preloaded with the file should be sufficient.
UPDATE: I found this post on vscode blog extremely helpful: https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation