emacs-devel
[Top][All Lists]
Advanced

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

optional argument defaults in `cl-defun' vs old way - warning, discrepan


From: Emanuel Berg
Subject: optional argument defaults in `cl-defun' vs old way - warning, discrepancy!
Date: Fri, 06 Oct 2023 04:30:54 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

The other day I said the CL way, as implemented in Elisp in
cl-lib, was superior for setting the defaults for
optional arguments, which is done with `cl-defun', as opposed
to the old way, using `defun' and then `or', `unless', or
`let' with a check for a nil value.

That comment refered to the cl-defun syntax which, by all
means, is more neat and compact. But it turns out, those
methods are not equivalent - check out the code below!

After changing 60 defun to cl-defun, maybe I have to change it
all back since the Elisp way of thinking - where nil means
"unset", i.e. use the default - that was the way I was
thinking when I wrote the code, and it has worked ever since.
And just now I run into an error which brought this all to
my attention.

But in a way the CL way is better even here, since explicit
nil really means nil, so one could use that as an optional
argument value.

But then, how would that mix with other code, evaluating to
nil and then being sent as argument. Is that an unset optional
argument which should get a default value, or is it a
set value, just as an explicit nil, only this time not written
by a programmer, but computed by a program, written by
a programmer?

Bottom line, the Elisp way is preferable since it is
consistent - see the three (1 2) results below, compared to
the CL ditto, with one (1 2) and two (nil nil).

;;; -*- lexical-binding: t -*-
;;
;; this file:
;;   https://dataswamp.org/~incal/emacs-init/geh.el

(require 'cl-lib)

(cl-defun test-opt-args-cl (&optional (one 1) (two 2))
  (interactive (list nil nil))
  (message "%s" (list one two)) )

;; (test-opt-args-cl)                      ; (1 2)
;; (test-opt-args-cl nil nil)              ; (nil nil)
;; (call-interactively #'test-opt-args-cl) ; (nil nil)

(defun test-opt-args (&optional one two)
  (interactive (list nil nil))
  (or one (setq one 1))
  (or two (setq two 2))
  (message "%s" (list one two)) )

;; (test-opt-args)                      ; (1 2)
;; (test-opt-args nil nil)              ; (1 2)
;; (call-interactively #'test-opt-args) ; (1 2)

-- 
underground experts united
https://dataswamp.org/~incal




reply via email to

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