~daanturo


#10 Missing command make-empty-file 2 years ago

on ~pkal/compat

"~daanturo" outgoing@sr.ht writes:

Thank you for your quick implementation.

Although I noticed that the original function is an interactive command for but for compat, it has been added without its interactive spec, was this intended?

Yes, Compat doesn't intend to provide any user-facing functionality.

#10 Missing command make-empty-file 2 years ago

Comment by ~daanturo on ~pkal/compat

Thank you for your quick implementation.

Although I notice that the original function is an interactive command but for compat, it has been added without the interactive spec, was this intended?

#10 Missing command make-empty-file 2 years ago

on ~pkal/compat

"~daanturo" outgoing@sr.ht writes:

Defined in Emacs 27.

Added in 6b7a3513dc9dce2e59ef8e11f73f2a011ea1ffeb.

#10 Missing command make-empty-file 2 years ago

Ticket created by ~daanturo on ~pkal/compat

Defined in Emacs 27.

#9 Invalid function: if-let when loading subr-x on Emacs 24.3 2 years ago

on ~pkal/compat

"~daanturo" outgoing@sr.ht writes:

Note the eval-after-load 'subr-x part, it will be called by the require advice.

(funcall (eval
	  
	  `(funcall ',(lambda nil
	                (defalias 'if-let* #'compat--if-let*)))
	  
	  t))

Invalid function: if-let* : looks like the error with if-let.

The background for what is happening here is to be found in https://nullprogram.com/blog/2018/02/22/ (as referenced in `compat--generate-default').

What this indicates to me is that the advice on require might be mistaken in the assumptions it makes on the structure of `after-load-alist' -- at least how it used to look like on Emacs 24.3.

You mentioned having a fix that appeared to work on your system, right? Could you formalise that into a patch?

#9 Invalid function: if-let when loading subr-x on Emacs 24.3 2 years ago

Comment by ~daanturo on ~pkal/compat

The expanded macro for if-let* as mentioned above (I forgot to include it):

(progn
  (defmacro compat--if-let*
    (varlist then &rest else)
    "[Compatibility macro for `if-let*']\n\nBind variables according to VARLIST and evaluate THEN or ELSE.\nThis is like `if-let' but doesn't handle a VARLIST of the form\n(SYMBOL SOMETHING) specially."
    (declare
     (indent 2)
     (debug
      ((&rest
	[&or symbolp
	     (symbolp form)
	     (form)])
       body)))
    (let
	((empty
	  (make-symbol "s"))
	 (last t)
	 list)
      (dolist
	  (var varlist)
	(push
	 `(,(if
		(cdr var)
		(car var)
	      empty)
	   (and ,last ,(or
			(cadr var)
			(car var))))
	 list)
	(when
	    (or
	     (cdr var)
	     (consp
	      (car var)))
	  (setq last
		(caar list))))
      `(let* ,(nreverse list)
	 (if ,(caar list)
	     ,then ,@else))))
  (when
      (and t
	   (not
	    (fboundp 'if-let*)))
    (eval-after-load 'subr-x
      `(funcall ',(lambda nil
		    (defalias 'if-let* #'compat--if-let*))))))

#9 Invalid function: if-let when loading subr-x on Emacs 24.3 2 years ago

Comment by ~daanturo on ~pkal/compat

Note the eval-after-load 'subr-x part, it will be called by the require advice.

(funcall (eval
	  
	  `(funcall ',(lambda nil
	                (defalias 'if-let* #'compat--if-let*)))
	  
	  t))

Invalid function: if-let* : looks like the error with if-let.

#9 Invalid function: if-let when loading subr-x on Emacs 24.3 2 years ago

on ~pkal/compat

"~daanturo" outgoing@sr.ht writes:

Could you macro-expand the definition the definition in compat-25.el for me to see if it is doing anything unusual?

(if
    (and t
	 (not
	  (fboundp 'if-let)))
    (progn
      (defmacro if-let
	(spec then &rest else)
	"[Compatibility macro for `if-let']\n\n:realname" compat--if-let :feature 'subr-x
	(declare
	 (indent 2)
	 (debug
	  ([&or
	    (symbolp form)
	    (&rest
	     [&or symbolp
		  (symbolp form)
		  (form)])]
	   body)))
	(when
	    (and
	     (<=
	      (length spec)
	      2)
	     (not
	      (listp
	       (car spec))))
	  (setq spec
		(list spec)))
	`(compat--if-let* ,spec ,then ,(macroexp-progn else)))))

This seems fine, what about if-let*? That is being used here (because the two macros are related), and all the "heavy lifting" is done in that macro.

#9 Invalid function: if-let when loading subr-x on Emacs 24.3 2 years ago

Comment by ~daanturo on ~pkal/compat

Could you macro-expand the definition the definition in compat-25.el for me to see if it is doing anything unusual?

(if
    (and t
	 (not
	  (fboundp 'if-let)))
    (progn
      (defmacro if-let
	(spec then &rest else)
	"[Compatibility macro for `if-let']\n\n:realname" compat--if-let :feature 'subr-x
	(declare
	 (indent 2)
	 (debug
	  ([&or
	    (symbolp form)
	    (&rest
	     [&or symbolp
		  (symbolp form)
		  (form)])]
	   body)))
	(when
	    (and
	     (<=
	      (length spec)
	      2)
	     (not
	      (listp
	       (car spec))))
	  (setq spec
		(list spec)))
	`(compat--if-let* ,spec ,then ,(macroexp-progn else)))))

The mentioned mirror was from https://elpamirror.emacs-china.org/ , although I don't live in China.

#9 Invalid function: if-let when loading subr-x on Emacs 24.3 2 years ago

on ~pkal/compat

"~daanturo" outgoing@sr.ht writes:

On Emacs 24.3.1/CentOS, when I try load subr-x, this error appears:

compat--require: Invalid function: if-let

That is an unusual error message...

Reproduction steps from emacs -q:

;; -*- lexical-binding: t; -*-

(require 'package)

(package-initialize)

;; For unknown reasons I can't reach the official elpa.gnu.org on CentOS 7 container
(setq package-archives '(("gnu" . "http://1.15.88.122/gnu/")))

(package-refresh-contents)

(unless (package-installed-p 'nadvice) (package-install 'nadvice))
(unless (package-installed-p 'compat) (package-install 'compat))

(require 'nadvice)

(require 'compat)

(require 'subr-x)

This looks fine. Is the mirror up to date?

Backtrace:

Debugger entered--Lisp error: (invalid-function if-let)
  if-let()
  funcall(if-let)
  (let ((form (car --dolist-tail--))) (funcall (eval form t)) (setq --dolist-tail-- (cdr --dolist-tail--)))
  (while --dolist-tail-- (let ((form (car --dolist-tail--))) (funcall (eval form t)) (setq --dolist-tail-- (cdr --dolist-tail--))))
  (let ((--dolist-tail-- (cdr entry))) (while --dolist-tail-- (let
((form (car --dolist-tail--))) (funcall (eval form t)) (setq
--dolist-tail-- (cdr --dolist-tail--)))))
  (let ((load-file-name nil)) (let ((--dolist-tail-- (cdr entry)))
(while --dolist-tail-- (let ((form (car --dolist-tail--))) (funcall
(eval form t)) (setq --dolist-tail-- (cdr --dolist-tail--))))))
  (let ((entry (assq feature after-load-alist))) (let ((load-file-name
nil)) (let ((--dolist-tail-- (cdr entry))) (while --dolist-tail-- (let
((form (car --dolist-tail--))) (funcall (eval form t)) (setq
--dolist-tail-- (cdr --dolist-tail--)))))))
  (if (eq feature (quote subr-x)) (let ((entry (assq feature
after-load-alist))) (let ((load-file-name nil)) (let ((--dolist-tail--
(cdr entry))) (while --dolist-tail-- (let ((form ...)) (funcall (eval
form t)) (setq --dolist-tail-- (cdr --dolist-tail--))))))) (apply
oldfun feature args))

Looks like it's related to this:

(compat-advise require (feature &rest args)
  "Allow for Emacs 24.x to require the inexistent FEATURE subr-x."
  ;; As the compatibility advise around `require` is more a hack than
  ;; of of actual value, the highlighting is suppressed.
  :no-highlight t
  (if (eq feature 'subr-x)
      (let ((entry (assq feature after-load-alist)))
        (let ((load-file-name nil))
          (dolist (form (cdr entry))
            (funcall (eval form t)))))
    (apply oldfun feature args)))

Inspecting after-load-alist:

(subr-x
 (if load-file-name
     (let ((fun (make-symbol "eval-after-load-helper")))
       (fset fun `(lambda (file)
                    (if (not (equal file ',load-file-name))
                        nil
                      (remove-hook 'after-load-functions ',fun)
                      ,'(funcall '(closure (t) nil
                                   (funcall
                                    '(closure (t) nil
                                      (defalias 'if-let #'compat--if-let))))))))
       (add-hook 'after-load-functions fun))
   (funcall '(closure (t) nil
              (funcall
               '(closure (t) nil
                 (defalias 'if-let #'compat--if-let)))))))
(funcall '(closure (t) nil (funcall '(closure (t) nil (defalias 'if-let #'compat--if-let)))))
=> if-let

(eval form t)
=>if-let

(funcall 'if-let)
=> Error!

It seems to be fixed if I change (funcall (eval form t)) to (eval form t) only.

I will have to take some time to take a look at what could be going wrong here. I suspect this might be an issue in compat-macs.el and code being generated when defining if-let... Could you macro-expand the definition the definition in compat-25.el for me to see if it is doing anything unusual?