Hacker News new | ask | show | jobs
by ljloisnflwef 1536 days ago
I encourage you to explore why generics exist in the first place by exploring topics such as Parametric Polymorphism, Higher Kinded Types, & Higher Kinded Polymorphism.

The truth will set you free.

1 comments

Better to start with the problem than the most abstract formulation of its solution-- which only makes sense after successive encounters with ever more complex problems.

Simply, of course, we can begin with why it should be that data structures have operations in common -- rather than, say, having each their own specific versions.

Why not elaborate some more? I'm bored, so...

    2 + 2  == 4
    "Hello" + "World" == "Hello World"
    [2, 2] + [3, 4] == [2, 2, 3, 4]

Should we bother reusing `+` for this? Why not,

    2 intPlus 2  == 4
    "Hello" strPlus "World" == "Hello World"
    [2, 2] arrayPlus [3, 4] == [2, 2, 3, 4]
    
Well: the polymorphism `+` allows us to express a common idea, that of "appending". For each of these specific types: int, string, array we can speak in the application-domain of "appending" whilst in the programming domain of "+"ing if we introduce an interface for `+`, that of "appendable",

    interface Appendable[A] {
      A + A -> A
      A + 0 -> A
    }  
    
This interface allows us to use `+` generically in a principled way, the technical name for Appendable is `Monoid`, but i prefer Appendable (incidentally, Monad is `Sequencable` or `Nestable`).

Polymorphism is just the ability to speak as generically in the programming-domain as we speak in the application domain, ie., to use the double-meanings of ordinary thinking in programming.

Yours is a beautiful example of how to shoot yourself in the foot with reckless generalization. Addition of integers is commutative; concatenation of strings is not. That's not "a common idea". Compilers can transform a+b into b+a for one, if it suits them, but not for the other.
While integers with addition are an additive monoid and thus commutable it's still also a valid multiplicative monoid (or semigroup as described in the parent) and handy to be able to be passed to code that just needs an associative closed operation, maybe with an identity value.

Integer addition is a magma, semigroup, monoid, and group. It's _also_ a commutative version of each of those structures, but we can still definitely use it with functions only expecting multiplicative structures just fine.

The issue I take with using + for a multiplicative monoid like string concatenation is that readers of code should expect it to be commutative. Using x or * is probably better, using ⓧ is mathematically nice but a pain to type, so something like ++, <>, .., or some other new operator just for concatenation is imo best.

As above, I was thinking of python in my choice of the `+` example.
I'm not sure I see the reckless generalisation. I said `+` meant append, not add. We can use addition in the case of integers to serve as `append`, but its a special case of appending where A+B == B+A.

In python, where I take the example, `+` performs that role,

    [a() + a() for a in (str, bool, int, list, tuple)]
etc.
Just a nit, for floats it is not commutative either, not sure how much freedom do compilers have here. E.g. try summing many floats in decreasing value - chances are that adding a very small number in the end will not even change the value.
A nit's nit, float addition is commutative. It is not associative.
Addition of ints is associative, addition of floats is not, yet generalizing over these two numeric types is a core ability people expect from generics.