1. 9
  1. 6

    It’s not visually obvious in the linked thread, but it’s discussing this post by Joe Armstrong

    1. 4

      I agree with the top comment on LtU (this is the case a lot actually). Modules != name spaces. The fact that most languages don’t have a separate module system from a namespace system is part of the problem here. There are a lot of cool uses of modules that can be represented with functions (see F-ing modules) but are really ugly to do so (see F-ing modules).

      I’d much rather live in a world where we have one namespace, but I can still think in terms of modules of code that bundle things together and provide abstractions. This seems to be what Joe wants with let-rec, but I want a lot more than just that: I’d like a first class representation of these blocks of code that’s

      1. Higher order
      2. Typed in a sane way
      3. Has some support for generative maps
      4. Isn’t simply isomorphic to files.

      This means I can think of my red black tree as

       module RedBlack : 
            module {type t; val cmp : t -> t -> Ordering}
           -> module {type t; type elem; .... }

      Rather than depending on the equivalent formulation of polymorphic functions. Maybe this argument doesn’t hold water without types which is the perspective Joe is probably thinking from.

      1. 3

        Right; the idea of a content-addressable store of individual functions is fascinating, but it makes the structure and human-addressability more important, not less. Technically it could be a completely flat store, but it would be practically useless for actual humans to interact with that way. We need structure as a way to organize and group related concepts. Git has the concept of branches on top of SHA trees because humans need labels.

      2. 4

        This reply hints at two good reasons for the existence of modules/namespaces:

        • to distinguish similar functions written by different people. For instance, adamsoftware.replace and bettysolutions.replace may take different function parameters, or one version may be faster for certain inputs.
        • to distinguish similar functions that use different data structures or different algorithms. For instance, customer_db.search and array.search both deserved to be called “search”, but do wildly different things.

        In both cases, the advantage of namespaces over function prefixes like johnsmith_replace is that the function can be imported and referred to its short name, like replace. That makes code more concise and easy to read, at the expense of being context-sensitive.

        Those two use-cases for modules could also be solved by annotating the functions with metadata about the author and context. I feel like such metadata would be more flexible than requiring that both use-cases use a single abstraction, namespaces. But this would violate the “unique distinct [function] names” part of Armstrong’s proposal, and make it more complicated to refer to the correct version of a function.