sellout/external-program

CMUCL: external-program:start Function with declared result type NIL returned:

Closed this issue · 4 comments

cmu-20c_release-20c__20c_unicode_-linux-x86.
quicklisp 2012-07-03

  • (external-program:start "echo" '("hello"))

Function with declared result type NIL returned:
(PCL:FAST-METHOD EXTERNAL-PROGRAM:START (T T))
[Condition of type KERNEL:SIMPLE-CONTROL-ERROR]

Restarts:
0: [ABORT] Return to Top-Level.

Debug (type H for help)

("LAMBDA (.KEYARGS-START. .VALID-KEYS. G3150)" # #
"echo" ("hello") ...)
Source: (FUNCALL (THE FUNCTION #'(PCL:FAST-METHOD EXTERNAL-PROGRAM:START #))
(PCL::FAST-METHOD-CALL-PV-CELL #:G3150)
(PCL::FAST-METHOD-CALL-NEXT-METHOD-CALL #:G3150)
PCL::.ARG0.
...)

I can reproduce this with cmucl 21a. It's related to issue #31, I believe. The structure of the external-program package is as follows: All the potentially available functions are implemented as dummies using defgeneric in external-program.lisp. Some of the functions are then redefined (and not specialised because no constraints are put in place) using defmethod in the implementation specific files. How these redefinitions are handled appears to be implementation-specific. The dummy code

  (:method (program args &rest rest)
    (declare (ignore program args rest))
    (error "This CL implementation does not support START."))

in the start function from external-program.lisp prompts cmucl to declare "start returns nil". When start is then redefined in cmucl.lisp, the return type is not updated, leading to the above failure.

The issue does not occur with run because here both the dummy code and the redefinition return nil.

Interesting. To me it looks like a CMUCL bug, what do you think?

To be honest, I simply don't know enough about defgeneric, defmethod, and redefinitions. I wouldn't be surprised if redefining a function led to undefined behaviour and thus into the world of nasal demons, so that CMUCL is really free to do whatever it desires.

This could be fixed by replacing the defgeneric/defmethod dance from external-program.lisp and the implementation-specific files with a single file full of defuns whose bodies ooze with #+cmucl etc.. But that would be quite a bit of work.

There is, as a matter of fact, already a bug at

https://gitlab.common-lisp.net/cmucl/cmucl/issues/23

for this. I'd post the considerably reduced example of

(defgeneric start (program args &key key)
  (:method (program args &rest rest)
    (declare (ignore program args rest))
    (error "This CL implementation does not support START.")))

(defmethod start (program args &rest rest)
  (apply #'ext:run-program program args :wait nil rest))

(start "cat" nil)

there but I don't have an account that would allow me to do that.

Update: I have an account now and I'm posting the code there as well.