Skip to content

Instantly share code, notes, and snippets.

@sogaiu
Created March 13, 2026 03:47
Show Gist options
  • Select an option

  • Save sogaiu/4039ce1c7517a616f98703585f6f0531 to your computer and use it in GitHub Desktop.

Select an option

Save sogaiu/4039ce1c7517a616f98703585f6f0531 to your computer and use it in GitHub Desktop.

2025-12-31

  • Writer Ted Chiang on AI and grappling with big ideas - Avery Keatley, Scott Detrow, Patrick Jarenwattananon

  • ChatGPT Is a Blurry JPEG of the Web - Ted Chiang - version archived elsewhere as original is paywalled

    In 2013, workers at a German construction company noticed something odd about their Xerox photocopier: when they made a copy of the floor plan of a house, the copy differed from the original in a subtle but significant way. In the original floor plan, each of the house’s three rooms was accompanied by a rectangle specifying its area: the rooms were 14.13, 21.11, and 17.42 square metres, respectively. However, in the photocopy, all three rooms were labelled as being 14.13 square metres in size. The company contacted the computer scientist David Kriesel to investigate this seemingly inconceivable result. They needed a computer scientist because a modern Xerox photocopier doesn’t use the physical xerographic process popularized in the nineteen-sixties. Instead, it scans the document digitally, and then prints the resulting image file. Combine that with the fact that virtually every digital image file is compressed to save space, and a solution to the mystery begins to suggest itself.

    Compressing a file requires two steps: first, the encoding, during which the file is converted into a more compact format, and then the decoding, whereby the process is reversed. If the restored file is identical to the original, then the compression process is described as lossless: no information has been discarded. By contrast, if the restored file is only an approximation of the original, the compression is described as lossy: some information has been discarded and is now unrecoverable. Lossless compression is what’s typically used for text files and computer programs, because those are domains in which even a single incorrect character has the potential to be disastrous. Lossy compression is often used for photos, audio, and video in situations in which absolute accuracy isn’t essential. Most of the time, we don’t notice if a picture, song, or movie isn’t perfectly reproduced. The loss in fidelity becomes more perceptible only as files are squeezed very tightly. In those cases, we notice what are known as compression artifacts: the fuzziness of the smallest jpeg and mpeg images, or the tinny sound of low-bit-rate MP3s.

    Xerox photocopiers use a lossy compression format known as jbig2, designed for use with black-and-white images. To save space, the copier identifies similar-looking regions in the image and stores a single copy for all of them; when the file is decompressed, it uses that copy repeatedly to reconstruct the image. It turned out that the photocopier had judged the labels specifying the area of the rooms to be similar enough that it needed to store only one of them—14.13—and it reused that one for all three rooms when printing the floor plan.

    The fact that Xerox photocopiers use a lossy compression format instead of a lossless one isn’t, in itself, a problem. The problem is that the photocopiers were degrading the image in a subtle way, in which the compression artifacts weren’t immediately recognizable. If the photocopier simply produced blurry printouts, everyone would know that they weren’t accurate reproductions of the originals. What led to problems was the fact that the photocopier was producing numbers that were readable but incorrect; it made the copies seem accurate when they weren’t.

  • Ted Chiang: The Incompatibilities Between Generative AI and Art

  • Why A.I. Isn't Going to Make Art - Ted Chiang

    Art is notoriously hard to define, and so are the differences between good art and bad art. But let me offer a generalization: art is something that results from making a lot of choices. This might be easiest to explain if we use fiction writing as an example. When you are writing fiction, you are - consciously or unconsciously - making a choice about almost every word you type; to oversimplify, we can imagine that a ten-thousand-word short story requires something on the order of ten thousand choices. When you give a generative-A.I. program a prompt, you are making very few choices; if you supply a hundred-word prompt, you have made on the order of a hundred choices.

    If an A.I. generates a ten-thousand-word story based on your prompt, it has to fill in for all of the choices that you are not making. There are various ways it can do this. One is to take an average of the choices that other writers have made, as represented by text found on the Internet; that average is equivalent to the least interesting choices possible, which is why A.I.-generated text is often really bland. Another is to instruct the program to engage in style mimicry, emulating the choices made by a specific writer, which produces a highly derivative story.In neither case is it creating interesting art.

    ...

    The companies promoting generative-A.I. programs claim that they will unleash creativity. In essence, they are saying that art can be all inspiration and no perspiration - but these things cannot be easily separated. I’m not saying that art has to involve tedium. What I’m saying is that art requires making choices at every scale; the countless small-scale choices made during implementation are just as important to the final product as the few large-scale choices made during the conception. It is a mistake to equate “large-scale”with “important” when it comes to the choices made when creating art; the interrelationship between the large scale and the small scale is where the artistry lies.

    ...

    Many of us have sent store-bought greeting cards, knowing that it will be clear to the recipient that we didn’t compose the words ourselves. We don’t copy the words from a Hallmark card in our own handwriting, because that would feel dishonest. The programmer Simon Willison has described the training for large language models as “money laundering for copyrighted data,” which I find a useful way to think about the appeal of generative-A.I. programs: they let you engage in something like plagiarism, but there’s no guilt associated with it because it’s not clear even to you that you’re copying.

  • ‘Do you really want to live forever?’ Sci-fi author Ted Chiang talks immortality

2025-12-30

  • The Best Things and Stuff of 2025 - fogus

    assess: LLMs - I’m into the 3rd AI hype-cycle in my life (at least) and this is not much different than they other two, save for the potential market and job disruptions in play. I tried in earnest to make AI work for me, with varying degrees of un-success. I’ve had zero success leveraging it in my work maintaining and evolving Clojure. For problem formation in the face of novelty, LLMs have been more frustrating than helpful and the little gains that I’ve found were in the very early phases of problem solving requiring a bare minimum of experimental code. But even these examples operate wholly in the known rather than in the unknown where I’d like to operate instead. Even in these early stages the “hand-holding” involved was more frustrating than helpful. In my work, the bottleneck is absolutely not the code. While I think that the kind of up-front work that I do could inform prompt-engineering to some degree, by the time that I get to that point the code is often perfunctory. Most of the work that I do is devising and investigating new problem framing rather than in interpolation of the known (i.e. analogy play). While the latter is important for sure, what’s known often acts as a source of tension to help motivate and tease out potentially new solutions. And this is a huge problem in the very nature of LLMs. That is, they are trained on the products of problem solving processes rather then also in the very processes themselves. Further, as a Socratic partner, LLMs are incredibly frustrating in their inability to move a “discussion” forward. A good Socratic partner creates pressure to move toward truth, but LLMs are too sycophantic, lack an awareness of useful tension,20 cannot often identify contradiction, and lack any ability to adhere to the trajectory of a conversation. So far I’m left wanting, but because LLMs are likely to never go away then I’ll see if these downsides get better in the future.21

2025-12-29

2025-12-28

2025-12-17

2025-12-16

2025-12-15

Anyone who knows, and knows that he knows, makes the steed of intelligence leap over the vault of heaven. Anyone who does not know but knows that he does not know, can bring his lame little donkey to the destination nonetheless. Anyone who does not know, and does not know that he does not know, is stuck forever in double ignorance.

-- Nasir al-Din al-Tusi

2025-12-14

2025-12-13

2025-12-12

2025-12-11

2025-12-10

2025-12-09

2025-12-08

2025-12-07

2025-12-06

2025-12-05

2025-12-04

2025-12-03

2025-12-02

2025-12-01


2025-11-30

2025-11-29

2025-11-28

  • Chartalism

    a theory in macroeconomics that views money as a creation of the state, introduced to control and organize economic activity rather than arising from barter or debt. It holds that fiat currency has value because governments impose taxes that must be paid in the currency they issue, creating demand for it.

2025-11-27

2025-11-26

2025-11-25

  • Miller Documentation

    Miller is a command-line tool for querying, shaping, and reformatting data files in various formats, including CSV, TSV, JSON, and JSON Lines.

2025-11-24

2025-11-23

2025-11-22

2025-11-21

2025-11-20

2025-11-19

2025-11-18

2025-11-17

2025-11-16

2025-11-15

2025-11-14

2025-11-13

2025-11-12

  • Caveman - A Clojure Web Framework

2025-11-11

2025-11-10

2025-11-09

2025-11-08

2025-11-07

2025-11-06

2025-11-05

2025-11-04

2025-11-03

2025-11-02

2025-11-01


2025-10-31

2025-10-30

2025-10-29

2025-10-28

2025-10-27

2025-10-26

2025-10-25

2025-10-24

  • Publishing semantic-namespace/contract lib - tangrammer

    There is no reason to limit our specifications to what we can prove, yet that is primarily what type systems do. There is so much more we want to communicate and verify about our systems. This goes beyond structural/representational types and tagging to predicates that e.g. narrow domains or detail relationships between inputs or between inputs and output. Additionally, the properties we care most about are often those of the runtime values, not some static notion. Thus spec is not a type system.

2025-10-23

  • Sound Default-Typed Scheme (Position Paper) - Jan-Paul Ramos-Davila

    We propose a new approach to typing Scheme programs based on the observation that programmers often have strong beliefs about the “normal” behavior of their code. Rather than forcing a binary choice between static types and runtime checks, we introduce default typing, where each program point carries a plausibility-ranked set of types. The highest-ranked type (rank 0) represents what the programmer believes will “almost always” be true, while higher ranks capture increasingly exceptional cases. By leveraging Racket’s macro-extensible type system and SMT-based constraint solving, we can verify whether a program type-checks using only the default assumptions. Success yields efficient code with no runtime overhead; failure produces a counterexample showing which assumptions are violated. We provide a precise notion of conditional soundness: programs are guaranteed type-safe only when their default assumptions hold at runtime.

2025-10-22

2025-10-21

2025-10-20

2025-10-19

2025-10-18

2025-10-17

2025-10-16

2025-10-15

2025-10-14

2025-10-13

2025-10-12

2025-10-11

2025-10-09

2025-10-08

2025-10-07

2025-10-06

2025-10-05

2025-10-04

2025-10-03

2025-10-02

2025-10-01


2025-09-30

2025-09-29

2025-09-28

2025-09-27

2025-09-26

2025-09-25

2025-09-24

2025-09-23

2025-09-22

2025-09-21

2025-09-20

2025-09-19

2025-09-18

2025-09-17

2025-09-16

2025-09-15

2025-09-14

2025-09-13

2025-09-12

2025-09-11

2025-09-10

2025-09-09

2025-09-08

2025-09-07

  • C4 - ISeq clarity - David Miller
  • Make Worse Software, Slower - Nathan Marz

    And for your convenience, here are some comments you can use prewritten by ChatGPT from the prompt “generate a range of typical Hacker News responses to this post”:

2025-09-06

2025-09-05

2025-09-04

2025-09-03

2025-09-02

2025-09-01


2025-08-31

2025-08-30

2025-08-29

2025-08-28

2025-08-27

2025-08-26

2025-08-25

2025-08-24

2025-08-23

2025-08-22

2025-08-21

2025-08-20

2025-08-19

2025-08-18

2025-08-17

2025-08-16

20225-08-15

2025-08-14

2025-08-13

2025-08-12

  • Designing extendable data applications

    I like static typing — I really do.

    But the love fades when I have to build large domain entities.

    I’ve been building supply chain management systems for decades, modeling complex domains with tens or even hundreds of properties. In long-lived data applications, one truth becomes clear: we want to extend code, not change it.

    Code mutation sends ripples through the system — and often breaks it. The programming industry has largely solved code modularity, yet we remain stuck with monolithic data structures. Code and data are glued together.

    Many business applications today are fragile because they rely on structs, records, and classes. Yes, these give compile-time safety — but also rigid, hard-to-extend designs.

    For me, the practical solution is simple: build entities on maps. You can add new properties to an existing map, or combine maps to create new, derived ones.

  • Managing Complexity - Or "Why do you code in F#?" - Anthony Lloyd

2025-08-11

2025-08-10

2025-08-09

2025-08-08

2025-08-07

2025-08-06

2025-08-05

2025-08-04

2025-08-03

2025-08-02

2025-08-01


2025-07-31

2025-07-30

2025-07-29

2025-07-28

2025-07-27

2025-07-26

2025-07-25

2025-07-24

2025-07-23

2025-07-22

  • Design Reboot - Jonathan Blow
  • Jai Demo and Design Explanation - Jonathan Blow - LambdaConf 2025
  • Demystifying Debuggers, Part 1: A Busy Intersection - Ryan Fleury

    To emphasize their importance, I’d like to reflect on the name “debugger”. It is not a name I would’ve chosen, because it can give the impression that a debugger is an auxiliary, only-relevant-when-things-break tool. Of course, a debugger is used to debug—which is why it was named as such—but it is also enormously useful to analyze working code’s behavior, and to verify code’s correctness, with respect to the expectations of the code.

    A good debugger provides clear and insightful visualizations into what code is doing. As such, they are also enormously useful educational tools—for beginners and experts alike—because they make what is normally opaque, visible. They provide these features by dynamically interacting with running programs—as such, they can also dynamically modify code. At the limit, this approximates (or employs) JIT-compilation and hot-reloading, making traditional compiled toolchains have much more runtime flexibility for developers.

    For these reasons, “debugger” is much too special-purpose of a name for the full set of capabilities that debuggers actually provide—they offer glimpses into the lower level inner-workings of a computer. If one designed a computing system from scratch, they might not ideally be independent from the operating system itself. Instead, perhaps the same capabilities could simply be provided through first-class visualization and dynamic execution adjustment features that the operating system naturally exposes. But that is a topic for another day.

    I hope this sheds light on the imbecility of Internet debates about the utility of debuggers—for example, where one might find comments like, “I don’t need debuggers, because I can just use printf”, or “I don’t need debuggers if I can statically guarantee correctness”. It’s akin to suggesting that someone does not benefit from vision, because they can feel their way around with a mobility cane, or read text through Braille. Even though mobility canes and Braille are obviously good inventions for people who can’t have vision, that doesn’t somehow imply that vision isn’t an obvious benefit, or that it isn’t obviously preferable. Similarly, even though logging and static verification are obviously good inventions for programs or circumstances which cannot be easily debugged at runtime, or when those things are simply preferable in context, that doesn’t somehow imply that actively visualizing the runtime execution of programs through a debugger isn’t an obvious net benefit, or that it isn’t obviously preferable in many cases. To suggest otherwise in either case is absurd. The more useful debuggers become, the shorter the iteration loop of the programmer, the more efficient software production becomes, and the more trivially that programmers can obtain true from-first-principles reasoning about their code.

2025-07-21

2025-07-20

2025-07-19

2025-07-18

2025-07-17

2025-07-16

2025-07-15

2025-07-14

2025-07-13

2025-07-12

2025-07-11

2025-07-10

2025-07-09

2025-07-08

2025-07-07

2025-07-06

2025-07-05

2025-07-04

2025-07-03

2025-07-02

2025-07-01

  • How to Upgrade Your PC to Windows 11
    • Turns out that if you're upgrading from Windows 10 and already have a local account, you may not be asked to create a MS account. One thing I did though was to forget my router's network before doing the restart that comes right after going through the initial "Download and install" part of Windows 11 via Windows Update. Don't know if that made a difference. (Note: this is like a log entry -- it's not something from the article linked above.)
  • How to bypass the Microsoft Account requirement during Windows setup
  • How to Set Up Windows 11 Without a Microsoft Account

    To bypass the Microsoft Account requirement, proceed with the first few steps of the installation process normally until you reach this screen ("Let's add your Microsfot account")

    Once you're there, press Shift + F10 to open up a Command Prompt Window and type:

    oobe\bypassnro

    It isn't case sensitive, but it is critical that you use the correct slash. Once you type in the command, press Enter and your PC will immediately restart.

    Now, you should completely disconnect your PC from the Internet at this point. If Windows 11 detects an Internet connection it will continue to try and force you to sign in with a Microsoft account. However, if you're disconnected from the Internet you'll see an "I Don't Have Internet" option, or you'll be prompted to create a local account immediately.

    Click "Continue with limited setup" on the next page if it appears, and then you'll be able to create a local account with a password and three security questions.

  • How to Delete a Saved Wi-Fi Network on Windows 10
  • Windows 11 OOBE Bypassnro Not Working
  • OOBE BypassNRO - Windows CMD - SS64.com

    bypassnro.cmd used to contain the following:

    @Echo off
    reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE /v BypassNRO /t REG_DWORD /d 1 /f
    shutdown /r /t 0
    
    1. On the Windows 11 setup screen, press Shift + F10 to open a CMD prompt and type regedit and press Enter.
    2. Go to Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE
    3. Click Edit > New > DWORD (32-bit) and rename the new value to BypassNRO
    4. Open the value and change its value data to 1
    5. Restart the system.

    You can now setup your computer without an active internet connection or a Microsoft Account, though this workaround may stop working at some point in the future.

  • [2025 Guide] Install Windows 11 24H2 on Unsupported PCs (Bypass Compatibility Check)

2025-06-30

  • borkdude in #off-topic at clojurians slack:

    I've used it two times. The second time I tried to make it create a markdown parser. When it got hard in the edge cases, it said things like: yeah, but I have 30 out of 40 passing tests, that's already quite impressive right! Yes, it was impressive sure, but it didn't get to the hard part "because it needed to go from a regex based approach to a delimited parser approach" yeah duh.

    My feeling is that "vibe" coding is best used to find problems, not to solve them

    Also the Claude/ChatGPT is stuff is handy for "dumb" things like "something is not right about my pom.xml, what is it"

    After a while I felt like I was tolerating too much generated shit code and it felt like a slot machine addition.

  • Producing a video lesson - Rakhim Davletkaliyev
  • Running Clojure in Wasm - Roman Liutikov
  • Clojure: SQLite C API with project Panama and Coffi - Anders Murphy

2025-06-29

  • What is an architecture decision record?

    An architecture decision record (ADR) is a document that captures an important architectural decision made along with its context and consequences.

    An architecture decision (AD) is a software design choice that addresses a significant requirement.

    An architecture decision log (ADL) is the collection of all ADRs created and maintained for a particular project (or organization).

    An architecturally-significant requirement (ASR) is a requirement that has a measurable effect on a software system’s architecture.

    All these are within the topic of architecture knowledge management (AKM).

2025-06-28

2025-06-27

2025-06-26

2025-06-25

2025-06-24

  • Quote from "I got bruned by haskell." (with slight editing):

    Dirk Roeckmann

    amano said:

    After coding in haskell for months, I prefer clojure. I would rather verify unstructured input data with spec or something similar and write tests than satisfy a complex type system.

    Python is probably the last frontier for clojure. When clojure is properly on python, I will only write clojure.

    That’s absolutely my opinion too. An official Clojure hosted on Python would be sensational for all data scientists/AI afficionados interested in FP and homoiconicity. This is the perfect marriage. Python is just the lingua franca of AI nowadays and full access to all the SOTA packages from within Clojure would be a dream. Basilisp is great, but official backing would be perfect

    walterl

    amano said:

    After coding in haskell for months, I prefer clojure. I would rather verify unstructured input data with spec or something similar and write tests than satisfy a complex type system.

    I've spent the last 2 years working in Julia, and I concur. Coming from Clojure it was interesting to see what I've come to describe as "type obsession" in action. There is no inclination to think of data as data. Everything must be typed, and considered in those terms.

2025-06-23

2025-06-22

  • Slop Deving v. Vibe Coding - Dio the Debugger

    I think many developers and even people today have heard of the term 'Vibe coding' the term was coined by Andrej Karpathy, a well known AI researcher and influencer in the field. I think that vibe coding does not capture that well the result of what is produced, it is also singular to code where as slop deving or slop development is more accurate. You want to just churn out effectively garbage content. A major thing that is missing from vibecoding is that you are not even coding at all. In fact, it isn't vibe coding if you are coding. Though the term has recently evovled to almost encompass any major usage of AI in writing code. The original usage of the term meant the wholesale abandonment of the code. Prompting the AI is all you need. We need a better term that captures this, because honestly its as bad as the term 'serverless'.

  • "Hallucinations"
    • @thefreedictionary

      Hallucinations are false or distorted sensory experiences that appear to be real perceptions. These sensory impressions are generated by the mind rather than by any external stimuli, and may be seen, heard, felt, and even smelled or tasted.

      • ...seems a rather difficult thing to prove "generated by the mind rather than by any external stimuli"
    • @Wikipedia

      Some researchers have highlighted a lack of consistency in how the term is used, but also identified several alternative terms in the literature, such as confabulations, fabrications, and factual errors.

      ...

      In the scientific community, some researchers avoid the term "hallucination", seeing it as potentially misleading. It has been criticized by Usama Fayyad, executive director of the Institute for Experimental Artificial Intelligence at Northeastern University, on the grounds that it misleadingly personifies large language models and is vague. Mary Shaw said, "The current fashion for calling generative AI’s errors 'hallucinations' is appalling. It anthropomorphizes the software, and it spins actual errors as somehow being idiosyncratic quirks of the system even when they’re objectively incorrect." In Salon, statistician Gary N. Smith argues that LLMs "do not understand what words mean" and consequently that the term "hallucination" unreasonably anthropomorphizes the machine. Some see the AI outputs not as illusory but as prospective—that is, having some chance of being true, similar to early-stage scientific conjectures. The term has also been criticized for its association with psychedelic drug experiences.

      • ...isn't everything from LLMs generated? sometimes what comes out is useful (even though it may be wrong), sometimes what comes out is not found to be useful...and may be it even depends on who looks at the results...and when...
  • "Retrieval"

2025-06-21

2025-06-20

2025-06-19

2025-06-18

2025-06-17

2025-06-16

2025-06-15

2025-06-14

2025-06-13

2025-06-12

2025-06-11

2025-06-10

2025-06-09

2025-06-08

  • Vibe Coding With Clojure-MCP - Bruce Hauman, Luke Burton, Gene Kim

    00:00 Introductions and Background

    03:17 First AI Coding Agent Experiences

    06:41 Discussing the Vibe Coding Book Project

    14:09 Setting Up Clojure MCP Demo

    41:45 Troubleshooting MCP Configuration

    55:30 Live Demo: Working with Book Data Structure

    01:31:08 Deep Dive: Clojure Edit vs S-Expression Editing

    01:49:53 Reflections on the Demo Experience

    01:52:00 OMG: Let’s go find/fix a crazy race condition! (And prove by showing contrapositive condition!)

    02:15:25 Discussion: REPL-Driven Development and AI

    02:28:24 Closing Thoughts and Future of AI Coding

  • On keys and their usage - Christian Johansen

  • Programming Languages - CSCI 1730 - Shriram Krishnamurthi (and others)

2025-06-07

2025-06-06

2025-06-05

2025-06-04

2025-06-03

2025-06-02

  • A break from programming languages - Alexis King

    I have often reflected on the fact that, although I have many personal projects, I have never chosen Haskell for any of them. Not once. Whenever I need to write a little code to accomplish some task, it’s always Racket. This blog is in Racket. My personal shell utilities are in Racket. When I want to scrape a website or wrap some library, I do it with Racket. Haskell is a language I have always exclusively written professionally, and although I do very earnestly love many things about it, it is not so precious to me that I feel motivated to contribute to it out of passion alone.

2025-06-01


2025-05-31

2025-05-30

2025-05-29

2025-05-28

2025-05-27

  • The Unix process API is unreliable and unsafe

  • A fork() in the road

    The received wisdom suggests that Unix’s unusual combination of fork() and exec() for process creation was an inspired design. In this paper, we argue that fork was a clever hack for machines and programs of the 1970s that has long outlived its usefulness and is now a liability. We catalog the ways in which fork is a terrible abstraction for the modern programmer to use, describe how it compromises OS implementations, and propose alternatives.

    As the designers and implementers of operating systems, we should acknowledge that fork’s continued existence as a first-class OS primitive holds back systems research, and deprecate it. As educators, we should teach fork as a historical artifact, and not the first process creation mechanism students encounter.

  • On Read/Write Code - 6cdh

  • Keep Healthy - 6cdh

2025-05-26

2025-05-25

2025-05-24

2025-05-23

2025-05-22

2025-05-21

2025-05-20

2025-05-19

2025-05-18

2025-05-17

2025-05-16

2025-05-15

2025-05-14

2025-05-13

2025-05-12

2025-05-11

  • Polylith

  • Vertical Slice Architecture - Jimmy Bogard

    • Onion / Clean -> Vertical Slice - Jimmy Bogard

      I was on a large project with the person that came up with Onion architecture. It had worked on smaller (max 3 months) projects, as it didn’t cave under its own weight.

      Fast forward 4 months and we realized that Onion (or Clean in its current incarnation) in fact cant scale with complexity or size. So we collapsed everything down and removed all the indirection.

      We couldn’t remove all the needless indirection and abstraction, but most of the silliness. The next big project I was on, I removed all of the sacred cows to see what patterns would naturally emerge. The result was the Vertical Slice Architecture stuff, built on the ashes of defactoring Onion/Clean. I blogged about this journey in my Put Your Controllers On a Diet series almost a decade ago.

  • Difficulty in demonstrating benefits of architectures - nanothief

    One large issue with demonstrating methodologies as clean architecture, microservices or object orientated programming is they only become beneficial at larger scales:

    • A program under 1000 LOC would rarely benefit from object inheritance; just use an if/switch statement

    • If you have less than 10 domain objects/database tables you probably don't need microservices or any of the "clean architecture" techniques; just make a single EF Core + ASP.net Core project.

    This causes a catch 22 problem when writing examples of those ideas. If you make a simple example, then using such methodologies is actually a net negative to the project - the complexity they add is far greater than the benefit they provide. Newer developers may look at such an example and think they should do it the same way for their project even though it isn't necessary.

    If you make a much larger example, then not only is it going to take a lot of time to complete, but it is going to make the example much harder to follow. It will likely not be tested well either (since an example app doesn't make you any money and isn't used anywhere there isn't any pressure to make it work well).

2025-05-10

2025-05-09

2025-05-08

2025-05-07

2025-05-06

2025-05-05

2025-05-04

2025-05-03

2025-05-02

  • Tai Chi Made Easy: Do I Really Need a Teacher? - David-Dorian Ross - some comments sort of along the lines of the "Practicing Versus Inventing With Contrasting Cases: The Effects of Telling First on Learning and Transfer" paper...

2025-05-01


2025-04-30

2025-04-29

2025-04-28

2025-04-27

2025-04-26

2025-04-25

  • Does learning by doing actually work? - Benjamin Keep
  • Transfer of learning - Taking Learning Seriously
    • About - Taking Learning Seriously

      In 1999, Lee Shulman, then President of the Carnegie Foundation for the Advancement of Teaching, published Taking Learning Seriously, a wonderful article in which he introduced the higher education community to three key concepts about learning. A gifted storyteller, Shulman described these as pathologies of learning, called them amnesia, fantasia, and inertia, and went on to explain how these pose ever present threats to derail new learning and undermine teaching.

      The technical terms for these pathologies are forgetting, misconceptions, and lack of transfer of learning, respectively. As many decades of research have shown, they are significant cognitive obstacles in learning. For example, students may demonstrate knowledge of a topic soon after learning it, but then forget it quickly (amnesia). The preconceptions and misconceptions students bring to a new learning situation profoundly affect whether and what they will learn (fantasia). And, even though students can demonstrate knowledge of a topic on one day, they may not be able to use it the next (inertia).

2025-04-24

2025-04-23

2025-04-22

2025-04-21

2025-04-20

2025-04-19

  • Rascal: a Haskell with more parentheses - what Hackett used to be called

  • Problems with Excel - Joel Dueck

    Spreadsheets work great for prototyping (although they still foster silent-error creep when used for complex models), and suck at operations when compared to suitable tools such as accounting software.

2025-04-18

2025-04-17

2025-04-16

2025-04-15

  • Clojure Brain Teasers Review
  • CommonMark Spec
    • 3. Blocks and inlines

      We can think of a document as a sequence of blocks—structural elements like paragraphs, block quotations, lists, headings, rules, and code blocks. Some blocks (like block quotes and list items) contain other blocks; others (like headings and paragraphs) contain inline content—text, links, emphasized text, images, code spans, and so on.

    • 5.2 List items

      The following rules define list items:

      [1] Basic case. If a sequence of lines Ls constitute a sequence of blocks Bs starting with a character other than a space or tab, and M is a list marker of width W followed by 1 ≤ N ≤ 4 spaces of indentation, then the result of prepending M and the following spaces to the first line of Ls, and indenting subsequent lines of Ls by W + N spaces, is a list item with Bs as its contents. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start number, based on the ordered list marker.

      Exceptions:

      1. When the first list item in a list interrupts a paragraph—that is, when it starts on a line that would otherwise count as paragraph continuation text—then (a) the lines Ls must not begin with a blank line, and (b) if the list item is ordered, the start number must be 1.
      2. If any line is a thematic break then that line is not a list item.


      [2] Item starting with indented code. If a sequence of lines Ls constitute a sequence of blocks Bs starting with an indented code block, and M is a list marker of width W followed by one space of indentation, then the result of prepending M and the following space to the first line of Ls, and indenting subsequent lines of Ls by W + 1 spaces, is a list item with Bs as its contents. If a line is empty, then it need not be indented. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start number, based on the ordered list marker.

      [3] Item starting with a blank line. If a sequence of lines Ls starting with a single blank line constitute a (possibly empty) sequence of blocks Bs, and M is a list marker of width W, then the result of prepending M to the first line of Ls, and preceding subsequent lines of Ls by W + 1 spaces of indentation, is a list item with Bs as its contents. If a line is empty, then it need not be indented. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start number, based on the ordered list marker.

      [4] Indentation. If a sequence of lines Ls constitutes a list item according to rule #1, #2, or #3, then the result of preceding each line of Ls by up to three spaces of indentation (the same for each line) also constitutes a list item with the same contents and attributes. If a line is empty, then it need not be indented.

      [5] Laziness. If a string of lines Ls constitute a list item with contents Bs, then the result of deleting some or all of the indentation from one or more lines in which the next character other than a space or tab after the indentation is paragraph continuation text is a list item with the same contents and attributes. The unindented lines are called lazy continuation lines.

      Going through the corresponding examples in the spec may be helpful in understanding the text above.

    • 5.3 Lists

      A list is a sequence of one or more list items of the same type. The list items may be separated by any number of blank lines.

    • Appendix: A parsing strategy

      Parsing has two phases:

      1. In the first phase, lines of input are consumed and the block structure of the document—its division into paragraphs, block quotes, list items, and so on—is constructed. Text is assigned to these blocks but not parsed. Link reference definitions are parsed and a map of links is constructed.

      2. In the second phase, the raw text contents of paragraphs and headings are parsed into sequences of Markdown inline elements (strings, code spans, links, emphasis, and so on), using the map of link references constructed in phase 1.

      At each point in processing, the document is represented as a tree of blocks. The root of the tree is a document block. The document may have any number of other blocks as children. These children may, in turn, have other blocks as children. The last child of a block is normally considered open, meaning that subsequent lines of input can alter its contents. (Blocks that are not open are closed.)

2025-04-14

2025-04-13

2025-04-12

  • CommonMark List Looseness / Tightness

    A list is loose if any of its constituent list items are separated by blank lines, or if any of its constituent list items directly contain two block-level elements with a blank line between them. Otherwise a list is tight. (The difference in HTML output is that paragraphs in a loose list are wrapped in <p> tags, while paragraphs in a tight list are not.)

  • Beyond Markdown - John MacFarlane

  • Djot

  • Structured Procrastination - via John MacFarlane

2025-04-11

2025-04-10

2025-04-09

2025-04-08

2025-04-07

  • Spec-ulation Keynote - Rich Hickey - Clojure/conj 2016

  • Thoughts about Spec-ulation - Edward Z. Yang

    Accretion is not a silver bullet... if you believe in data hiding. In his talk, Rich implies that backwards compatibility can be maintained simply by committing not to "remove things". As a Haskeller, this sounds obviously false to me: if I change the internal representation of some abstract type (or even the internal invariants), I cannot just load up both old and new copies of the library and expect to pass values of this type between the two. Indeed, the typechecker won't even let you do this even if the representation hasn't changed.

    But, at least for Clojure, I think Rich is right. The reason is this: Clojure doesn't believe data hiding! The prevailing style of Clojure code is that data types consist of immutable records with public fields that are passed around. And so a change to the representation of the data is a possibly a breaking change; non-breaking representation changes are simply not done.

2025-04-06

2025-04-05

2025-04-04

2025-04-03

2025-04-02

2025-04-01

  • 93: Diversity of Approach (David Nolen) - Giant Robots Smashing Into Other Giant Robots

  • The Disconnect Between AI Benchmarks and Math Research

    Current AI systems boast impressive scores on mathematical benchmarks. Yet when confronted with the questions mathematicians actually ask in their daily research, these same systems often struggle, and don't even realize they are struggling.

  • The Cultural Divide between Mathematics and AI

    To understand the cultural divide, we must first understand what mathematics truly is. Paul Halmos captured this beautifully in I Want to Be a Mathematician (1985): "The youngster who is presented with a proof of a difficult theorem admires the achievement and is left wondering: How was this proof found? How could I invent something like this? No hints are given in the books." This gets at a fundamental truth: mathematics isn't primarily about finding proofs; it's about building understanding.

    May be actually teaching about how to solve things directly from an early age might have a positive impact?

  • .bat wrapper script

  • Exploring the Methodology of “A performance comparison of Clojure and Java” by Gustav Krantz - joinr

    • The M6

      We are a small team of nerds sharing writings on the internet. If you think about it, that’s how the internet started, before its commercialization. Remember the 90s? (Ok, some of you don’t.) Not that we are against commercial activity per se — we’re not. However, this is the way that we remember the internet when it first started, and we’re proud to join the few who are still keeping, in effect, this tradition alive.


2025-03-31

2025-03-30

2025-03-29

2025-03-28

  • clojure.spec - Rich Hickey - LispNYC 2016 - transcript

    As you build larger systems, you realize that so much happens at run time, and so many things happen over wires. And there is sort of presumption in many languages that the type system is going to solve every problem. It is just not practical. There is the famous adage about every large C program has a little crappy Lisp implementation inside it. That is not my adage. That is an old one. But it does, and I used to write crappy Lisps inside C++ programs.

    And after you have done that for a while, you realize: I am doing this because I do not have sufficient flexibility. My systems are large. I need them to be malleable. I cannot afford to change the whole world whenever some small thing changes.

    So when you get to the dynamic edges of those programs, you end up doing this stuff. In Clojure, we do it this way all of the time. But there are still edges to our programs, and if you do something in the language that is just about the language, you run up against the wire, and then it stops helping you.

  • Agility & Robustness: Clojure spec - (video at youtube) - Stuart Halloway - Strange Loop 2016

  • Clojure Spec: Expressing Data Constraints without Types - (video at youtube) - Alex Miller - Emerging Technologies Conference 2017

2025-03-27

2025-03-26

2025-03-25

2025-03-24

2025-03-23

2025-03-22

  • How Data Abstraction changed Computing forever - Barbara Liskov - TEDxMIT

  • Fresh variable Wikipedia Page

    In formal reasoning, in particular in mathematical logic, computer algebra, and automated theorem proving, a fresh variable is a variable that did not occur in the context considered so far. The concept is often used without explanation.

  • Temporary symbol creation section of Hygienic Macro Wikipedia Page

    In some programming languages, it is possible for a new variable name, or symbol, to be generated and bound to a temporary location. The language processing system ensures that this never clashes with another name or location in the execution environment. The responsibility for choosing to use this feature within the body of a macro definition is left to the programmer. This method was used in MacLisp, where a function named gensym could be used to generate a new symbol name. Similar functions (usually named gensym as well) exist in many Lisp-like languages, including the widely implemented Common Lisp standard and Elisp.

2025-03-21

2025-03-20

2025-03-19

2025-03-18

  • Ep 042: What does it mean to be 'data-oriented'? - Functional Design in Clojure

  • What is commutativity and why is it so useful in distributed systems? - Eric Normand

    When you have distributed systems, one of the most costly, expensive things you can do between those nodes and the system is to communicate, so that you can coordinate.

    You don't want to be waiting for each other. You don't want to be waiting for messages to travel across the network. The whole point is that you can work independently. [...]

    We want to reduce the interdependence of the ordering of our operations. We want to make it so that the order the work gets done in doesn't matter. That's what commutativity is.

  • CRDT Wikipedia Page

    To ensure eventual convergence the functions should fulfill the following properties: The merge function should compute the join for any pair of replica states, and should form a semilattice with the initial state as the neutral element. In particular this means, that the merge function must be commutative, associative, and idempotent. The intuition behind commutativity, associativity and idempotence is that these properties are used to make the CRDT invariant under package re-ordering and duplication.

  • Applications of Continuations - Daniel P. Friedman

  • The Rhombus Programming Language Home Page

2025-03-17

  • markdown editors - because working with gists for content that gets longer is terrible

    • markdown-mode - emacs mode, not as pretty, but seems to work better than alternatives tested below
    • ghostwriter - dark mode out-of-the-box, but handling of links to local files not so great?
    • ReText - no issue with links, but dark mode doesn't work here
    • Marker - A gtk3 markdown editor - mostly good except problems with navigating to local files?
  • Tidy Data - Hadley Wickham

  • sherpa-onnx

    Speech-to-text, text-to-speech, speaker diarization, speech enhancement, and VAD using next-gen Kaldi with onnxruntime without Internet connection. Support embedded systems, Android, iOS, HarmonyOS, Raspberry Pi, RISC-V, x86_64 servers, websocket server/client, support 11 programming languages

  • Netsec Tools for Executables - Matthew Flatt

2025-03-16

  • Smooth, iterative deepening - Niko Matsakis

    The idea is that a user’s first experience should be simple–they should be able to get up and going quickly. As they get further into their project, the user will find places where it’s not doing what they want, and they’ll need to take control. They should be able to do this in a localized way, changing one part of their project without disturbing everything else.

    Smooth, iterative deepening sounds easy but is in fact very hard. Many projects fail either because the initial experience is hard or because the step from simple-to-control is in fact more like scaling a cliff, requiring users to learn a lot of background material. Rust certainly doesn’t always succeed–but we succeed enough, and I like to think we’re always working to do better.

  • Why getters and setters are terrible - Eric Normand

  • What is a calculation? - Eric Normand - some operations that don't have side-effects are not functions in some languages (e.g. + in javascript), having a term that can capture these types of things along with pure functions might be less confusing...hence "calculation"

2025-03-15

2025-03-14

2025-03-13

2025-03-12

2025-03-11

2025-03-10

2025-03-09

2025-03-08

2025-03-07

2025-03-06

2025-03-05

2025-03-04

2025-03-03

2025-03-02

2025-03-01


2025-02-28

2025-02-27

2025-02-26

2025-02-25

2025-02-24

2025-02-23

2025-02-22

2025-02-21

2025-02-20

2025-02-19

2025-02-18

2025-02-17

2025-02-16

2025-02-15

2025-02-14

2025-02-11

2025-02-10

2025-02-09

2025-02-08

2025-02-07

2025-02-05

2025-02-04

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment