Glamorize your problem domain (2022)
twitchard.github.io
twitchard.github.io
Programming languages are typically designed to be relatively simple and easy to compile. Line-of-business software tends to be as complicated and arbitrary as the organization requires. Trying too hard to make your mundane app into a compiler can push the software in a direction that makes it difficult to change in the messy ways you'll need to later on.
Note, for instance, that the author worked on a system that generates SDKs in multiple languages. This is pretty obviously a sort of compiler. Are your requirements really so fancy? Or are you making a CRUD app hooked up to a couple external integration APIs?
It's useful to see the analogies between one's domain and compilers, but see if you can't keep that analogy in your head and out of the code whenever possible.
I don't think many people would argue with that. I'm just not sure what it is contributing to this discussion.
The number of people who know compilers well enough to know how to jam them somewhere inappropriate is probably...startingly low, too.
Agreed, I had a number of students complain to me in my programming languages class that I was focusing too much on compilers, and who would ever really need to write a compiler except compiler writers? They would rather I had taught them Go or Python. But I had to tell them, guys, compilers are awesome. There are so many uses! You can use them everywhere!
No one seems to want to :(
Nah, (almost) everyone that don't have a clue what they're doing does this for every app, be it required or not; it's however called "Babel" or "Webpack" because "compiler" is "scary".
Just today, me and a coworker kinda laughed about the fact that this was the second or third time we kinda ended up with an induction proof about the overall correctness of our backup retention handling for off-boarded customers, correctness being dictated by the contractual regulations of our customers. When we stopped laughing, our team lead pointed out a logical problem in one of the steps, and we were eventually able to construct a counter-example which would violate the contracts. Dang it.
Call me silly, but at this point I'm entirely ready to take a day or three off of other work to pick up a formal verification tool to validate our backup retention strategies against the different classes of contracts we have.
In a similar vein, we're starting to work towards certifications like an ISO27001. And there is a staggering amount of similarity between policies and invariants, if you look at them on a systemic level. And from there you can enter the ideas of different algebraic constructs - just like you can have broader and narrower clasess of servers with different amounts of invariants holding or not holding for them.
On top, we've started to pull data from large numbers of system to jam them through jupyter notebooks so we can use data visualization tools to get a stronger impression of what reality is like. It's pretty interesting if you can use data visualization tools like scatter plots and such to deduce the existence of a default value for a config setting. Or, to pull data and to realize: "hello. This is reality calling. Two out of three assumptions you made about systems are incorrect."
There's a lot of lessons from software engineering that can be expanded to other fields with that insight. Best practices for version control of source code applies to anything that can be called a kind of "source". And you need not just to maintain the source, but also the tools with which the source is edited, and the pipeline with which that source is transformed into a shippable product.
There's value even in the basic idea that any given "thing" can have multiple distinct representations, with one optimized for editing, versioning and collaboration, while another representation might be optimized for distribution and/or consumption (and you might have intermediate representations optimized for other steps in the pipeline toward distribution). It might be overkill for many use cases, but it's helpful simply to know that it's a sane model to evolve toward as a project grows.
http://steve-yegge.blogspot.com/2007/06/rich-programmer-food...
For years I struggled to grok the difference between regular expression and parsing. The conversations I would hear about the topic always left me feeling there must be some interesting meat to the difference...and so I would go read up on it only to find myself with the same problem a few months down the line.
The only difference is layers. Enough regular expression becomes a parser. A slim enough compiler is just a templating engine.
Insisting it's a deep, dark magic and not the advanced application of `str.replace` does the industry a disservice.
It is fundamentally impossible to correctly parse e.g. HTML with regular expressions. See: https://stackoverflow.com/a/1732454
Respectfully, this perspective contradicts the computer science underlying our work--there are in fact different categories of string "languages" that can be parsed using different technologies, and regular expressions are not enough for most "languages".
See https://en.wikipedia.org/wiki/Chomsky_hierarchy for the different categories of languages and the required tech to parse them.
I consider CS theory to be about the deepest and darkest magic I get to use on a daily basis :P.
> The only difference is layers. Enough regular expression becomes a parser. A slim enough compiler is just a templating engine.
You can't add enough layers of standard regex to parse, say, C++ or even a tree of matching parenthesis. You need a different tech like CFGs.
Hope this helps improve the grokking! The "interesting meat" here actually points at some really deep, fundamental CS theory that's really worth knowing.
I appreciate the academic frameworks that have led to the development of systems, however as a working engineer, ignoring where the rubber meets the road is my entire complaint.
by ftxbro - March 27, 2023
I gave a conference talk last year, tldr: “we build apps. Here are all the lessons we’ve learned from framing this as a blockchain problem.”
My introductory joke was “how to become a blockchain expert in three easy steps”.
Work in software
Work on a project
Decide that whatever you’re working on is a blockchain
But was I truly joking? I genuinely believe teams should try really really hard to draw analogies between what they are building and “classic”, well-understood, formally studied systems and ideas in computing. Is your web API a blockchain if you squint? Is your authentication system really a smart contract if you squint? Squint, I tell you, squint!The reason is not so you will somehow be able to apply advanced techniques from research journals to your web apps. You won’t. But there are other advantages.
First, you get a vocabulary for free. If you pretend your app is actually a blockchain, you can talk about “blocks” and “transactions” and “smart contracts” and “consensus algorithms” – things that you would otherwise have to invent bespoke names for, or be unable to talk about at all.
Second, analogies can be a good source of interesting ideas. If your web app is a blockchain, HTTP is your transaction protocol, and user authentication is your smart contract, could you build a “mining pool”? What would that mean? Could you attribute the performance issues in your app to particular parts of the blockchain? Also what are your consensus algorithms? Is it worth introducing a new one? Should your app be a proof of work blockchain or a proof of stake blockchain? Does that distinction even make sense? These won’t all be good ideas, it is plain to see. But you might strike gold.
Third, morale. It’s fun to be able to think of yourself as a blockchain* expert, even if the asterisk is big and the analogy is a little hazy.
Last, I’ll observe it’s quite within the realm of possibility you’ll encounter a problem that truly belongs to the domain of e.g. blockchain development, no squinting required. Satoshi Nakamoto wrote
The root problem with conventional currency is all the trust that's required to make it work. The central bank must be trusted not to debase the currency, but the history of fiat currencies is full of breaches of that trust. Banks must be trusted to hold our money and transfer it electronically, but they lend it out in waves of credit bubbles with barely a fraction in reserve. We have to trust them with our privacy, trust them not to let identity thieves drain our accounts.
I agree something seems to be awry with the financial industry’s popular “fiat currencies”. You can hardly spit without hitting a currency that, frankly, deserves it. Cryptocurrency these days is “blockchain heaven”. I was on a team years ago that sunk weeks into debugging our app’s flaky payment system, entirely thanks to the traditional banking system’s poor transparency and terrible security. In theory, cryptocurrencies that are based on blockchain technology – i.e. Bitcoin, Ethereum, and others – should be better than fiat currencies. In practice, though, the blockchains of these cryptocurrencies fail to inherit most of the UX benefits of traditional currencies, i.e. it is not natural to use them for everyday transactions, they are not widely accepted, and they are subject to extreme volatility. (Searching the Internet indicates that some of this is possible, I have never seen it done.)Nakamoto, a blockchain developer, unsurprisingly prescribes blockchain theory as a remedy. Our cryptocurrencies would be better if their authors knew how to write smart contracts, formally define their blockchain’s consensus algorithms, etc.
Maybe so, but I’ll settle for far less than formal semantics. I just want the authors of cryptocurrencies to think of themselves more glamorously. Don’t be a payment system designer - your job isn’t just to facilitate transactions in a rigid way. Be a blockchain developer - your job is to give your users a way to express themselves, to send and receive money, elegantly, in a decentralized way - to guide them interactively, help them discover what is possible, and steer them away from scams. Provide the trappings that you would demand of a modern, widely accepted currency – a user-friendly wallet, fast transaction times, low fees, and so on – or at least as many as you can afford.
Doing this correctly without reinventing the wheel (please don’t reinvent the wheel) almost always involves building your cryptocurrency on a larger, established blockchain. I find the “Ethereum” blockchain by Vitalik Buterin to be an excellent example of what I think is a great UX for a cryptocurrency. Ethereum is just a blockchain, and so you can use all the features that the blockchain ecosystem provides without any fuss. The Dogecoin blockchain by Billy Markus is a less stellar example. It is based on the “Litecoin” blockchain, and so gains the security of that blockchain – however it obscures the entry point and execution path from the user, and so has a poor user experience. (It’s a similar story for many other cryptocurrencies.) Of course, still miles better than traditional banking.
Even if you don’t work on a finance-related product, the internal tools and systems of a large-ish organization probably have a “blockchain” or two that would benefit from being recognized as such. I often think about a talk I saw that describes IBM’s approach to supply chain management and “Hyperledger Fabric”, a blockchain IBM invented for describing supply chain transactions and cross-organization requests. I can’t speak personally to how effective their tool is, but I’m comfortable predicting that it is better than the counterfactual where developers just do everything in traditional databases.
Go forth, the blog post is ended.
i.e. in the future, DSL/languages will be input and output specifications, some guidelines/constraints and optimization functions... and maybe not even that? e.g. provide a few examples and the neural net writes the specifications, fleshes out more examples, you approve this and a (decently optimizing?) compiler is generated in seconds... ?
Humans will learn to just double-check its work the same way that non-programmers currently double-check programmers and the same way I double-check compilers in my day job.