help-gnu-emacs
[Top][All Lists]
Advanced

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

RE: [External] : Re: How to make M-x TAB not work on (interactive) decla


From: Drew Adams
Subject: RE: [External] : Re: How to make M-x TAB not work on (interactive) declaration?
Date: Tue, 17 Jan 2023 22:20:47 +0000

> > > Any number means also no argument? To me that is not clear.
> >
> > That's why I pointed out that _zero is a number_.
> 
> Those are big words :-)
> 
> Minus one is also a number, but we'd be hard pressed to come
> up with a function taking minus one arguments. Three-quarters,
> the square root of two and pi are numbers. Arguably, "the"
> Chaitin constant [1] (actually there are many of them)is also
> a number.
> 
> I think the manual wants to say "natural number" and just
> says "number", but that's OK, because it is directed at humans,
> and we humans are usually better at disambiguating given a
> context than at staying awake in front of long and boring texts.
> 
> Arguably, "zero or more" might be clearer here, but I don't
> know (after all, the square root of two is bigger than zero,
> too).

1. I said "More precisely: zero or more" in my
second reply to this thread:

  Not to belabor this... but perhaps you're missing
  understanding _zero as a number_, in "number of
  arguments".  More precisely: zero or more args.

2. There's no need to say anything more than
"any number of arguments" - the number of args
has to be zero or more, because we allow nullary
functions.

3. If someone has a hard time with functions of
variable arity, then just pretend you have this
equivalent: replace each Lisp function that
accepts a variable number of args with a function
that accepts a _list arg_ (whose elements are
what would be the variable number of args) in
their place.

Most functional, logic, etc. languages just use
a list arg - same difference.  There's nothing
magic about variable-arity functions - they're
really just functions that accept a list arg.

________________________
Jean Louis:

Imagine that functions such as + and * accept a
single _list_ argument, _instead of_ a variable
number (including zero) of arguments.

Can you see that such a function is useful?
Can you see that it's general - and that you
can even pass it the empty list or a singleton
list?

OK, let's look into that...

Such functions would cdr down the list argument
adding/multiplying the next number from the list
by the sum/product accumulated so far.

The functions would have to start with _some_
initial value for the accumulated sum/product.

If they use simple recursion, applying the same
operation at each level (add/multiply next number
by accumulated sum/product), they need to start
by initializing the sum/product.

For them to seemingly start with the first number
in the list they'd need to initialize instead
within the general operation performed at each
level, which would require extra fiddling, to
(1) test whether it's the first time through
and if so then (2) initialize.

It's far simpler and more general for them to
initialize at the top level: _before_ dealing
with the first arg.  The obvious init-value
choice for + is zero, and the obvious choice
for * is one.  That's all that's going on.

Or, what initial values would you have such
functions start with, for their accumulating
sum/product?  Clearly you'd want + to start
with 0 and * to start with 1, no?

Now, what value would you have + return for a
singleton list - e.g., (42)?  What value would
you have it return for the empty list, ()?  I
think you'd want (+ '(42)) to return 42 and
(+ ()) to return 0, no?  If so, why?  (That's
the question others have been answering by
mentioning additive/multiplicative identities.)

Now, since Lisp allows variable-arity functions,
there's no reason to insist that an _explicit
list_ be passed, instead of just the elements
(numbers, here) that would be in that list.
That's the shortcut that Lisp takes: don't
bother to wrap the numbers in a list.

(Creating lists is costly: consing, and then
later garbage-collecting all those conses.
Using an explicit list gains us nothing.)

Now consider functions such as min and max.

There's no minimum or maximum number, so they
clearly can't be called with _no_ args.  But
they can be called with a _single_ arg, and,
like + and *, their definitions return that
number - it's _not compared_ with any other
number, so how can we say it's the smallest
or largest?  It's the smallest/largest of the
numbers provided - no comparison is needed.

And as for doc, note that the doc tells us
that there _must be at least one_ arg.  Well,
it doesn't tell you this in so many words (it
could; perhaps it should).  But the function
signature is part of its doc, and `C-h f max'
tells us:
___
max is a built-in function in ‘C source code’.

(max NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS)

Return largest of all the arguments (which must be numbers or markers).
The value is always a number; markers are converted to numbers.
___

"NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS"
tells you the function requires an argument,
and it accepts more than one arg.  If it
didn't require at least one arg then the
signature would be "&rest NUMBERS-OR-MARKERS ".
___

If you don't like Lisp's predefined +, *, etc.
it's simple enough to roll your own, and make
them _require at least 2_ arguments.  E.g.:

(defmacro my-plus (n1 n2 &rest ns)
  "..."
  `(+ ,n1 ,n2 ,@ns))

And if you prefer to handle the identity
element explicitly, here's how to define a
`plus' function that does what + does, using
a more general, higher-order function, called
`reduce', aka `foldr':

(defun foldr (f init xs)
  (if (null xs)
      init
    (funcall f (car xs) (foldr f init (cdr xs)))))

(defun plus (&rest ns)
  (foldr #'my-plus 0 ns))

That is, Elisp's + (named `plus' here), could
be defined based on your `my-plus', using
`foldr', passing it 0 (additive identity) as
the initial element, argument INIT.

`plus' is just (1) your `my-plus', which
_requires two numbers_, (2) _folded_ into an
_explicit list_ of numbers - a list that
_can_ be empty or a singleton.

Elisp's + acts the same as that `plus', but
it's coded in C, and it creates no useless
intermediate list (to be garbage-collected).
________________________

Back to Tomas's mail...

> Now mathematicians don't agree on whether 
> zero is a natural number. 

That's just saying that they define "natural
number" differently.

> The faculty I studied in started counting from zero,
> but I've seen faculties which count from one. I once asked
> a friend of mine teaching at one uni, and he told me faculties
> having a strong mathematical logic department tended to start
> with zero.

This is a red herring here.  "Natural", "whole",
"countable"/"counting" numbers are just names.
Different definitions are sometimes given to the
names, yes.

When talking about the number of args a Lisp
function accepts, or the number of elements a list
can have, the counting is clearly zero-based: a
function can be nullary, and a list can be empty:
().  (Likewise, a string or a vector.)

> So zero may be a number or not, at least if you read "number"
> as "natural number", and you ask a mathematician :)

And if you read "number" as "triangular number"
then it's not.  This is really irrelevant here.
Clearly, if you read "number" as some set that
_excludes zero_, then zero doesn't belong to it.

Lisp functions can be nullary: take no arguments.
How many arguments?  Zero.  What's the _number_
of arguments a nullary function takes?  Zero.

reply via email to

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