HNHacker News
TopNewBestAskShowJobs

Twisol

3,397 karma · joined July 20, 2010

Software developer and mathematician; areas of interest include programming language semantics and concurrency. I <3 Rust.

Currently a graduate student at UC Santa Cruz; previously worked at Caltech's Jet Propulsion Laboratory (JPL) on mission planning+simulation software.

Blog: https://www.jonathan.com/

Twitter: https://twitter.com/Twisol

GitHub: https://github.com/Twisol

Email: twisolar <at> gmail (please don't come selling any services; otherwise, please let me know you found me via HN or something, because cold calls are confusing enough)

[ my public key: https://keybase.io/twisol; my proof: https://keybase.io/twisol/sigs/t3hJmOxbrWLW5PpKNS3nbtl1bOYx5bSTwF75FHAW6Hw ]

submissionscomments
Twisol··on Ask HN: How can we solve the loneliness epidemic?
I need to take a heaping spoonful of my own advice here, but: yeah, kind of yes. You don't have to think of them as the people you've been searching all your life for, but to meet people, you need a source of people to draw from. Those two people you talk to on a semi-regular basis are entry nodes into the social network.
Twisol··on Play Aardwolf MUD
> I think Achaea and some of the other big ones do though.

Achaea's had a premium shop for a long, long time, yes. It seems they've recently added ways for players to accumulate "credits" (the premium currency) just by playing the game normally -- it's called the "renown" system. (And there have always been other programs that involve volunteering behind the scenes -- the most obvious and in-the-open one is being an official newbie guide.)

I haven't felt any strong desire to put money into Achaea, personally. There are a lot of nice-to-haves, and yes, a good number of premium artefacts that give real advantages in gameplay; but the selling point for me has always been the RP-focused world and community, and mechanically speaking you don't need artefacts for PvE. Probably the most common premium items I've seen are non-decaying vials (which are, IIRC, extremely cheap and very accessible via accumulated renown) and the Atavian wings that let you travel to a lot of different locations very quickly.

I did make a small cash purchase once, to ensure that my character would never get deleted from inactivity, but these days it seems a sufficient amount of total game time is enough to avoid that fate.

I'd definitely recommend Achaea if you're interested in a heavily character-driven world with a community that's passionate about roleplay. The cash shop is by no means a necessity (unless you're getting very deep into PvP, where my expertise runs out, so it could go either way). The volunteer staff (the "Garden of the Gods", as it were) are super active with both large and small RP events, so there's a lot of both official and "unofficial" goings-on in the world. It's really fantastic.

(If anybody here remembers Soludra, hi, that was me!)

Twisol··on Bruno Simon – 3D Portfolio
Weirdly, playing games is typically something I the feel least guilty doing, precisely because it's a distraction from the other stuff I'd otherwise not be doing. There's just a lot of stuff I want to do, that I struggle to do, and so I feel guilty about not making progress on that stuff. Then, whenever I try to do something else, I feel too guilty to do that something else.

It's a real self-reinforcing negative feedback loop. I agree that it's not healthy. It's just hard to break out of.

Twisol··on Bruno Simon – 3D Portfolio
> What changed?

Personally, I feel too guilty about everything else I'm not doing. (This results in me feeling maximal guilt and doing minimal anything at all.)

Twisol··on TCP, the workhorse of the internet
That would be IP over some lower level physical layer, not some custom content stuffed into an IP packet :)

(It's absolutely worth reading some of those old April Fools' RFCs, by the way [0]. I'm a big fan of RFC 7168, which introduced HTTP response code 418 "I'm a teapot".)

[0]: https://en.wikipedia.org/wiki/April_Fools%27_Day_Request_for...

Twisol··on TCP, the workhorse of the internet
UDP pretty much just tacks a source/destination port pair onto every IP datagram, so its primary function is to allow multiple independent UDP peers to coexist on the same IP host. (That is, UDP just multiplexes an IP link.) UDP as a protocol doesn't add any additional network guarantees or services on top of IP.

QUIC is still "their own protocol", just implemented as another protocol nested inside a UDP envelope, the same way that HTTP is another protocol typically nested inside a TCP connection. It makes some sense that they'd piggyback on UDP, since (1) it doesn't require an additional IP protocol header code to be assigned by IANA, (2) QUIC definitely wants to coexist with other services on any given node, and (3) it allows whatever middleware analyses that exist for UDP to apply naturally to QUIC applications.

(Regarding (3) specifically, I imagine NAT in particular requires cooperation from residential gateways, including awareness of both the IP and the TCP/UDP port. Allowing a well-known outer UDP header to surface port information, instead of re-implementing ports somewhere in the QUIC header, means all existing NAT implementations should work unchanged for QUIC.)

Twisol··on TCP, the workhorse of the internet
They probably can do deep/shallow packet inspection for that purpose (being one of the non-nefarious applications I alluded to), but that's not to say their correct functioning relies on it. Those routers also need to support at least UDP, and UDP provides almost no extra information at that level -- just the source and destination ports (so, perhaps QoS prioritization) and the inner payload's length and checksum (so, perhaps dropping bad packets quickly).

If middleware decides to do packet inspection, it better make sure that any behavioral differences (relative to not doing any inspection) is strictly an optimization and does not impact the correctness of the link.

Also, although I'm not a network operator by any stretch, my understanding is that TCP congestion control is primarily a function of the endpoints of the TCP link, not the IP routers along the way. As Wikipedia explains [0]:

> Per the end-to-end principle, congestion control is largely a function of internet hosts, not the network itself.

[0]: https://en.wikipedia.org/wiki/TCP_congestion_control

Twisol··on Löb and Möb: Loops in Haskell (2013)
> This shows how moeb is a generalization of fix.

To be fair, loeb was already a generalization of fix. If `f` is the identity functor, then `loeb` has type `(a -> a) -> a`, and the `fmap` used in its definition resolves to `id`.

It's a shame there aren't any other example applications of moeb. The author mentions using `traverse` and `foldMap`, but those are also based fundamentally on `fmap` in some sense, and I wouldn't be too surprised if they also ended up being literally `fmap` for some specific choice of functor.

Twisol··on TCP, the workhorse of the internet
> If it's IPv4, you need to put a number between 0 and 255 to the protocol field from this list:

To save a skim (though it's an interesting list!), protocol codes 253 and 254 are suitable "for experimentation and testing".

Twisol··on TCP, the workhorse of the internet
As far as I'm aware, sure you can. TCP packets and UDP datagrams are wrapped in IP datagrams, and it's the job of an IP network to ship your data from point A (sender) to point B (receiver). Nodes along the way might do so-called "deep packet inspection" to snoop on the payload of your IP datagrams (for various reasons, not all nefarious), but they don't need to do that to do the basic job of routing. From a semantic standpoint, the information in the TCP and UDP headers (as part of the IP payload) is only there to govern interactions between the two endpoint parties. (For instance, the "port" of a TCP or UDP packet is a node-local identifier for one of many services that might exist at the IP address the packet was routed to, allowing many services to coexist at the same node.)
Twisol··on Simplify your code: Functional core, imperative shell
I like this example :) Another good example might be Git's distinction between "porcelain" and "plumbing"; the porcelain is implemented in terms of the plumbing, and gives a nicer* interface in terms of what people generally want to do with Git, but the plumbing is what actually does all the general, low-level stuff.

* opinions vary

Twisol··on Simplify your code: Functional core, imperative shell
Everything "potentially leads" to adverse outcomes if not applied with due care and cognizance. That includes KISS and YAGNI. If you're looking for a principle you can apply in 100% of cases without consideration of context, I'm afraid you'll need to shop elsewhere.
Twisol··on Simplify your code: Functional core, imperative shell
Yep! I remember the phrase "functional core, imperative shell" being popularized by Gary Bernhardt in ~2012 [0][1]; in his talk Boundaries [0] (around 31:00), he even mentions "hexagonal architecture" by name.

[0]: https://www.destroyallsoftware.com/talks/boundaries

[1]: https://www.destroyallsoftware.com/screencasts/catalog/funct...

Twisol··on Simplify your code: Functional core, imperative shell
> But no advice that you give about "the correct philosophy" is going to instantly transfer enough knowledge to make all large companies write good code, if only they followed it.

Good old "Programming as Theory Building". It's almost impossible to achieve this kind of transfer without already having the requisite lived experience.

[0]: https://ratfactor.com/papers/naur1_theory_building.pdf

Twisol··on Simplify your code: Functional core, imperative shell
> Take the tax calculation for example. That cannot be decomposed into pieces that are generic, and potentially reusable elsewhere.

Quite right! However, the tax code does change with some regularity, and we can expect that companies like Intuit should have gotten quite good by now -- even on a pure profit motive -- at making it possible to relatively quickly modify only the parts of their products that require updating to the latest tax code. To put it another way, while it might be the case that the tax code for any given year is not amenable to decomposition, all tax codes within a certain span of years might be specific instances of a more general problem. (I recall a POPL keynote some years back that argued for formalizing tax codes in terms of default logic!) By solving that general problem, you can instantiate your solution on the given year's tax code without needing to recreate the entire program from scratch.

To be clear, I'm the one who brought subproblem decomposition into the mix, and we shouldn't tar the top-level commenter with that brush unnecessarily. Of course some problems will be un-decomposable "leaves". I believe their original point, about a specific business layer sitting on top of a more general core, still applies.

> So a game is a good example where the core can be more specialized than the shell. You can imagine a generic UI library shared by a bunch of games, but a generic game rules engine - that's just a programming language.

As it happens, the "ECS pattern" (Entity, Component, and System) is often considered to be a pretty good way of conceptualizing the rules of a game. An ECS framework solves the general problem (of associating components to entities and executing the systems that act over them), and a game developer adapts an ECS framework to their specific needs. The value in this arrangement is precisely that, as the game evolves and takes shape, only the logic specific to the game needs to be changed. The underlying ECS framework is on the whole just as appropriate for one game as for any other.

(I could also make a broader point about game engines like Unity and Unreal, and how so many games these days take the "general" problem solved by these engines and adapt them to the "specific" problem of their particular game. In general, nobody particularly wants to make engine-level changes for each experiment during the development of a game, even though sometimes a particular concept for a game demands a new engine.)

> Sure, but this discussion is about FCIS, that's the context, and the GP should consider that.

I understood the original commenter as criticizing FCIS (or at least the original post, as "grasping for straws") and suggesting that GCSS is generally more appropriate. In that context, I think it's natural to interpret their use of "core" and "shell" as competing rather than concordant with FCIS.

Twisol··on Simplify your code: Functional core, imperative shell
> then the definition of the "shell" and "core" becomes problematic in this comparison

I agree -- if you're trying to make the words "shell" and "core" mean the same things between FCIS and GCSS, or identify the same parts of a program, then there will be problems. I think FCIS and GCSS are just two different ways of analyzing a program into pieces. Just as the number 8 can be seen through addition as 3 + 8 and through multiplication as 2 * 4, a program can be analyzed in multiple ways. If you view a program through the lens of FCIS, you expect to see a broad region of the program in which side-effects don't occur and a narrow region in which they do. If you view a program through the lens of GCSS, you expect to see broad parts of the program that solve general problems, and narrower regions in which those problems are instantiated in specific. The narrower regions are all "shell"-shaped, but that doesn't mean they are "the" shell. They have in common simply that they wrap a bulk of functionality to interface it to a larger context.

> At the core, things can be more integrated than at the boundary, and so it can have more business-specific rules.

I tend to disagree. Decomposition is a fundamental part of software engineering: we decompose a large problem into smaller ones, solve those, them compose those solutions into a solution to the large problem (c.f. Parnas' "On the criteria to be used in decomposing systems into modules"). It is often easier to solve a more general problem than the one originally given (Polya's principle). Combining the two yields GCSS.

A solution to each individual small problem can be construed as having its own generic core, and the principles used in composing sibling solutions constitute the specific shells that wrap them, allow them to interface, and together implement a solution to a higher-level problem.

Because there are multiple of these "cores", each solving a decomposed part of the top-level problem, it's hard for me to see how "At the core, things can be more integrated than at the boundary".

> The definition question is, if you take an application, where is the business logic, is it in the "core" or not?

I don't mean to be a sophist, but I think I need a more precise meaning of "business logic" before I can answer this question. In the process of solving successively smaller (and more general) problems, we abstract away from the totality of the business problem being solved, and address smaller and less-specific aspects of that problem. It may be that each subproblem's solution is architected as an individual instance of FCIS, as is often argued for microservice architectures; or that each subproblem is purely functional and only the top-level solution is wrapped in an imperative core; or anywhere in between. Needless to say, I think that choice is orthogonal.

As a result, I would say that the business logic itself has been factorized and distributed across the many subproblems and their solutions, and that indeed the "specific shell"s that are responsible for specializing solutions toward the specific case of the business need may necessarily include business logic. For instance, when automating a business process, one often needs to perform a complex step A before a complex step B. While both A and B might be independently solvable, orchestrating them together is still "business logic", because they need to be performed in order according to business needs.

(In all of this, perhaps you can see why I don't think the "core" and "shell" of FCIS should be identified with the "core" and "shell" of GCSS. Words are allowed to have contextual meanings!)

Twisol··on Simplify your code: Functional core, imperative shell
I disagree that these two pieces of advice are opposed. I think they are orthogonal at worst, and in agreement at best.

"Functional core, imperative shell" (FCIS) is a matter of implementing individual software components that need to engage with side-effects --- that is, they have some impact on some external resources. Rather than threading representations of the external resources throughout the implementation, FCIS tells us to expel those concerns to the boundary. This makes the bulk of the component easier to reason about, being concerned with pure values and mere descriptions of effects, and minimizes the amount of code that must deal with actual effects (i.e. turning descriptions of effects into actual effects). It's a matter of comprehensibility and testability, which I'll clumsily categorize as "verification": "Does it do what it's supposed to do?"

"Generic core, specific shell" (GCSS) is a matter of addressing needs in context. The problems we need solved will shift over time; rather than throwing away a solution and re-solving the new problem from scratch, we'd prefer to only change the parts that need changing. GCSS tells us we shouldn't simply solve the one and only problem in front of us; we should use our eyes and ears and human brains to understand the context in which that problem exists. We should produce a generic core that can be applied to a family of related problems, and adapt that to our specific problem at any specific time using a, yes, specific shell. It's a matter of adaptability and solving the right problem, which I'll clumsily categorize as "validation": "Is what it's supposed to do what we actually need it to do?"

Ideally, GCSS is applied recursively: a specific shell may adapt an only slightly more generic core, which then decomposes into a smaller handful of problems that are themselves implemented with GCSS. When business needs change in a way that the outermost "generic core" can't cover, odds are still good that some (or all) of its components can still be applied in solving the new top-level problem. FCIS isn't really amenable to the same recursion.

Both verification and validation activities are necessary. One is a matter of internal consistency within the component; the other is a matter of external consistency relative to the context the component is being used in. FCIS and GCSS advise on how to address each concern in turn.

Twisol··on IRS open sources its fact graph
Seems so, according to this file: https://github.com/IRS-Public/fact-graph/blob/main/docs/from...

> The main changes are: [...] converting the fact-graph to a standalone library [...]

Twisol··on Testing a compiler-driven full-stack web framework
Oh! The thread must have been boosted on a resubmission, or something, because for me it shows your comment as having only been posted yesterday D:
Twisol··on Testing a compiler-driven full-stack web framework
ICFP and SPLASH are this week, actually! Here's the program website for anyone interested: https://conf.researchr.org/program/icfp-splash-2025/program-...

(I have a pretty unfavorable view of LLMs myself, but) a quick search for "LLM" does find four sessions of the colocated LMPL workshop that are explicitly about LLMs and AI agents, plus a spread of other work across the schedule. ("LMPL" stands for "Language Models and Programming Languages", so I guess that's no surprise.)

Twisol··on The SAT Game
I guess this links to the "very hard" difficulty, but I lucked myself into a winning solve without needing to backtrack at all.

I'm a big fan of things that let me do manually what computers normally do automatically, so this is a neat page.

Twisol··on Xmonad seeking help for Wayland port (2023)
This is dated in October of 2023. I wonder if there's been any progress since then?
Twisol··on Why are anime catgirls blocking my access to the Linux kernel?
Yes, Anubis is a dog-headed or jackal-headed god. I actually can't find anywhere on the Anubis website where they talk about their mascot; they just refer to her neutrally as the "default branding".

Since dog girls and cat girls in anime can look rather similar (both being mostly human + ears/tail), and the project doesn't address the point outright, we can probably forgive Tavis for assuming catgirl.

Twisol··on A spellchecker used to be a major feat of software engineering (2008)
"Hypo", meaning low; "glyc-", meaning sugar; and "emia", meaning of the blood. "Low sugar of the blood". (With apologies to chubbyemu.)

Since "typo" comes from "typography", it roughly means "symbolic". So "typoglycemia" should mean "symbolic sugar of the blood". Low typos in your blood would be "hypotypemia".

I have no idea why "typoglycemia" refers to a human ability to autocorrect, but it brings me joy, so I'm not going to question it ^_^

Twisol··on Hilbert's sixth problem: derivation of fluid equations via Boltzmann's theory
I know it wasn't you :) Sorry if I came across that way.
Twisol··on Hilbert's sixth problem: derivation of fluid equations via Boltzmann's theory
Your second paragraph is a much more thoughtful critique, and posting that below the original answer would focus the subsequent conversation on those points. The issue here isn't whether the comment was AI-generated; it's how we carry the conversation forward even if we suspect that it is.

(For the record, if I had attempted to answer the earlier question, I probably would have laid out a similar narrative. The asker's questions were of a kind asking for the greater context, and the fact that Hilbert (mentioned in the submission title) posed the question is pretty important grounding. But, that's beside the point.)

Twisol··on Hilbert's sixth problem: derivation of fluid equations via Boltzmann's theory
Not enough em-dashes for it to be AI.

(Less jokingly, nothing strikes me as particularly AI about the comment, not to mention its author addressed the question perfectly adequately. Your comment comes off as a spurious dismissal.)

Twisol··on Systems Correctness Practices at Amazon Web Services
I've heard that called "validation". In other words, you verify that your solution meets the problem specification, but you validate that your specification is actually what you need.
Twisol··on VR Design Unpacked: The secret to Beat Saber's fun
Audica is sick! I definitely enjoyed it a lot more than Beat Saber, for the reasons you give -- it feels way more technical, and (therefore?) much more satisfying to learn.
Twisol··on How I accepted myself into Canada's largest AI hackathon
It's in one of the screenshots, in the part about how they could fetch their reviewer's full name and comments.
← PreviousPage 2 of 34Next →