[erlang-questions] A question of style
Jesper Louis Andersen
Wed Mar 18 14:23:07 CET 2015
On Tue, Mar 17, 2015 at 2:55 PM, Joe Armstrong <erlang@REDACTED> wrote:
> The more I think about it the more I come to the conclusion that we
> should not be writing polymorphic interfaces to libraries and making
> them easy to use. Instead we should be writing minimal libraries
> containing only essential features.
This has always been my point of view. Several remarks:
* It is by far the solution with the best type-system overlay. Suppose
Erlang had a static type system. Then this is essentially the first and
simplest solution that comes up if you have static types. The key is how
your library composes with other code. And compositionally with
"everything" has considerably less structural rigor than "only composable
with this or that".
* The library becomes much simpler. If you really want, then having a
compatibility layer module is probably better in the long run. Convert in
the layer and then pass on the data to the real system. Programmers who
know the API can call it directly, avoiding the conversion layer.
* It is transparent. Code calling binary_to_list/1 internally increases the
memory resource pressure by a factor of 20. Hiding this in the library
gives you less information. You thought it operated on binary data, but it
really operates on strings, internally. This tells you a lot about its
resource consumption. For instance that it isn't made to be used with
binary data several megabytes in size.
* Breaking the assumption crashes the process. This is a good thing!
Implicit polymorphic conversion *decides for you*. Sometimes the code makes
the right call, and the conversion is exactly like you want. Sometimes, it
accepts the wrong data, converts it to something completely random and
processes that. It can lead to misery. Library code shouldn't decide for
the caller what to do. The caller knows.
* A major problem in all software is the question "does my data have the
right structure here?" We do lots of conversions all the time. We read a
binary() value. We convert it into structural JSON. We grab fields in the
JSON structure and interpret them into other internal data values. The
purpose of conversion code is to handle this, and it is hard to see how you
can get around having to describe the conversion at least somewhere in the
* Hidden conversions between data and polymorphic acceptance is costly. If
your internals are converting back and forth between representations of the
same data, you want to know this is the case. Once you compose several
polymorphic accepting functions, you pay in execution speed, memory usage
through extra GC pressure and lack of precise understanding of data
mangling (which misconverts your data). It is evil!
* The more generic an API, the less it tends to say. As one who enjoys
programming OCaml, the power stemming from a type-level restriction is the
precision in the surrounding code context. You know exactly what data you
have and thus also exactly what functions can manipulate it. This
restriction is a spotlight on API-usage because I can ask "what API calls
can satisfy my need?" and not get back "EVERYTHING! BLOODY EVERYTHING!"
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the erlang-questions