emacs-tangents
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [External] : Re: Shrinking the C core


From: Drew Adams
Subject: RE: [External] : Re: Shrinking the C core
Date: Sun, 17 Sep 2023 17:16:58 +0000

> Many functions that each do little are easier to see than few
> functions that each do a lot, because with many functions that
> each do little, the function names are often enough to
> understand what they do and how they work - and they require
> none or very little documentation.
> 
> But with few functions that each do a lot, one has to check
> the documentation for each function, and the documentation
> will be huge, because few functions that each do a lot either
> have to have an almost endless list of arguments or rely on an
> equally long list of possible keywords to control
> their behavior.
> 
> For example, (+ ...), (- ...) etc are preferable to
> (arithmetic :operation 'addition ...),
> (arithmetic :operation 'subtraction ...) etc.

You continue to ignore this in your posts:

  The ability to have &optional, &rest, and keyword
  arguments doesn't prevent anyone from _not_ making
  use of any of those and instead defining 8000
  separate functions (to further the exaggeration).

  Do _you_ ever use &optional or &rest when defining
  functions?  If so, why, since you apparently have
  a blanket rule that using multiple separate
  functions is always better?
 
Everything you've said against keyword args (even
just allowing them?) applies equally to &optional
and &rest.  Should they be outlawed or deprecated?

Please answer the question: do you define functions
that use those?  If so, how do you reconcile that
practice with your claim that it's always better to
define separate functions instead?  Why do you use

 (defun foo (arg1 &optional arg2 arg3 arg4)...)

instead of these, since you argue that these must
be better?

 (defun foo1 (arg1) ...)
 (defun foo2 (arg1 arg2) ...)
 (defun foo3 (arg1 arg2 arg3) ...)
 (defun foo4 (arg1 arg2 arg3 arg4) ...)

It's a no-brainer that:

1. Providing the _possibility_ of using &optional,
   &rest - and, yes, keyword args - doesn't _oblige_
   anyone to define functions that use those.

   Such arguments just _allow_ you to define, and
   users to use, a function that takes the place
   of multiple related functions.  Or that serves
   as a helper/workhorse, to _define_ multiple
   related functions.

2. That provides a place and a name for the family
   as a whole, and a place for their _relations_
   to be set forth explicitly in doc.  You get not
   only individual views of particular trees but
   views of tree communities: particular forests.

3. Keyword args let users use fewer actual args
   than when &optional args are used - nils that
   are only positional placeholders disappear.

4. Keyword args make clear what the intention of
   each arg is (it's named!).  Contrast that with
   having to consult the doc each time to figure
   out what each positional arg means.

When calling a function, both (1) the need to stick
in positional-placeholder nils and (2) the need to
identify a keyword arg by its name make function
calls more verbose (an argument you could have made,
but didn't, in favor of not using &optional, &rest,
and keyword args).

It's a tradeoff, for not needing to define and use
more functions.  When defining functions _you_ get
to make that tradeoff decision.  That's the point -
the language doesn't decide for you, by offering
only one possibility.  Lisp says, "You're welcome!"

If every function had no relatives, you might have
an argument.  But if that were the case then no one
would ever define or use &optional or &rest or
keyword args, and those never would have been added
to Lisp in the first place.

(BTW, &rest is essentially just a shortcut for an
explicit list argument.  Some languages make you
pass a vector/sequence/list each time, even when
that's empty: [], "", ().)

Finally, perhaps the most common uses of &optional,
&rest, and keyword args are for defining a family
workhorse function, which is then used to define
other functions with fewer or no such args, which
serve particularly common use cases.

And often the most common use case, even for end
users, is just to call the workhorse function with
no such actual args.  IOW, the "family" function
is often, maybe even typically, defined so that it
can be used as is, with no such args, to provide a
useful default behavior.

Thus it has been, for decades.  And thus it will
continue to be...



reply via email to

[Prev in Thread] Current Thread [Next in Thread]