Sunday, June 24, 2018

Interoperability

Looking back at my earlier posts, I'm surprised how utterly Java-centric everything I did was. Never mind things like bytecode instrumentation, of course that's JVM specific, and it's cool stuff!

But for other things, I think I would try to achieve more interoperability these days. Specifically, I'm looking at JGroups. It has some nice features in terms of consensus, making sure that all known nodes have the same view of the system, but looking at it purely as a networking library, it shockingly limits you to implement all your nodes in a JVM language.

I think there are generally three layers of interoperability. The JGroups example is one extreme, basically no interoperability. It has one Java implementation and its network protocols are specific to that implementation. I don't know the specifics of JGroups, but the protocol used may well be tailored to transmit very specific manipulations of JGroups nodes' states. In other word, there are lots of assumptions that make JGroups easy to implement in Java, but very, very hard to port to another language.

One kind of interoperability comes through dynamic linking. For example, through native methods, Java can call code written in C or another language that is compiled into machine code. As long as the JVM uses the ABI and calling conventions of the native library, access is no problem. The native code is executed in the calling process, so this kind of interoperability is strictly for libraries, not for client/server communication.

So if it was CGroups instead - written in C - then there could simply be a Java binding and a .Net binding etc., and all platforms using these bindings could cooperate. Unfortunately the reverse isn't true: the JVM is, quite obviously, a virtual machine, and you can't simply call code targeted at a VM. That VM first has to run, and then you have to interface with the VM before finally getting access to the library. This is true for all languages requiring a runtime environment (i.e. interpreted languages), but it gets worse the more complicated the runtime gets.

Which leads me to the third kind of interoperability: wire protocols, which solve the issue of having a protocol that is full of assumptions from the original implementation. Instead, the first step to designing the application or library is to design a binary or text based encoding and to clearly states what kinds of communication are allowed, in what order, at what time, etc. The protocol has to be simple and explicit enough to write down, so it should also be possible to implement in different languages. That doesn't allow you to use one library in different contexts, but it makes it feasible to port the library for different platforms.

If it weren't for that last kind of interoperability, the Internet would be a very different place. Imagine if websites used a browser-specific protocol instead of HTTP! Microservice architectures also rely on well-defined protocols to connect otherwise incompatible systems: of course, a service written in Java can expose some JGroups-derived functionality via, say, HTTP, and then any other application can access that service.

Sunday, June 17, 2018

Blogging on a Time Budget

I've never been regular in writing blog posts, and in the past years I never found the time necessary to do serious Magic programming. I enjoy thinking about general ways to model the Magic rules in a program, but without a serious amount of time, it will always remain tinkering. It's an interest, but not serious enough to resolve to put out thousands of lines of code to make it work.

However, I'm still a passionate programmer and learner. While most of my posts so far have had a Magic context, they were always about programming. And this is where I want to shift the focus: non-MtG posts aren't off-topic, and that should encourage me to write more about what I'm currently doing. I know I won't start spewing out post after post, but as long as I find the time, I shouldn't run out of topics.

So what have I learned about in the three years since my last blog post?

I have shortly continued with Scala, but got demotivated by the compile times. A lot of time was spent working with Python, and it's currently my most fluent language. I have written web applications with Django, learned about generators and async/await, and constructed protocols and servers using ZeroMQ.

There has also been a considerable amount of JavaScript and some TypeScript, mostly using Vue.js to create reactive frontends for my web applications. I have also looked at web-technologies, such as Webpack and, although briefly, Websockets, PWAs (particularly service workers) and WebAssembly.

Recently, I re-discovered Rust after playing with it years ago. In terms of languages-to-use-if-you-want-to-get-things-done-in-a-reasonable-amount-of-time, Rust is about as far away from Python and JS as you can get (yes, there's also C and C++, but I don't think they're farther away, just slightly worse at getting things done... just my opinion though).

I intend to write about most of these things, if they're still relevant when I get around to them. If there be still readers here, let me know with what to start.

Oh, and I have watched tons of programming videos on YouTube! There's lots of great content. But there are also videos that suffer from what I call "boring tutorial syndrome": they try to teach good programming style (or something), but actually don't go far beyond how to write an idiomatic Hello World program (or whatever the basics of the respective topic are). The problem is that by starting from scratch, these tutorials don't manage to reach a reasonable depth. So whatever I write, don't expect start-at-zero tutorials, expect food for thought and self-study!

PS: if you're looking for videos that don't suffer from the boring-tutorial-syndrome, try LiveOverflow