Understanding Programs Using Graphs
engineering.shopify.com
engineering.shopify.com
I have a notebook here which can visualize the table structure of any Datasette-hosted database: https://observablehq.com/@simonw/datasette-table-diagram
My first version used a force-directed graph for this, but then Thomas Ballinger from the Observable team showed me how to use a DOT diagram, which is a much better visualization for relational tables.
d1 = n % 10
d2 = n/10 % 10
...
dk = n/10^(k-1) % 10
There are a number of implementations possible, iterative is probably more economical. Another way that avoids integer division (if you just want +/-/* ) is doing all your arithmetic in BCD (binary coded decimal), using 4 bits per digit.
I think those kinds of exercises are useful because there is some confusion around arithmetic. Sometimes there's confusion between what are numbers, and what are number encodings or digits (which themselves represent individual numbers). I found myself confusing (or simply not having the concept of differentiating) the digits of a number and a number itself. Say '14' to me was uniquely associated to those two digits. When you learn binary arithmetic, you start generalizing and see it could be written '1110' as well. The number 18 is a concept independent of its representation. So you can talk about the digits of a number: the digits represent individual numbers themselves, but they are taken together to represent another number. In my example, I had 'dk' and 'n', where n is a number that will usually be represented in binary form, but that is irrelevant, and 'dk' are their digits, as numbers, also usually represented in some binary form (again might or might not be relevant). You even consider simpler encodings such as unary (e.g. as used in tally marks or finger counting), those of course have lower efficiency (O(logn) vs O(n)). They're all just representations of this abstract concept that are numbers (with which we can do mathematics and arithmetic operations).
I think it's illuminating to distinguish between digital properties (properties specific to a digital representation), and properties of numbers. For example, 4 in base 3 is 11, which violates the property that even numbers are those whose last digit is even (only true for even bases). Divisibility by two is a numerical property, last even digit (implying evenness) is a digital property.
Numbers are so simple conceptually, it's their digital representation (and digital arithmetic) that's a bit more complicated.
The article makes it seem as if TruffleRuby is a Shopify project, where this GitHub repo seems to differ on that point: https://github.com/oracle/truffleruby. What's the deal?
I'm also very curious about how much TruffleRuby helps you save in infrastructure costs. It looks like Shopify is starting to put together serious systems around optimization of Ruby code.
> I'm also very curious about how much TruffleRuby helps you save in infrastructure costs.
We don't have an empirical answer to this yet. We're working on it. We're investing in MRI, TruffleRuby, and many other parts of the Ruby ecosystem.
You could introduce some kind of hidden local variables and assign to those, but then you're kind of building a graph in an AST, and might as well use a graph, and those variables are harder to understand for other optimisations.
(Note that these aren't 'my' optimisations, I'm just writing about them.)
The problem comes when the design and the code get out of step, but there are tools available to round-trip the code and model to keep everything in sync. Executable UML used to be a thing too, but I was never very convinced by it.
By right I mean, the first time someone comes along and says “it’s not a visual language anymore” the response is “wrong, and you’re fired.”
Compilers convert source code into graphs and then perform optimizations on these graphs. They never work directly on the source code itself. Once the graphs have been optimized, they're then converted into the target format, which is typically assembly language or bytecode.
So mostly this is about techniques compilers use to optimize and transform code.
Instead of, or perhaps as well as, converting to assembly or byte code, here the author is producing a visualisation of the internal graph structure contained within the compiler.
The graph isn’t necessarily a one-to-one match with the AST derived from the source, due to graph transformations that take place during the optimising phase of the compiler/runtime. This makes it even more important/interesting to see what is going on under the hood.
Usually, in high-level programming languages one rarely has concerns regarding how easily the compiler might deal with the code - one just codes, and uses language features appropriately, as needed. With the only caveat here being the extreme performance crew, e.g. games programmers might use a restricted subset of C++, and also might disassemble compiler output, and use that information to help try and optimise their source somewhat.
The ast's are usually language specific, therefore it's not cross language.
Static graphs are still useful to understand a new piece of code, see Source Trail[1] [1]: https://www.sourcetrail.com/
The article's title is not optimal. It's really about compilation to machine code, and for that you do need all these details. The only "understanding" of these graphs is about understanding what the compiler is doing with the code, it's not for program understanding on a high level.
An example of a concrete difference here is that Ruby checks for overflow on integer maths, where Java does not. This means each maths operation is a little cluster of nodes, rather than a single node.
Another example is that Ruby has dynamic typing, so values that come into the function need to be type checked, and values going out need to put into a format where they can have their type inspected.
One more example is that the call to fib in Java is static - we know exactly where that goes. In Ruby the call is dynamic, so we need to check we're calling the correct method.
Here's a full SVG copy of that diagram https://www.dropbox.com/s/k68id9aqu258blw/fib-ruby.svg.