[erlang-questions] A question of style

Garrett Smith g@REDACTED
Tue Mar 17 15:58:47 CET 2015


I'm now starting my replies with a top post.

On Tue, Mar 17, 2015 at 8:55 AM, Joe Armstrong <erlang@REDACTED> wrote:
>
> A Question of Style

-snip-

> After a bit of thought I decided to re-write parts of my library
> code. I decide that internally I'd only use lists and I'd remove all
> the convenience functions.
>
> The result was library code that was far shorter and easier to
> understand.  I made a design decision to minimize the use of binaries
> for string processing and only use lists of integers (on input I use
> binaries and convert them to lists) on output I convert the lists to
> binaries (but no messing in the middle of my code). Previously I have
> a lot of code with binary_to_list and list_to_binary all over the
> place - all my problems with utf8/latin1 etc. almost vanished. The
> data comes in as a UTF8 binary (or something) but then gets
> immediately converted to a list of integer character Unicode code
> points and stays that way as long as possible.
>
> 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 sounds right. Though I suspect you'll start to see a lot of
"wrapper functions" emerge in the client code. I doubt as a library
user you'd want to routinely write those.

I tend to write as little code as possible and start to use it - then
observe the patterns that emerge. If there's something that shows up
consistently enough, I think that becomes a function, somewhere. If
you love your users (and I know you do) you'll be nice and provide
that function in your library :)

> We should make our minds up about things like filenames, directory
> names etc. representations and we should enforce them uniformly
> accross all libraries. (My choice would be that filenames are always
> represented by flat lists of Unicode integers, directory names always
> have a trailing "/") etc.

I think this will be hard to achieve in Erlangdom :)

> Paradoxically the goal of making a particular library easy to use by
> offering multiple polymorphic entry points not only makes it far more
> difficult to understand, but difficult to compose the code in
> different modules.  Polymorphic data types muck up the type signatures
> since the types of the polymorphic arguments tend to escape the module
> and propagate silly types all over the place.

I like libraries that are easy to use and wouldn't want to shift the
burden to the caller, if you know how the caller will tend to use the
library.

You could accomplish both goals I think with two modules - one for the
implementation, which is minimal and focused on maintainability, and
another that focuses on usability issues.

I might have done this once - I don't see the big trade offs that
you're describing. Then again, I haven't looked for them. I will now -
I think it's a very good observation and I'm sure there's a lot of
code out there that could be dramatically simplified by separating
these two concerns.

> Note: a similar argument can be made for code that provides default
> arguments to a generic function. Suppose we have an essential function
> with seven arguments, should we provide half a dozen helper functions
> that provide default arguments the the big function in different ways?

I'm a fan of the getopt approach of separating truly essential
arguments from optional arguments. Looking over lots of functions, I
see there's usually zero to three truly essential args (on average, it
seems) and the rest go into a proplist.

That approach cuts down on the arity permutations, but doesn't say
whether you're highly polymorphic or not. I think it eases the burden.

> So am I right? - should we junk all the convenience functions in a
> module and stick to essential functionality offering only one way to
> do something?

I like the idea of separating code that helps the user from code that
implements the core functionality. I don't like the idea of pushing
common patterns off on the user which in turn makes her code more
complicated. That said...

> I'll do this for a while and see what happens.

This!

Garrett



More information about the erlang-questions mailing list