ciplogic.com
Live with grace. Write superb software.

mildly depressing

  • JavaScript Exception Error Logging Pattern

    Many times in JavaScript, I like to log errors in case exceptions happen, that output what exactly went wrong, without actually taking action.

    For example:

    1
    2
    3
    4
    5
    6
    try {
      callPotentialDangerousStuff();
    } catch (e) {
      console.error("dangerous stuff is not working :(");
      throw e;
    }

    This has the side effect of loosing the stack trace if I break on "uncaught exceptions", and breaking on "all exceptions" is absolutely no option, since many frameworks use the exception handling as mechanisms of detecting various features of the browser environment.

    Thus I came up with this pattern:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var executionSuccessful = false;
     
    try {
      callPotentialDangerousStuff();
      executionSuccessful = true;
    } finally {
      if (!executionSuccessful) {
        console.error("dangerous stuff is not working :(");
      }
    }

    So if an exception happens, I can still break on all exceptions, but also get my log right.

    Can you imagine how cool it would be to chain exceptions like in Java? For example:

    1
    2
    3
    4
    5
    6
    try {
      callPotentialDangerousStuff();
    } catch (e) {
      console.error("dangerous stuff is not working :(");
      throw new Error("dangerous stuff", e);
    }

    At least we can dream about it, and appreciate more languages that do offer chaining of exceptions.

  • Pointy Thingie: The Linux Font Measuring Unit

    Since I don't want eye strain, and have a mild OCD, I want the same font and sizes across all the monospaced text editors that I am using.

    The font I decided in using is Ubuntu Mono with some patches to look good on my vim. It's a regular truetype font.

    Thus I went into the journey of setting it up across four applications (gvim, terminal, IDEA and VS Code).

    Turns out that IDEA and Visual Studio Code think that the font size should be 16 Pointy Thinigies, while GVim and the terminal would rather go for 12 Pointy Thingies, to render a text with the exact same size in pixels.

    Good job Linux.

  • Programming Vocabulary

    Whenever talking to each other, whenever that happens, developers tend to formalize specific concepts and map them to specific words.

    For example you all know what a singleton is. We don't need to disambiguate in regards to it. Nor do we need to disambiguate in regards to what an object, function, or method are.

    And this is why the following article A Factory Should Create, Not Retain, in which Paul M. Jones claims that a factory that retains references to its created instances it's not truly a factory, came as a surprise for me.

    The article TL;DR: A factory just creates objects, a registry just references objects, a container does both.

    Fine.

    But while this might be technically correct, it's not actually meaningful in any way to make this distinction, except tedious mental exercise. Don't worry, here come examples (Java, but, you get the picture).

     

    1. Caching factories are containers

    In java numbers can be represented as either primitives, either immutable objects. To convert from one another, e.g. from `int` to `Integer`, the Integer class has a factory function named: `valueOf(int) : Integer`. This makes the Integer class a factory for Integer objects.

    Except that I lied a bit.

    Creating objects for every number it's expensive, and since the low indexes are heavily used, they are pre-cached (at least in the Oracle's Java version they are). This is not part of the functional specification, it's just an implementation detail, on how the objects are going to be fetched. Note that objects outside that range are always created.

    http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.java#Integer.valueOf%28int%29

    1
    2
    3
    4
    5
    6
    7
        public static Integer valueOf(int i) {
            final int offset = 128;
            if (i >= -128 && i <= 127) { // must cache
                return IntegerCache.cache[i + offset];
            }
            return new Integer(i);
        }

    Can you be pedantic and say, that this is a container, and not actually a factory? Yes. Does it add value to the conversation? No. I'm going later to explain why this is an issue.

    Note that if I just comment those caching lines, my container magically transforms to a factory, and if I uncomment it, it's back a container, even if functionally its behaviour is the same. But whatever.

    By the same definition...

     

    2. Registries that create objects are containers as well

    Again in java there is an amazing class, named TreeMap. TreeMap holds instances to these objects into a tree structure, thus its full of imagination name of TreeMap. Tree... Map. TreeMap.

    Someone could argue that this is a registry, but again, if we want to be pedantic about it, this is no ordinary registry. Because it creates its keys, so it's also a factory.

    http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/TreeMap.java#TreeMap.put%28java.lang.Object%2Cjava.lang.Object%29

    Among the many separation of concerns that this class blatantly violates, are also creating and reordering objects, but for the sake of our discution, we can safely say that the TreeMap is technically also a factory, since it creates its keys:

    1
    2
    3
    4
    5
          Entry<K,V> e = new Entry<K,V>(key, value, parent);
          if (cmp < 0)
              parent.left = e;
          else
              parent.right = e;

     

    3. Singleton

    Finally, I said that I will explain why I find it as an issue, with being pedantic about separation of concerns. Because it stiffles communication. We actually lose more time trying to disambiguate things that our so specific vocabulary would allegedly try to disambiguate.

    The best example is Singleton.

    Singleton it's a pattern that describes how single instances can be created for an application. This is made by having a single static instance on the class, and using it across the application.

    Except that this is not true if you use Dependency Injection. The singleton class will not have the single instance bound to the class. It will not implement the actual pattern. Actually might not even be a singleton in certain cases, since now this might be a configuration issue. So I should not use the "singleton" word to describe it at all, since it's not implementing the pattern, nor can I guarantee that it will always be a singleton.

    Conclusion

    But that's why this whole thing makes no sense. If I know that in my application an object has a single instance (provided by the DI, or its own static reference, or the JVM that creates it via some callback method, etc), then I can say it is a singleton. Its meaning is derived from its behavior, not the actual implementation on how the singleton behavior will be provided. That is an implementation detail.

    Similarily, if I have an object that creates other objects as one of its main purposes in life, it is a factory, irrespective on what kind of caching (if any it uses). It's meaningless to say that valueOf from Integer is actually a container method. There is no gained value out of it.

    If an object is used to mainly store references to other objects, then yes, it's a registry. The same goes on key creation. This doesn't changes the purpose of the class.

    It makes no sense looking at every tidbit of implementation details, with super categorization. There is no benefit out of it. No cleaner code, no better communication. Nothing.

    We can't see the forest anymore, since so many trees are blocking our view.

Germanium

The one to rule them all. The browsers that is.

SharpKnight

SharpKnight is an Android chess game.

MagicGroup

MagicGroup is an eclipse plugin.