-
Writing about Haskell is Hard
Nov 5, 2021If your first thought upon clicking on a blog post entitled “Writing about Haskell is Hard” was “I bet this guy was writing a very different sort of post, got frustrated, and went back to the drawing board,” congradulations, you’re right! Because when I sat down after work and decided to do some blogging about programming, I originally wanted to write an introduction to my new JSON library,
jordan
. Jordan has a few features that I haven’t seen in other JSON parsers:-
Jordan directly generates wire-format parsers for your custom types. That is, if you have a data type like:
data Person = Person { name :: String , age :: Int }
And you’re trying to parse this in the obvious way:
{ "name": "Bob Smith", "age": 55, "profession": "writer" }
Jordan will not construct any sort of
Map<String, JSONValue>
in the middle. It also will immediately discard the “profession” key. With a bit of refactoring (which I plan to do soon), it won’t even ever store a string for “writer” in memory. Jordan will instead generate an actual UTF-8 Parser that directly converts from your type to JSON. - Jordan directly writes wire-format JSON without any intermediate types, either.
You can even write the JSON right to a file handle, which potentially saves on memory consumption in a serious way.
Haskell’s default JSON library,
aeson
, also supports this (and supports it in a way that’s marginally faster than Jordan without compiler flags), but it’s not required for all types, just an option you can (and should) make use of - Jordan can generate documentation for your JSON types, using the same definitions as your parsers and serializers. That is, if you write some way to parse or serialize JSON, you can generate OpenAPI types automatically with no intermediate step.
- Jordan parsers and serializers are in an abstract, user-extendable format.
So, if you have some crazy wire protocol for sending JSON, like
BSON
or whatever, you can probably write a Jordan “interpreter” that will directly serialize to that.
These features are all, in my opinion, very cool. They’re not only efficient, but they solve the “Documentation about JSON format and actual JSON format are out of sync” problem, which is the bane of my freaking existence on many web-dev projects. I wanted to write a blog post explaining how Jordan works, and how Haskell helped me to write it.
My first post was a disaster that I discarded. Here’s a second attempt.
-
-
Error Messages in Haskell, and how to Improve them
May 14, 2020I’ve been writing more and more Haskell lately, as part of a side project involving GraphQL. As part of working with the language, I’ve had to work with its compile errors. The Haskell compiler gives you errors that are extremely informative—if you know the language. If you don’t know the language very well, the compiler errors can occasionally be opaque and unhelpful.
I’ve very much enjoyed using Haskell, and I figure the best way for me to give back to the community is to make this situation a little better. In order to do this, we’re going to take a fun dive into Haskell errors, why they’re confusing, and how they might be improved.
This is very much not a literate Haskell file, because none of the snippets within will actually compile! You can discuss this post here.
-
On the internet, it isn’t particularly hard to find technology postmortems. Some of them are from large, venture-funded companies which eventually keeled over and died after the investors ran out of confidence and the bank account ran out of money. Others are from open-source initiatives that failed to find a footing and drifted off into darkness until their creator decided to turn the lights off for good. And others are much more personal, the story of a small, not-well-funded team that couldn’t quite get up to snuff. The term originates in medicine, where it describes a detailed account of all the things that eventually lead to the death of a patient. Such reports aren’t written unless there’s a need to. There’s no knowledge to be gained from an obese man in his late seventies succumbing to heart disease, or a trauma patient simply dying after succumbing to injuries no human can survive. If the cause of death is obvious, a postmortem report is frivolous. All of my previous failures, I believe, fell under this particular category. I’ve never felt a need to write a postmortem for them because it was obvious, even to me, why they did not succeed.
I graduated college with a Bachelor’s in Computer Science in December of 2017, after studying for five semesters plus two summer classes. Instead of going the typical route and trying to find a job immediately, I decided that I would embark on a project of my own, take another stab at entrepreneurship, and try to pursue a dream I remember having as a child. I was going to make a video game, and a good one at that, and I was going to sell it on steam and turn its moderate success into a fledgling indie studio. Unfortunately, however, I find myself in the morgue, staring down at my game’s corpse and trying to decide if it’s worth the time and effort to investigate exactly how it died.
In this case I’m not quite sure if I’m even writing a postmortem, or if it’s a sort of obituary. I’ll admit openly that I am partially writing this for emotional closure and not purely as an objective report so that I may discover why and how this project died. Still, I do think there is some value to be gained in organizing my thoughts on the matter. So, without further ado, let us examine my failed attempt at game development, so we can try to pinpoint exactly where things went wrong.
-
Dynamic Syntax Highlighting with React.js
Apr 26, 2018Let’s say you’re building a modern web app. You’re using react, you’re set up with webpack code splitting, you render stuff on the server-side, everything is awesome. Even better, your dependencies are really lean-and-mean: you fetch stuff as you go, so the initial bundle is very small!
You might run into a problem, though, if you need to render user-generated Markdown. You’re already using the excellent react-markdown library, so that’s all working fine, but the recommended way to do syntax highlighting has the rather large problem that you need to manually require the languages you want to use. Worse, they’re all bundled together.
You don’t want this. You want to be able to deliver no highlighting code, then allow the user to dynamically fetch the required highlighting files, like how the rest of your app works. Ideally, you even want it to render a non-highlighted version first, then switch to the highlighted one when its ready. How might this get done?
-
Templates, Index Sequence, and Optimization
Mar 21, 2018Recently, I’ve been working on a 2D game. Full-time, in fact: I recently graduated early, and I figured I might as well take a year and a half to work on this project before getting a “real” job. I initially started creating a game in Unity, however, I quickly realized that I didn’t actually like the engine. I actually disliked it fairly heavily, and it was hurting my productivity. So, naturally, my next thought was to code the game from scratch.
The natural choice for this was C++. I messed around with making a 2D engine before and enjoyed it, even if I didn’t actually get very far. I took a bit of a different approach this time, intentionally trying to make a game instead of an engine. However, that doesn’t mean that I don’t occasionally encounter engine-dev-related problems. One interesting recent one: optimizing a component of my ECS system.