If you want to make a dent in the world…

Managing organized complexity

I was reading the beginning of the History of Clojure (a language that I have no time to invest in learning, but still interesting to me):

I started working on Clojure in 2005, during a sabbatical I funded out of retirement savings. The purpose of the sabbatical was to give myself the opportunity to work on whatever I found interesting, without regard to outcome, commercial viability or the opinions of others. One might say these are prerequisites for working on Lisps or functional languages.

If you want to make any dent in the world, you either make it at a personal cost (not always monetary), or with other people’s money. Savings I have none. Self realizations are evident.

Δείτε την αρχική δημοσίευση

40 days after first contact

In a blog post I wrote a little over a month ago, I tried to make a plausible analogy of the introduction a new tech stack into a software team, to civilizations making first contact. In fact, my experiences at that point in time had been so dramatic that the term that immediately popped in my head was that of the Prime Directive, a higher order principle used in the fictional universe of Star Trek. This directive basically sums up to: «Don’t interfere with the normal and healthy development of alien life and culture. Such interference includes introducing superior knowledge, strength, or technology to a world whose society is incapable of handling such advantages wisely».

40 days after writing that blog post, I’m happy to say I was completely wrong about this analogy. Elixir is not «alien technology» – nor is my team ‘incapable of handing’ it, not at all! In fact, things have improved quite dramatically, and this blog post is about contemplating a) why I felt and reacted this way and b) how mixed-stack teams can work better together.

As I’m writing these lines, there are two new members to the Elixir team, the first of which joined about 3 weeks ago and delivered a tremendous psychological boost to the whole company by demo’ing his first (fully working) Elixir prototype of a project we’ve initially set aside for our MVP in no more than the end of his 2nd week (!). What makes it even more interesting is that he hasn’t touched any Elixir code before. The second member joined about a week ago and has already started writing code too.

With just these two new team additions, both counter-arguments posed when I made the case for Elixir in our company, magically became obsoleted:

‘How relevant will we be in 5 years if we’re taking the plunge and learning a new radically different language’: well, I still think that learning happens to be the key to being relevant and staying current in the IT industry, and not any particular language. You don’t have to fear the new/different, you just need to break out of your comfort zone and explore what’s out there. Try it. It might cling on you, or it might be repulsive. You don’t know unless you’ve tried.

– ‘Who’s going to support our Elixir projects in the long term?‘: Well, if you can get a senior engineer who has had no Elixir experience to write an MVP in 2 weeks, (and he’s not just forked an existing project off GitHub and changed a couple of lines!), then most probably you have a tech stack that’s supportable. If you can get people interested in a stack, and you can combine that interest with solid engineering practices, then the end result will almost always be supportable.

Of Elixir, Phoenix, and analogies to the Prime Directive

I spent the last couple of months working from home (thanks to the lockdown) and it sure felt like an opportunity for a fresh jump, like learning a new technology which is both promising and mature enough to use in production: Elixir .

I’ve experimented with Erlang in the past, but I can’t say that was amusing (I recall I had to learn Erlang to support a legacy product in a previous company). From this 1st encounter with the Erlang ecosystem I keep the positives, which is the «Programming Erlang» book by Joe Armstrong and the amazing discovery that Erlang basically powers the Internet as we know it.

I also happened to work for a few months in a software product that was based in Akka, which is merely a JVM implementation of the Erlang actor model, but this too didn’t attract my attention. Somewhere after 2016 I discovered this cool new kid on the block (Elixir) but didn’t devote much time into it at that time, as it was being advertised simply as a replacement for Rails.

So to make things short, it happened that we did a 2-week «innovation sprint» in my current company,  We were to write a ‘walking skeleton’ of our next version product suite, and for the part I picked up, I set up a Phoenix based REST API in literally no time (thanks to the built-in generators) and managed to progress from «proof-of-concept» to «hey this actually works with real data» in spectacularly short time. Then as I dived more and more into the language, more miraculous stuff began to happen:

I started adding features at an astonishing rate. (Ad-hoc drilldowns? auditing? live updates? performance monitoring dashboards?) As I added more and more functionality, I realized I wanted to test with more diverse set of input data that no canned-response API would be able to provide. For this purpose:

I took interest in rewriting an abandoned sibling project (that was transforming data for feeding the PoC REST API from XML). This Spring Boot project was initially written in some 2400 lines of Java (but was still incomplete). After a couple of days of effort I ended up with… 500 lines of XSLT (yes, good-old XML stylesheets!) and 350 lines of Elixir. The fun part is that the Elixir implementation includes testing and satisfies all MVP-scope requirements.

In doing so I accidentally discovered a real-world analogy of the Prime Directive in exposing this «alien technology» to the rest of the development team, for they simply wouldn’t accept my statements as valid («what do you mean, it’s ready? what do you mean you added auditing?«), and would even refuse to look at the code. To this day I’ve yet to find a soul to review my merge requests, so I rely on automated tools like Dialyxir to run code checks automatically.

I’ve now stepped into dangerous territory of trying to convince coworkers (better yet, friends that I know for years!) that I’m not threatening their job security (yes, for Christ sake!).

  • «Who’s going to support any Elixir code? What if you get hit by a bus? (which reads: «please stop what you’re doing, you’re harming the team and the company«)
  • «If some of us take the plunge and learn Elixir, how relevant will we be with the job market and its then-current trends in say 5 years?«

In short, both valid questions, but then both just as invalid as counter-arguments to trying out a new language. Can you not learn a second foreign language? Do all students studying Spanish need to wipe their memory clean of their German?

Well, maybe my coworkers are right, maybe the walking skeleton proof-of-concept was the Kobayashi Maru. Unlike what Spock thinks, I didn’t cheat out on this one, but I think maybe I did something more like what Zefram Cochrane did , which led the Vulcans to come pay us a visit (and upload some cool new Elixir artifacts to hex.pm as welcome gifts 🙂 )

 

Data as Code and Code as Data together in Harmony… or not?

There seems to be a battle of paradigms brewing and I think its important to choose sides.

Clojure (and Lisp in general) seem to endorse the homoiconicity principle. Code is data and data is code, in both form and function. I can extend my «program» with forms «on the fly» and this of course raises some serious security concerns. Will this be Clojure’s major drawback? Will we move from naive «so 20th century» stack overflows to «31337» symbol replacement exploits?

OTOH, the incumbent security paradigm cries for clean and absolute separation of «code» and «data». For Christ’s sake, this is even implemented in Ring-0 and the hardware!

But what the heck, once you’ve given ‘eval’ to the rest of the world via all the scripting languages out there then I guess the genie is already out of the bottle…

Imperative thinking vs Language expressiveness vs. Versatility

one-more-for-the-road

Its always nice to complete a challenge in 4clojure.com, especially when you feel you’ve articulated the solution in the most readable form. I’ve just completed the pairwise-disjoint problem, which is pure set algebra: Given a set of sets, find out if these sets have any elements in common. Enough with talk, here’s the code in all its recursive beauty:

(fn pairwise-disjoint [set-of-sets]
 (or
  (empty? set-of-sets) 
  (let [examined-set   (first set-of-sets)
        remaining-sets (rest set-of-sets)
        disjoint-map   (map #(clojure.set/intersection examined-set %) remaining-sets)
        disjoint       (every? empty? disjoint-map)]
   (and disjoint (pairwise-disjoint remaining-sets))
)))

The nice thing about 4Clojure is that it reveals other users’ answers so I just found out you can do the same in one single line, so the solution can be as terse as:

one-more-for-the-road-2

Woa there! I understand that the «imperative» way of thinking prevails throughout my solution, but is this one single line readable? Yes it achieves the same goal, but does the poor soul that’ll read this single line in 20 years from now understand its purpose?