Kartones Blog

Be the change you want to see in this world

All roads lead to static typing

Note: Just in case you need a quick refresher, wikipedia has a nice description of strong and weak typing.

In recent years I became a firm defender of Python static typing (via type hints and MyPy, more details at this blog post). It is not that Dropbox, Stripe, Microsoft, Facebook and many others are creating immense projects around dynamically-typed languages, I've also worked with big and sometimes codebases in a variety of languages, and I've seen first-hand how difficult and mentally exhausting is to understand code when there are no type hints, how error-prone it is no matter the amount of tests you add (many of them superfluous and just palliating the fact that any variable can hold anything) and how your IDEs and tools can barely cope with those big codebases (even if it's a robust one like PHPStorm, RubyMine or Visual Studio Code). For an early startup of course you go faster with a dynamic language, I love Python because I get what I want with so few lines of code, but I would probably never ever use it "naked" anymore for anything serious if the plan is to evolve it and work with other people.

Now that I'm working with Java I'm back to real compiled languages, after more than a decade using dynamically typed ones: PHP, Javascript, Ruby and Python. And one thing struck me from that list... all of them have evolved into supporting static typing one way or another, and most directly inside the language core.

PHP introduced type hints in PHP 5.1, but really until version 7 didn't have enough primitive declarations. HipHop compiler was an amazing idea to speed up PHP: Simply compile all of it into C binaries, and now there's a full virtual machine (HHVM) making it more akin to Java than C++, although it's diverging into Facebook's Hack language so it's no longer "pure PHP".

Javascript is a curious creature. I guess the community is reluctant to adding types because being so old and evolving so much in other areas, typing is still weak and dynamic. But that didn't stop folks from adding types with TypeScript, a compiler transpiler that adds types and generates "typed javascript". I haven't personally used it, just seen and reviewed code written with TS, and it looks great. For sure adds more "boilerplate" but no more than for example React adds when you're building a simple form compared with an old HTML + JS implementation.

Ruby until recently only had external type checkers, like Sorbet, but it seems that finally Ruby version 3 will include RBS, a new language for defining types and some related command line tools.

Python has had type hints since version 3.5, optional and allowing also "gradual typing", but with the deprecation of Python 2 its gaining a lot of traction. The benefits will be broader once specific compilers (like mypyc) get more mature, as then Python modules would be able to be compiled into way faster C extensions (much like PHP's HipHop principles).

I think that this static typing convergence of many development languages is just one way of dealing with bugs and errors in long-lasting projects. Code linters and auto-formatters (example for python) are another way, dealing in this case with the human factor: Nobody will remember always all the rules, or will spend time nitpicking instead of focusing on real code issues, so better to enforce them automatically. Other more radical approaches are directly new languages: Both Go and Rust were born to try to fix C++ problems, and Hack derives from PHP.

In the end, all seems to circle around the same: Trying to build robust software in a scalable way requires certain development language guarantees and safeties.


Book Review: The Business Book - Big Ideas Simply Explained

Review

The Business Book - Big Ideas Simply Explained book cover

Title: The Business Book - Big Ideas Simply Explained (Audiobook format)

Author(s): Dorling Kindersley Ltd (DK)

I am lately expanding to not only reading about pure technology related topics, and business is something I don't pay much attention to, and I should. I also decided to digest this title in the form of an audiobook, convinced that, with a duration over 16 hours, it was not going to be a smaller version of the textbook. I definitely don't regret spending the time.

Inside, we find a lot. As the description says, learning about "more than 80 theories and big ideas about trade, commerce, and management" means it can't spend too much on each topic, and while a few feel too brief, it's enough to spark interest on reading more of any that sounds interesting to you. All of them go from the past up until 2013, so a few times it feels a bit outdated. For example, mentions Netflix, Amazon and Dell, but the data and sometimes even the techniques mentioned are different today (e.g. Dell now offers a much narrower customization of laptops/PCs, precisely what in the past made it so successful).

There are great insights and topics relevant today, from applying Kaizen, to the benefits of cross-functional teams, and of course mentions the Agile Manifesto. There are very few software related theories, mostly are generic, which I appreciate as we can still apply them, but they are less "tainted" this way. Again as an example, we're told studies and experiments were made to confirm that cross-functional teams work better, faster and even create stronger bonds between its members. Now think about the typical silos in software company: Systems, Design, Product,...

I've focused on a few samples, but there are way more. Even the book cover provides some hints about what you will find inside:

Full-size The Business Book cover

I enjoyed it a lot, so much as to going to read/listen to more titles from DK, and maybe even in the future grab the book to see the illustrations (which look to be really nice summaries).


Debouncing, Throttling and Queueing

Throttling can be used in a myriad of scenarios, from reliability (avoid flooding with actions) to performance (not doing anything more times than needed in a specific time-frame). I was checking for ways to throttle some event handlers in Javascript for a personal experiment, and gathered 3 (well, in practice 4) approaches, each with different subtleties. So, to keep them at hand I've decided to write this small post.

Debounce

Debouncing a function means delaying executing the function/callback until after a certain delay. The function will only execute once, no matter how many times you trigger it.

Example code (source):

function debounce(callback, delay) {
    let timeout;

    return function() {
        const context = this;
        let later = function() {
            timeout = null;
            callback.apply(context);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, delay);
    }
}

Leading Edge Debounce

Pretty similar to the normal debounce, but instead of waiting before executing the callback, in this mode (also known as immediate debounce) we first execute the callback and then disallow further invocations until the delay is over.

Example code (source):

function debounce_plus(func, wait, immediate) {
    let timeout;

    return function() {
        const context = this, args = arguments;
        let later = function() {
            timeout = null;
            if (!immediate)
                func.apply(context, args);
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow)
            func.apply(context, args);
    };
};

Throttle

Throttling is an old but always effective technique. In its simplest form, we only allow at most one function execution in the specified threshold (very similar to immediate debouncing). Further calls are discarded.

Example code (source):

function throttle(callback, threshold) {
    let last;
    let timeout;

    return function() {
        const context = this;
        const now = Date.now();

        if (last && now < last + threshold) {
            window.clearTimeout(timeout);
            timeout = window.setTimeout(function() {
                last = now;
                callback.apply(context);
            }, threshold);
        } else {
            last = now;
            callback.apply(context);
        }
    };
}

Queue

Queueing is another mature technique, by which we build a "tasks list" and then execute it (usually in a certain order).

The benefits of this technique are mainly that a) you don't lose any invocation request (you enqueue it 3 times, 3 times will be executed) and b) you get fine control of when it will be executed, and can do any kind of operations over it (throttle the dequeueing speed, remove duplicates/aggregate similar calls, etc.).

Example code (source), buffering into a FIFO queue and adding an initial processing start delay:

function Buffer(startDelay) {
    var queue = [];
    let timeout;

    function taskHandler(task, callback) {
        console.log("Queue size: " + queue.length);
        task();

        // call the buffer callback.
        callback();
    }

    function run() {
        var callback = function () {
                if (queue.length > 0) {
                    run();
                } else {
                    // signal the buffer we're done processing
                timeout = null;
                }
        }

        // give the first item in the queue & the callback to the handler
        taskHandler(queue.shift(), callback);
    }

    // push the task to the queue. If the queue was empty before the task was pushed we start processing
    this.append = function(task) {
        queue.push(task);

        // Simulate a delayed start. In the real world, should just be what's inside of the function,
        // and there would be no need of a timeout except if we want a delayed start of queue processing
        if (queue.length && !timeout) {
            clearTimeout(timeout);
            timeout = window.setTimeout(function() {
                run();
            }, startDelay);
        }
    }
}

A minimalistic working example can be checked at https://kartones.net/demos/023/. Just some inputs, each applying a different technique to the onkeyup event.


We are creatures of habit

We are creatures of habit. By repetition, may it be willingly or unintentionally, we add new actions, reactions, ways of thinking... habits come in so varied ways.

Some habits take time to acquire; Some people say you need 60 days of repeating something for it to become a habit... or was it 61 times? I love those off-by-one errors even outside of software development 😂 Anyway, you get the point: they don't simply suddenly appear and "now you have it".

Habits can be good and healthy: For example, thanks to the COVID-19 house confinement (which lasted 2.5 months in Spain) I've introduced myself into meditation, and now have the habit of doing it first time in the morning almost every day. Regarding development, as an example I've been an avid fan of practising the pomodoro technique as a way to maintain focus while working.

But we sadly can also merge bad habits to our lives.

I've always disliked open offices, mostly because of the noise they help spread and the education in silence that employees need when working in such a wide space. Yes, I do have noise cancelling headphones since 2010 or 2011, and many times listening to electronic music gets me into the zone and boosts my coding speed, but I also like sometimes to enjoy the sound of silence. And that is almost impossible in any office nowadays.

And is not just a matter of some noise, is more of an issue of constant interruptions: "Did you read the Slack I just sent you?", "Hey, just in case you didn't saw the email invite and Google Calendar reminder, I come to your place to remind you about that incredibly [irrelevant] meeting everyone including you should attend!", phone calls, mobile phone notifications, a colleage speaking on the phone right next to you, somebody screaming somewhere loud enough you can hear it even without pinpointing the source...

To provide specific metrics, I am still not able to do more than 5 or 6 50-minute pomodoros in a single 8h work shift (not cheating, any distraction means you reset the timer). And I'm usually regarded as a very focused person by my colleagues. I don't think so many people suddenly have ADD (Attention Deficit Disorder) magically. I think is just that, with so many distractions, we've created the habit of doing single-core multitasking (quickly doing context switching, and thus partially losing focus). "Just answering that email and going back to the task", "just replying xxxxx's chat", etcetera. Not counting if you check your phone with each notification, then I simply wonder how anybody can even reach a state of concentration at all.

The good news is that almost, if not all, bad habits, can be also nullified. Sometimes it is hard, because for example a toxic environment is harder to fight than a self-created "fake need". But sometimes it is easy, as eating healthier (you just start removing crappy food and slowly adding better substitutes, and doesn't feels hard to progress). But I believe that it is always in our hands, somehow, a way out of any bad habit. Even if it means a drastic change.

It took me some vacations and one month to be again almost in total control of my attention when coding. Now, most of the time I am the one choosing to check the phone only either then the pomodoro is over, or while the code is compiling, the server starting or some other task that I can't avoid waiting for. And many times, it is actually more interesting to keep reading article X or one page of book Y.


Book Review: Sams Teach Yourself Java in 21 Days

Review

Sams Teach Yourself Java in 21 Days book cover

Title: Sams Teach Yourself Java in 21 Days, 7th Edition

Author(s): Rogers Cadenhead

I had three premises while searching for a next read: 1. I needed to learn some Java, because I know some, but university level 2. I needed to target at minimum Java 8 3. I wanted something that covered a broad spectrum of the language, while not being way too entry-level

I decided to go with this book because it covers Java 8, it starts simple but covers everything regarding language fundamentals, and it goes into more "advanced" topics like threading, sockets and web requests. It also strikes a good balance between teaching you about a topic without becoming a reference book that lists every single method, parameter and overload of every class available (which can be useful, but not for initial learning).

I must confess I skimmed through the chapters about Swing and Java2D, RSS and Android. I want to do backend-related development so I don't need Swing (and it looked similar to back when I learned it) and the other topics were interesting examples but not of my interest right now.

I was pleased to see that Java now has channels, generics and lambdas, and the book does a good job of explaining them simply and clearly. I had fun writing some of the book examples and altering them a bit, or doing some tiny refactors here and there.

If I had to complain about something, it'd be that the code sometimes can be improved: There are too many examples in which all (sometimes really heavy) logic is done inside the class constructor, constants are mentioned but never used afterwards, variables are created a bit chaotically, sometimes inside loops and the like, and variable namings are reminiscent of old C days (in, buff, pw, ...). But even with that the code purposes are nice and easily understood.


Previous entries