, 25 tweets, 4 min read Read on Twitter
So. What is TSD? It's a small library whose purpose is to make it easy to collect, render, compare, diff, and test tree-shaped data.
Once we get past basic programming, it is very common to have to create orchestras of objects that form conceptual trees. Note, these aren't *literal* trees. Hmmm. Better talk about that.
Consider my mp3 collection. A Recording has a number of fields. They include primitives, psuedo-primitives (like String and Date), and references to other objects, like Performers, Label, Producers, etc.
Those referenced objects themselves include both embedded fields and references to still other objects. A Performers includes a list of Performer objects, a common collective name, possibly some Session objects, and so on.
None of this is explicitly modeled as a Tree interface or class, nor does the app navigate that object graph using tree-like notation. When it wants to show who performed it, it just de-references the Performers field.
One *could* say "OH MY GOD EVERYTHING IS A TREE", and try to code it as such. That's fine and its doable, but it's going to create a great deal of weight. You're essentially now programming in a new language, TinkerPop or some such, and you gain generality and lose naturalness.
There are cases where that tradeoff says "yes", but there are plenty where it says "no no no". Generality *is* awesome. But easy natural expression is far more important for most programming problems.
So this data is "tree-shaped". It's not a tree. It's just grokkable as a tree. There's a single root object at the top, and it spreads out and eventually bottoms out into a bunch of leaf objects at the bottom. The nodes are of different type to one another, usually "by level".
(Most object graphs aren't true trees anyway, they're just DAGs, directed acyclic graphs. Multiple higher-level nodes can point at the same lower-level node, normal in a DAG, forbidden in a true tree.)
Now, spoze you're a TDD'er. I am. That means you have to repeatedly set up various object graphs like this, manipulate them, then test the results. Further, you want to *grok* the setup and *grok* the results, especially when the test fails.
There are a lot of over-simple examples of these sorts of tests on the internet, used to illustrate various library features.
Some of the simplifications: 1) that's one test, you'll have hundreds. 2) the trees have two layers, not 5 or 9. 3) the tests are built around simple equality. 4) when the tests fail you'll have no idea why. 5) they don't handle irrelevance well.
Even setting aside TDD, there's an issue with just rendering. It's normal in all development styles to want to *see* the state of these tree-shaped object collections. (This is "print debugging", of course, which is unfairly maligned.)
But if you want to "dump" tree-shaped datasets like this, you're going to have to write that code yourself. If you're wondering, a) that's tedious, and b) there's housekeeping, and c) it feels like you're not working on your story, and d) there's no standard to the output.
Now what you *could* do is add 'toJson()' to every class. Now you've got a json root, which is one representation of a tree, and you can print it, pretty-print it, diff it, log it, and so on.

That's better, for sure. It was in fact the experience that got me started on TSD.
But it's not quite enough. JSON or XML are "human readable", but they're not necessarily human grokkable, and grokkability is key.
Once those trees get big? Look out. If you've lived in web-land, you for sure have seen JSON with hundreds or even thousands of characters. Further, depending on context, most of those characters are noise.
So. Now you see the problem. I want to non-tediously enhance my objects so they can make real trees out of tree-shaped data. I want to make those trees easy to make, test, compare, and render.
tsd intrudes on your existing object class by requiring a mix-in interface with one method:

fun toTsd(output: TsdOutput)

The TsdOutput is seen by your class like a kind of print stream or console that, basically, expects key-value pairs with indentation.
To your class, it looks a lot like you're printing a key-value ASCII tree using just four methods. There are overloads for all the basic types and for the toTsd interface.
Under the hood, of course, TsdOutput isn't printing anything yet. It's collecting the data and making it in to a true tree. Once it's that, the rest of the library can do all sorts of things with it.
So now you have the basic concept of the tsd library. The first time I coded it, maybe 2014 or 2015, it was in java. I found it very useful. My particular favorite feature was an advanced one: a UI that popped up on fails showing me both whole trees and a diff tree.
That kinda thing is of course not bound into tsd's core, depending on UI and Junit in non-portable ways. But I'll be doing it again, and putting it into an adjunct library, and hopefully others can do the same for their environment.
tsd is open source MIT license, here:

github.com/GeePawHill/tsd

it doesn't do anything yet. First I had to learn how to do multi-project gradle builds. But I'll be working on it, here and there now and then, and sharing notes. If you want to help, ping me!
The next step for me? Play around to see if Kotlin can express those four basic API's in a way that makes the toTsd methods look and feel as obvious as possible.
Missing some Tweet in this thread?
You can try to force a refresh.

Like this thread? Get email updates or save it to PDF!

Subscribe to GeePaw Hill
Profile picture

Get real-time email alerts when new unrolls are available from this author!

This content may be removed anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Follow Us on Twitter!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3.00/month or $30.00/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!