An oral history of Bank Python

𝘉𝘢𝘤𝘬 𝘵𝘰 𝘉𝘢𝘴𝘪𝘤𝘴: go read Cal Paterson’s “An oral history of Bank Python”. It describes a class of software systems that run inside large investment banks, and it is a instructive case study on software architecture. You will probable start reading and thinking “wow, this does not seem right”. Until you realize the constraints that produced them.

Every system runs on limits, whether you name them or not, what’s allowed to change independently, what has to stay coupled, what the system will simply refuse to do, what trade-off you’re accepting today so you don’t have to relitigate it tomorrow. Good architecture isn’t the absence of constraints. It’s choosing the right ones, early, on purpose.

https://calpaterson.com/bank-python.html

Automation

Last Wednesday at the ING TownHall there was an interesting presentation about reducing toil, a lot of it was around automation. Next day I read this article from Austin and both events reminded me of this XKCD strip.

Austin is a Microsoft engineer and he describes what happened when he took a colleague’s advice to never do anything three times, meaning that any task performed more than twice should immediately be handed over to automation. He assumed he had very little left to automate, since most of his coding work was already delegated to AI agents, and he expected the remaining fragments to be too awkward or too specialized to bother with at all.

He was, in his own words, very wrong, and the particular way in which he was wrong is far more interesting than a simple story about a productivity gain. He automated all the obvious parts and this gain shifted the work he needs to do. It made visible all the non-parts, what he calls “the glue work that never bothered me before”.

When start hardcore automating stuff it may be a rabbit hole 🙂

https://austinhenley.com/blog/automatingmyjob.html

https://xkcd.com/1319

Towards Resiliency

This post from Amex reminded of my time at PagBank, we had a huge monolith there and we spent so much effort into converting it to a service architecture. The idea around a microservice, we all know, is about independency of the services leading to resiliency.

What makes Amex’s approach compelling is not the novelty of isolation as a concept ofc, since engineers have pursued fault containment for decades, but rather the discipline required to enforce it in practice. Cells in their design never span multiple regions, no transaction in the critical path waits on a synchronous call to another cell, and a global router sits at the edge to deterministically send each transaction to the cell that already holds the authoritative data it needs. Reference data such as currency rates and merchant category codes gets replicated into every cell well ahead of time, which means transaction processing never has to reach back to a central system of record while a customer is waiting on a response.

The trade off is honest and worth dwelling on, because cellular isolation increases operational overhead and architectural complexity, and it occasionally forces teams to duplicate services that a single shared implementation would otherwise simplify. Again, at Pagbank, we lived this, sometimes was a step back to make two upfront. For systems where the cost of a widespread outage dwarfs the cost of that added complexity, the exchange tends to be worth making, and the broader lesson generalizes well beyond the world of payments. Resiliency is rarely achieved through monitoring and retries alone, it is achieved by defining clear failure boundaries and then enforcing them relentlessly through design decisions that the rest of the organization has to live with every day.

https://americanexpress.io/cell-based-architecture-for-resilient-payment-systems

The Proof in the Code: How a Truth Machine Is Transforming Math and AI

Book recommendation: “The Proof in the Code: How a Truth Machine Is Transforming Math and AI” by Kevin Hartnett.

This is about the creation of the Z3 solver and how it drove the creation of the Lean programming language, such a fun and thoughtful reading. And the cherry on top is that Z3 was created by a Brazilian, Leonardo de Moura. In the WC mood, VAI BRASIL! 😀

AI Engineer

The last 2 weeks we were flooded with posts about DeepSeek. I am not writing about DS, but it is related, I cant escape 🙂

This article is excellent to sharp your skills as an engineer. This is even more important as the AI world is moving rapidly towards an Open Source world, where we will have a plethora of options available.

https://www.latent.space/p/2025-papers

QueryGPT

Uber has introduced QueryGPT, a tool that leverages generative AI to translate natural language prompts into SQL queries, streamlining data analysis processes. With LLM’s, QueryGPT reduces query authoring time from approximately 10 minutes to 3 minutes. It is cool and impressive, what I found interesting are some restrictions and assumptions:

– “We introduced “workspaces,” which are curated collections of SQL samples and tables tailored to specific business domains”

– “Another issue we found was that it’s incredibly challenging to go from a user’s natural language prompt to finding the relevant schemas”

– “Allowing users to select the tables used in the query generation came up as feedback from some users who saw that the tables that were eventually picked by QueryGPT were not correct “

– “We’ve been experimenting with prompts to reduce hallucinations”

So, we still need to understand the problem space and come up with solutions tailored to our business, let alone don’t forget it will always hallucinate at some point.

QueryGPT – Natural Language to SQL using Generative AI

Advent of Code

I love December. Christmas, New Year, a week or 2 holidays, a look back at the year’s achievements and… AdventOfCode. AdventOfCode is an annual programming challenge consisting of puzzles that can be solved in any programming language. The event is aimed at people with different levels of programming skills and offers an opportunity to improve our skills and learn new techniques. Challenges are launched daily during the month of December until the 25th, at Christmas. There are always 2 problems and for each one solved you get a star.

I’ll be honest and say that until 2022 I solved some challenges but I was never consistent. This year I decided to take it seriously and by the 8th I had collected all 16 stars. And as I said above, I’m seeing it as a learning opportunity: every problem has an example with a solution, so here I am doing TDD, the classic red-green-refactor cycle; every day you download a text file as input and solve for each of the stars, so here I am with an automated template in node that generates a common structure of files and folders; Problems can be solved in several ways, so here I am calculating the performance of my solution and optimising; I’m publishing my answers day by day, so here I am commenting on my code so that my intentions are clear; As there is one issue per day, so here I am looking at each day as a release, I automated the generation of releases on Github using release-please.

My strategy every day has been the most naive, I try to solve everything by brute force. When it takes too long, I stop and think of something better. If it’s acceptable (well, it’s quite subjective here, anything running in less than 3 minutes, ok), I send the answers and at the end of the day I revisit the problem and reflect on whether there’s a better way to do it. For example, one day it was necessary to calculate paths using a map with instructions. My first approach was with a loop, after solving it I realised that I could use the least common multiple of the different paths. Nice!

Let’s see if I can keep up with the issues, it’s been a lot of fun, I highly recommend it!

OpenAI Dev Day

I need to talk about the OpenAI keynote at the developer event this week (https://www.youtube.com/watch?v=U9mJuUkhUzk). There was a perception that ChatGPT was in decline, that the responses were not so good. In this tweet, Mike Young lists several threads on Reddit with the same complaint (https://twitter.com/mikeyoung44/status/1672971689573990400); this paper (https://arxiv.org/pdf/2307.09009.pdf) quantifies the drop in accuracy in the algorithm); and, in this interview (https://olhardigital.com.br/2023/08/22/pro/chatgpt-ja-esta-em-declinio-afirma-neurocientista-da-unifesp/), neuroscientist Álvaro Dias also says that ChatGPT is getting worse. Add to this the ongoing lawsuits for misuse (https://www.bbc.com/news/technology-66164228#:~:text=US%20comedian%20Sarah%20Silverman%20is,of%20the%20firms’ %20AI%20systems.
, https://llmlitigation.com, https://www.ft.com/content/aec1679b-5a34-4dad-9fc9-f4d8cdd124b9, https://www.npr.org/2023/08/16/1194202562/new -york-times-considers-legal-action-against-openai-as-copyright-tensions-swirl). It didn’t seem like a good time but the new news about the event puts ChatGPT in the headlines again.

Now there is the possibility of creating customized versions of ChatGPT for specific needs, without needing to know how to code. I already said that my parameter here is my 16-year-old son who uses the chat every day. He sat down with me on Friday and we did a personalized chat, which receives a text written by him and corrects it using the standards established by the school. We did a test and the recommendations are much more accurate comparing the “normal” model and the “international school” model. And he can share this with his colleagues, it’s a steroid version of custom prompts. OpenAI understood that the common user needs to make their lives easier.

Another example of this is the ability to send attachments (currently limited to 10 files). Before you needed to use a plugin, which sent the document to a service and from there ChatGPT analysed it. We tested this with a meteorological data file, 80MB and bzipped. He was able to open the file and do the analysis. Which brings me to another new feature, the “Data Analysis” agent. This could already be done before, but this personalised chat makes it even easier to discover trends and anomalies. In that file of mine, I must admit that the graphics he put together were better than mine ¯\_(ツ)_/¯

One more? You don’t have to switch modes to create images or browse the web. The algorithm can determine which mode you need for the interaction.

And for the corporate world, two messages: Sam stressed that ChatGPT Enterprise does not use the information submitted for model training, i.e., there is no risk of your spreadsheet with the last quarter’s sales data appearing to your competitor. And that OpenAI has an initiative, called “Copyright Shield”, in which it will bear the legal costs of actions for copyright infringement. The company defends its use of data under the claim of “fair use” under US copyright law, a standard that allows for a more liberal interpretation of copyright law in line with American ideals of free expression.

Exciting!

Arguments and results

After returning from API Days in London, I’m studying design patterns for APIs. The last paper I read was “Arguments and Results” by James Noble (1), published in 1997 and still extremely relevant. Part of my current work, developing a data warehouse, is to optimize the transport of huge volumes of data. And if I want to use APIs, how can I do this efficiently? There is a consensus that REST API’s are not suitable in high-volume scenarios and studying this topic I arrived at Noble.

The article discusses patterns for object protocols and for this there are two groups:

  • How to send objects (Arguments): Arguments object, Selector object and Curried object
  • How to receive objects (Results): Result object, Future object and Lazy object

Patterns

  • Arguments object: This pattern is utilised to streamline a method’s signature by consolidating common arguments and objects, and modifying the method signature to accept this consolidated object instead. It brings several advantages, you make your domain explicit; your customers can use what they have at hand (the objects, instead of separated values); and you are able to separate the processing logic from your business logic

From

    void Send-FixedIncome(EntityName, IssueDate, MaturityDate, PrincipalAmount, ...) { }

To

    void Send-FixedIncome(FixedIncome) { }

“adding an eleventh argument to a message with ten arguments is qualitatively quite different to adding a second argument to a unary message”

  • Selector object: When you have methods with quite similar arguments, this patterns introduces a selector that enables you to pick one of them. Noble mentioned you could a enum, maybe using GoF a Flyweight would do the trick.

From

    void CalculateHomeLoanAmount(HomeLoan, Collateral) { }
    void CalculateHomeLoanAmount(HomeLoan) { }
    void CalculateAutoLoanAmount(AutoLoan) { }
    void CalculatePersonalLoanAmount(PersonalLoan) { }

To

    void CalculateAmount(LoanType, Loan) { } //Loan would be the interface for all loan types

“Protocols (APIs) where many messages perform similar functions are often difficult to learn and to use, especially as the similarity is often not obvious from the protocol’s documentation”

  • Curried object: from the functional programming world, currying breaks a function with several arguments into smaller functions, where each one of those functions takes some (usually one) of the original arguments; these functions are called in sequence then. Noble introduces this pattern for a scenario where the caller should not need to supply all arguments (e.g. constants), the method can supply on their behalf. In GoF terms, it acts as a proxy.

From

    void SettleDebt(Loan, ParcelsToPay) { } # no. of parcels can be retrieved from the loan 

To

    int GetOpenParcels(Loan) { }
    void SettleDebt(Loan) { () => Settle(Loan) } # in Settle no. of parcels is retrieved

“These kinds of arguments increase the complexity of a protocol. The protocol will be difficult to learn, as programmers must work out which arguments must be changed, and which must remain constant.”

  • Results object: For complex scenatios, one might need several method calls to generate the expected result. Your results object should be a single one with everything on it. This pattern can be seen as the flip side of the Curried Object pattern. One aspect worth mentioning is when those several calls mean several systems. In this case. a result object helps to reduce the coupling and acts as an abstraction around them.

“Perhaps the computation returns more than on object”

  • Future object: This pattern is employed when we need to execute a time-consuming operation and perform other tasks while waiting for the operation to complete. In essence, we aim to process a result asynchronously and then likely invoke a callback upon completion.

” Sometimes you need to ask a question, then do something else while waiting for the answer to arrive”

  • Lazy object: Sometimes you need to supply a result, though it is not 100% sure whether the method will be called. The advantage of this is that we don’t get data unnecessarily.

“Some computations can best be performed immediately but the computation’s result may never be needed”

All in all, these concepts are quite widespread. Any mainstream programming language has support for async methods (Future object) and lazy evaluation (Lazy object). Moreover, good OO design makes ‘Arguments object’ and ‘Seletor object’ quite naturally appear. Even though it was a good back-to-basics article to remind me the importance of good design in my API methods.

(1) https://www.researchgate.net/publication/2733549_Arguments_and_Results

CSS made easy

Damien Riehl is a technology lawyer and musician. And he doesn’t agree with copyright infringement lawsuits, for him music is mathematics. And if you remember that there are only 8 musical notes, Damien had the brilliant idea of making an algorithm that made all the combinations and put it in the public domain. According to him, this can help in those cases where someone is prosecuted just because they used a combination used by another, and the second person didn’t even know. See the faq at http://allthemusic.info/ to understand better.

I’m not a lawyer, nor am I defending piracy, what caught my attention was the idea of noting that there is a finite space of possibilities. I think there is a fascination in being able to say ‘here’s everything about topic X’, personally that’s what attracted me to the master’s degree. I won’t be arrogant and say that I know everything about Design Thinking but I approached my studies with this objective.

Another topic: Think about the design of an HTML or SPA page, how many different ways are there to do it? We use CSS to control what is displayed. The colors are finite, ranging from #000000 to #FFFFFF; borders are top-bottom-left-right; and so on. Adam Wathan noticed this and developed TailwindCSS. With TailWind, you can write your CSS without leaving your HTML page. See the difference, before, if I wanted my text to be blue and bold, I would do this:

style.css

.info{
color: blue;
font-weight: bold;
}

index.html

<p class="info>
  Lorem Ipsum
</p>

And voilà, bold blue text. TailWindCSS allows you to write directly and it has a library with hundreds and hundreds of possibilities. As soon as you use it in your html, it automatically generates the CSS. This is a detail, an application runs in your terminal and scans your pages to know what to generate:

index.html

<p class="text-blue font-bold">
  Lorem Ipsum
</p>

or very large, bold, underlined, sky blue text centered on the page:

<p class="text-3xl font-bold underline text-sky-400 text-center">
  Lorem Ipsum
</p>

UnoCSS takes the idea further and eliminates the css file completely. In UnoCSS there is a script that analyses your pages at runtime and generates classes for you. And there is no need for an application running in the background. Magic! Note that the way of writing is exactly the same as TailWindCSS.

index.html

<p class="text-blue font-bold">
  Lorem Ipsum
</p>

I’ve been using UnoCSS a lot. But I have my criticisms, the large number of classes can make HTML code verbose, and it’s a fact, your HTML is difficult to understand. And the CSS generated by TailWindCSS is only readable by… TailWind developers 😀.

Additionally, the framework’s reliance on utility classes can lead to a lack of consistency in design across the site, as different people may use different classes to achieve similar effects. And since there is no CSS file maintained by the team, the need to document style choices is essential.

Still, the practicality seems to me to show that frameworks like these will be increasingly popular.