"ponderous pensées on human frailty by an apologetic autocrat"
From this article about a different emperor: https://www.lrb.co.uk/the-paper/v41/n04/christopher-kelly/a-...
HN user
productivedetour.blogspot.com
"ponderous pensées on human frailty by an apologetic autocrat"
From this article about a different emperor: https://www.lrb.co.uk/the-paper/v41/n04/christopher-kelly/a-...
The memoir "Street without a Name: Childhood and Other Misadventures in Bulgaria" by Kapka Kassabova (2008) covers similar ground. https://www.goodreads.com/book/show/3808716-street-without-a...
I would also recommend the site "Science Fiction Ruminations": https://sciencefictionruminations.com/
Lots of thoughtful sf book reviews with a heavy (but not exclusive) focus on the New Wave.
I'm not a mathematician, but I feel the "syntethic"/"analythic" distinction in mathematics is an interesting and useful concept.
"In modern mathematics, an analytic theory is one whose basic objects are defined in some other theory, whereas a synthetic theory is one whose basic objects are undefined terms given meaning by rules and axioms"—Michael Shulman
In programming terms, I guess "synthetic" mathematics feels a bit like programming to an abstract interface.
https://ncatlab.org/nlab/show/synthetic+mathematics
In the first part of this video Cédric Villani gives (in French) a nice explanation of the distinction: https://youtu.be/xzVk56EKBUI?t=258
Edit: an English explanation, also by Villani: https://www.youtube.com/watch?v=AIrLXbwyYXQ
However, even for these tasks, its performance has dropped measurably since the early 2060s and is now considered subpar compared to more recent uploads. This is primarily attributed to MMAcevedo's lack of understanding of the technological, social and political changes which have occurred in modern society since its creation in 2031. This phenomenon has also been observed in other uploads created after MMAcevedo, and is now referred to as context drift.
Purifying an (unnecessarily-) IO function into an ordinary function is a good exercise.
Agree! And I would add that you can "purify" a monadic function without having to rewrite it in non-monadic style. You can make it polymorphic over all monads and relegate the "impurity" to monadic functions that you pass as arguments/dependencies. A trivial example:
twice :: IO ()
twice = do
putStrLn "foo"
putStrLn "foo"
twice' :: forall m. m () -> m ()
twice' action = do
action
action
This is not that different to having a Spring bean that doesn't perform any effect directly—say, a direct invocation to "Instant.now()"—but instead receives a "Clock" object through dependency injection.Haskell lets you express the idea of "program logic that only has effects through its dependencies" by being polymorphic over all monads.
Consequently, while al-Qazwīnī was wont to include tales about islands at the end of the world where women grew on trees and other dubious mirabilia, his purpose was lofty indeed.
Collections of marvels and extraordinary things were their own genre called ‘aǧā’ib. Here is an open-access example, "The Marvels Found in the Great Cities and in the Seas and on the Islands" https://library.oapen.org/handle/20.500.12657/46307
The classical world had a similar genre, paradoxography: https://en.wikipedia.org/wiki/Paradoxography
There's also jOOQ for Java. https://www.jooq.org/
Adult Swim's "Lords of Synth" comedy short contains a homage to Wendy Carlos in the form of a certain "Carla Wendos" https://www.youtube.com/watch?v=WXgNo5Smino
There's also the documentary "Sisters with transistors" about women pioneers of electronic music https://www.youtube.com/watch?v=7r-3hlzpV7M
My own solution was to keep no entity state in memory and translate everything into DB updates immediately
Did you encounter some part of the domain which was difficult to "push down" into SQL?
Also, how would this compare with encoding your domain code in a bunch of stored procedures, largely skipping a "conventional" programming language?
Consistent with my loyalty to the functional-programming idiom, I designed my initial bf implementation so that each instruction would copy the existing bytes into a new array, change the byte of interest, return this new byte array, and abandon the old array (which would eventually be garbage-collected).
This would be a fun task to attempt with the new linear features of Haskell https://hackage.haskell.org/package/linear-base-0.1.0/docs/D...
A related answer in the CS Stack Exchange: https://cs.stackexchange.com/a/91345/5296
type theory is not about syntax. It is a mathematical theory of constructions, just like set theory is a mathematical theory of collections. It just so happens that the usual presentations of type theory emphasize syntax, and consequently people end up thinking type theory is syntax. This is not the case.
If we need to compose these errors in a larger program we can simply wrap previous errors in a bigger sumtype
This approach is being adopted in GHC itself to compose errors happening at different stages of the compilation pipeline: each stage has its own error type which later becomes a branch of the global error type.
Another interesting post about errors-as-values in Haskell is "The Trouble with Typed Errors": https://www.parsonsmatt.org/2018/11/03/trouble_with_typed_er...
Maybe Grothendieck, like Avicenna's conception of God, only knew particulars "in as much as they are universal".
Grothendieck once flunked an exam due to—in his own words— "une erreur idiote de calcul numérique".
A recent video about -fdefer-type-errors: https://www.youtube.com/watch?v=hPVjA3TO9OI
Another useful feature of Spring is aspect-oriented-programming (like when we manage transactions boundaries with @Transactional).
Spring takes care of that, but doing it manually (and without dynamic proxies) would add to the verbosity.
I think that, when talking about idempotency, there's the implicit assumption that the "rest of the world" stays the same while the sequence of operations is performed.
rfc2616 says:
Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
https://datatracker.ietf.org/doc/html/rfc2616#page-51
Perhaps changes in the underlying data could be considered "expiration issues". Otherwise not even GET could be considered idempotent in many cases.
So that means that, without a cache, repeating a QUERY might create two response resources but, with a cache, only one will be created. I find that odd. My understanding of HTTP idempotency is that it's more of a "whole-server" concept (excepting perhaps things like creation of log entries and metrics). Always creating a new resource for each request seems contrary to that.
A way to square creation of response resources with idempotency could be: the second identical QUERY that arrives should always reuse the result resource created by the first QUERY.
QUERY requests are both safe and idempotent with regards to the resource identified by the request URI. That is, QUERY requests do not alter the state of the targeted resource. However, while processing a QUERY request, a server can be expected to allocate computing and memory resources or even create additional HTTP resources through which the response can be retrieved.
The possible creation of extra HTTP resources (response resorces?) seems to me contrary to idempotency. That seems more like the territory of POST.
If two identical QUERY requests might produce different response resources, how to square that with the the fact that QUERY will be cacheable?
This "Design Patterns for Parser Combinators" https://www.youtube.com/watch?v=RwzX1XltOGY video (an the associated pdf https://dl.acm.org/doi/abs/10.1145/3471874.3472984) explains some techniques that are good to know—how to deal with left recursion, for example.
It's also notable for being a continuous integration-driven talk!
A video about Wingman with detailed examples https://www.youtube.com/watch?v=S0HvfXq3454 including custom tactics https://www.youtube.com/watch?v=S0HvfXq3454&t=2139s
Once the graph of dependencies between components gets complex, passing all those beans as positional arguments might get tiresome, and type-directed autowiring begins to seem more appealing. Most of the information required for constructing the graph resides in the types themselves, after all.
DI frameworks also provide aspect-oriented-programming services (transactionality, logging...). Doing that with plain functions in an arity-polymorphic way is possible, but not completely trivial, in my (Haskell) experience. http://web.cecs.pdx.edu/~ntc2/haskell-decorator-paper.pdf
I once coded red-black-trees in Haskell at the type level and yes, I had to write some type-level tests.
In a real dependently-typed language the friction would be lower, because it's easier to put "normal code" at the type level.
Perhaps I could have skipped some type-level tests by introducing more kind-safety...
"Spectacle" is a Haskell DSL for writing TLA+ specifications: https://awakesecurity.com/blog/spectacle-a-language-for-writ...
One way I like to think of application contexts in frameworks like Spring is as a huge product type with one "field" for each managed component. Objects have views of particular sections of this product, namely, their own dependencies. Viewing the full product would increase coupling.
Seen in this light, the van Laarhoven Free Monad seems closer to how application contexts work that the typical "free monad" type used in functional programming.
Because it's polymorphic over the underlying monad ("forall m. Monad m => ops m -> m a") I believe it lets you express the idea of "pure component whose effects are carried out only through its own dependencies". For example, injecting java.time.Clock in your program logic instead of calling LocalTime.now().
Don't just read stuff, run it in GHCI
Newcomers should absolutely use ghci commands like :t :type https://downloads.haskell.org/ghc/latest/docs/html/users_gui... to tinker and experiment. Also :info and :instances https://downloads.haskell.org/ghc/latest/docs/html/users_gui... once they start learning about typeclasses.
Typed holes can also be really helpful https://downloads.haskell.org/ghc/latest/docs/html/users_gui...
Don Quixote is windmillpunk! Less facetiously, it's a work informed by the technological developments of its time. http://www.cervantesvirtual.com/obra-visor/cervantes-bulleti...
According to this article https://www.depauw.edu/sfs/backissues/2/plank2art.htm "windmills were first erected in La Mancha thirty years or less before Don Quixote was written" and this gives new nuances to Quixote's delusion.
That's not the only encounter with "advanced" technology; there's also the episode with the water-powered "fulling-hammers" https://www.cliffsnotes.com/literature/d/don-quixote/summary...
Don Quixote also rails against modern military technology like firearms.
It's interesting to compare Copilot with Wingman for Haskell: https://youtu.be/S0HvfXq3454?t=550 Both attempts at somewhat automating repetitive aspects of programming, but with completely different approaches. Wingman was inspired by tactic metaprogramming in theorem provers like Coq.
Textile terminology proliferates throughout the English language.
I think "seam" ("a place where two parts of the code meet and where something else can be injected") is a felicitous metaphor.
"thread" as well. Wikipedia credits the term to Victor A. Vyssotsky https://en.wikipedia.org/wiki/Thread_(computing)#History
(1) Dennis and Van Horn [11] have used the words "locus of control within an instruction sequence." to describe a process; the alternative term "thread" (suggested by V. Vyssotsky) is suggestive of the abstract concept embodied in the term "process."
Was it chosen because it suggests a linear sequence of executing instructions, or perhaps because a thread that appears and disappears in the fabric with every stitch resembles a process getting and losing hold of the CPU?
I wish programming had more sewing and textile metaphors and less architecture-related ones.
We could begin with associating the idea of "patterns" in programming with sewing patterns rather than with architectural ones. They actually fit the former better.
Aspect-oriented programming is alive and well and living in the Spring Framework.
While it can be misused (by making unclear what aspects are being applied, as you mention) it can be very useful and avoid a lot of boilerplate code and repeated logic.