[erlang-questions] Style wars: junk comments

210 views
Skip to first unread message

Richard O'Keefe

unread,
Sep 12, 2012, 3:56:19 AM9/12/12
to Erlang-Questions Questions
I was looking at some Erlang code today,
and it had comments like

% Include files
% External exports
% Internal exports
% Macros
% Records
% External functions
% Internal functions

only bulked up, and present even when the sections were empty.

I take the definition of a "junk comment" to be
"a comment that repeats something immediately obvious
from the adjacent code".

I can tell
an include because it starts with -include
an export because it starts with -export
a macro because it starts with -defined
a record because it starts with -record
a function because it does not start with -
so most of these are technically junk comments.

In fact they remind most unpleasantly of COBOL (IDENTIFICATION
DIVISION, DATA DIVISION, PROCEDURE DIVISION) and Classic Pascal's
rigid (label; const; type; var; procedure; begin) ordering.

In fact this ordering strikes me as pernicious in a very very
similar way. Suppose for example I have a sliding window module
in which there is

%------------------------
% Purging
%------------------------

purge(Window) -> ...

and this function uses a number of helper functions and macros
that are not used in other parts of the file. I want to put
them *here*, close by the function(s) needing them, not to rip
them away from their context just because some boilerplate comment
says so.

In fact I had been thinking about proposing a conventional use
of an attribute:

-section(creating).
-section(adding).
-section(purging).
-section(testing).
-section(formatting).

This is something that is already allowed by Erlang syntax, so there
is no actual language change. The proposal is to use _this_ attribute
for _this_ purpose: *semantic* sectioning.

Yes, the debt to the Smalltalk 4-pane browser and its "method
categories" *is* pretty obvious, isn't it?

The function of the -section attribute is to provide something a
text editor can set automatic bookmarks from or at least let you
search for, that _cannot_ be trivially determined from the source
code.

Have I missed an important benefit of the rigid syntactic ordering?

While I'm at it, why don't other people sort their export lists into
alphabetic order?

function and its supporte

_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Daniel Eliasson

unread,
Sep 12, 2012, 4:26:12 AM9/12/12
to Richard O'Keefe, Erlang-Questions Questions
I've seen comments beginning with %%%_* that I believe are used as a
tag for some kind of text folding mode in Emacs.

I also don't get why people wouldn't sort their export lists alphabetically.

Ivan Uemlianin

unread,
Sep 12, 2012, 4:33:36 AM9/12/12
to erlang-q...@erlang.org
I agree.

The emacs gen_server skeleton has things like:

%%%===================================================================
%%% API
%%%===================================================================

...

%%%===================================================================
%%% Internal functions
%%%===================================================================

(note 70 chars wide)

It's as if they're section headings at the top of a page in a book.

> -section(creating).
> ...
> The function of the -section attribute is to provide something a
> text editor can set automatic bookmarks from or at least let you
> search for, that _cannot_ be trivially determined from the source
> code.

A section attribute would be perfect. If required emacs erlang-mode
could give it a (70 char wide) tastefully coloured highlight.

Ivan
--
============================================================
Ivan A. Uemlianin PhD
Llaisdy
Speech Technology Research and Development

iv...@llaisdy.com
www.llaisdy.com
llaisdy.wordpress.com
github.com/llaisdy
www.linkedin.com/in/ivanuemlianin

"hilaritas excessum habere nequit"
(Spinoza, Ethica, IV, XLII)
============================================================

Bengt Kleberg

unread,
Sep 12, 2012, 4:42:08 AM9/12/12
to Erlang-Questions Questions
If you expect your code to be read/reviewed when printed, you should
have the functions alphabetically ordered.
Grouping exported/internal functions also help the reviewers.


bengt

Niclas Eklund

unread,
Sep 12, 2012, 4:45:59 AM9/12/12
to erlang-q...@erlang.org
On 09/12/2012 10:33 AM, Ivan Uemlianin wrote:
> I agree.
>
> The emacs gen_server skeleton has things like:
>
> %%%===================================================================
> %%% Internal functions
> %%%===================================================================
>
> (note 70 chars wide)
>
> It's as if they're section headings at the top of a page in a book.
>

Would you prefer 80 chars? Must the IBM punch card still haunt us?! ;-)

http://programmers.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width

/Nick

Michael Richter

unread,
Sep 12, 2012, 4:57:11 AM9/12/12
to Erlang Users' List
On 12 September 2012 15:56, Richard O'Keefe <o...@cs.otago.ac.nz> wrote:
        % Include files
        % External exports
        % Internal exports
        % Macros
        % Records
        % External functions
        % Internal functions

only bulked up, and present even when the sections were empty.


 
I can tell

  an include because it starts with -include
  an export  because it starts with -export
  a macro    because it starts with -defined
  a record   because it starts with -record
  a function because it does not start with -


Can you tell this while quickly scanning over the code?  Can you tell this while page-flipping like a madman in your text editor because you're looking for a particular section of your code?

The "bulked up" section that you omitted is, if I guess correctly, something like this:

%==================================================

And the fact, if I'm correct, that you think of this as "bulking up" is you gloriously missing the entire point of heading-style comments: they help you quickly locate particular sections of code, or particular functions or whatnot by calling attention to themselves.  Personally, when I'm handed code to maintain that has no such navigation aids, I grit my teeth, say a few very unpleasant things about the parentage of the person who wrote it under my breath and then spend the next little while adding those navigation aids myself.

--
"Perhaps people don't believe this, but throughout all of the discussions of entering China our focus has really been what's best for the Chinese people. It's not been about our revenue or profit or whatnot."
--Sergey Brin, demonstrating the emptiness of the "don't be evil" mantra.

Anders Dahlin

unread,
Sep 12, 2012, 4:58:05 AM9/12/12
to erlang-q...@erlang.org
On 2012-09-12 10:45, Niclas Eklund wrote:
> On 09/12/2012 10:33 AM, Ivan Uemlianin wrote:
>> I agree.
>>
>> The emacs gen_server skeleton has things like:
>>
>> %%%===================================================================
>> %%% Internal functions
>> %%%===================================================================
>>
>> (note 70 chars wide)
>>
>> It's as if they're section headings at the top of a page in a book.
>>
>
> Would you prefer 80 chars? Must the IBM punch card still haunt us?! ;-)
>
> http://programmers.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width

;; Set the length of the skeleton separators.
(setq erlang-skel-separator-length 42)

/A

Ivan Uemlianin

unread,
Sep 12, 2012, 5:01:30 AM9/12/12
to erlang-q...@erlang.org
On 12/09/2012 09:58, Anders Dahlin wrote:
> On 2012-09-12 10:45, Niclas Eklund wrote:
>> On 09/12/2012 10:33 AM, Ivan Uemlianin wrote:
>>> I agree.
>>>
>>> The emacs gen_server skeleton has things like:
>>>
>>> %%%===================================================================
>>> %%% Internal functions
>>> %%%===================================================================
>>>
>>> (note 70 chars wide)
>>>
>>> It's as if they're section headings at the top of a page in a book.
>>>
>>
>> Would you prefer 80 chars? Must the IBM punch card still haunt us?! ;-)
>>
>> http://programmers.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width
>
> ;; Set the length of the skeleton separators.
> (setq erlang-skel-separator-length 42)
>
> /A

Ha! I should have known.


--
============================================================
Ivan A. Uemlianin PhD
Llaisdy
Speech Technology Research and Development

iv...@llaisdy.com
www.llaisdy.com
llaisdy.wordpress.com
github.com/llaisdy
www.linkedin.com/in/ivanuemlianin

"hilaritas excessum habere nequit"
(Spinoza, Ethica, IV, XLII)
============================================================

Valentin Micic

unread,
Sep 12, 2012, 5:00:26 AM9/12/12
to bengt....@ericsson.com, Erlang-Questions Questions
I can understand that if you know what you're looking for (and just want to check, say, function signature), then the alphabetic ordering may help.
However, if one wants to find out what is particular module doing/responsible for, I would really like to learn how can alphabetic ordering help.
And if this turns to be useful, well, why not go the whole hog and order code alphabetically as well ;-)

V/

Ivan Uemlianin

unread,
Sep 12, 2012, 5:12:09 AM9/12/12
to erlang-q...@erlang.org
If you are reading code on paper, it helps if functions are positioned
predictably in the stack of paper. Alphabetic ordering of functions and
grouping functions into sections are two good ways of doing this.

> ... if one wants to find out what is particular module
> doing/responsible for, ...

In this case all you should need to do is read the api or exported
functions section.
--
============================================================
Ivan A. Uemlianin PhD
Llaisdy
Speech Technology Research and Development

iv...@llaisdy.com
www.llaisdy.com
llaisdy.wordpress.com
github.com/llaisdy
www.linkedin.com/in/ivanuemlianin

"hilaritas excessum habere nequit"
(Spinoza, Ethica, IV, XLII)
============================================================

Bengt Kleberg

unread,
Sep 12, 2012, 5:14:05 AM9/12/12
to Erlang-Questions Questions
When trying to "find out what is particular module doing/responsible
for", on paper, it helps if you can find things. When reading on paper
it is easier to find things when they are alphabetically ordered.

OK? Not OK?


bengt

Anthony Ramine

unread,
Sep 12, 2012, 5:14:02 AM9/12/12
to Richard O'Keefe, Erlang-Questions Questions
Hi,

Unfortunately, attributes other than -record, -opaque, -type and -spec are forbidden after the first function form. See erl_lint:function_state/2.

Regards,

--
Anthony Ramine

Le 12 sept. 2012 à 09:56, "Richard O'Keefe" <o...@cs.otago.ac.nz> a écrit :

> This is something that is already allowed by Erlang syntax, so there
> is no actual language change. The proposal is to use _this_ attribute
> for _this_ purpose: *semantic* sectioning.

o...@cs.otago.ac.nz

unread,
Sep 12, 2012, 5:18:27 AM9/12/12
to Niclas Eklund, erlang-q...@erlang.org
> On 09/12/2012 10:33 AM, Ivan Uemlianin wrote:

> Would you prefer 80 chars? Must the IBM punch card still haunt us?! ;-)

You're right. 80 characters is too wide for readability.
We should probably take 72 or 65 as the default.

I would point out that I have actually used an
IBM 96-column keypunch that produced these cute little
96-column cards. Just because it's an IBM punched card
never did mean it's 80 columns. (The really amusing
thing, considering these came from IBM, is that they
used the ASCII code.)

However, it's worth asking why the 80 column card became
a standard, and what the standard actually was.

The actual standard for programming commonly involved an
8 character sequence number on the right (or a differently
sized sequence number on the left for COBOL) so the
*actual* text width was typically 72 characters, which was
rather better for readability.

(I have a colleague who thinks there is nothing wrong with
300-character lines. Needless to say, I have never been
able to read his otherwise superb code.)

Pierpaolo Bernardi

unread,
Sep 12, 2012, 5:18:39 AM9/12/12
to Ivan Uemlianin, erlang-q...@erlang.org
On Wed, Sep 12, 2012 at 11:12 AM, Ivan Uemlianin <iv...@llaisdy.com> wrote:
> If you are reading code on paper, it helps if functions are positioned
> predictably in the stack of paper. Alphabetic ordering of functions and
> grouping functions into sections are two good ways of doing this.

"Reading code on paper" has already been mentioned some times in this thread.
But really people read code on paper, nowadays?

(Except illustrative code in books, of course).

P.

Michael Turner

unread,
Sep 12, 2012, 5:20:24 AM9/12/12
to Ivan Uemlianin, erlang-q...@erlang.org
On Wed, Sep 12, 2012 at 6:12 PM, Ivan Uemlianin <iv...@llaisdy.com> wrote:
> If you are reading code on paper, it helps if functions are positioned
> predictably in the stack of paper. [snip]

And COBOL's DIVISIONs made sense when you could get color-coded
pre-punched DIVISION cards in the keypunch rooms, to save time typing
and to help you see, from the top of the deck, which division was
which. Also good back when a COBOL compiler might have five-to-eight
passes, on a machine with 4K instruction space: you could write a
customer parser for each pass.

Just saying.

^_~

-michael turner
--
Regards,
Michael Turner
Project Persephone
1-25-33 Takadanobaba
Shinjuku-ku Tokyo 169-0075
(+81) 90-5203-8682
tur...@projectpersephone.org
http://www.projectpersephone.org/

"Love does not consist in gazing at each other, but in looking outward
together in the same direction." -- Antoine de Saint-Exupéry

Ivan Uemlianin

unread,
Sep 12, 2012, 5:24:21 AM9/12/12
to Pierpaolo Bernardi, erlang-q...@erlang.org
On 12/09/2012 10:18, Pierpaolo Bernardi wrote:
> On Wed, Sep 12, 2012 at 11:12 AM, Ivan Uemlianin <iv...@llaisdy.com> wrote:
>> If you are reading code on paper, it helps if functions are positioned
>> predictably in the stack of paper. Alphabetic ordering of functions and
>> grouping functions into sections are two good ways of doing this.
>
> "Reading code on paper" has already been mentioned some times in this thread.
> But really people read code on paper, nowadays?

Yes. Presumably at least the people who have mentioned it already.

It is very easy to underestimate the convenience, reliability, and power
of paper and pencil (and perhaps crayons).

Ivan


--
============================================================
Ivan A. Uemlianin PhD
Llaisdy
Speech Technology Research and Development

iv...@llaisdy.com
www.llaisdy.com
llaisdy.wordpress.com
github.com/llaisdy
www.linkedin.com/in/ivanuemlianin

"hilaritas excessum habere nequit"
(Spinoza, Ethica, IV, XLII)
============================================================

o...@cs.otago.ac.nz

unread,
Sep 12, 2012, 5:52:23 AM9/12/12
to Michael Richter, Erlang Users' List
> On 12 September 2012 15:56, Richard O'Keefe <o...@cs.otago.ac.nz> wrote:
>
>> % Include files
>> % External exports
>> % Internal exports
>> % Macros
>> % Records
>> % External functions
>> % Internal functions
>>
>> only bulked up, and present even when the sections were empty.
>>
>
> …
>
>
>> I can tell
>> an include because it starts with -include
>> an export because it starts with -export
>> a macro because it starts with -defined
>> a record because it starts with -record
>> a function because it does not start with -
>
> Can you tell this while quickly scanning over the code?

(A) Yes of course I can. It's right at the xxxxing left margin!
It's the very easiest most obvious place to find stuff.

(B) I have no *reason* to because it is nothing I find useful
to know.

> Can you tell this
> while page-flipping like a madman in your text editor because you're
> looking for a particular section of your code?

I have *NEVER*, not in nearly 40 years of programming,
found it useful to "go where the macros are".
Putting all your macros in front of all your functions
makes about as much sense as putting all the nouns in
your sentences ahead of all the verbs and adjectives.

From time to time I try to tell people that COBOL
isn't all that bad, and then I remember my intense
frustration at being unable to place data near the
paragraphs that needed them. Syntactic sectioning
(put all the files in one place, put all the variables
in another place, put all the code in a third place)
did not *solve* the page flipping problem, it *caused*
the page flipping problem. I actually have a free
COBOL compiler on my machine, and for this reason
above all others, have never been able to bring myself
to use it.

Indeed, this has driven me to wonder whether Ada-style
'child' modules (which are very different from Java-style
'packages') might be a good thing in Erlang. Haskell
programmers seem to use semantic sectioning in cutting
modules into lots of submodules, although I feel they
take it to an extreme which also hurts readability.

Over and over and over again I have found it amazingly
useful to use SEMANTIC sectioning. In C code, for example,
I actively and positively want NOT to know whether
attribute_name() -- to take an example from my DVM2 library
for handing XML in C -- is a macro or an exported function
or an internal function, but I want very much to "find
the stuff that handles attributes", and I want to find it
*there* whichever of the three it is.

In any case, you may find it hard to believe, but it is
literally true that when I stripped the junk comments out
of the code I was looking at, the page count of nearly
all the files halved. Junk comments don't *solve* the
page flipping problem, they *exacerbate* it.

>
> The "bulked up" section that you omitted is, if I guess correctly,
> something like this:
>
> %==================================================

It includes but is not limited to such things, yes.
>
> And the fact, if I'm correct, that you think of this as "bulking up" is
> you
> gloriously missing the entire *point* of heading-style comments: they help
> you quickly locate particular sections of code, or particular functions or
> whatnot by calling attention to themselves.

No, they don't.
* They really do not help me find anything when
using a text editor. If I *did* want to search for
one of these sections, I'd be searching for '% Includes',
not for '==='.
* When looking at a printed listing, they don't help
nearly as much as a page break, they only need one line
of fat dashes, not two or more, and they don't help nearly
as much as an Interlisp technique I'll return to
* I was not talking about function headers, not one word
about those. I have nothing against devices that help me
find particular functions. However, even then there's
something much better than lines of dashes, the Interlisp
thing I'll get back to.
* The most important point is that these bulked out junk
comments I'm talking about are utterly useless for locating
particular sections of code, quickly or otherwise, because
of their content. They are SYNTACTIC sections, which
cleave asunder that which should be kept together and
unnaturally conjoin that which should be kept apart.
The includes, types, macros, exported functions, and
internal functions that work tightly coupled to achieve
a particular task are scattered across many syntactic
sections. Unrelated functions are placed together merely
because none of them are exported.

If someone wants to mark *SEMANTIC* sections up with
bulked out comments, fair play to them, it's not me that
will complain. Indeed, I'll say "thank'ee kindly."

OK, what did Interlisp do?

When you asked Interlisp to make a listing of a file,
it understood which functions and macros defined things,
and where the name being defined could be found. So it
displayed those names in a larger font. Looking at an
Interlisp listing, you could see which functions were
defined where from the other side of the table.

> code to maintain that has no such navigation aids, I grit my teeth, say a
> few very unpleasant things about the parentage of the person who wrote it
> under my breath and then spend the next little while adding those
> navigation aids myself.

Imagine "navigation aids" in the form of signposts
that say things like "signpost", "a street somewhere",
"here", "these are letters". That's the kind of
junk comment "navigation aid" I am complaining about.

Valentin Micic

unread,
Sep 12, 2012, 5:52:28 AM9/12/12
to bengt....@ericsson.com, Erlang-Questions Questions
Hmmm…. maybe it's about time to go green? (Just kidding, of course… or am I?).

V/

o...@cs.otago.ac.nz

unread,
Sep 12, 2012, 6:10:20 AM9/12/12
to Valentin Micic, Erlang-Questions Questions
> I can understand that if you know what you're looking for (and just want
> to check, say, function signature), then the alphabetic ordering may help.
> However, if one wants to find out what is particular module
> doing/responsible for, I would really like to learn how can alphabetic
> ordering help.

Just to make it clear, I was advocating that the list of
function names in an -export directive should be sorted,
while the function definitions should be grouped into
semantic categories.

Two historic comparisons:
* the Burroughs Extended Algol compiler had a long list
of forward procedure declarations near the front, each
with an associated sequence number. Then the actual
procedure definitions were grouped semantically. One
typically kept a couple of punched cards stuck in the
six-inch listing as bookmarks, one or more of them in
the index. You could find your way around in this
huge listing with astonishing ease.
* the Smalltalk 5-pane browser (yes, I know I said 4-pane
in a previous essage, but I'm typing with a laptop on
my chest and am not catching all my typos).
Top, left to right:
class categories (think 'applications'), alphabetically
classes within current category, alphabetically
method categories within class (semantic sections), alphabetically
methods within category, alphabetically
Bottom:
Edit window for class definition, class comment,
or method definition.
Add in the 'find definition' 'find callers' and other
single keystroke operations, and you can really *fly*
in that interface. Oh, guess what? No junk comments!

If you want to find out what a module is doing or responsible
for, you should be reading the module comment, not looking at
the functions. And there should BE one that TELLS you.

Note that if you have semantic -sections, then

egrep '^-(module|section)' foobar.erl

would tell you quite a bit about what the module is up to.

Niclas Eklund

unread,
Sep 12, 2012, 6:11:41 AM9/12/12
to erlang-q...@erlang.org
On 09/12/2012 11:18 AM, o...@cs.otago.ac.nz wrote:
>> On 09/12/2012 10:33 AM, Ivan Uemlianin wrote:
>> Would you prefer 80 chars? Must the IBM punch card still haunt us?! ;-)
> You're right. 80 characters is too wide for readability.
> We should probably take 72 or 65 as the default.
>
> I would point out that I have actually used an
> IBM 96-column keypunch that produced these cute little
> 96-column cards. Just because it's an IBM punched card
> never did mean it's 80 columns. (The really amusing
> thing, considering these came from IBM, is that they
> used the ASCII code.)
>
> However, it's worth asking why the 80 column card became
> a standard, and what the standard actually was.
>
> The actual standard for programming commonly involved an
> 8 character sequence number on the right (or a differently
> sized sequence number on the left for COBOL) so the
> *actual* text width was typically 72 characters, which was
> rather better for readability.
>
> (I have a colleague who thinks there is nothing wrong with
> 300-character lines. Needless to say, I have never been
> able to read his otherwise superb code.)
>

Another historical influence is the U.S. standard railroad gauge -
http://www.straightdope.com/columns/read/2538/was-standard-railroad-gauge-48-determined-by-roman-chariot-ruts


/Nick

o...@cs.otago.ac.nz

unread,
Sep 12, 2012, 6:27:04 AM9/12/12
to Pierpaolo Bernardi, erlang-q...@erlang.org
> On Wed, Sep 12, 2012 at 11:12 AM, Ivan Uemlianin <iv...@llaisdy.com> wrote:
>> If you are reading code on paper, it helps if functions are positioned
>> predictably in the stack of paper. Alphabetic ordering of functions and
>> grouping functions into sections are two good ways of doing this.
>
> "Reading code on paper" has already been mentioned some times in this
> thread.
> But really people read code on paper, nowadays?

Yes, me, lots.

Let me offer you a paradox, half fun and full earnest.'

Fancy text editors and IDEs are tools for NOT reading code.

If you actually want to read code, paper (ideally augmented
with literate-programming-style automatically generated
indices) is way better. If you don't know what I'm talking
about, look at Knuth's "The Stanford GraphBase".

Just today, I found a bug in a Smalltalk class that had
defeated me for a day because using an IDE is too much
like tunnel vision. Given a printed listing, it took me
half an hour to read the whole class, and the bug practically
jumped up and down and shouted to get my attention. (In
fact there were two copies of it.) And another bug that I
hadn't tested for yet also demanded and got my attention;
working with the code in the IDE my attention was constantly
directed *away* from stuff I wasn't currently working on or
currently testing.

When you are coping with over 100,000 lines of code,
tools that help you *NOT* read are desperately valuable.

o...@cs.otago.ac.nz

unread,
Sep 12, 2012, 6:33:18 AM9/12/12
to Michael Turner, erlang-q...@erlang.org
> And COBOL's DIVISIONs made sense when you could get color-coded
> pre-punched DIVISION cards in the keypunch rooms, to save time typing
> and to help you see, from the top of the deck, which division was
> which. Also good back when a COBOL compiler might have five-to-eight
> passes, on a machine with 4K instruction space: you could write a
> customer parser for each pass.

COBOL doesn't have _that_ many DIVISIONs.
IDENTIFICATION, ENVIRONMENT, DATA, and PROCEDURE,
in COBOL 85. In a program with a couple of hundred
lines, having those cards pre-punched saved practically
no time. Using the colour-coded stock to punch
semantically-named SECTIONs made a lot more sense.

Bengt Kleberg

unread,
Sep 12, 2012, 6:41:30 AM9/12/12
to Erlang-Questions Questions
Just in case that semantic categories means that functions that belong
together are placed together, I solve that kind of problem by having the
same prefix on functions that deal with the same thing.


bengt

o...@cs.otago.ac.nz

unread,
Sep 12, 2012, 6:45:39 AM9/12/12
to bengt....@ericsson.com, "...@cs.otago.ac.nz, Erlang-Questions Questions
> When trying to "find out what is particular module doing/responsible
> for", on paper, it helps if you can find things. When reading on paper
> it is easier to find things when they are alphabetically ordered.

I suggest that a listing generator that appends a table of contents
mapping each function name to a page number is another way to do this.
I really don't care for any syntactic ordering principle.

For example, separating the exported functions from the private
ones is a bad idea, because I might want to conceal something
that used to be exported, or vice versa, and suddenly what *should*
be a one-line change is a big change.

With alphabetic ordering, again, what *should* be a small change
to the name of a function -- with corresponding changes to callers --
becomes a violent change of place.

I agree 100% that being able to find things alphabetically is
very useful. If it comes to that, being able to find functions
by who last edited them, or when they were last edited, or how
many bugs have been found in them, &c &c can be convenient.
That doesn't mean that any of these, or any other extrinsic
ordering, is a good way to organise a group of definitions
that need to be comprehended together.

Let's put it this way:
for things that do NOT have to be comprehended together,
alphabetic ordering is great;
for things that DO having to be comprehended together,
any extrinsic ordering is bad.

Let me give an example.
It's really simple one just to make a point.

-export([ ... sum/1 ...]).

sum(Xs) -> add_up(Xs, 0).

add_up([X|Xs], S) -> add_sup(Xs, S+X);
add_up([], S) -> S.

If the comment on sum/1 is not enough,
you have to read them *together*.
But if you separate exported functions from internal ones,
these two functions are on different pages.
If you order function definitions alphabetically,
these two functions are on different pages.

Ulf Wiger

unread,
Sep 12, 2012, 6:51:33 AM9/12/12
to o...@cs.otago.ac.nz, erlang-q...@erlang.org

On 12 Sep 2012, at 12:27, o...@cs.otago.ac.nz wrote:

>> "Reading code on paper" has already been mentioned some times in this
>> thread.
>> But really people read code on paper, nowadays?
>
> Yes, me, lots.

The problem is often the same when reading code in a tty (which typically
defaults to 80x25). If I need to browse code from a command line, on a
laptop with a 15" screen, I do tend to mutter a few curses in the direction
of programmers who seem to think that everyone is sitting in front of
a lineup of >27" screens, just because they happen to. ;-)

This is hardly a new problem. In my first serious project, I recall an incident
where the coders of a UI had become too enamored with their new 17"
screens, and completely forgot that the most important users were using
Mac SE30s (with a 9" screen), for the simple reason that they had to
jump out of airplanes with them.

A spicy brew of fighter-pilot language was hurled at the developers when
it was discovered that the new decision support system was unusable on
anything but the very latest, sexiest monitors that only the developers had.*

BR,
Ulf W

* As you can guess, this was in the 90s, when a 17" monitor was indeed sexy.

Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
http://feuerlabs.com

Robert Virding

unread,
Sep 12, 2012, 7:11:21 AM9/12/12
to bengt kleberg, Erlang-Questions Questions
No!

I find it much easier to understand what is going on if I group the main function together with its "helper" functions. They are working together as one unit and often the helper functions only have meaning within the context of the main function. It also makes it easier to comment the whole unit and have local comments where necessary. The comment to the main functions describes what this functions does and how it does it, while comments for the helper functions just describe features of that function. In many cases this is the erlang alternative to having local functions. The only problem is when helper functions are shared between main functions in which case I usually put them together with the first function.

I never order my API functions alphabetically but prefer to group them according to what they do. For example if there is a server I will have the start/start_link/stop functions together as they managed the server as a whole. I will group API functions after what they do, so I will put functions that access one property together.

I will also group my export declarations in a similar way, sometimes commented, just to make it easier to see which exported functions belong together.

Robert

Pierpaolo Bernardi

unread,
Sep 12, 2012, 7:19:29 AM9/12/12
to o...@cs.otago.ac.nz, erlang-q...@erlang.org
On Wed, Sep 12, 2012 at 12:27 PM, <o...@cs.otago.ac.nz> wrote:
>> On Wed, Sep 12, 2012 at 11:12 AM, Ivan Uemlianin <iv...@llaisdy.com> wrote:
>>> If you are reading code on paper, it helps if functions are positioned
>>> predictably in the stack of paper. Alphabetic ordering of functions and
>>> grouping functions into sections are two good ways of doing this.
>>
>> "Reading code on paper" has already been mentioned some times in this
>> thread.
>> But really people read code on paper, nowadays?
>
> Yes, me, lots.
>
> Let me offer you a paradox, half fun and full earnest.'
>
> Fancy text editors and IDEs are tools for NOT reading code.
>
> If you actually want to read code, paper (ideally augmented
> with literate-programming-style automatically generated
> indices) is way better. If you don't know what I'm talking
> about, look at Knuth's "The Stanford GraphBase".

I have this book. Love the content. Hate how it's presented.

(And I wish Knuth had abstained from using the ignoble, hackish,
sometimes not complying to C of any standard, tricks, which makes the
code presented hard to reuse, and instead had concentrated on a higher
level view.)

> Just today, I found a bug in a Smalltalk class that had
> defeated me for a day because using an IDE is too much
> like tunnel vision. Given a printed listing, it took me
> half an hour to read the whole class, and the bug practically
> jumped up and down and shouted to get my attention.

I have little experiences with Smalltalk, but when I tried it, it's
usual IDEs gave me the impression of looking at the code through a
keyhole.
So I understand that in this case printed source is liberating.

P.

o...@cs.otago.ac.nz

unread,
Sep 12, 2012, 7:25:40 AM9/12/12
to bengt....@ericsson.com, "...@cs.otago.ac.nz, Erlang-Questions Questions
> Just in case that semantic categories means that functions that belong
> together are placed together, I solve that kind of problem by having the
> same prefix on functions that deal with the same thing.

Squeak 4.1:
'Collections-Unordered' "A group of related classes"
Dictionary "A particular class"
enumerating "A group of methods that all iterate"
#associationsDo: "iterate over (key->values) pairs"
#associationsSelect: "select subset of (key->value) pairs"
#collect: "map, function applied to values only"
#do: "iterate over values"
#keysAndValuesDo: "iterate over keys and values"
#keysDo: "iterate over keys"
#select: "select maplets looking just at values"
#valuesDo: "another name for #do:, at least here"

Giving these methods a common prefix would very definitely
reduce readability.

Take a look at lists.erl some time.

keysort/2 is in one place.
It calls keysort_1/5 and keysplit_1/8.
Now keysort_1/5 follows right after;
it calls keysplit_1/8 and keysplit_2/8,
which are 1000 lines and 1030 lines
away respectively.

That kind of nonsense is why I want tightly
coupled functions close together, regardless
of name, if that is possible.

This is actually a place where I would
do one of two things:
split keysort/2 and its support functions
into a separate module, and re-export it,
or split keysort/2 and its support functions
into a separate file, and -include it.

Fred Hebert

unread,
Sep 12, 2012, 7:48:15 AM9/12/12
to Robert Virding, Erlang-Questions Questions
This is the approach I like the most.

It's something I picked up when working with Scheme, where functions can
contain the definitions of their helpers within them, which made the
code much clearer to me.

I rarely read code on paper anymore, so while I understand the concern,
grouping alphabetically tends to be more useless to me than:
1. reading around the current unit I'm in is to get all its context
2. using my editor's quick jumping function when I need to skip around

Same with grouping export declarations. Most of the time, an action has
an opposite (add -> remove, start -> stop, push -> pop, etc) and it
makes sense to me to put these together.

But really, to me, grouping things related together is just a way to
make related code more compact, and easy to remember at once, as one
unit. Peter Norvig mentioned at some point that what he found important
was to be able to fit a problem in its entirety in his head so that he
can think about it more effectively.

Anton Lebedevich

unread,
Sep 12, 2012, 8:05:15 AM9/12/12
to erlang-q...@erlang.org
Distel helps a lot for reviewing code on screen. It has function
erl-find-source-under-point, which is bound to M-. This function allows
to jump to the source code that defines the function being called at
point. erl-find-source-unwind bound to M-, allows to return back after
reading the function.

Vlad Dumitrescu

unread,
Sep 12, 2012, 8:15:58 AM9/12/12
to Anton Lebedevich, erlang-q...@erlang.org
This is slightly the wrong crowd to mention erlide to :-) but it can
also navigate to the definition of things. This discussion also
prompted me to create a ticket for an feature where the related
functions can be shown together in the editor, regardless of where
they are located in the file. Also we could group and arrange the
source code too, using topological sort based on the dependencies.

regards,
vlad

Alexandre Aguiar

unread,
Sep 12, 2012, 9:47:05 AM9/12/12
to erlang-q...@erlang.org
Hi.

As far as I am not an Erlang expert, some ideas discussed here are not peculiar to Erlang.

Bengt Kleberg <bengt....@ericsson.com> escreveu:


>If you expect your code to be read/reviewed when printed, you should
>have the functions alphabetically ordered.
>Grouping exported/internal functions also help the reviewers.

Alphabetical order may or may not help. Modular code produces modules with small number of objects that can be efficiently visually navigated. The relationship between how efficiently and the number of objects, AFAIK, is undetermined.

Some convention to ease navigation accross different modules would be more sensible and worthwhile, IMVVVHO, of course.

>> On 12 September 2012 09:56, Richard O'Keefe <o...@cs.otago.ac.nz>

>> that repeats something immediately obvious

Obviousness is a function of familiarity. I often see this in software documentation that is obvious for the author. :-)

Style is not about aesthetics. It is about discipline. And discipline is about standards. Navigating a module with a previously known internal organization is far more efficient. Several languages have (or had) structural rules for their codings.

Some tags and comments work as markups that can ease learning and navigating by working as coding standards. Besides, disk space is not expensive today. :-) Not to mention that such standard markups will be essential for future implementation of cross module indexing systems and other indexing mechanisms.

My 2 cents.


--

Alexandre

--
Sent from my tablet. Please, excuse my brevity.
Enviado do tablet. Por favor, perdoe a brevidade.
Publié de le tablet. S'il vous plaît pardonnez la brièveté.
Veröffentlicht aus dem Tablet. Bitte verzeihen Sie die Kürze.
Enviado desde mi tablet. Por favor, disculpen mi brevedad.
Inviato dal mio tablet. Per favore, scusate la mia brevità.

Bengt Kleberg

unread,
Sep 12, 2012, 10:09:09 AM9/12/12
to erlang-q...@erlang.org
It would surprise me if a module with a small number of objects is more
difficult to navigate if the objects are in alphabetical order.

The idea of having a visual convention to help navigate across modules
sound very interesting. Any examples?


bengt

On Wed, 2012-09-12 at 15:47 +0200, Alexandre Aguiar wrote:
> Hi.
>
> As far as I am not an Erlang expert, some ideas discussed here are not peculiar to Erlang.
>
> Bengt Kleberg <bengt....@ericsson.com> escreveu:
> >If you expect your code to be read/reviewed when printed, you should
> >have the functions alphabetically ordered.
> >Grouping exported/internal functions also help the reviewers.
>
> Alphabetical order may or may not help. Modular code produces modules with small number of objects that can be efficiently visually navigated. The relationship between how efficiently and the number of objects, AFAIK, is undetermined.
>
> Some convention to ease navigation accross different modules would be more sensible and worthwhile, IMVVVHO, of course.
>
> >> On 12 September 2012 09:56, Richard O'Keefe <o...@cs.otago.ac.nz>
> >> that repeats something immediately obvious
>
> Obviousness is a function of familiarity. I often see this in software documentation that is obvious for the author. :-)
>
> Style is not about aesthetics. It is about discipline. And discipline is about standards. Navigating a module with a previously known internal organization is far more efficient. Several languages have (or had) structural rules for their codings.
>
> Some tags and comments work as markups that can ease learning and navigating by working as coding standards. Besides, disk space is not expensive today. :-) Not to mention that such standard markups will be essential for future implementation of cross module indexing systems and other indexing mechanisms.
>
> My 2 cents.
>
>
> --
>
> Alexandre
>

Alexandre Aguiar

unread,
Sep 12, 2012, 10:13:28 AM9/12/12
to o...@cs.otago.ac.nz, erlang-q...@erlang.org
o...@cs.otago.ac.nz escreveu:

>When you are coping with over 100,000 lines of code,
>tools that help you *NOT* read are desperately valuable.

Note that your case report is perfect to demonstrate that printing should *not* be routine. Printing selected limited portions is what helped you. At a 100 lines per page, handling a 1,000 pages (probably unindexed) is a hard task. :-) And, of course, a waste.
But, of course, each one knows how high piles of paper can handle and afford.


--

Alexandre

--
Sent from my tablet. Please, excuse my brevity.
Enviado do tablet. Por favor, perdoe a brevidade.
Publié de le tablet. S'il vous plaît pardonnez la brièveté.
Veröffentlicht aus dem Tablet. Bitte verzeihen Sie die Kürze.
Enviado desde mi tablet. Por favor, disculpen mi brevedad.
Inviato dal mio tablet. Per favore, scusate la mia brevità.

_______________________________________________

Robert Virding

unread,
Sep 12, 2012, 10:14:36 AM9/12/12
to Niclas Eklund, erlang-q...@erlang.org
Computers speak ASCII and lines are 80 chars long, that's just the way it is.

Robert

----- Original Message -----
> From: "Niclas Eklund" <ni...@tail-f.com>
> To: erlang-q...@erlang.org
> Sent: Wednesday, 12 September, 2012 10:45:59 AM
> Subject: Re: [erlang-questions] Style wars: junk comments
>
> On 09/12/2012 10:33 AM, Ivan Uemlianin wrote:
> > I agree.
> >
> > The emacs gen_server skeleton has things like:
> >
> > %%%===================================================================
> > %%% Internal functions
> > %%%===================================================================
> >
> > (note 70 chars wide)
> >
> > It's as if they're section headings at the top of a page in a book.
> >
>
> Would you prefer 80 chars? Must the IBM punch card still haunt us?!
> ;-)
>
> http://programmers.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width
>
> /Nick

Alexandre Aguiar

unread,
Sep 12, 2012, 12:01:54 PM9/12/12
to bengt....@ericsson.com, erlang-q...@erlang.org
Bengt Kleberg <bengt....@ericsson.com> escreveu:

>It would surprise me if a module with a small number of objects is more
>difficult to navigate if the objects are in alphabetical order.

The smaller the number of objects the lesser the need for indexing. And with larger numbers of objects the need for indexing will depend on the use of the source code. I do not remember any effort to sort source code content. And also do not know of any tools that build static indexes of code objects. Compilers do it at compile time, OO languages have virtual tables that, as in C++ for instance, are indexed at runtime. But nothing on source code.

>The idea of having a visual convention to help navigate across modules
>sound very interesting. Any examples?

I do not know any. It is interesting that other people have expressed the need for that within this thread (that, btw, has long abandoned the 'junk comments' discussion). :-) Indexing may or may not be useful. Sorting has a cost that is not always effective.

--

Alexandre

--
Sent from my tablet. Please, excuse my brevity.
Enviado do tablet. Por favor, perdoe a brevidade.
Publié de le tablet. S'il vous plaît pardonnez la brièveté.
Veröffentlicht aus dem Tablet. Bitte verzeihen Sie die Kürze.
Enviado desde mi tablet. Por favor, disculpen mi brevedad.
Inviato dal mio tablet. Per favore, scusate la mia brevità.

_______________________________________________

David Mercer

unread,
Sep 12, 2012, 12:58:05 PM9/12/12
to erlang-q...@erlang.org
On Wednesday, September 12, 2012, Vlad Dumitrescu wrote:

> This is slightly the wrong crowd to mention erlide to :-) but it can
> also navigate to the definition of things. This discussion also
> prompted me to create a ticket for an feature where the related
> functions can be shown together in the editor, regardless of where
> they are located in the file. Also we could group and arrange the
> source code too, using topological sort based on the dependencies.

Interesting idea for a source code transform that can compute the directed
graph of function dependencies and serialize them in an intelligent order,
grouping connected function close to each other.

(1) Anyone know of any good directed graph clustering and serialization
algorithm that might be appropriate for this?

(2) How would we handle semantically related but dependency unrelated
functions, such as start & stop, push & pop, add & remove, etc.?

Cheers,

DBM

Björn-Egil Dahlberg

unread,
Sep 12, 2012, 1:11:56 PM9/12/12
to Robert Virding, erlang-q...@erlang.org
12 sep 2012 kl. 16:14 skrev Robert Virding
<robert....@erlang-solutions.com>:

> Computers speak ASCII and lines are 80 chars long, that's just the way it is.

The only good thing about a 80 char limit is that it forces developers
to structure their code in more functions. That increases readability
imho.

Not a big fan otherwise. I think I have suppressed memories of a
fortran compiler hurling fatal errors at me for using more than 80
chars some time in the past. Horrible experience.

// Björn-Egil

Vlad Dumitrescu

unread,
Sep 12, 2012, 3:25:21 PM9/12/12
to David Mercer, erlang-q...@erlang.org
On Wed, Sep 12, 2012 at 6:58 PM, David Mercer <dme...@gmail.com> wrote:
> On Wednesday, September 12, 2012, Vlad Dumitrescu wrote:
>> a feature where the related
>> functions can be shown together in the editor, regardless of where
>> they are located in the file. Also we could group and arrange the
>> source code too, using topological sort based on the dependencies.
>
> (1) Anyone know of any good directed graph clustering and serialization
> algorithm that might be appropriate for this?
> (2) How would we handle semantically related but dependency unrelated
> functions, such as start & stop, push & pop, add & remove, etc.?

I think that generic algorithms would not work well enough because, as
#2 above asks, there are specific constraints for this use case. Some
of these will be up to the developer's taste, so the algorithm needs
to be configurable in this respect. There may be such algorithms, but
I couldn't find any that wouldn't need heavy customization.

One simple idea about #2 is to use multiple -export declarations to do
the grouping. In many cases this is something that people already do.
But then we come to the "taste"-related questions: do you want 'start'
and 'stop' together and both their helpers right after, or do you want
'start', its helpers, 'stop', its helpers? It could become a mess
trying to satisfy all these conflicting requirements, though.

regards,
Vlad

Richard O'Keefe

unread,
Sep 12, 2012, 5:59:15 PM9/12/12
to Fred Hebert, Erlang-Questions Questions

On 12/09/2012, at 11:48 PM, Fred Hebert wrote:

> This is the approach I like the most.
>
> It's something I picked up when working with Scheme, where functions can contain the definitions of their helpers within them, which made the code much clearer to me.

Scheme and ML have features that make this rather more useful
than it is in languages like Clean and Haskell. In ML you can
write
local
<private definitions>
in
<public definitions>
end

and this has the effect that the things defined in
<private definitions> are visible in <public
definitions>, but not outside, while the things
defined in <public definitions> are visible outside.
For example, you might have

local
fun rebalance t = ...
in
fun add k v t = ...
fun del k t = ...
end

Scheme lets you hack this by doing
(define add)
(define del)
(letrec ((rebalance (lambda (t) ...))
(set! add (lambda (k v t) ...))
(set! del (lambda (k t) ...))
'ok)

I see this quite a lot in Scheme.
If Joe's still thinking about Erlang 2, I hope he'll consider
the functionality of local-in-end.

Richard O'Keefe

unread,
Sep 12, 2012, 7:59:53 PM9/12/12
to Alexandre Aguiar, erlang-q...@erlang.org

On 13/09/2012, at 1:47 AM, Alexandre Aguiar wrote:
>
>>> On 12 September 2012 09:56, Richard O'Keefe <o...@cs.otago.ac.nz>
>>> that repeats something immediately obvious
>
> Obviousness is a function of familiarity.

I am talking about things like

%%===================================
%% Macros
%%===================================

-define(FOO, bar).
...

where the two immediately following tokens ("-" and "define")
tell you "hey, this is a macro"!

If you don't understand enough Erlang to know what -define is,
you don't understand enough Erlang to know what a macro is either.
I did not *just* say obvious, but referred to repeating information
in adjacent tokens, so that a trivial computer program could
derive the comment from the code in constant time.

I've also seen code like

%%
%% fred
%%

fred(X, Y) ->
jim({a, X, Y}).

where the entire text of the comment just repeats the next token.
It would be a very strange programmer who did not find *that* obvious.

And please, don't waste any time telling me comments like that are
useful for navigation. Even in vi I can do
/^fred(
to find fred. Admittedly, an Emacs user might find it easier to
do Ctrl-S % % f r e d RET . That's why in my own otherwise
emacs-like editor it would be Ctrl-S RET fred ( ESC.

I do agree that somehow highlighting the first line of a
function definition could be useful, but honestly, that's a simple
syntax colouring task. Here's a highlighter in AWK that I whipped
up in a few minutes.

For a -module, -define, or -record line, it highlights the word
immediately after the left parenthesis.
For any other -xxx line, it highlights xxx.
For function definition lines, it highlights the quoted or unquoted
atom that begins in column 1 if and only the last function
definition line did not begin with the same word.

awk -vhtml=0 -f hle.awk foo.erl
Uses ANSI terminal escapes for bolding and unbolding.
awk -vhtml=1 -f hle.awk foo.erl
Generates HTML with <b> for bolding.

#!/bin/awk
# Script : hle.awk
# Author : Richard A. O'Keefe
# SCCS : "@(#)2012/09/13 hle.awk 1.1"
# Purpose: HighLight Erlang for finding functions &c quickly.
# Usage : awk -vhtml=0 hle.awk foobar.erl >foobar.txt
# : copies the input adding ANS terminal escapes for bolding;
# : awk -vhtml=1 hle.awk foobarerl >foobar.htm
# : adds HTML markup using <b> for bolding.

function escape(s) {
if (html) {
gsub(/&/, "&amp;", s)
gsub(/</, "&lt;", s)
}
return s
}

function print_with_bold() {
print escape(substr($0, 1, RSTART-1)) bold \
escape(substr($0, RSTART, RLENGTH)) unbold \
escape(substr($0, RSTART+RLENGTH))
}

function print_sans_bold() {
print escape($0)
}

BEGIN {
if (html) {
bold = "<b>"
unbold = "</b>"
print "<html><head><title>Highlighted Erlang Source</title></head>"
print "<body><pre>"
} else {
bold = "\033[1m"
unbold = "\033[0m"
}
last = ""
}

END {
if (html) {
print "</pre></body></html>"
}
}

/^- *(define|module|record) *\( *[a-zA-Z][a-zA-Z0-9_]*/ {
# Highlight the word after the left parenthesis.
match($0, /\( */)
n = RSTART+RLENGTH
match(substr($0, n), /[a-zA-Z][a-zA-Z0-9_]*/)
RSTART += n - 1
print_with_bold()
next
}

/^- *[a-z]+ *[(]/ {
# Highlight the annotation name.
match($0, /[a-z]+/)
print_with_bold()
next
}

/^([a-z][a-zA-Z0-9_]*|'([^']|\\.)*')/ {
# Highlight the function name if it's not the same as the last one.
if (match($0, /[^ (%]*/)) {
name = substr($0, RSTART, RLENGTH)
if (name != last) {
last = name
print_with_bold()
next
}
}
}

{
# Don't highlight anything.
print_sans_bold()
}

# End of hle.awk

Combine that with html2ps, and you have a neat little .erl -> .ps
listing generator. It's easy to tweak. For example, we could make
-section(X).
turn into <h2>X</h2>
quite easily.
It is also easy to generate a cross reference table,

(1) > Style is not about aesthetics. It is about discipline.
(2) > And discipline is about standards.
(3) > Navigating a module with a previously known internal organization
> is far more efficient.
(4) > Several languages have (or had) structural rules for their codings.

Ad (4), I have already mentioned COBOL and Pascal and what an
*imperial* pain in the arse their non-semantic ordering (imposed not
for the benefit of the programmer but for the benefit of the compiler;
I know that to be the case for Pascal and I believe it to be so for
COBOL) was. Practically everyone who wrote a compiler relaxed that
order as pretty much the first extension they added, and Pascal's
successor languages dropped it as if it were red hot.

Ad (3), that claim is obviously untrue in general.
A known internal organisation helps navigation only if it is
*RELEVANT* to navigation, and my claim is that *syntactic*
sectioning is *NOT* relevant to navigation. It is quite
certainly irrelevant to any kind of navigation I have ever
tried to do. I never want to ask "where are the includes?"
because I can find them with a trivial Ctrl-R RET -include ESC
or ?^-include. I might well want to ask "which include file
did _this_ come from", pointing, but syntactic sectioning is
no help whatever in answering that question. I might well want
to find a particular function, but that's what tag files are
for (or automatically produced tables of contents).

Ad (2), discipline and standards are a means to an end.
Casabianca http://sniff.numachi.com/pages/tiBOYDECK.html
was disciplined and faithfully followed the standard set him,
but the result was a useless death.
The purpose of coding standards is working maintainable software.

A commenting convention that bloats the text (and I am prompted
here by actual *measured* factors of 2 and even more) thus
*creating* a navigation problem that would not otherwise have
existed is not a standard that *ought* to be followed.

A commenting convention that results in syntactic section headers
being left in when there is *nothing* for them to comment on is
a standard that *impairs* navigation by falsely suggesting that
there is a landing point when there is none.

Ad (1), no, style is not primarily about discipline, it is
primarily about COMMUNICATION.

A whole bunch of things converged at the same time:

- Talking to some people about how to present information
in graphs, about simplifying, about not depending on
the red-green distinction two of my colleagues here cannot
perceive, &c. I like the way Crothers said it in
"On the graphical presentation of quantitative data":
The graph is never an end in itself, it is not the
"result", and it is important to assess the Usefulness
of a presentation as well as such criteria as Clarity,
Accuracy, Space, and SPeed when deciding which
techniques to employ.

- Slogging through some web standards (which follow a
regular structure quite faithfully) and discovering
at the end that the syntax had no semantics.

- Reading an education report whose title was
"<cultural group> students in <field of study>:
identifying the barriers"
and realising at the end that while it had all the
conventional structure and paraphernalia of an
eduational report, it had not in fact identified any
barriers.

- Working through the ethics approval paperwork for an
educational experiment I'm 3rd investigator on and
seeing a rigid conventional structure followed perfectly
but the actual forms to be given to the subjects were
in heavily bureaucratic and somewhat garbled language.
(Lots of passives, nobody doing anything but things
mysteriously happening, comments removing themselves...)

- Encountering this particular body of Erlang code with
a rigid structure that was WORSE THAN USELESS FOR
ACTUAL COMPREHENSION.

We use TOOLS to aid NAVIGATION;
we use STYLE to aid COMPREHENSION.

Because the purpose of style is to help the reader understand,
rigidly following any rule is likely to be a bad idea.
Not because rules are bad as such, but because our finite
mental capacity means that we can never envisage all the
situations that may arise, so that we are likely to meet
situations where following the letter of the rule will
violate the intent of the rule. One of the wisest things
in the Ada Quality and Style Guidelines is that they
offer a rationale for every guideline, and make it clear
that the expected benefits of following style rules are
what really matter, not the rules as such.

> Some tags and comments work as markups that can ease learning

None of the examples I have complained of can credibly be said
to ease learning.

> and navigating

None of the examples I have complained of can credibly be said
to aid navigation in any realistic sense.

> by working as coding standards. Besides, disk space is not expensive today. :-)

Disc space is not the issue. But SCREEN space is limited.
A style that bloats the code with junk comments reduces
the amount of *useful* text I can see at one time and thereby
reduces my ability to understand the code. For the life of
me, I cannot see this as a good thing.

> Not to mention that such standard markups will be essential for future implementation of cross module indexing systems and other indexing mehanisms.

You will have to provide more detail.
The junk comments I am talking about are ones that are
trivially automatically derivable from at most the first
two tokens of the next code line.
It is hard to see how those can be essential for any
indexing system.

Be really clear and explicit:
in what way is a comment

%%======================================%%
%% Macros %%
%%======================================%%

(which might not in fact be followed by any macros at all)
essential to a cross module or other indexing system,
given that it is actually the presence of '-define'
that creates the condition "a macro is here".

Richard O'Keefe

unread,
Sep 12, 2012, 8:11:49 PM9/12/12
to Alexandre Aguiar, erlang-q...@erlang.org

On 13/09/2012, at 2:13 AM, Alexandre Aguiar wrote:

> o...@cs.otago.ac.nz escreveu:
>> When you are coping with over 100,000 lines of code,
>> tools that help you *NOT* read are desperately valuable.
>
> Note that your case report is perfect to demonstrate that printing should *not* be routine.

Bad logic. Yes, printing the *whole* thing should not be routine.
It does *NOT* follow that you should not print a small number of
modules.

> Printing selected limited portions is what helped you.

Exactly so, but we are talking about
- the entirety of a 'module'
- up to 100 pages.

> At a 100 lines per page, handling a 1,000 pages (probably unindexed) is a hard task.

50 to 60 lines per page would be more realistic.

Why on earth do you say "probably unindexed"?
Part of the point of printing is to use listing programs
that generate aids to navigation, like headers that
identify module and function, tables of contents, and
indices.

The 2009-08-23 draft of the COBOL standard is 910 pages.
I have in fact been reading it on an iPad, but the whole
time I've been wishing I had a paper copy.
The SQL standard dwarfs it.

> :-) And, of course, a waste.

Why "of course"? Printing something is a waste if and only if
the cost in time, paper, toner, environmental effects, &c
exceeds the benefits. If it gets read, especially if it gets
read more than once, it is not a waste. If you can read it
more comfortably than you can on screen, it is not a waste.
The iPad 3 has a lovely screen, but even that is still not as
good as paper. If printing saves eyestrain (and for me it
often does), it's not a waste.

In the case of the 100,000 lines of code I mentioned, every
line has been printed at least once, and it has _always_ paid
off *for me*.

The relevant factor here is probably how much you can read
before it gets out of date

Richard O'Keefe

unread,
Sep 12, 2012, 8:15:36 PM9/12/12
to David Mercer, erlang-q...@erlang.org

On 13/09/2012, at 4:58 AM, David Mercer wrote:
> (2) How would we handle semantically related but dependency unrelated
> functions, such as start & stop, push & pop, add & remove, etc.?

Eiffel-style controlled vocabulary and manual SEE-ALSO links,
possibly pattern-specified.

Fred Hebert

unread,
Sep 12, 2012, 9:38:57 PM9/12/12
to Richard O'Keefe, Erlang-Questions Questions
Some Schemes also allow things like:

(define (fib x)
(define (fib-rec n a b)
(cond [(= n 0) b]
[true (fib-rec (- n 1) b (+ a b))]))
(fib-rec x 0 1))

which can be called as(fib 4). This allows to define private or helper
functions within the context of their main function, without needing
destructive assignment or whatever, and then later on executing it.
Python allows something similar:

def fib(x):
def fib_rec(x, a, b):
if x == 0:
return b
else:
return fib_rec(x-1, b, a+b)
return fib_rec(x, 0, 1)

though it would be nicer if Python indeed had tail recursion ;) Whether
the functions come before or after the final higher-level call doesn't
especially matter to me, but code becomes way nicer to read to me when
described that way.

You can separate one-use helpers from module-wide helpers that way, too.

Nothing would keep us from doing something similar in Erlang iff
anonymous functions were not so anonymous (and if self-recursion in
anonymous function wasn't that annoying to read).

Richard O'Keefe

unread,
Sep 12, 2012, 10:38:23 PM9/12/12
to Fred Hebert, Erlang-Questions Questions

On 13/09/2012, at 1:38 PM, Fred Hebert wrote:

> Some Schemes also allow things like:
>
> (define (fib x)
> (define (fib-rec n a b)
> (cond [(= n 0) b]
> [true (fib-rec (- n 1) b (+ a b))]))
> (fib-rec x 0 1))
>
> which can be called as(fib 4).

I think you missed the point. Except for the use of square brackets,
this is absolutely standard RnRS Scheme for at least n = 2..5. It is
also trivial and in this context unhelpful, because a helper function
defined this way is necessarily private to its client. You can do
_this_ much in practically every functional language but Erlang.

Defining one function inside another is just plain not interesting;
we've been able to do _that_ since 1960. Only languages in the
BCPL->C->C++->Java lineage think there is anything unusual or
tricky about *that*. (Even Fortran and COBOL let you defined
nested procedures.)

Heck, even in Erlang you can do

fib(X) ->
F = fun (_, 0, _, B) -> B
; (G, N, A, B) -> G(G, N-1, B, A+B)
end,
F(F, X, 0, 1).


> This allows to define private or helper functions within the context of their main function, without needing destructive assignment or whatever, and then later on executing it.

Even Scheme doesn't _really_ need destructive assignment;
you can manage without it by introducing an auxiliary name:

(define add-and-del
(letrec ((rebalance (lambda (t) ...))
(list (lambda (k v t) ...)) ;add
(lambda (k t) ...)))) ;del
(define add (car add-and-del))
(define del (cadr add-and-del))

Common Lisp lets you get the multiple-private-helpers-
shared-by-multiple-clients effect by bending the
scope rules rather horribly:

(labels ((rebalance (t) ...))
(defun add (k v t) ...)
(defun del (k t) ...))

DEFUN always "Defines a new function ... in the global environment."

The mechanics are of no great interest,
what is of interest is the ability by _some_ mechanism
to have one or more helper functions that are
*outside* their clients (so they do *not* have access to
the clients' internal data) and are accessible to one or
*more* clients without being accessible to _all_ the
top-level functions in the module.

Defining a function inside another function does NOT allow
- private helper functions used by two or more functions
(which was the point of what I was talking about)
- private helper functions used in more than one clause
of the same function, a very important issue in Erlang.

> Python allows something similar:
>
> def fib(x):
> def fib_rec(x, a, b):
> if x == 0:
> return b
> else:
> return fib_rec(x-1, b, a+b)
> return fib_rec(x, 0, 1)

Yawn. So Python has caught up with 1960. This *still* cannot
handle the non-trivial case of a helper function shared by more
than one function.
>
> You can separate one-use helpers from module-wide helpers that way, too.

Yes, that's been pretty much obvious since 1960.
The issue is helpers that are NEITHER one-use NOR module-wide.

Non-functional languages usually go for nested modules for that.
Like I said, I don't care about the mechanics.
>
> Nothing would keep us from doing something similar in Erlang iff anonymous functions were not so anonymous (and if self-recursion in anonymous function wasn't that annoying to read).

I don't see anything *annoying* in
F = fun (_, 0, _, B) -> B
; (G, N, A, B) -> G(G, N-1, B, A+B)
end,
Mildly irritating, yes; annoying, no.
I seem to recall suggesting a small syntax
extension where

fun F(X, Y, Z) -> ... F(...) ...
; F(...) ... F ...
end

would turn into

F = (fun (G) -> fun (X, Y, Z) -> G(G, X, Y, Z) end end)
(fun (F, X, Y, Z) -> ... F(F,...) ...
; (F, ...) ... fun (X, Y, Z) -> G(G, X, Y, Z) end ...
end)

but on the whole, perhaps not.

Fred Hebert

unread,
Sep 12, 2012, 10:48:43 PM9/12/12
to Richard O'Keefe, Erlang-Questions Questions
I was agreeing with you, just showing an alternative form from the one
you showed. I don't know what you're trying to convince me of there.

Gianfranco Alongi

unread,
Sep 13, 2012, 1:39:36 AM9/13/12
to Richard O'Keefe, Erlang-Questions Questions
I've been following this whole thread with mild amusement and I am
siding with Richard on this.

I would go the extra mile to and say, documentation that is not
executable to test for correctness is sure to rot.

So, on top of the mind-cycle-wasting comments which section the source
file in obvious ways, we have these others which just state the
obvious and then go bad when the code changes.

In general I get a strong feeling that people who don't feel
comfortable with the language, riddle it with sectioning comments in
order to feel some form of control.

I can't be the only one who read The Pragmatic Programmer: From
Journeyman to Master, Clean Code and The Clean Coder.

/G

Toby Thain

unread,
Sep 13, 2012, 11:33:49 AM9/13/12
to Gianfranco Alongi, Erlang-Questions Questions
On 13/09/12 1:39 AM, Gianfranco Alongi wrote:
> ...
> I can't be the only one who read The Pragmatic Programmer: From
> Journeyman to Master, Clean Code and The Clean Coder.

Don't miss "The Elements of Programming Style", Kernighan & Plauger.

--Toby

>
> /G

Steve Davis

unread,
Sep 13, 2012, 7:56:40 PM9/13/12
to erlang-pr...@googlegroups.com, Erlang-Questions Questions, o...@cs.otago.ac.nz
Yes, to me that stuff seems to be obvious and distracting BS. 

e.g. anything "internal" isn't exported by definition, right?

There *is* an issue between making a distinction between -export for API use and -export needed for use only within the app or library.

Anything else is not a weakness of erlang syntax IMHO. 

/s

Richard O'Keefe

unread,
Sep 14, 2012, 12:42:52 AM9/14/12
to Steve Davis, erlang-pr...@googlegroups.com, Erlang-Questions Questions

On 14/09/2012, at 11:56 AM, Steve Davis wrote:
> There *is* an issue between making a distinction between -export for API use and -export needed for use only within the app or library.

That is what -export_to was invented for. It's not just that you
want to >say< that something is exported for very specific reasons,
you want to >enforce< that it's only usable by things you mean to
export it to. It is also more precise than "internal exports",
which I used to think only meant functions exported back to the
module itself for use with 'apply'.

The intellectual debt to Eiffel's {targeting} of feature availability
seems obvious, but if memory serves me correctly, I thought of
-export_to before I learned Eiffel.

Alexandre Santos Aguiar

unread,
Sep 14, 2012, 9:05:06 AM9/14/12
to Richard O'Keefe, erlang-q...@erlang.org
Richard O'Keefe,

Although my first impulse was simlpy ignore your message, I felt I could
contribute some Physiology, Rhetorics and a little of IT on the
discussion you yourself proposed about 'junk comments'. However, I
noticed with extreme delay that the discussion under 'junk comments'
really has nothing to do with 'junk comments' as further messages make it
evident.

Em Qua 12 Set 2012 às 20:59, falávamos sobre "Re: [erlang-questions] Style
wars: junk comments", e você escreveu:
> Ad (1), no, style is not primarily about discipline, it is
> primarily about COMMUNICATION.

Being *about* something is being *related to* something and not being
something. Your statement does not contradict mine but actually adds that
communication is related to standards and standards are related to
discipline.

> Style is not about aesthetics.

This was incomplete: it shuold read 'style is not *only* about
aesthetics'. Not a deadly omission, I guess.

> we use STYLE to aid COMPREHENSION.

STANDARDS (ouch, I am yelling too! :-D), as in my *full statement*, for
communication. Every language, spoken or not, is (and it can't be
otherwise) a *standard* or it won't be useful for communication if it is
not a *standard*. Some can be more or less flexible. Spoken languages are
flexible due to the very nature of our brains that are able to work fine
in the presence of error or incomplete information.

While computer programming languages are only written (not spoken) and
computer work applies only to syntax, the portions of source code we
call 'comments' are useless to the primary purpose (computer processing)
and can simply be ignored by humans interested only on the syntax.
Coments are used exclusively for (non verbal?) communication with other
humans and, above all, in human fashion! As there are no rules for this
communication through comments, that means there are no *standards*,
comments may be neither effective nor efficient for communications. But
as they can be effectively and efficiently ignored, there is no point in
trying to impose the rigidity of computer language syntax (computers
can't do their jobs in the presence even of minor errors in syntax) to
human comments.

Brains have neither the precision nor the consistency of computers. Human
style won't meet machine standards no matter what you or anybody else may
think about it. Comments in source code are free (both of freedom *and*
of costs)! :-D

This seeming uselessness of the topic you proposed might explain why
nobody else cared about your points on 'junk comments' and went on to
discuss syntax! I myself thought you had a point and really wanted to
discuss issues on source code comments as this is unexplored subject and
thus could result in some discovery provided some knowledge was applied
to the problem. Sorry for taking you wrong.

> > Note that your case report is perfect to demonstrate that printing
> > should *not* be routine.
> Bad logic. Yes, printing the *whole* thing should not be routine.
> It does *NOT* follow that you should not print a small number of
> modules.

That, BTW, is *not* what is written in my message (this thing of small
number of modules). You even agreed with what you called 'bad logic'. :-)

> > At a 100 lines per page, handling a 1,000 pages (probably unindexed)
> > is a hard task.
> 50 to 60 lines per page would be more realistic.

In Rhetoric it is a technique to use parameters against your argument when
building a scenario. The proof of your point gets more effect. Is this
explanation enough, sir? This is style, btw. :-) Using your *realistic*
parameter would double the actual use of printing stuff. The factor 2 may
not have been picked by chance, sir. :-)

> Why on earth do you say "probably unindexed"?

Because I have never seen an index in a printed listing of source code!
Function X, page A, function Y, page B, etc. I guess this is not common
practice and so, as I do not know but have limited (only personal)
experience, I bayesianly stated 'probably'. My own prejudices are neither
reality nor can be used to model reality. Is this reasoning ok for you,
sir?

> I've been wishing I had a paper copy.

There is a reason for that: on screens humans read slower and retain less
in memory. Human physiology sometimes is so limiting... :-)

> > :-) And, of course, a waste.
> Why "of course"? Printing something is a waste if and only if
> the cost in time, paper, toner, environmental effects, &c
> exceeds the benefits. If it gets read, especially if it gets
> read more than once,

*If* and only *if* it is read. That is not what happens according to
studies in the 90's performed after it was learned that office computers
doubled the consumption of paper.

> But SCREEN space is limited.

And the world should change the way people think because of screen space?
If this is your point I regret having spent your time and very especially
mine.

However, if instead of yelling and pushing on personal prejudices you want
to share and build some real knowledge, your messages will no longer be
filtered out.

Greetings,

--


Alexandre Aguiar, MD, SCT

--
People change and forget to tell each other.
-- Lillian Hellman
--
All messages from my addresses express my own (often obscure) opinions and
have no relationship to the views of past|current|future places I work,
their administrations, employees, my wife, my daughters, the nation, the
world or the universe in general. Enough?
signature.asc

Steve Davis

unread,
Sep 16, 2012, 3:12:16 PM9/16/12
to Richard O'Keefe, Erlang-Questions Questions
Since you can invent attributes, I have played with:

-api({{Name, Arity}, "Short Descriptive Usage Comment"}).

...as a means of compiling brief module self-documention that is visible in X:module_info(attributes).

Richard O'Keefe

unread,
Sep 16, 2012, 6:26:27 PM9/16/12
to Steve Davis, Erlang-Questions Questions

On 17/09/2012, at 7:12 AM, Steve Davis wrote:

> Since you can invent attributes, I have played with:
>
> -api({{Name, Arity}, "Short Descriptive Usage Comment"}).
>
> ...as a means of compiling brief module self-documention that is visible in X:module_info(attributes).

That's a nice one. Except that I hate 'api'. It is still defined as
"Application Programming Interface" and is the interface presented by
a library layer such as an operating system or the X11 window system
to application programs. Some people started using it to mean
"function" apparently because "function" had too few syllables.
How about "purpose" (two syllables instead of three) or even "for" (one)?

EEP 24 suggested allowing Name/Arity anywhere in any attribute.

-for({foo/1, "listing clowns"}).
-for({bar/2, "telling a clown what routine to use"}).
-for({ugh/3, "advising a clown which way to run and how fast"}).

That EEP has R12B-5 written beside it, so it _should_ work...

Steve Davis

unread,
Sep 17, 2012, 9:43:19 AM9/17/12
to Richard O'Keefe, Erlang-Questions Questions
Good naming is often the hardest game.

I have also used "public" rather than "api"... but that too has overtones; but maybe it's better

- and you could go further I guess:

-public([
{foo, [term, list], number, "Finds number of terms in list"},
{bar, ....}
]).

Just playing :)

/s

Vlad Dumitrescu

unread,
Sep 17, 2012, 9:53:59 AM9/17/12
to Steve Davis, Erlang-Questions Questions
Hi,

On Mon, Sep 17, 2012 at 3:43 PM, Steve Davis
<steven.cha...@gmail.com> wrote:
> Good naming is often the hardest game.
>
> I have also used "public" rather than "api"... but that too has overtones; but maybe it's better
>
> - and you could go further I guess:
>
> -public([
> {foo, [term, list], number, "Finds number of terms in list"},
> {bar, ....}
> ]).

When this kind of description grows in detail, why not use the edocs
and the -specs? The edocs could be parsed and stored in an attribute
available at runtime, and the -spec is more complete that the simple
types above. A lot of Erlang code already has edoc comments and
-specs. Why invent a new format that says the same thing?

Just playing ;-)

regards,
Vlad

Steve Davis

unread,
Sep 17, 2012, 7:23:22 PM9/17/12
to Vlad Dumitrescu, Erlang-Questions Questions
Well, I guess I was just playing...

However, since you ask, what this approach does do that -spec and edoc do not, is make a module self-documenting even when compiled.

What's often missing with docs is "what is important here" and "what is the intention". So a distillation, for me at least, is more useful than verbose documentation which does tend to get out of date with the source no matter how well-intentioned.

Also, and again a personal observation, I find -spec confusing as it looks like code and I find myself *reading it as code* and not documentation all too often (maybe I'm just dumb). My preference is a source file without it.

My 2c,
/s

Steve Davis

unread,
Sep 17, 2012, 7:29:39 PM9/17/12
to Vlad Dumitrescu, Erlang-Questions Questions
Also, in case the point got lost, it does let you know which functions are intended to be used outside the app, rather than just ones that must be exported for internal use within, say, the library itself.

Vlad Dumitrescu

unread,
Sep 18, 2012, 2:35:28 AM9/18/12
to Steve Davis, Erlang-Questions Questions
Hi,

On Tue, Sep 18, 2012 at 1:29 AM, Steve Davis
<steven.cha...@gmail.com> wrote:
> Also, in case the point got lost, it does let you know which functions are intended to be used outside the app, rather than just ones that must be exported for internal use within, say, the library itself.

No, the point was not lost. There's nothing preventing edoc have
another @tag with this meaning. The edoc+spec information can be kept
at runtime too, inside a beam chunk, so that's not an issue. The full
edoc comments are maybe too verbose, but by convention the first
sentence should be exactly the succint description that you mentioned.
Also, when presenting the doc/spec to the user at runtime, the spec
could get simplified, if requested.

What I mean is that I think that your suggestions can be implemented
with tools that already exist and are in use, with the advantage that
many modules already have this information in them. I am not very keen
on having yet another annotation that in time will get out of sync
with the code proper...

regards,
Vlad

Steve Davis

unread,
Sep 18, 2012, 8:20:56 AM9/18/12
to Vlad Dumitrescu, Erlang-Questions Questions
Both good points. Perhaps some standard way of making this distinction should be provided.

Best,
/s

On Sep 18, 2012, at 1:35 AM, Vlad Dumitrescu <vlad...@gmail.com> wrote:

> Hi,
>
> On Tue, Sep 18, 2012 at 1:29 AM, Steve Davis
> <steven.cha...@gmail.com> wrote:
>> Also, in case the point got lost, it does let you know which functions are intended to be used outside the app, rather than just ones that must be exported for internal use within, say, the library itself.
>
> No, the point was not lost. There's nothing preventing edoc have
> another @tag with this meaning. The edoc+spec information can be kept
> at runtime too, inside a beam chunk, so that's not an issue. The full
> edoc comments are maybe too verbose, but by convention the first
> sentence should be exactly the succint description that you mentioned.
> Also, when presenting the doc/spec to the user at runtime, the spec
> could get simplified, if requested.
>
> What I mean is that I think that your suggestions can be implemented
> with tools that already exist and are in use, with the advantage that
> many modules already have this information in them. I am not very keen
> on having yet another annotation that in time will get out of sync
> with the code proper...
>
> regards,
> Vlad
Reply all
Reply to author
Forward
0 new messages