Russ Allbery: Review: Allow Me to Retort
| Publisher: | The New Press |
| Copyright: | 2022 |
| ISBN: | 1-62097-690-0 |
| Format: | Kindle |
| Pages: | 257 |
| Publisher: | The New Press |
| Copyright: | 2022 |
| ISBN: | 1-62097-690-0 |
| Format: | Kindle |
| Pages: | 257 |
parser.peg. Here is a simplified rule:
ConditionIPExpr "condition on IP" column:("ExporterAddress"i return "ExporterAddress", nil / "SrcAddr"i return "SrcAddr", nil / "DstAddr"i return "DstAddr", nil ) _ operator:("=" / "!=") _ ip:IP return fmt.Sprintf("%s %s IPv6StringToNum(%s)", toString(column), toString(operator), quote(ip)), nil
ConditionIPExpr. It case-insensitively matches
ExporterAddress, SrcAddr, or DstAddr. The action for each case returns the
proper case for the column name. That s what is stored in the column variable.
Then, it matches one of the possible operators. As there is no code block, it
stores the matched string directly in the operator variable. Then, it tries to
match the IP rule, which is defined elsewhere in the grammar. If it succeeds,
it stores the result of the match in the ip variable and executes the final
action. The action turns the column, operator, and IP into a proper expression
for ClickHouse. For example, if we have ExporterAddress = 203.0.113.15, we
get ExporterAddress = IPv6StringToNum('203.0.113.15').
The IP rule uses a rudimentary regular expression but checks if the matched
address is correct in the action block, thanks to netip.ParseAddr():
IP "IP address" [0-9A-Fa-f:.]+ ip, err := netip.ParseAddr(string(c.text)) if err != nil return "", errors.New("expecting an IP address") return ip.String(), nil
WHERE clause accepted by
ClickHouse:3
WHERE InIfBoundary = 'external' AND ExporterRegion = 'france' AND InIfConnectivity = 'transit' AND SrcAS = 15169 AND DstAddr BETWEEN toIPv6('2a01:e0f:ffff::') AND toIPv6('2a01:e0f:ffff:ffff:ffff:ffff:ffff:ffff')
InputFilter, uses CodeMirror as its foundation and
leverages features such as syntax highlighting, linting, and completion. The
source code for these capabilities can be found in the
codemirror/lang-filter/ directory.
@top Filter expression expression Not expression "(" expression ")" "(" expression ")" And expression "(" expression ")" Or expression comparisonExpression And expression comparisonExpression Or expression comparisonExpression comparisonExpression Column Operator Value Value String Literal ValueLParen ListOfValues ValueRParen ListOfValues ListOfValues ValueComma (String Literal) String Literal // [ ] @tokens // [ ] Column std.asciiLetter (std.asciiLetter std.digit)* Operator $[a-zA-Z!=><]+ String '"' (![\\\n"] "\\" _)* '"'? "'" (![\\\n'] "\\" _)* "'"? Literal (std.digit std.asciiLetter $[.:/])+ // [ ]
SrcAS = 12322 AND (DstAS = 1299 OR SrcAS = 29447) is parsed to:
Filter(Column, Operator, Value(Literal), And, Column, Operator, Value(Literal), Or, Column, Operator, Value(Literal))
export const FilterLanguage = LRLanguage.define( parser: parser.configure( props: [ styleTags( Column: t.propertyName, String: t.string, Literal: t.literal, LineComment: t.lineComment, BlockComment: t.blockComment, Or: t.logicOperator, And: t.logicOperator, Not: t.logicOperator, Operator: t.compareOperator, "( )": t.paren, ), ], ), );
/api/v0/console/filter/validate endpoint accepts a filter and returns a JSON
structure with the errors that were found:
"message": "at line 1, position 12: string literal not terminated", "errors": [ "line": 1, "column": 12, "offset": 11, "message": "string literal not terminated", ]
/api/v0/console/filter/complete endpoint.
Walking the syntax tree was not as easy as I thought, but unit tests helped
a lot.
The backend uses the parser generated by pigeon to complete a column name
or a comparison operator. For values, the completions are either static or
extracted from the ClickHouse database. A user can complete an AS number from
an organization name thanks to the following snippet:
results := []struct Label string ch:"label" Detail string ch:"detail" columnName := "DstAS" sqlQuery := fmt.Sprintf( SELECT concat('AS', toString(%s)) AS label, dictGet('asns', 'name', %s) AS detail FROM flows WHERE TimeReceived > date_sub(minute, 1, now()) AND detail != '' AND positionCaseInsensitive(detail, $1) >= 1 GROUP BY label, detail ORDER BY COUNT(*) DESC LIMIT 20 , columnName, columnName) if err := conn.Select(ctx, &results, sqlQuery, input.Prefix); err != nil c.r.Err(err).Msg("unable to query database") break for _, result := range results completions = append(completions, filterCompletion Label: result.Label, Detail: result.Detail, Quoted: false, )
In my previous post I introduced yet another Lisp interpreter. When it was posted there was no support for macros.
Since I've recently returned from a visit to the UK, and caught COVID-19 while I was there, I figured I'd see if my brain was fried by adding macro support.
I know lisp macros are awesome, it's one of those things that everybody is told. Repeatedly. I've used macros in my emacs programming off and on for a good few years, but despite that I'd not really given them too much thought.
If you know anything about lisp you know that it's all about the lists, the parenthesis, and the macros. Here's a simple macro I wrote:
(define if2 (macro (pred one two)
(if ~pred (begin ~one ~two))))
The standard lisp if function allows you to write:
(if (= 1 a) (print "a == 1") (print "a != 1"))
There are three arguments supplied to the if form:
if2 macro instead has three arguments:
(if2 blah
(one..)
(two..))
Rather than:
(if blah
(begin
(one..)
(two..)))
It is simple, clear, and easy to understand and a good building-block for writing a while function:
(define while-fun (lambda (predicate body)
(if2 (predicate)
(body)
(while-fun predicate body))))
There you see that if the condition is true then we call the supplied body, and then recurse. Doing two actions as a result of the single if test is a neat shortcut.
Of course we need to wrap that up in a macro, for neatness:
(define while (macro (expression body)
(list 'while-fun
(list 'lambda '() expression)
(list 'lambda '() body))))
Now we're done, and we can run a loop five times like so:
(let ((a 5))
(while (> a 0)
(begin
(print "(while) loop - iteration %s" a)
(set! a (- a 1) true))))
Output:
(while) loop - iteration 5
(while) loop - iteration 4
(while) loop - iteration 3
(while) loop - iteration 2
(while) loop - iteration 1
We've gone from using lists to having a while-loop, with a couple of simple macros and one neat recursive function.
There are a lot of cute things you can do with macros, and now I'm starting to appreciate them a little more. Of course it's not quite as magical as FORTH, but damn close!
| Series: | Discworld #20 |
| Publisher: | Harper |
| Copyright: | 1996 |
| Printing: | February 2014 |
| ISBN: | 0-06-227628-X |
| Format: | Mass market |
| Pages: | 402 |
"Look at it this way, then," she said, and took a deep mental breath. "Wherever people are obtuse and absurd... and wherever they have, by even the most generous standards, the attention span of a small chicken in a hurricane and the investigative ability of a one-legged cockroach... and wherever people are inanely credulous, pathetically attached to the certainties of the nursery and, in general, have as much grasp of the physical universe as an oyster has of mountaineering... yes, Twyla: there is a Hogfather.Meanwhile, the Auditors, last seen meddling with Death in Reaper Man, approach the Assassin's Guild in Ankh-Morpork to hire the assassination of the Hogfather. This rather unusual assignment falls to Mister Teatime, an orphan who was taken in by the guild at an early age and trained to be an assassin. Teatime is a little unnerving, mostly because he enjoys being an assassin. Rather a lot. Hogfather has two major things to recommend it: it's a Death novel, and it features Susan, who is one of my favorite Discworld characters. It also has two major strikes against it, at least for me. The first is relatively minor but, for me, the most irritating. A bit of the way into the story, Pratchett introduces the Oh God of Hangovers fair, that's a good pun and then decides that's a good excuse for nausea and vomiting jokes. A lot of nausea and vomiting jokes. Look. I know a lot of people don't mind this. But I beg authors (and, even more so, filmmakers and cartoonists) to consider whether a joke that some of your audience might like is worth making other parts of your audience feel physically ill while trying to enjoy your work. It's not at all a pleasant experience, and while I handle it better in written form, it still knocks me out of the story and makes me want to skip over scenes with the obnoxious character who won't shut up about it. Thankfully this does stop by the end of the book, but there are several segments in the middle that were rather unpleasant. The second is that Pratchett tries to convince the reader of the mythical importance of the Santa Claus myth (for which Hogfather is an obvious stand-in, if with a Discworld twist), an effort for which I am a highly unsympathetic audience. I'm with Susan above, with an extra helping of deep dislike for telling children who trust you something that's literally untrue. Pratchett does try: he has Death makes a memorable and frequently-quoted point near the end of the book (transcribed below) that I don't entirely agree with but still respect. But still, the book is very invested in convincing Susan that people believing mythology is critically important to humanity, and I have so many problems with the literalness of "believing" and the use of trusting children for this purpose by adults who know better. There are few topics that bring out my grumpiness more than Santa Claus. Grumbling aside, though, I did enjoy this book anyway. Susan is always a delight, and I could read about her adventures as a governess for as long as Pratchett wanted to write them. Death is filling in for the Hogfather for most of the book, which is hilarious because he's far too good at it, in his painfully earnest and literal way, to be entirely safe. I was less fond of Albert's supporting role (who I am increasingly coming to dislike as a character), but the entire scene of Death as a mall Santa is brilliant. And Teatime is an effective, creepy villain, something that the Discworld series doesn't always deliver. The powers arrayed on Discworld are so strong that it can be hard to design a villain who effectively challenges them, but Teatime has a sociopathic Professor Moriarty energy with added creepiness that fills that role in this book satisfyingly. As is typical for Pratchett (at least for me), the plot was serviceable but not the highlight. Pratchett plays in some interesting ways with a child's view of the world, the Unseen University bumbles around as a side plot, and it comes together at the end in a way that makes sense, but the journey is the fun of the story. The conclusion felt a bit gratuitous, there mostly to wrap up the story than something that followed naturally from the previous plot. But it does feature one of the most quoted bits in Discworld:
"All right," said Susan. "I'm not stupid. You're saying humans need... fantasies to make life bearable." REALLY? AS IF IT WAS SOME KIND OF PINK PILL? NO. HUMANS NEED FANTASY TO BE HUMAN. TO BE THE PLACE WHERE THE FALLING ANGEL MEETS THE RISING APE. "Tooth fairies? Hogfathers? Little " YES. AS PRACTICE. YOU HAVE TO START OUT LEARNING TO BELIEVE THE LITTLE LIES. "So we can believe the big ones?" YES. JUSTICE. MERCY. DUTY. THAT SORT OF THING. "They're not the same at all!" YOU THINK SO? THEN TAKE THE UNIVERSE AND GRIND IT DOWN TO THE FINEST POWDER AND SIEVE IT THROUGH THE FINEST SIEVE AND THEN SHOW ME ONE ATOM OF JUSTICE, ONE MOLECULE OF MERCY. AND YET Death waved a hand. AND YET YOU ACT AS IF THERE IS SOME IDEAL ORDER IN THE WORLD, AS IF THERE IS SOME...SOME RIGHTNESS IN THE UNIVERSE BY WHICH IT MAY BE JUDGED. "Yes, but people have got to believe that, or what's the point " MY POINT EXACTLY.Here's the thing, though: Susan is right. They're not the same sort of thing at all, and Pratchett doesn't present an argument that they are. Death's response is great, but it's also a non sequitur: it is true and correct but has nothing to do with Susan's argument. Justice is not a lie in the sense that Santa Claus is a lie: justice is something that humans can create, just like humans can create gift-giving or a tradition of imaginative story-telling. But this is not at all the same thing as encouraging children to believe in the literal existence of a fat man in red who comes down chimneys to deliver gifts by magic. And Death isn't even correct in Discworld! If one pays careful attention to the story, the consequences he's thinks would follow from the Auditors' attempt on the Hogfather not only don't happen, the exact opposite happens. This is the point of the Unseen University subplot, and it's also what happened in Reaper Man. The Auditors may be trying to kill mythology, but what the books show is that the real danger comes from the backlash. The force they're meddling with is far more powerful and persistent than they are. Death appears to be, by the stated events of the story, completely incorrect in his analysis of Discworld's metaphysics. Maybe Pratchett knows this? He did write a story that contradicts Death's analysis if one reads it carefully. But if so, this is not obvious from the text, or from Susan's reaction to Death's speech, which makes the metaphysics weirdly unsatisfying. So, overall, a mixed bag. Most of the book is very fun, but the metaphysics heavily rest on a pet peeve of mine, and I really could have done without the loving descriptions of the effects of hangovers. This is one of the more famous Discworld novels for the above quote, and on its own this is deserved (it's a great quote), but I think the logic is muddled and the story itself contradicts the implications. A rather odd reading experience. Followed by Jingo in publication order, and Thief of Time thematically. Rating: 7 out of 10
| Series: | Machine Mandate #1 |
| Publisher: | Prime Books |
| Copyright: | 2019 |
| ISBN: | 1-60701-533-1 |
| Format: | Kindle |
| Pages: | 86 |
vnl-filter tool. The new options are
vnl-filter -l
vnl-filter --sub-abs
abs() function in the default awk mode. I've been
low-level wanting this for years as well. Previously I'd use --perl just to
get abs(), or I'd explicitly define it: = sub 'abs(x) return x>0?x:-x; '=.
Typing all that out was becoming tiresome, and now I don't need to anymore.
vnl-filter --begin ... and vnl-filter --end ...
BEGIN and END clauses. They're useful to, for instance, use a
perl module in BEGIN, or to print out some final output in END. Previously
you'd add these inside the --eval block, but that was awkward because BEGIN
and END would then appear inside the while(<>) loop. And there was no
clear was to do it in the normal -p mode (no --eval).
Clearly these are all minor, since the toolkit is now mature. It does everything
I want it to, that doesn't require lots of work to implement. The big missing
features that I want would patch the underlying GNU coreutils instead of vnlog:
sort tool can select different sorting modes, but join works only
with alphanumeric sorting. join should have similarly selectable sorting
modes. In the vnlog wrappe I can currently do something like vnl-join
--vnl-sort n. This would pre-sort the input alphanumerically, and then
post-sort it numerically. That is slow for big datasets. If join could
handle numerically-sorted data directly, neither the pre- or post-sorts would
be needed
join should be able to do some sort of
interpolation when given fields that don't match exactly.
We currently use cookies to support our use of Google Analytics on the Website and Service. Google Analytics collects information about how you use the Website and Service. [...] This helps us to provide you with a good experience when you browse our Website and use our Service and also allows us to improve our Website and our Service.When I asked Matrix people about why they were using Google Analytics, they explained this was for development purposes and they were aiming for velocity at the time, not privacy (paraphrasing here). They also included a "free to snitch" clause:
If we are or believe that we are under a duty to disclose or share your personal data, we will do so in order to comply with any legal obligation, the instructions or requests of a governmental authority or regulator, including those outside of the UK.Those are really broad terms, above and beyond what is typically expected legally. Like the current retention policies, such user tracking and ... "liberal" collaboration practices with the state set a bad precedent for other home servers. Thankfully, since the above policy was published (2017), the GDPR was "implemented" (2018) and it seems like both the Element.io privacy policy and the Matrix.org privacy policy have been somewhat improved since. Notable points of the new privacy policies:
matrix.org serviceWe will forget your copy of your data upon your request. We will also forward your request to be forgotten onto federated homeservers. However - these homeservers are outside our span of control, so we cannot guarantee they will forget your data.It's great they implemented those mechanisms and, after all, if there's an hostile party in there, nothing can prevent them from using screenshots to just exfiltrate your data away from the client side anyways, even with services typically seen as more secure, like Signal. As an aside, I also appreciate that Matrix.org has a fairly decent code of conduct, based on the TODO CoC which checks all the boxes in the geekfeminism wiki.
matrix.org to block
known abusers (users or servers). Bans are pretty flexible and
can operate at the user, room, or server level.
Matrix people suggest making the bot admin of your channels, because
you can't take back admin from a user once given.
This tool and Mjolnir are based on the admin API built into Synapse.
- System notify users (all users/users from a list, specific user)
- delete sessions/devices not seen for X days
- purge the remote media cache
- select rooms with various criteria (external/local/empty/created by/encrypted/cleartext)
- purge history of theses rooms
- shutdown rooms
+R mode ("only
registered users can join") by default, except that anyone can
register their own homeserver, which makes this limited.
Server admins can block IP addresses and home servers, but those tools
are not easily available to room admins. There is an API
(m.room.server_acl in /devtools) but it is not reliable
(thanks Austin Huang for the clarification).
Matrix has the concept of guest accounts, but it is not used very
much, and virtually no client or homeserver supports it. This contrasts with the way
IRC works: by default, anyone can join an IRC network even without
authentication. Some channels require registration, but in general you
are free to join and look around (until you get blocked, of course).
I have seen anecdotal evidence (CW: Twitter, nitter link) that "moderating bridges is hell", and
I can imagine why. Moderation is already hard enough on one
federation, when you bridge a room with another network, you inherit
all the problems from that network but without the entire abuse
control tools from the original network's API...
joe on server B,
they will hijack that room on that specific server. This will not
(necessarily) affect users on the other servers, as servers could
refuse parts of the updates or ban the compromised account (or
server).
It does seem like a major flaw that room credentials are bound to
Matrix identifiers, as opposed to the E2E encryption credentials. In
an encrypted room even with fully verified members, a compromised or
hostile home server can still take over the room by impersonating an
admin. That admin (or even a newly minted user) can then send events
or listen on the conversations.
This is even more frustrating when you consider that Matrix events are
actually signed and therefore have some authentication attached
to them, acting like some sort of Merkle tree (as it contains a link
to previous events). That signature, however, is made from the
homeserver PKI keys, not the client's E2E keys, which makes E2E feel
like it has been "bolted on" later.
connect block on both servers@anarcat:matrix.org) is bound to
that specific home server. If that server goes down, that user is
completely disconnected. They could register a new account elsewhere
and reconnect, but then they basically lose all their configuration:
contacts, joined channels are all lost.
(Also notice how the Matrix IDs don't look like a typical user address
like an email in XMPP. They at least did their homework and got the
allocation for the scheme.)
#room:matrix.org is also
visible as #room:example.com on the example.com home server. Both
addresses refer to the same room underlying room.
(Finding this in the Element settings is not obvious though, because
that "alias" are actually called a "local address" there. So to create
such an alias (in Element), you need to go in the room settings'
"General" section, "Show more" in "Local address", then add the alias
name (e.g. foo), and then that room will be available on your
example.com homeserver as #foo:example.com.)
So a room doesn't belong to a server, it belongs to the federation,
and anyone can join the room from any serer (if the room is public, or
if invited otherwise). You can create a room on server A and when a
user from server B joins, the room will be replicated on server B as
well. If server A fails, server B will keep relaying traffic to
connected users and servers.
A room is therefore not fundamentally addressed with the above alias,
instead ,it has a internal Matrix ID, which basically a random
string. It has a server name attached to it, but that was made just to
avoid collisions. That can get a little confusing. For example, the
#fractal:gnome.org room is an alias on the gnome.org server, but
the room ID is !hwiGbsdSTZIwSRfybq:matrix.org. That's because the
room was created on matrix.org, but the preferred branding is
gnome.org now.
As an aside, rooms, by default, live forever, even after the last user
quits. There's an admin API to delete rooms and a tombstone
event to redirect to another one, but neither have a GUI yet. The
latter is part of MSC1501 ("Room version upgrades") which allows
a room admin to close a room, with a message and a pointer to another
room.
matrix.example.com) must never change in
the future, as renaming home servers is not supported.
The documentation used to say you could "run a hot spare" but that has
been removed. Last I heard, it was not possible to run a
high-availability setup where multiple, separate locations could
replace each other automatically. You can have high performance
setups where the load gets distributed among workers, but those
are based on a shared database (Redis and PostgreSQL) backend.
So my guess is it would be possible to create a "warm" spare server of
a matrix home server with regular PostgreSQL replication, but
that is not documented in the Synapse manual. This sort of setup
would also not be useful to deal with networking issues or denial of
service attacks, as you will not be able to spread the load over
multiple network locations easily. Redis and PostgreSQL heroes are
welcome to provide their multi-primary solution in the comments. In
the meantime, I'll just point out this is a solution that's handled
somewhat more gracefully in IRC, by having the possibility of
delegating the authentication layer.
.well-known pattern (or SRV
records, but that's "not recommended" and a bit confusing) to
delegate that service to another server. Be warned that the server
still needs to be explicitly configured for your domain. You can't
just put:
"m.server": "matrix.org:443"
... on https://example.com/.well-known/matrix/server and start using
@you:example.com as a Matrix ID. That's because Matrix doesn't
support "virtual hosting" and you'd still be connecting to rooms and
people with your matrix.org identity, not example.com as you would
normally expect. This is also why you cannot rename your home
server.
The server discovery API is what allows servers to find each
other. Clients, on the other hand, use the client-server discovery
API: this is what allows a given client to find your home server
when you type your Matrix ID on login.
matrix.debian.social) takes a few minutes
and then fails. That is because the home server has to sync the
entire room state when you join the room. There was promising work on
this announced in the lengthy 2021 retrospective, and some of
that work landed (partial sync) in the 1.53 release already.
Other improvements coming include sliding sync, lazy loading
over federation, and fast room joins. So that's actually
something that could be fixed in the fairly short term.
But in general, communication in Matrix doesn't feel as "snappy" as on
IRC or even Signal. It's hard to quantify this without instrumenting a
full latency test bed (for example the tools I used in the terminal
emulators latency tests), but
even just typing in a web browser feels slower than typing in a xterm
or Emacs for me.
Even in conversations, I "feel" people don't immediately respond as
fast. In fact, this could be an interesting double-blind experiment to
make: have people guess whether they are talking to a person on
Matrix, XMPP, or IRC, for example. My theory would be that people
could notice that Matrix users are slower, if only because of the TCP
round-trip time each message has to take.
matrix: scheme, it's just not exactly clear what they should do with
it, especially when the handler is just another web page (e.g. Element
web).
In general, when compared with tools like Signal or WhatsApp, Matrix
doesn't fare so well in terms of user discovery. I probably have some
of my normal contacts that have a Matrix account as well, but there's
really no way to know. It's kind of creepy when Signal tells you
"this person is on Signal!" but it's also pretty cool that it works,
and they actually implemented it pretty well.
Registration is also less obvious: in Signal, the app confirms your
phone number automatically. It's friction-less and quick. In Matrix,
you need to learn about home servers, pick one, register (with a
password! aargh!), and then setup encryption keys (not default),
etc. It's a lot more friction.
And look, I understand: giving away your phone number is a huge
trade-off. I don't like it either. But it solves a real problem and
makes encryption accessible to a ton more people. Matrix does have
"identity servers" that can serve that purpose, but I don't feel
confident sharing my phone number there. It doesn't help that the
identity servers don't have private contact discovery: giving them
your phone number is a more serious security compromise than with
Signal.
There's a catch-22 here too: because no one feels like giving away
their phone numbers, no one does, and everyone assumes that stuff
doesn't work anyways. Like it or not, Signal forcing people to
divulge their phone number actually gives them critical mass that
means actually a lot of my relatives are on Signal and I don't have
to install crap like WhatsApp to talk with them.
/READ command for
the latter:
/ALIAS READ script exec \$_->activity(0) for Irssi::windows
And yes, that's a Perl script in my IRC client. I am not aware of any
Matrix client that does stuff like that, except maybe Weechat, if we
can call it a Matrix client, or Irssi itself, now that it has a
Matrix plugin (!).
As for other clients, I have looked through the Matrix Client
Matrix (confusing right?) to try to figure out which one to try,
and, even after selecting Linux as a filter, the chart is just too
wide to figure out anything. So I tried those, kind of randomly:
weechat-matrix or gomuks. At least Weechat
is scriptable so I could continue playing the power-user. Right now my
strategy with messaging (and that includes microblogging like Twitter
or Mastodon) is that everything goes through my IRC client, so Weechat
could actually fit well in there. Going with gomuks, on the other
hand, would mean running it in parallel with Irssi or ... ditching
IRC, which is a leap I'm not quite ready to take just yet.
Oh, and basically none of those clients (except Nheko and Element)
support VoIP, which is still kind of a second-class citizen in
Matrix. It does not support large multimedia rooms, for example:
Jitsi was used for FOSDEM instead of the native videoconferencing
system.
matrix.org publishes a (federated) block list
of hostile servers (#matrix-org-coc-bl:matrix.org, yes, of course
it's a room).
Interestingly, Email is also in that stage, where there are block
lists of spammers, and it's a race between those blockers and
spammers. Large email providers, obviously, are getting closer to the
EFnet stage: you could consider they only accept email from themselves
or between themselves. It's getting increasingly hard to deliver mail
to Outlook and Gmail for example, partly because of bias against small
providers, but also because they are including more and more
machine-learning tools to sort through email and those systems are,
fundamentally, unknowable. It's not quite the same as splitting the
federation the way EFnet did, but the effect is similar.
HTTP has somehow managed to live in a parallel universe, as it's
technically still completely federated: anyone can start a web server
if they have a public IP address and anyone can connect to it. The
catch, of course, is how you find the darn thing. Which is how Google
became one of the most powerful corporations on earth, and how they
became the gatekeepers of human knowledge online.
I have only briefly mentioned XMPP here, and my XMPP fans will
undoubtedly comment on that, but I think it's somewhere in the middle
of all of this. It was co-opted by Facebook and Google, and
both corporations have abandoned it to its fate. I remember fondly the
days where I could do instant messaging with my contacts who had a
Gmail account. Those days are gone, and I don't talk to anyone over
Jabber anymore, unfortunately. And this is a threat that Matrix still
has to face.
It's also the threat Email is currently facing. On the one hand
corporations like Facebook want to completely destroy it and have
mostly succeeded: many people just have an email account to
register on things and talk to their friends over Instagram or
(lately) TikTok (which, I know, is not Facebook, but they started that
fire).
On the other hand, you have corporations like Microsoft and Google who
are still using and providing email services because, frankly, you
still do need email for stuff, just like fax is still around
but they are more and more isolated in their own silo. At this point,
it's only a matter of time they reach critical mass and just decide
that the risk of allowing external mail coming in is not worth the
cost. They'll simply flip the switch and work on an allow-list
principle. Then we'll have closed the loop and email will be
dead, just like IRC is "dead" now.
I wonder which path Matrix will take. Could it liberate us from these
vicious cycles?
Update: this generated some discussions on lobste.rs.
In my two most recent posts, I listed the memoirs and biographies and followed this up with the non-fiction I enjoyed the most in 2021. I'll leave my roundup of 'classic' fiction until tomorrow, but today I'll be going over my favourite fiction.
Books that just miss the cut here include Kingsley Amis' comic Lucky Jim, Cormac McCarthy's The Road (although see below for McCarthy's Blood Meridian) and the Complete Adventures of Tintin by Herg , the latter forming an inadvertently incisive portrait of the first half of the 20th century.
Like ever, there were a handful of books that didn't live up to prior expectations. Despite all of the hype, Emily St. John Mandel's post-pandemic dystopia Station Eleven didn't match her superb The Glass Hotel (one of my favourite books of 2020). The same could be said of John le Carr 's The Spy Who Came in from the Cold, which felt significantly shallower compared to Tinker, Tailor, Soldier, Spy again, a favourite of last year. The strangest book (and most difficult to classify at all) was undoubtedly Patrick S skind's Perfume: The Story of a Murderer, and the non-fiction book I disliked the most was almost-certainly Beartown by Fredrik Bachman.
Two other mild disappointments were actually film adaptions. Specifically, the original source for Vertigo by Pierre Boileau and Thomas Narcejac didn't match Alfred Hitchock's 1958 masterpiece, as did James Sallis' Drive which was made into a superb 2011 neon-noir directed by Nicolas Winding Refn. These two films thus defy the usual trend and are 'better than the book', but that's a post for another day.
A Wizard of Earthsea (1971) Ursula K. Le Guin How did it come to be that Harry Potter is the publishing sensation of the century, yet Ursula K. Le Guin's Earthsea is only a popular cult novel? Indeed, the comparisons and unintentional intertextuality with Harry Potter are entirely unavoidable when reading this book, and, in almost every respect, Ursula K. Le Guin's universe comes out the victor. In particular, the wizarding world that Le Guin portrays feels a lot more generous and humble than the class-ridden world of Hogwarts School of Witchcraft and Wizardry. Just to take one example from many, in Earthsea, magic turns out to be nurtured in a bottom-up manner within small village communities, in almost complete contrast to J. K. Rowling's concept of benevolent government departments and NGOs-like institutions, which now seems a far too New Labour for me. Indeed, imagine an entire world imbued with the kindly benevolence of Dumbledore, and you've got some of the moral palette of Earthsea. The gently moralising tone that runs through A Wizard of Earthsea may put some people off:
Vetch had been three years at the School and soon would be made Sorcerer; he thought no more of performing the lesser arts of magic than a bird thinks of flying. Yet a greater, unlearned skill he possessed, which was the art of kindness.Still, these parables aimed directly at the reader are fairly rare, and, for me, remain on the right side of being mawkish or hectoring. I'm thus looking forward to reading the next two books in the series soon.
Blood Meridian (1985) Cormac McCarthy Blood Meridian follows a band of American bounty hunters who are roaming the Mexican-American borderlands in the late 1840s. Far from being remotely swashbuckling, though, the group are collecting scalps for money and killing anyone who crosses their path. It is the most unsparing treatment of American genocide and moral depravity I have ever come across, an anti-Western that flouts every convention of the genre. Blood Meridian thus has a family resemblance to that other great anti-Western, Once Upon a Time in the West: after making a number of gun-toting films that venerate the American West (ie. his Dollars Trilogy), Sergio Leone turned his cynical eye to the western. Yet my previous paragraph actually euphemises just how violent Blood Meridian is. Indeed, I would need to be a much better writer (indeed, perhaps McCarthy himself) to adequately 0utline the tone of this book. In a certain sense, it's less than you read this book in a conventional sense, but rather that you are forced to witness successive chapters of grotesque violence... all occurring for no obvious reason. It is often said that books 'subvert' a genre and, indeed, I implied as such above. But the term subvert implies a kind of Puck-like mischievousness, or brings to mind court jesters licensed to poke fun at the courtiers. By contrast, however, Blood Meridian isn't funny in the slightest. There isn't animal cruelty per se, but rather wanton negligence of another kind entirely. In fact, recalling a particular passage involving an injured horse makes me feel physically ill. McCarthy's prose is at once both baroque in its language and thrifty in its presentation. As Philip Connors wrote back in 2007, McCarthy has spent forty years writing as if he were trying to expand the Old Testament, and learning that McCarthy grew up around the Church therefore came as no real surprise. As an example of his textual frugality, I often looked for greater precision in the text, finding myself asking whether who a particular 'he' is, or to which side of a fight some two men belonged to. Yet we must always remember that there is no precision to found in a gunfight, so this infidelity is turned into a virtue. It's not that these are fair fights anyway, or even 'murder': Blood Meridian is just slaughter; pure butchery. Murder is a gross understatement for what this book is, and at many points we are grateful that McCarthy spares us precision. At others, however, we can be thankful for his exactitude. There is no ambiguity regarding the morality of the puppy-drowning Judge, for example: a Colonel Kurtz who has been given free license over the entire American south. There is, thank God, no danger of Hollywood mythologising him into a badass hero. Indeed, we must all be thankful that it is impossible to film this ultra-violent book... Indeed, the broader idea of 'adapting' anything to this world is, beyond sick. An absolutely brutal read; I cannot recommend it highly enough.
Bodies of Light (2014) Sarah Moss Bodies of Light is a 2014 book by Glasgow-born Sarah Moss on the stirrings of women's suffrage within an arty clique in nineteenth-century England. Set in the intellectually smoggy cities of Manchester and London, this poignant book follows the studiously intelligent Alethia 'Ally' Moberly who is struggling to gain the acceptance of herself, her mother and the General Medical Council. You can read my full review from July.
House of Leaves (2000) Mark Z. Danielewski House of Leaves is a remarkably difficult book to explain. Although the plot refers to a fictional documentary about a family whose house is somehow larger on the inside than the outside, this quotidian horror premise doesn't explain the complex meta-commentary that Danielewski adds on top. For instance, the book contains a large number of pseudo-academic footnotes (many of which contain footnotes themselves), with references to scholarly papers, books, films and other articles. Most of these references are obviously fictional, but it's the kind of book where the joke is that some of them are not. The format, structure and typography of the book is highly unconventional too, with extremely unusual page layouts and styles. It's the sort of book and idea that should be a tired gimmick but somehow isn't. This is particularly so when you realise it seems specifically designed to create a fandom around it and to manufacturer its own 'cult' status, something that should be extremely tedious. But not only does this not happen, House of Leaves seems to have survived through two exhausting decades of found footage: The Blair Witch Project and Paranormal Activity are, to an admittedly lesser degree, doing much of the same thing as House of Leaves. House of Leaves might have its origins in Nabokov's Pale Fire or even Derrida's Glas, but it seems to have more in common with the claustrophobic horror of Cube (1997). And like all of these works, House of Leaves book has an extremely strange effect on the reader or viewer, something quite unlike reading a conventional book. It wasn't so much what I got out of the book itself, but how it added a glow to everything else I read, watched or saw at the time. An experience.
Milkman (2018) Anna Burns This quietly dazzling novel from Irish author Anna Burns is full of intellectual whimsy and oddball incident. Incongruously set in 1970s Belfast during The Irish Troubles, Milkman's 18-year-old narrator (known only as middle sister ), is the kind of dreamer who walks down the street with a Victorian-era novel in her hand. It's usually an error for a book that specifically mention other books, if only because inviting comparisons to great novels is grossly ill-advised. But it is a credit to Burns' writing that the references here actually add to the text and don't feel like they are a kind of literary paint by numbers. Our humble narrator has a boyfriend of sorts, but the figure who looms the largest in her life is a creepy milkman an older, married man who's deeply integrated in the paramilitary tribalism. And when gossip about the narrator and the milkman surfaces, the milkman beings to invade her life to a suffocating degree. Yet this milkman is not even a milkman at all. Indeed, it's precisely this kind of oblique irony that runs through this daring but darkly compelling book.
The First Fifteen Lives of Harry August (2014) Claire North Harry August is born, lives a relatively unremarkable life and finally dies a relatively unremarkable death. Not worth writing a novel about, I suppose. But then Harry finds himself born again in the very same circumstances, and as he grows from infancy into childhood again, he starts to remember his previous lives. This loop naturally drives Harry insane at first, but after finding that suicide doesn't stop the quasi-reincarnation, he becomes somewhat acclimatised to his fate. He prospers much better at school the next time around and is ultimately able to make better decisions about his life, especially when he just happens to know how to stay out of trouble during the Second World War. Yet what caught my attention in this 'soft' sci-fi book was not necessarily the book's core idea but rather the way its connotations were so intelligently thought through. Just like in a musical theme and varations, the success of any concept-driven book is far more a product of how the implications of the key idea are played out than how clever the central idea was to begin with. Otherwise, you just have another neat Borges short story: satisfying, to be sure, but in a narrower way. From her relatively simple premise, for example, North has divined that if there was a community of people who could remember their past lives, this would actually allow messages and knowledge to be passed backwards and forwards in time. Ah, of course! Indeed, this very mechanism drives the plot: news comes back from the future that the progress of history is being interfered with, and, because of this, the end of the world is slowly coming. Through the lives that follow, Harry sets out to find out who is passing on technology before its time, and work out how to stop them. With its gently-moralising romp through the salient historical touchpoints of the twentieth century, I sometimes got a whiff of Forrest Gump. But it must be stressed that this book is far less certain of its 'right-on' liberal credentials than Robert Zemeckis' badly-aged film. And whilst we're on the topic of other media, if you liked the underlying conceit behind Stuart Turton's The Seven Deaths of Evelyn Hardcastle yet didn't enjoy the 'variations' of that particular tale, then I'd definitely give The First Fifteen Lives a try. At the very least, 15 is bigger than 7. More seriously, though, The First Fifteen Lives appears to reflect anxieties about technology, particularly around modern technological accelerationism. At no point does it seriously suggest that if we could somehow possess the technology from a decade in the future then our lives would be improved in any meaningful way. Indeed, precisely the opposite is invariably implied. To me, at least, homo sapiens often seems to be merely marking time until we can blow each other up and destroying the climate whilst sleepwalking into some crisis that might precipitate a thermonuclear genocide sometimes seems to be built into our DNA. In an era of cli-fi fiction and our non-fiction newspaper headlines, to label North's insight as 'prescience' might perhaps be overstating it, but perhaps that is the point: this destructive and negative streak is universal to all periods of our violent, insecure species.
The Goldfinch (2013) Donna Tartt After Breaking Bad, the second biggest runaway success of 2014 was probably Donna Tartt's doorstop of a novel, The Goldfinch. Yet upon its release and popular reception, it got a significant number of bad reviews in the literary press with, of course, an equal number of predictable think pieces claiming this was sour grapes on the part of the cognoscenti. Ah, to be in 2014 again, when our arguments were so much more trivial. For the uninitiated, The Goldfinch is a sprawling bildungsroman that centres on Theo Decker, a 13-year-old whose world is turned upside down when a terrorist bomb goes off whilst visiting the Metropolitan Museum of Art, killing his mother among other bystanders. Perhaps more importantly, he makes off with a painting in order to fulfil a promise to a dying old man: Carel Fabritius' 1654 masterpiece The Goldfinch. For the next 14 years (and almost 800 pages), the painting becomes the only connection to his lost mother as he's flung, almost entirely rudderless, around the Western world, encountering an array of eccentric characters. Whatever the critics claimed, Tartt's near-perfect evocation of scenes, from the everyday to the unimaginable, is difficult to summarise. I wouldn't label it 'cinematic' due to her evocation of the interiority of the characters. Take, for example: Even the suggestion that my father had close friends conveyed a misunderstanding of his personality that I didn't know how to respond it's precisely this kind of relatable inner subjectivity that cannot be easily conveyed by film, likely is one of the main reasons why the 2019 film adaptation was such a damp squib. Tartt's writing is definitely not 'impressionistic' either: there are many near-perfect evocations of scenes, even ones we hope we cannot recognise from real life. In particular, some of the drug-taking scenes feel so credibly authentic that I sometimes worried about the author herself. Almost eight months on from first reading this novel, what I remember most was what a joy this was to read. I do worry that it won't stand up to a more critical re-reading (the character named Xandra even sounds like the pharmaceuticals she is taking), but I think I'll always treasure the first days I spent with this often-beautiful novel.
Beyond Black (2005) Hilary Mantel Published about five years before the hyperfamous Wolf Hall (2004), Hilary Mantel's Beyond Black is a deeply disturbing book about spiritualism and the nature of Hell, somewhat incongruously set in modern-day England. Alison Harte is a middle-aged physic medium who works in the various towns of the London orbital motorway. She is accompanied by her stuffy assistant, Colette, and her spirit guide, Morris, who is invisible to everyone but Alison. However, this is no gentle and musk-smelling world of the clairvoyant and mystic, for Alison is plagued by spirits from her past who infiltrate her physical world, becoming stronger and nastier every day. Alison's smiling and rotund persona thus conceals a truly desperate woman: she knows beyond doubt the terrors of the next life, yet must studiously conceal them from her credulous clients. Beyond Black would be worth reading for its dark atmosphere alone, but it offers much more than a chilling and creepy tale. Indeed, it is extraordinarily observant as well as unsettlingly funny about a particular tranche of British middle-class life. Still, the book's unnerving nature that sticks in the mind, and reading it noticeably changed my mood for days afterwards, and not necessarily for the best.
The Wall (2019) John Lanchester The Wall tells the story of a young man called Kavanagh, one of the thousands of Defenders standing guard around a solid fortress that envelopes the British Isles. A national service of sorts, it is Kavanagh's job to stop the so-called Others getting in. Lanchester is frank about what his wall provides to those who stand guard: the Defenders of the Wall are conscripted for two years on the Wall, with no exceptions, giving everyone in society a life plan and a story. But whilst The Wall is ostensibly about a physical wall, it works even better as a story about the walls in our mind. In fact, the book blends together of some of the most important issues of our time: climate change, increasing isolation, Brexit and other widening societal divisions. If you liked P. D. James' The Children of Men you'll undoubtedly recognise much of the same intellectual atmosphere, although the sterility of John Lanchester's dystopia is definitely figurative and textual rather than literal. Despite the final chapters perhaps not living up to the world-building of the opening, The Wall features a taut and engrossing narrative, and it undoubtedly warrants even the most cursory glance at its symbolism. I've yet to read something by Lanchester I haven't enjoyed (even his short essay on cheating in sports, for example) and will be definitely reading more from him in 2022.
The Only Story (2018) Julian Barnes The Only Story is the story of Paul, a 19-year-old boy who falls in love with 42-year-old Susan, a married woman with two daughters who are about Paul's age. The book begins with how Paul meets Susan in happy (albeit complicated) circumstances, but as the story unfolds, the novel becomes significantly more tragic and moving. Whilst the story begins from the first-person perspective, midway through the book it shifts into the second person, and, later, into the third as well. Both of these narrative changes suggested to me an attempt on the part of Paul the narrator (if not Barnes himself), to distance himself emotionally from the events taking place. This effect is a lot more subtle than it sounds, however: far more prominent and devastating is the underlying and deeply moving story about the relationship ends up. Throughout this touching book, Barnes uses his mastery of language and observation to avoid the saccharine and the maudlin, and ends up with a heart-wrenching and emotive narrative. Without a doubt, this is the saddest book I read this year.
atmost and atleast and implies, that we will make use of together
with boolean variables to translate the dependency problem to a form Z3
understands.
In this post, we ll see how we can apply Z3 to the dependency resolution
in APT. We ll only discuss the basics here, a future post will explore
optimization criteria and recommends.
P. We then
translate each version P1, P2, and so on. Translating a version means building
a boolean literal for it, e.g. P1, and then translating the dependencies as shown below.
We now need to create two more clauses to satisfy the basic requirements for debs:
P == atleast( P1,P2 , 1).atmost( P1,P2 , 1).P.V.!P.A Depends: X Y, Z. To represent that
dependency, we expand each name to a list of versions that can satisfy
the dependency, for example X1 X2 Y1, Z1.
Translating this dependency list to our Z3 solver, we create boolean variables
X1,X2,Y1,Z1 and define two rules:
A implies atleast( X1,X2,Y1 , 1)A implies atleast( Z1 , 1)not A. It would be possible to simply not tell Z3 about the version at
all as an optimization, but that adds more complexity, and the not A constraint
should not cause too many problems.
or in them. A dependency B Conflicts: X, Y means that only
one of B, X, and Y can be installed. We can directly encode this in Z3 by using the
constraint atmost( B,X,Y , 1). This is an optimized encoding of the constraint: We
could have encoded each conflict in the form !B or !X, !B or !X, and so on. Usually
this leads to worse performance as it introduces additional clauses.
a below.
Package: a
Version: 1
Depends: c b
Package: b
Version: 1
Package: b
Version: 2
Conflicts: x
Package: d
Version: 1
Package: x
Version: 1
The translation in Z3 rules looks like this:
a:
a == atleast( a1 , 1) - package is installed iff one version isatmost( a1 , 1) - only one version may be installeda a must be installeda
implies(a1, atleast( b2, b1 , 1)) the translated dependency above. note that c is gone, it s not reachable.b:
b == atleast( b1,b2 , 1) - package is installed iff one version isatmost( b1, b2 , 1) - only one version may be installedb (= 2):
atmost( b2, x1 , 1) - the conflicts between x and b = 2 abovex:
x == atleast( x1 , 1) - package is installed iff one version isatmost( x1 , 1) - only one version may be installedd is not translated, as it is not reachable from the root
set a1 , the transitive root set is a1,b1,b2,x1 .
| Publisher: | Tordotcom |
| Copyright: | 2021 |
| ISBN: | 1-250-30112-2 |
| Format: | Kindle |
| Pages: | 151 |
I'm awfully lucky when you think about it. Garbagetown is the most wonderful place anybody has ever lived in the history of the world, even if you count the Pyramids and New York City and Camelot. I have Grape Crush and Big Bargains and my hibiscus flower, and I can fish like I've got bait for a heart so I hardly ever go hungry, and once I found a ruby ring and a New Mexico license plate inside a bluefin tuna. Everyone says they only hate me because I annihilated hope and butchered our future, but I know better, and anyway, it's a lie. Some people are just born to be despised. The Loathing of Tetley began small and grew bigger and bigger, like the Thames, until it swallowed me whole.Garbagetown is a giant floating pile of garbage in the middle of the ocean, and it is, so far as anyone knows, the only "land" left in the world. Global warming has flooded everything until the remaining Fuckwits (as their future descendants call everyone who was alive at the time) took to the Misery Boats and searched hopelessly for land. Eventually they realized they could live on top of the now-massive Pacific Garbage Patch and began the Great Sorting, which is fifty years into Tetley's past. All of the types of garbage were moved into their own areas, allowing small micronations of scavengers to form and giving each area its own character.
Candle Hole is the most beautiful place in Garbagetown, which is the most beautiful place in the world. All of the stubs of candles the Fuckwits threw out piled up into hills and mountains and caverns and dells, votive candles and taper candles and tea lights and birthday candles and big fat colorful pillar candles, stacked and somewhat melted into a great crumbling gorgeous warren of wicks and wax. All the houses are cozy little honeycombs melted into hillside, with smooth round windows and low golden ceilings. At night, from far away, Candle Hole looks like a firefly palace. When the wind blows, it smells like cinnamon, and freesia, and cranberries, and lavender, and Fresh Linen Scent, and New Car Smell.Two things should be obvious from this introduction. First, do not read this book looking for an accurate, technical projection of our environmental future. Or, for that matter, physical realism of any kind. That's not the book that Valente is writing and you'll just frustrate yourself. This is science fiction as concretized metaphor rather than prediction or scientific exploration. We Fuckwits have drowned the world with our greed and left our descendants living in piles of our garbage; you have to suspend disbelief and go with the premise. The second thing is that either you will like Tetley's storytelling style or you will not like this book. I find Valente very hit-and-miss, but this time it worked for me. The language is a bit less over-the-top than Space Opera, and it fits Tetley's insistent, aggressive optimism so well that it carries much of the weight of characterization. Mileage will definitely vary; this is probably a love-it-or-hate-it book. The Past is Red is divided into two parts. The first part is the short story "The Future is Blue," previously published in Clarkesworld and in Valente's short story collection of the same name. It tells the story of Tetley's early life, how she got her name, and how she became the most hated person in Garbagetown. The second part is much longer and features an older, quieter, more thoughtful, and somewhat more cynical Tetley, more life philosophy, and a bit of more-traditional puzzle science fiction. It lacks some of the bubbly energy of "The Future is Blue" but also features less violence and abuse. The overall work is a long novella or very short novel. This book has a lot of feelings about the environment, capitalism, greed, and the desire to let other people solve your problems for you, and it is not subtle about any of them. It's satisfying in the way that a good rant is satisfying, not in the way that a coherent political strategy is satisfying. What saves it from being too didactic or self-righteous is Tetley, who is happy to record her own emotions and her moments of wonder and is mostly uninterested in telling other people what to do. The setting sounds darkly depressing, and there are moments where it feels that way in the book, but the core of the story and of Tetley's life philosophy is a type of personal resilience: find the things that make you happy, put one foot in front of the other, and enjoy the world for what it is rather than what it could be or what other people want to convince you it might be. It's also surprisingly funny, particularly if you see the humor in bizarrely-specific piles of the detritus of civilization. The one place where I will argue with Valente a bit is that The Past is Red thoroughly embraces an environmental philosophy of personal responsibility. The devastating critique aimed at the Fuckwits is universal and undistinguished except slightly by class. Tetley and the other inhabitants of Garbagetown make no distinction between types of Fuckits or attempt to apportion blame in any way more granular than entire generations and eras. This is probably realistic. I understand why, by Tetley's time, no one is interested in the fine points of history. But the story was written today, for readers in our time, and this type of responsibility collapse is intentionally and carefully constructed by the largest polluters and the people with the most power. Collective and undifferentiated responsibility means that we're using up our energy fretting about whether we took two showers, which partly deflects attention from the companies, industries, and individuals that are directly responsible for the vast majority of environmental damage. We don't live in a world full of fuckwits; we live in a world run by fuckwits and full of the demoralized, harried, conned, manipulated, overwhelmed, and apathetic, which is a small but important difference. This book is not the right venue to explore that difference, but I wish the vitriol had not been applied quite so indiscriminately. The rest, though, worked for me. Valente tends to describe things by piling clauses on top of adjectives, which objectively isn't the best writing but it fits everything about Tetley's personality so well that I think this is the book where it works. I found her strange mix of optimism, practicality, and unbreakable inner ethics oddly endearing. "The Future is Blue" is available for free on-line, so if in doubt, read some or all of it, and that should tell you whether you're interested in the expansion. I'm glad I picked it up. Content warning for physical and sexual abuse of the first-person protagonist, mostly in the first section. Rating: 7 out of 10
| Illustrator: | Pauline Baynes |
| Series: | Chronicles of Narnia #1 |
| Publisher: | Collier Books |
| Copyright: | 1950 |
| Printing: | 1978 |
| ISBN: | 0-02-044220-3 |
| Format: | Mass market |
| Pages: | 186 |
"Oh, Aslan!" whispered Susan in the Lion's ear, "can't we I mean, you won't, will you? Can't we do something about the Deep Magic? Isn't there something you can work against it?" "Work against the Emperor's magic?" said Aslan, turning to her with something like a frown on his face. And nobody ever made that suggestion to him again.The problem with substitutionary atonement is why would a supposedly benevolent god create such a morally abhorrent rule in the first place? And Lewis totally punts. Susan is simply not allowed to ask the question. Lewis does try to tackle this problem elsewhere in his apologetics for adults (without, in my opinion, much success). But here it's just a part of the laws of this universe, which all of the characters, including Aslan, have to work within. That leads to another interesting point of theology, which is that if you didn't already know about the Christian doctrine of the trinity, you would never guess it from this book. The Emperor-Beyond-the-Sea and Aslan are clearly separate characters, with Aslan below the Emperor in the pantheon. This makes rules like the above work out more smoothly than they do in Christianity because Aslan is bound by the Emperor's rules and the Emperor is inscrutable and not present in the story. (The Holy Spirit is Deity Not-appearing-in-this-book, but to be fair to Lewis, that's largely true of the Bible as well.) What all this means is that Aslan's death is presented straightforwardly as a magic spell. It works because Aslan has the deepest understanding of the fixed laws of the Emperor's magic, and it looks nothing like what we normally think of as religion. Faith is not that important in this book because Aslan is physically present, so it doesn't require any faith for the children to believe he exists. (The Beavers, who believed in him from prophecy without having seen him, are another matter, but this book never talks about that.) The structure of religion is therefore remarkably absent despite the story's Christian parallels. All that's expected of the kids is the normal moral virtues of loyalty and courage and opposition to cruelty. I have read this book so many times that I've scrutinized every word, so I have to resist the temptation to dig into every nook and cranny: the beautiful description of spring, the weird insertion of Lilith as Adam's first wife, how the controversial appearance of Santa Claus in this book reveals Lewis's love of Platonic ideals... the list is endless, and the review is already much longer than normal. But I never get to talk about book endings in reviews, so one more indulgence. The best thing that can be said about the ending of TLtWatW is that it is partly redeemed by the start of Prince Caspian. Other than that, the last chapter of this book has always been one of my least favorite parts of The Chronicles of Narnia. For those who haven't read it (and who by this point clearly don't mind spoilers), the four kids are immediately and improbably crowned Kings and Queens of Narnia. Apparently, to answer the Professor from earlier in the book, ruling magical kingdoms is what they were teaching in those schools? They then spend years in Narnia, never apparently giving a second thought to their parents (you know, the ones who are caught up in World War II, which prompted the evacuation of the kids to the country in the first place). This, for some reason, leaves them talking like medieval literature, which may be moderately funny if you read their dialogue in silly voices to a five-year-old and is otherwise kind of tedious. Finally, in a hunt for the white stag, they stumble across the wardrobe and tumble back into their own world, where they are children again and not a moment has passed. I will give Lewis credit for not doing a full reset and having the kids not remember anything, which is possibly my least favorite trope in fiction. But this is almost as bad. If the kids returned immediately, that would make sense. If they stayed in Narnia until they died, that arguably would also make sense (their poor parents!). But growing up in Narnia and then returning as if nothing happened doesn't work. Do they remember all of their skills? How do you readjust to going to school after you've lived a life as a medieval Queen? Do they remember any of their friends after fifteen years in Narnia? Argh. It's a very "adventures are over, now time for bed" sort of ending, although the next book does try to patch some of this up. As a single book taken on its own terms, TLtWatW is weirdly slight, disjointed, and hits almost none of the beats that one would expect from a children's novel. What saves it is a sense of delight and joy that suffuses the descriptions of Narnia, even when locked in endless winter, and Aslan. The plot is full of holes, the role of the children in that plot makes no sense, and Santa Claus literally shows up in the middle of the story to hand out plot devices and make an incredibly sexist statement about war. And yet, I memorized every gift the children received as a kid, I can still feel the coziness of the Beaver's home while Mr. Beaver is explaining prophecy, and the night at the Stone Table remains ten times more emotionally effective for me than the description of the analogous event in the Bible. And, of course, there's Aslan.
"Safe?" said Mr. Beaver. "Don't you hear what Mrs. Beaver tells you? Who said anything about safe? 'Course he isn't safe. But he's good. He's the king, I tell you."Aslan is not a tame lion, to use the phrase that echos through this series. That, I think, is the key to the god that I find the most memorable in all of fantasy literature, even in this awkward, flawed, and decidedly strange introduction. Followed by Prince Caspian, in which the children return to a much-changed Narnia. Lewis has gotten most of the obligatory cosmological beats out of the way in this book, so subsequent books can tell more conventional stories. Rating: 7 out of 10
| Publisher: | Tor |
| Copyright: | September 2019 |
| ISBN: | 0-7653-9212-7 |
| Format: | Kindle |
| Pages: | 350 |
I won't reveal precisely how many books I read in 2020, but it was definitely an improvement on 74 in 2019, 53 in 2018 and 50 in 2017. But not only did I read more in a quantitative sense, the quality seemed higher as well. There were certainly fewer disappointments: given its cultural resonance, I was nonplussed by Nick Hornby's Fever Pitch and whilst Ian Fleming's The Man with the Golden Gun was a little thin (again, given the obvious influence of the Bond franchise) the booked lacked 'thinness' in a way that made it interesting to critique. The weakest novel I read this year was probably J. M. Berger's Optimal, but even this hybrid of Ready Player One late-period Black Mirror wasn't that cringeworthy, all things considered. Alas, graphic novels continue to not quite be my thing, I'm afraid.
I perhaps experienced more disappointments in the non-fiction section. Paul Bloom's Against Empathy was frustrating, particularly in that it expended unnecessary energy battling its misleading title and accepted terminology, and it could so easily have been an 20-minute video essay instead). (Elsewhere in the social sciences, David and Goliath will likely be the last Malcolm Gladwell book I voluntarily read.) After so many positive citations, I was also more than a little underwhelmed by Shoshana Zuboff's The Age of Surveillance Capitalism, and after Ryan Holiday's many engaging reboots of Stoic philosophy, his Conspiracy (on Peter Thiel and Hulk Hogan taking on Gawker) was slightly wide of the mark for me.
Anyway, here follows a selection of my favourites from 2020, in no particular order:
The disease stiffened and carried off three or four patients who were expected to recover. These were the unfortunates of the plague, those whom it killed when hope was highIt somehow captured the nostalgic yearning for high-definition videos of cities and public transport; one character even visits the completely deserted railway station in Oman simply to read the timetables on the wall.
Small, podgy, and at best middle-aged, Smiley was by appearance one of London's meek who do not inherit the earth. His legs were short, his gait anything but agile, his dress costly, ill-fitting, and extremely wet.Almost a direct rebuttal to Ian Fleming's 007, Tinker, Tailor has broken-down cars, bad clothes, women with their own internal and external lives (!), pathetically primitive gadgets, and (contra Mad Men) hangovers that significantly longer than ten minutes. In fact, the main aspect that the mostly excellent 2011 film adaption doesn't really capture is the smoggy and run-down nature of 1970s London this is not your proto-Cool Britannia of Austin Powers or GTA:1969, the city is truly 'gritty' in the sense there is a thin film of dirt and grime on every surface imaginable. Another angle that the film cannot capture well is just how purposefully the novel does not mention the United States. Despite the US obviously being the dominant power, the British vacillate between pretending it doesn't exist or implying its irrelevance to the matter at hand. This is no mistake on Le Carr 's part, as careful readers are rewarded by finding this denial of US hegemony in metaphor throughout --pace Ian Fleming, there is no obvious Felix Leiter to loudly throw money at the problem or a Sheriff Pepper to serve as cartoon racist for the Brits to feel superior about. By contrast, I recall that a clever allusion to "dusty teabags" is subtly mirrored a few paragraphs later with a reference to the installation of a coffee machine in the office, likely symbolic of the omnipresent and unavoidable influence of America. (The officer class convince themselves that coffee is a European import.) Indeed, Le Carr communicates a feeling of being surrounded on all sides by the peeling wallpaper of Empire. Oftentimes, the writing style matches the graceless and inelegance of the world it depicts. The sentences are dense and you find your brain performing a fair amount of mid-flight sentence reconstruction, reparsing clauses, commas and conjunctions to interpret Le Carr 's intended meaning. In fact, in his eulogy-cum-analysis of Le Carr 's writing style, William Boyd, himself a ventrioquilist of Ian Fleming, named this intentional technique 'staccato'. Like the musical term, I suspect the effect of this literary staccato is as much about the impact it makes on a sentence as the imperceptible space it generates after it. Lastly, the large cast in this sprawling novel is completely believable, all the way from the Russian spymaster Karla to minor schoolboy Roach the latter possibly a stand-in for Le Carr himself. I got through the 500-odd pages in just a few days, somehow managing to hold the almost-absurdly complicated plot in my head. This is one of those classic books of the genre that made me wonder why I had not got around to it before.
Perhaps his life might have veered elsewhere if the US government had opened the country to colored advancement like they opened the army. But it was one thing to allow someone to kill for you and another to let him live next door.Sardonic aper us of this kind are pretty relentless throughout the book, but it never tips its hand too far into on nihilism, especially when some of the visual metaphors are often first-rate: "An American flag sighed on a pole" is one I can easily recall from memory. In general though, The Nickel Boys is not only more world-weary in tenor than his previous novel, the United States it describes seems almost too beaten down to have the energy conjure up the Swiftian magical realism that prevented The Underground Railroad from being overly lachrymose. Indeed, even we Whitehead transports us a present-day New York City, we can't indulge in another kind of fantasy, the one where America has solved its problems:
The Daily News review described the [Manhattan restaurant] as nouveau Southern, "down-home plates with a twist." What was the twist that it was soul food made by white people?It might be overly reductionist to connect Whitehead's tonal downshift with the racial justice movements of the past few years, but whatever the reason, we've ended up with a hard-hitting, crushing and frankly excellent book.
"Earlier tonight I gave some thought to stealing a kiss from you, though you are very young, and sick and unattractive to boot, but now I am of a mind to give you five or six good licks with my belt." "One would be as unpleasant as the other."Perhaps this should be unsurprising. Maddie, a fourteen-year-old girl from Yell County, Arkansas, can barely fire her father's heavy pistol, so she can only has words to wield as her weapon. Anyway, it's not just me who treasures this book. In her encomium that presages most modern editions, Donna Tartt of The Secret History fame traces the novels origins through Huckleberry Finn, praising its elegance and economy: "The plot of True Grit is uncomplicated and as pure in its way as one of the Canterbury Tales". I've read any Chaucer, but I am inclined to agree. Tartt also recalls that True Grit vanished almost entirely from the public eye after the release of John Wayne's flimsy cinematic vehicle in 1969 this earlier film was, Tartt believes, "good enough, but doesn't do the book justice". As it happens, reading a book with its big screen adaptation as a chaser has been a minor theme of my 2020, including P. D. James' The Children of Men, Kazuo Ishiguro's Never Let Me Go, Patricia Highsmith's Strangers on a Train, James Ellroy's The Black Dahlia, John Green's The Fault in Our Stars, John le Carr 's Tinker, Tailor Soldier, Spy and even a staged production of Charles Dicken's A Christmas Carol streamed from The Old Vic. For an autodidact with no academic background in literature or cinema, I've been finding this an effective and enjoyable means of getting closer to these fine books and films it is precisely where they deviate (or perhaps where they are deficient) that offers a means by which one can see how they were constructed. I've also found that adaptations can also tell you a lot about the culture in which they were made: take the 'straightwashing' in the film version of Strangers on a Train (1951) compared to the original novel, for example. It is certainly true that adaptions rarely (as Tartt put it) "do the book justice", but she might be also right to alight on a legal metaphor, for as the saying goes, to judge a movie in comparison to the book is to do both a disservice.
We're accustomed to worrying about AI systems being built that will either "go rogue" and attack us, or succeed us in a bizarre evolution of, um, evolution what we didn't reckon on is the sheer inscrutability of these manufactured minds. And minds is not a misnomer. How else should we think about the neural network Google has built so its translator can model the interrelation of all words in all languages, in a kind of three-dimensional "semantic space"?New Dark Age also turns its attention to the weird, algorithmically-derived products offered for sale on Amazon as well as the disturbing and abusive videos that are automatically uploaded by bots to YouTube. It should, by rights, be a mess of disparate ideas and concerns, but Bridle has a flair for introducing topics which reveals he comes to computer science from another discipline altogether; indeed, on a four-part series he made for Radio 4, he's primarily referred to as "an artist". Whilst New Dark Age has rather abstract section topics, Adam Greenfield's Radical Technologies is a rather different book altogether. Each chapter dissects one of the so-called 'radical' technologies that condition the choices available to us, asking how do they work, what challenges do they present to us and who ultimately benefits from their adoption. Greenfield takes his scalpel to smartphones, machine learning, cryptocurrencies, artificial intelligence, etc., and I don't think it would be unfair to say that starts and ends with a cynical point of view. He is no reactionary Luddite, though, and this is both informed and extremely well-explained, and it also lacks the lazy, affected and Private Eye-like cynicism of, say, Attack of the 50 Foot Blockchain. The books aren't a natural pair, for Bridle's writing contains quite a bit of air in places, ironically mimics the very 'clouds' he inveighs against. Greenfield's book, by contrast, as little air and much lower pH value. Still, it was more than refreshing to read two technology books that do not limit themselves to platitudinal booleans, be those dangerously naive (e.g. Kevin Kelly's The Inevitable) or relentlessly nihilistic (Shoshana Zuboff's The Age of Surveillance Capitalism). Sure, they are both anti-technology screeds, but they tend to make arguments about systems of power rather than specific companies and avoid being too anti-'Big Tech' through a narrower, Silicon Valley obsessed lens for that (dipping into some other 2020 reading of mine) I might suggest Wendy Liu's Abolish Silicon Valley or Scott Galloway's The Four. Still, both books are superlatively written. In fact, Adam Greenfield has some of the best non-fiction writing around, both in terms of how he can explain complicated concepts (particularly the smart contract mechanism of the Ethereum cryptocurrency) as well as in the extremely finely-crafted sentences I often felt that the writing style almost had no need to be that poetic, and I particularly enjoyed his fictional scenarios at the end of the book.
A better proxy for your life isn't your first home, but your last. Where you draw your last breath is more meaningful, as it's a reflection of your success and, more important, the number of people who care about your well-being. Your first house signals the meaningful your future and possibility. Your last home signals the profound the people who love you. Where you die, and who is around you at the end, is a strong signal of your success or failure in life.Nir Eyal's Indistractable, however, is a totally different kind of 'self-help' book. The important background story is that Eyal was the author of the widely-read Hooked which turned into a secular Bible of so-called 'addictive design'. (If you've ever been cornered by a techbro wielding a Wikipedia-thin knowledge of B. F. Skinner's behaviourist psychology and how it can get you to click 'Like' more often, it ultimately came from Hooked.) However, Eyal's latest effort is actually an extended mea culpa for his previous sin and he offers both high and low-level palliative advice on how to avoid falling for the tricks he so studiously espoused before. I suppose we should be thankful to capitalism for selling both cause and cure. Speaking of markets, there appears to be a growing appetite for books in this 'anti-distraction' category, and whilst I cannot claim to have done an exhausting study of this nascent field, Indistractable argues its points well without relying on accurate-but-dry "studies show..." or, worse, Gladwellian gotchas. My main criticism, however, would be that Eyal doesn't acknowledge the limits of a self-help approach to this problem; it seems that many of the issues he outlines are an inescapable part of the alienation in modern Western society, and the only way one can really avoid distraction is to move up the income ladder or move out to a 500-acre ranch.
WITH [MATERIALIZED]
optimisation fence
Background history
PostgreSQL has a sophisticated query planner which usually gets
the right answer. For good reasons, the pgsql project has
resisted providing lots of knobs to control query planning. But
there are a few ways to influence the query planner, for when the
programmer knows more than the planner.
One of these is the use of a WITH common table
expression. In pgsql versions prior to 12, the planner would
first make a plan for the WITH clause; and then, it would make
a plan for the second half, counting the WITH clause's likely
output as a given. So WITH acts as an "optimisation fence".
This was documented in the manual - not entirely clearly, but
a careful reading of the docs reveals this behaviour:
The WITH query will generally be evaluated as written,
without suppression of rows that the parent query might
discard afterwards.
Users (authors of applications which use PostgreSQL) have been
using this technique for a long time.
New behaviour in PostgreSQL 12
In PostgreSQL 12 upstream were able to make the query planner
more sophisticated. In particular, it is now often capable of
looking "into" the WITH common table expression. Much of the time
this will make things better and faster.
But if WITH was being used for its side-effect as an optimisation
fence, this change will break things: queries that ran very quickly
in earlier versions might now run very slowly. Helpfully,
pgsql 12 still has a way to specify an optimisation fence:
specifying WITH ... AS MATERIALIZED in the query.
So far so good.
Upgrade path for existing users of WITH fence
But what about the upgrade path for existing users of the WITH
fence behaviour?
Such users will have to update their queries to add AS MATERIALIZED.
This is a small change. Having to update a query like this
is part of routine software maintenance and not in itself
very objectionable. However, this change cannnot be made
in advance because pgsql versions prior to 12 will reject
the new syntax.
So the users are in a bit of a bind. The old query syntax
can be unuseably slow with the new database and the new syntax
is rejected by the old database. Upgrading both the database
and the application, in lockstep, is a flag day upgrade,
which every good sysadmin will want to avoid.
A solution to this problem
Colin Watson proposed a very simple solution:
make the earlier PostgreSQL versions accept the new MATERIALIZED syntax.
This is correct since the new syntax specifies precisely
the actual behaviour of the old databases. It has no
deleterious effect on any users of older pgsql versions.
It makes it possible to add the new syntax to the
application, before doing the database upgrade, decoupling
the two upgrades.
Colin Watson even provided an implementation of this proposal.
The solution is rejected by upstream
Unfortunately upstream did not accept this idea. You can read
the whole thread
yourself if you like. But in summary, the objections were
(italic indicates literal quotes):
OFFSET 0 trick
One of the responses in the thread mentions OFFSET 0.
As part of writing the queries in the Xen Project CI system, and
preparing for our system upgrade, I had carefully read the relevant
pgsql documentation. This OFFSET 0 trick was new to me.
But, now that I know the answer, it is easy to provide the right
search terms and find, for example, this
answer on stackmumble.
Apparently adding a no-op OFFSET 0 to the subquery
defeats the pgsql 12 query planner's ability to see into the subquery.
I thinkSo in fact there is a syntax for an optimisation fence that is accepted by both earlier and later PostgreSQL versions. It's even recommended by pgsql devs. It's just not documented, and is described by pgsql developers as a "hack". Astonishingly, the fact that it is a "hack" is given as a reason to use it! Well, I have therefore deployed this "hack". No doubt it will stay in our codebase indefinitely. Please don't be like that! I could come up with a lot more examples of other projects that have exhibited similar arrogance. It is becoming a plague! But every example is contentious, and I don't really feel I need to annoy a dozen separate Free Software communities. So I won't make a laundry list of obstructiveness. If you are an upstream software developer, or a distributor of software to users (eg, a distro maintainer), you have a lot of practical power. In theory it is Free Software so your users could just change it themselves. But for a user or downstream, carrying a patch is often an unsustainable amount of work and risk. Most of us have patches we would love to be running, but which we haven't even written because simply running a nonstandard build is too difficult, no matter how technically excellent our delta. As an upstream, it is very easy to get into a mindset of defending your code's existing behaviour, and to turn your project's guidelines into inflexible rules. Constant exposure to users who make silly mistakes, and rudely ask for absurd changes, can lead to core project members feeling embattled. But there is no need for an upstream to feel embattled! You have the vast majority of the power over the software, and over your project communication fora. Use that power consciously, for good. I can't say that arrogance will hurt you in the short term. Users of software with obstructive upstreams do not have many good immediate options. But we do have longer-term choices: we can choose which software to use, and we can choose whether to try to help improve the software we use. After reading Colin's experience, I am less likely to try to help improve the experience of other PostgreSQL users by contributing upstream. It doesn't seem like there would be any point. Indeed, instead of helping the PostgreSQL community I am now using them as an example of bad practice. I'm only half sorry about that.OFFSET 0is the better approach since it's more obviously a hack showing that something weird is going on, and it's unlikely we'll ever change the optimiser behaviour aroundOFFSET 0... wherashopefully CTEs will become inlineable at some pointCTEs became inlineable by default in PostgreSQL 12.
From: Ian Jackson <*****>
To: support@bountysource.com
Subject: Re: Update to our Terms of Service
Date: Wed, 17 Jun 2020 16:26:46 +0100
Bountysource writes ("Update to our Terms of Service"):
> You are receiving this email because we are updating the Bountysource Terms of
> Service, effective 1st July 2020.
>
> What's changing?
> We have added a Time-Out clause to the Bounties section of the agreement:
>
> 2.13 Bounty Time-Out.
> If no Solution is accepted within two years after a Bounty is posted, then the
> Bounty will be withdrawn and the amount posted for the Bounty will be retained
> by Bountysource. For Bounties posted before June 30, 2018, the Backer may
> redeploy their Bounty to a new Issue by contacting support@bountysource.com
> before July 1, 2020. If the Backer does not redeploy their Bounty by the
> deadline, the Bounty will be withdrawn and the amount posted for the Bounty
> will be retained by Bountysource.
>
> You can read the full Terms of Service here
>
> What do I need to do?
> If you agree to the new terms, you don't have to do anything.
>
> If you have a bounty posted prior to June 30, 2018 that is not currently being
> solved, email us at support@bountysource.com to redeploy your bounty. Or, if
> you do not agree with the new terms, please discontinue using Bountysource.
I do not agree to this change to the Terms and Conditions.
Accordingly, I will not post any more bounties on BountySource.
I currently have one outstanding bounty of $200 on
https://www.bountysource.com/issues/86138921-rfe-add-a-frontend-for-the-rust-programming-language
That was posted in December 2019. It is not clear now whether that
bounty will be claimed within your 2-year timeout period.
Since I have not accepted the T&C change, please can you confirm that
(i) My bounty will not be retained by BountySource even if no solution
is accepted by December 2021.
(ii) As a backer, you will permit me to vote on acceptance of that
bounty should a solution be proposed before then.
I suspect that you intend to rely on the term in the previous T&C
giving you unlimited ability to modify the terms and conditions. Of
course such a term is an unfair contract term, because if it were
effective it would give you the power to do whatever you like. So it
is not binding on me.
I look forward to hearing from you by the 8th of July. If I do not
hear from you I will take the matter up with my credit card company.
Thank you for your attention.
Ian.
They will try to say "oh it's all governed by US law" but of
course section 75 of the Consumer Credit Act makes the card
company jointly liable for Bountysource's breach of contract and
a UK court will apply UK consumer protection law even to a
contract which says it is to be governed by US law - because you
can't contract out of consumer protection. So the card company
are on the hook and I can use them
as a lever.
Update - BountySource have changed their mind
From: Bountysource <support@bountysource.com> To: ***** Subject: Re: Update to our Terms of Service Date: Wed, 17 Jun 2020 18:51:11 -0700 Hi Ian The new terms of service has with withdrawn.This is not the end of the matter, I'm sure. They will want to get long-unclaimed bounties off their books (and having the cash sat forever at BountySource is not ideal for backers either). Hopefully they can engage in a dialogue and find a way that is fair, and that doesn't incentivise BountySource to sabotage bounty claims(!) I think that means that whatever it is, BountySource mustn't keep the money. There are established ways of dealing with similar problems (eg ancient charitable trusts; unclaimed bank accounts). I remain wary. That BountySource is now owned by cryptocurrency company is not encouraging. That they would even try what they just did is a really bad sign. Edited 2020-06-17 16:28 for a typo in Bountysource's email address
Here's a practical example of applying Template Haskell to reduce
the amount of boilerplate code that is otherwise required. I wrote the below
after following this excellent blog post by Matt Parsons. This post will be much higher-level, read
Matt's blog for the gorier details.
Liquorice
Liquorice is a toy project of mine from a few years ago that lets you
draw 2D geometric structures similar to LOGO. Liquorice offers two interfaces:
pure functions that operate on an explicit Context (the pen location:
existing lines, etc.), and a second "stateful" interface where the input and
output are handled in the background.
I prefix the pure ones P. and the stateful ones S. in this blog post for
clarity.
The stateful interface can be much nicer to use for larger drawings.
Compare example8b.hs,
written in terms of the pure functions, and the stateful equivalent
example8.hs.
The majority of the stateful functions are "wrapped" versions of the pure
functions. For example, the pure function P.step takes two numbers
and moves the pen forward and sideways. Its type signature is
P.step :: Int -> Int -> Context -> Context
Here's the signature and implementation of the stateful equivalent:
S.step :: Int -> Int -> State Context ()
S.step x y = modify (P.step x y)
Writing these wrapped functions for the 29 pure functions is boilerplate that
can be generated automatically with Template Haskell.
Generating the wrapper functions
Given the Name of a function to wrap, we construct an instance of FunD, the
TH data-type representing a function definition. We use the base name of the
incoming function as the name for the new one.
mkWrap fn = do
let name = mkName (nameBase fn)
return $ FunD name [ Clause (map VarP args) (NormalB rhs) [] ]
To determine how many arguments the wrapper function needs to accept, we need
to determine the input function's arity. We use Template Haskell's reify
function to get type information about the function, and derive the arity from
that. Matt Parson's covers this exactly in his blog.
info <- reify fn
let ty = (\(VarI _ t _ ) -> t) info
let n = arity ty - 1
args <- replicateM n (newName "arg")
We can use the list "args" directly in the clause part of the function
definition, as the data-type expects a list. For the right-hand side, we need
to convert from a list of arguments to function application. That's a simple
left-fold:
-- mkFnApp f [a,b,c] => ((f a) b) c => f a b c
mkFnApp = foldl (\e -> appE e . varE)
rhs <- [ modify $(mkFnApp (varE fn) args) :: State Context () ]
We use TH's oxford brackets for the definition of rhs. This permits us
to write real Haskell inside the brackets, and get an expression data-type
outside them. Within we have a splice (the $( )), which does the opposite:
the code is evaluated at compile time and generates an Exp that is then
converted into the equivalent Haskell code and spliced into place.
Finally, we need to apply the above to a list of Names. Sadly, we can't get at
the list of exported names from a Module automatically. There is an open
request for a TH extension for
this. In the meantime,
we export a list of the functions to wrap from the Pure module and operate
on that
import Liquorice.Pure
wrapPureFunctions = mapM mkWrap pureFns
Finally, we 'call' wrapPureFunctions at the top level in our state module
and Template Haskell splices all the function definitions into place.
The final code ended up only around 30 lines of code, and saved about the
same number of lines of boilerplate. But in doing this I noticed some missing
functions, and it will pay dividends if more pure functions are added.
Limitations
The current implementation has one significant limitation: it cannot handle
higher-order functions. An example of a pure higher-order function is
place, which moves the pen, performs an operation, and then moves it back:
P.place :: Int -> Int -> (Context -> Context) -> Context -> Context
Wrapping this is not sufficient because the higher-order parameter has
the pure function signature Context -> Context. If we wrapped it, the
stateful version of the function would accept a pure function as the
parameter, but you would expect it to accept another stateful function.
To handle these, at a minimum we would need to detect the function arguments
that have type Context -> Context and replace them with State Context ().
The right-hand side of the wrapped function would also need to do more work to
handle wrapping and unwrapping the parameter. I haven't spent much time
thinking about it but I'm not sure that a general purpose wrapper would work
for all higher-order functions. For the time being I've just re-implemented the
half-dozen of them.
sip:657837644.522827@192.168.169.170Now if only jami would reduce its memory usage, I could even recommend this setup to others. :) As usual, if you use Bitcoin and want to show your support of my activities, please send Bitcoin donations to my address 15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b.
dak, the Debian Archive Kit, has been replaced by a neural network for processing package uploads and other archive maintenance. All FTP masters and assistants have been re-deployed to concentrate on managing neuraldak.
neuraldak is an advanced machine learning algorithm which has been taught about appropriate uploads, can write to maintainers about their bugs and can automatically make an evaluation about suitable licenses and code quality. Any uploads which do not meet its standards will be rejected with prejudice.
We anticipate that neuraldak will also monitor social media for discontent about package uploads, and train itself to do better with its decisions.
In terms of licensing , neuraldak has been seeded only with the GPL license. This we consider the gold standard of licenses, and its clauses will be the basis for neuraldak evaluating other licenses as it is exposed to them.
Over the course of the next few weeks, neuraldak will also learn to manage the testing suite. Once it is established, we expect to be able to make a full stable release of Debian approximately every six weeks. We have therefore also re-purposed Janelle Shane s cat name algorithm to invent suitable release names, since the list of Toy Story names is likely to be exhausted before 2021.
neuraldak is an independent software project. Rumours of it being derived from Skynet are entirely unfounded.
The post neuraldak appeared first on jwiltshire.org.uk.
Everywhere I worked in the past, the only feedback that was asked of
employees was during a yearly evaluation meeting. These meetings always felt to me
like talking to Santa Claus and his Knecht Ruprecht. I was asked: Were you a good
employee last year? If yes, we might give you a raise. If no, admit all
your mistakes now, even if we already know everything, ho ho ho. And don't you talk about your feelings, or your
well-being, or say anything about the organization's (invisible)
hierarchies, otherwise we will put you on the "naughty list", and that's it with candy. The
yearly evaluation set aside, there was no other place to give feedback (except by escalating a matter by involving the Labour Court, if you happen to work in France, or going on strike, also mostly part of French culture).
Feedback allows to reflect on work processes, to situate oneself, and to get closure.
How surprised was I when, some years ago, I received an email from a
collaborator asking me: kindly for just few paragraphs (doesn t have to be
anything long) to hear from you about the process, your work, challenges
you had, or anything else you want to mention there.. Wow!Next.