24 Feb 2017
I find work related inspiration many places, among others, colleagues meetups and conferences. But most inspiration comes while purposeless roaming the internet. I’ve always been interested in more that just writing the code for the software. Whether it be participating in meetings and discussions that would help me better understand the business. Gathering data to predict how a UI should be formed for optimal user experience. Learning how to avoid making poor software design decisions that would bring the nice people in operations in trouble. But also the softer things like how culture and circumstances affects us as developers and individuals.
Prior getting the responsibility for a team, all the above would just be archived mentally as “work/software development”. These days, stuff related to work culture and people have earned its own archive label. Suddenly these things have a slightly different meaning to me.
Before I was laughing when seeing/reading things like these (and I still do):
Now failing to do my job properly… the joke will be on me.
To get to the core of the matter. I would like to share the following links because they either gave me food for thought or just solidified my view on matters:
26 Nov 2016
It takes time to understand a problem, because before you can fully understand it, you need to also understand its context. As a code base grows, depending on how well the code is structured, the context in which you need to understand the problem can (and often will) grow.
When a problem or its context is misunderstood there is a tendency to oversimplify the problem. I’m all for finding a simple and elegant solution but not at the cost of correctness. Oversimplified solutions will not be able to handle all special cases, and special cases lead to crashes or data corruption… or both. This in turn leads to maintenance and clean up by the programmer which I would much rather have coding on this next big thing.
The available time to implement a solution is not only challenged by a push for quick deliveries but also a lack of respect that creating software is actually hard. I’ve experience this lack of respect from all involved parties (including the programmer).
Even though I strive to “do things right”, I also think it is okay and often necessary no to. But it should be a conscious decision.
I.e. making sure to handle two use cases (corner cases) will increase development time but at the same time those a very unlikely to happen or if they happen they are very easy to correct manually. If someone makes a conscious decision that these cases should be handled outside the software, then it is okay.
It is NOT okay (and very short sighted) when the pressure doesn’t allow collecting the necessary information to make that decision.
So by all means cut corners - but only do so together with proper risk assessment.
08 Oct 2016
Having been given a new area of responsibility as team lead inspired me to think about aspects of coding beyond just typing it.
I’ve experienced we where chasing our own tail. Trying to close issues “fast” and hurry on to the next in line. But something wasn’t working. Every time we changed a comma in one end, something in the other end would break horribly. Bug fixing was feeling like killing a hydra. I started blaming the “fast” way of doing things.
I needed to figure out what was wrong with our approach and transition into one that would result in “making stable software”. My gut feeling told me that we needed to become better at “decoupling” and “breaking the code into smaller pieces”.
But I was missing the direct link between my gut feeling and how it would translate into “stable software” until I saw a tweet which brought the things together:
one of the most important quality parameters for stable code is that it not change too much - apart from the essential bugs of course #hint
Okay I could easily follow the logic: Code that doesn’t change much, is usually a sign of stable code (why change it, if it works - right?).
The solution would be to write code that doesn’t need to be changed in the first place, and when “decoupling” and “breaking code into smaller pieces” are done correctly, it does exactly that. Code impacted by changes is greatly reduced.
Imagine a piece of software consisting of a single function. Now every time a change is made (a bug is fixed or a feature is implemented) in that function 100% of the system is changed. If instead it was possible to split this function up into 3 functions then having to change a function would only mean that 33% of the system was changed.
33% beats 100% every time.
And before someone says it I would like to entertain the possibility that the exact same code from the 3 functions was gathered in 1 function. What would be the difference?
The computational results of the two pieces of code right then and there would of course be the same. But the fact that the code isn’t already split up is in my experience a sign of too tightly coupled code. Also having the code split up usually makes it both easier to test and reason about (win/win).
Having to change a long chain of functions to fix a bug or implement a new feature is usually ALSO a sign of too tightly coupled code. Just to point out that having a lot of functions doesn’t necessarily decouple the code :-)
Anyways… for identifying both what and how to “decouple” and “break down” code, I use my “hands on” experience from functional programming and async systems. Also reading about S.O.L.I.D. principles is i good source of inspiration, though nothing beats “hands on”.
16 May 2015
When learning something new (in this case Laravel and it’s ORM Eloquent) it is always nice to be able to “look behind the curtains” to see what actually happens. This both help you understand the internals of the things you are using and can sometime make bug squashing a lot easier.
I wanted to be able to see the SQL that Eloquents query builder was producing, because SQL is something I’m fairly proficient with.
I found several questions and answers on different approaches on StackOverflow but one approach stood out for me: Using Laravels internal events.
Every time Laravel does anything through a database connection an event i fired with the prepared statement and its bindings. But creating SQL queries from this still required some manual labor because I needed to replace all the question marks with the binding in order.
So to close this gab further I had the prepared SQL and bindings crunched by
sprintf before writing it to a log file or stdout, like so:
function($query, $params, $time, $conn)
$sql = str_replace('?', '%s', $query);
$preppedSql = call_user_func_array('sprintf', array_merge([$sql], $params));
echo $preppedSql . "\n"; // or write it to a log file
28 Apr 2015
I had a problem where I needed to partition a collection when ever a specific element occurred.
The data I was working with wasn’t numbers but for the sake of making an example lets imagine something like the following where
1 indicates a new partition:
(def coll [1 2 3 4 5 1 2 3 1 2 3 4])
I started looking a partition-by which resulted in:
> (partition-by #(= 1 %) coll)
((1) (2 3 4 5) (1) (2 3) (1) (2 3 4))
After a short while I came to the conclusion that non of the existing core functions
split-with did what I needed. The closest function I could think of was
clojure.string/split but I wasn’t working with a string and also the “splitter” needed to be kept.
I needed an end result like the following:
((1 2 3 4 5) (1 2 3) (1 2 3 4))
I went down several mental paths trying to find a solution that didn’t feel clumpsy. Suddenly realize that
partition-by actually wasn’t that far off.
I got the following working and named my function
(map (fn [[a b]] (concat a b))
(partition-all 2 (partition-by f coll))))
I didn’t like the above anonymous function which led me to the followin end result:
"Like partition-by except it splits every other time f returns a new value."
(map #(apply concat %) (partition-all 2 (partition-by f coll))))
I haven’t tested the performance of it compared a loop-recur solution, but I’m pretty happy about the readability of it. I find my self time and again solving a problem in one way, just to realize that there is a better (often shorter aka. more readable and resource effecient) way.
I don’t think Clojure will ever stop amaze me with the endless compositions of core functions.