From: Lowell
Subject: general order of parameters
Date: 
Message-ID: <bf2vtq$3tv$1@mughi.cs.ubc.ca>
I'm curious if there are general rules that most people follow when it 
comes to the order of parameters for a function. I think it would be 
good to have some rules so that I wouldn't have to check with a 
function's implementation every time I want to apply it.

With some functions, the order seems natural and never gets mixed up. 
For instance, the CL function 'nth' seems like it should be followed by 
its numeric argument since the concept of nth-ness seems more closely 
related to a number than a list. On the other hand, the (almost 
identical) list-ref function feels natural having a list as its first arg.

Are there any common guidelines that people generally follow for this 
type of thing? Please share :)

Lowell

From: Rob Warnock
Subject: Re: general order of parameters
Date: 
Message-ID: <H5ucnZloAfeghYiiXTWc-g@speakeasy.net>
Lowell <······@cs.ubc.ca> wrote:
+---------------
| With some functions, the order seems natural and never gets mixed up. 
| For instance, the CL function 'nth' seems like it should be followed by 
| its numeric argument since the concept of nth-ness seems more closely 
| related to a number than a list. On the other hand, the (almost 
| identical) list-ref function feels natural having a list as its first arg.
+---------------

When learning Common Lisp, one must get used to the fact that when the
ANSI standard was being developed compatibility with existing Lisp
implementations & practice was (generally) deemed more important than
making every last little corner consistent in style [what some might
call "clean" -- others might say "too pure"]. As a result, there are
a number of such little oddities of function naming, argument-order,
and other little things that might have been done differently (and more
consistently) had there not already been a couple of decades of prior art. 

As another poster suggested, for your *own* code just pick a style
that seems natural to you and stick to it, without worrying too much
about the inconsistencies of CL itself. On the other hand, if you're
working from or extending a significant body of existing code that
clearly has an existing style of its own, then it's generally best
to simply adapt to that style and not gratuitously change it just
because you don't happen to like it as well as your own.


-Rob

-----
Rob Warnock, PP-ASEL-IA		<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Kaz Kylheku
Subject: Re: general order of parameters
Date: 
Message-ID: <cf333042.0307160805.3f0bab08@posting.google.com>
····@rpw3.org (Rob Warnock) wrote in message news:<······················@speakeasy.net>...
> Lowell <······@cs.ubc.ca> wrote:
> +---------------
> | With some functions, the order seems natural and never gets mixed up. 
> | For instance, the CL function 'nth' seems like it should be followed by 
> | its numeric argument since the concept of nth-ness seems more closely 
> | related to a number than a list. On the other hand, the (almost 
> | identical) list-ref function feels natural having a list as its first arg.
> +---------------
> 
> When learning Common Lisp, one must get used to the fact that when the
> ANSI standard was being developed compatibility with existing Lisp
> implementations & practice was (generally) deemed more important than
> making every last little corner consistent in style [what some might
> call "clean" -- others might say "too pure"]. As a result, there are
> a number of such little oddities of function naming, argument-order,
> and other little things that might have been done differently (and more
> consistently) had there not already been a couple of decades of prior art.

Same thing in some other languages:

   char *fgets(char *, int, FILE *);
   int fprintf(FILE *, const char *, ...);

Oops!
From: Anton van Straaten
Subject: Re: general order of parameters
Date: 
Message-ID: <9wfRa.104116$Io.8946640@newsread2.prod.itd.earthlink.net>
Kaz Kylheku wrote:
> > As a result, there are
> > a number of such little oddities of function naming, argument-order,
> > and other little things that might have been done differently (and more
> > consistently) had there not already been a couple of decades of prior
art.
>
> Same thing in some other languages:
>
>    char *fgets(char *, int, FILE *);
>    int fprintf(FILE *, const char *, ...);
>
> Oops!

Except there are some pretty good justifications for that example, not just
historical ones.  First, gets and fgets are setter-like functions, and
having the value being set as the first parameter is consistent with
functions like strcpy (heck, it's even consistent with Lisp).  But this
doesn't apply to printf or fprintf.  In addition, the FILE* being the last
parameter in fgets is desirable because of the symmetry with 'gets'.  But
the variable arguments of fprintf make it unsatisfactory to put the FILE*
parameter last.

I therefore conclude that this example is a model of carefully-thought-out
consistency, and you're going to have to try harder to show that C is as
inconsistent as CL!  <duck>

Anton
From: Kaz Kylheku
Subject: Re: general order of parameters
Date: 
Message-ID: <cf333042.0307161428.456634cf@posting.google.com>
"Anton van Straaten" <·····@appsolutions.com> wrote in message news:<·······················@newsread2.prod.itd.earthlink.net>...
> Kaz Kylheku wrote:
> > > As a result, there are
> > > a number of such little oddities of function naming, argument-order,
> > > and other little things that might have been done differently (and more
> > > consistently) had there not already been a couple of decades of prior
>  art.
> >
> > Same thing in some other languages:
> >
> >    char *fgets(char *, int, FILE *);
> >    int fprintf(FILE *, const char *, ...);
> >
> > Oops!
> 
> Except there are some pretty good justifications for that example, not just
> historical ones.  First, gets and fgets are setter-like functions, and

   int fputc(int ch, FILE *); /* stream manipulator */
   int fseek(FILE *, long, int); /* stream manipulator */

[ snip ]
> doesn't apply to printf or fprintf.  In addition, the FILE* being the last
> parameter in fgets is desirable because of the symmetry with 'gets'.

Right, symmetry with the poster child function for the buffer overflow
undercurrent in software development: very important! ;)
From: Anton van Straaten
Subject: Re: general order of parameters
Date: 
Message-ID: <lllRa.104974$Io.8988595@newsread2.prod.itd.earthlink.net>
Kaz Kylheku wrote:
>    int fputc(int ch, FILE *); /* stream manipulator */
>    int fseek(FILE *, long, int); /* stream manipulator */

Well, see, the reason for that one is...  uh...  hey, look over there!!

> [ snip ]
> > doesn't apply to printf or fprintf.  In addition, the FILE* being the
last
> > parameter in fgets is desirable because of the symmetry with 'gets'.
>
> Right, symmetry with the poster child function for the buffer overflow
> undercurrent in software development: very important! ;)

Good point.  The symmetry really needed to go the other way, so that 'gets'
had a size parameter, like fgets - so, the root cause of those buffer
overflows was in fact a lack of the right sort of symmetry...  :)

'gets' may be one of the best examples of an API that should never have
survived, regardless of "existing implementations & practice".  Of course,
poor APIs in safer languages don't have such directly catastrophic
consequences - but perhaps that's all the more reason to try to be
consistent, since the negative consequences of inconsistencies may not be
apparent until it's too late to fix them.

Anton
From: Steven M. Haflich
Subject: Re: general order of parameters
Date: 
Message-ID: <3F16B7BA.70807@alum.mit.edu>
Rob Warnock wrote:

> As another poster suggested, for your *own* code just pick a style
> that seems natural to you and stick to it, without worrying too much
> about the inconsistencies of CL itself. 

This discussion misses a point that should not be missed:  CL provides
an elegant mechanism that in many important situations eliminates the
need for defining an argument order.  Paul Graham has spoken passionately
about it.

Keyword arguments remove the need for remembering argument order for the
difficult cases -- functions with many optional arguments.  They allow
a function to be extended without the need to visit every existing call
to the function.  They eliminate coding mistakes from elided positional
arguments.

Some programmers shy away from keyword arguments for fear of losing
efficiency.  While processing keywords does consume some processor time,
modern implementations are fairly efficient, and the time is insignificant
except for low-level high-bandwidth functions.  One would not want to lard
arithmetic functions with keyword processing, but there is little reason
not to use keywords for lower-bandwidth functions such as open.  Further,
a compiler macro can eliminate run-time keyword processing for
speed-critical functions while preserving the coding benefits of keywords.
From: Paul Dietz
Subject: Re: general order of parameters
Date: 
Message-ID: <3F2177C7.E2DCF206@motorola.com>
"Steven M. Haflich" wrote:

> Some programmers shy away from keyword arguments for fear of losing
> efficiency.  While processing keywords does consume some processor time,
> modern implementations are fairly efficient, and the time is insignificant
> except for low-level high-bandwidth functions.  One would not want to lard
> arithmetic functions with keyword processing, but there is little reason
> not to use keywords for lower-bandwidth functions such as open.  Further,
> a compiler macro can eliminate run-time keyword processing for
> speed-critical functions while preserving the coding benefits of keywords.

What's more, the specialized functions each with a fixed set of keyword
parameters can be introduced dynamically by compiling a stub function at
the first call, without the need for the user to add compiler macros
for each such function.  After this, the overhead would be a single branch
instruction.  I don't know of any lisps that do this, but it shouldn't
be too difficult to do.  Calls within the same file to functions
that aren't declared not-inline can have a static version of this
optimization.

	Paul
From: Pascal Costanza
Subject: Re: general order of parameters
Date: 
Message-ID: <costanza-24136C.10070616072003@news.netcologne.de>
In article <············@mughi.cs.ubc.ca>, Lowell <······@cs.ubc.ca> 
wrote:

> I'm curious if there are general rules that most people follow when it 
> comes to the order of parameters for a function. I think it would be 
> good to have some rules so that I wouldn't have to check with a 
> function's implementation every time I want to apply it.
> 
> With some functions, the order seems natural and never gets mixed up. 
> For instance, the CL function 'nth' seems like it should be followed by 
> its numeric argument since the concept of nth-ness seems more closely 
> related to a number than a list. On the other hand, the (almost 
> identical) list-ref function feels natural having a list as its first arg.
> 
> Are there any common guidelines that people generally follow for this 
> type of thing? Please share :)

My guideline would be: follow your gut feelings. If you think something 
feels natural then it's probably the same for other people as well.

Furthermore, I have made good experiences with publishing my code here 
in c.l.l - I have got some very good recommendations for naming code 
elements by others.

(As a sidenote, the whole question depends a little on whether you 
regard programming more as a form of art or more as an engineering 
discipline, or similar discussions along these lines.)


Pascal