Behaviour of PROCLAIM in initialization file(s)

Bug #655201 reported by Jānis Džeriņš
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Triaged
Medium
Unassigned

Bug Description

I have split up initialization files of common lisp implementations I use at the moment into two parts: things common to all implementations (like setting up ASDF paths) go into a common file (~/.common.lisp), and implementation specific things go into the respective files read by implementations. The common file is LOADed from the latter like so:

  (load (merge-pathnames ".common.lisp" (user-homedir-pathname)))

Now, while developing, I want to have high SAFETY and DEBUG settings, so I put the following proclamation in ~/.common.lisp:

  (proclaim '(optimize (safety 3) (debug 3)))

The unexpected part is that the effects of this proclamation _persist_ if they are in ~/.sbclrc, but _do_not_persist_ if they are in ~/.common.lisp file (as found out by sb-ext:describe-compiler-policy function). Wrapping the proclamation in an EVAL-WHEN also does not help.

Here is a test case (which most probably will have to be corrected):

(defun alists-same-p (a b &key (key-test 'eql) (value-test 'eql))
  (loop
     for (key . value) in a
     always (let ((cons (assoc key b :test key-test)))
              (and cons
                   (funcall value-test value (cdr cons))))))

(defun get-policy (&optional initfile)
  (read-from-string
   (with-output-to-string (stream)
     (run-program "/usr/local/bin/sbcl"
                  `("--noinform"
                    ,@(if initfile
                          (list "--userinit" initfile)
                          (list "--no-userinit"))
                    "--noprint"
                    "--eval" "(progn (write sb-c::*policy* :stream t) (finish-output t))")
                  :output stream
                  :wait t))))

(defun test ()
  (flet ((write-to-file (file-name form)
           (with-open-file (out file-name
                                :direction :output
                                :if-exists :overwrite
                                :if-does-not-exist :create)
             (write form :stream out))))
    (let* ((proclaim-file "proclaim.tmp")
           (load-file "load.tmp"))
      (write-to-file proclaim-file '(proclaim '(optimize (debug 3) (safety 3))))
      (write-to-file load-file `(load ,proclaim-file))
      (unwind-protect
           (let ((default-policy (get-policy nil))
                 (init-policy (get-policy proclaim-file))
                 (load-policy (get-policy load-file)))
             ;; This is not really a failure, just my lazyness of making a
             ;; generic-enough testcase.
             (assert (not (alists-same-p default-policy init-policy))
                     (default-policy init-policy)
                     "Assumed the default compiler policy is different from customised one, which is not true.")
             ;; This is what we really want to be true, but it will only work
             ;; if the previous assertion holds.
             (assert (alists-same-p init-policy load-policy)
                     (init-policy load-policy)
                     "Random CL user wanted~% ~S~%and~% ~S~%to be the same." init-policy load-policy))
        (delete-file proclaim-file)
        (delete-file load-file)))))

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

[15:51] <Krystof> I think that where people nowadays say (declaim ...) they really mean (eval-when (:compile-toplevel) (proclaim '(...)))
[15:51] <nikodemus> well, PROCLAIM is broken now. i think unbreaking it and making DECLAIM somewhat differently broken might be a win here :)
[15:52] <Krystof> I think I'd be happy with that
[15:53] <Krystof> (declaim ...) => (progn (eval-when (:compile-toplevel :execute) (something)) (eval-when (:load-toplevel) (something-else))) maybe
[15:53] <jsnell> you mean declaim having no :load-toplevel or :execute? that does not sound good
[15:53] <Krystof> I think I mean declaim optimize having no load-toplevel

Changed in sbcl:
importance: Undecided → Medium
status: New → Triaged
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.