checking implementation defined and implementation dependent behaviour



Hi,

CLHS invites implementations to document the gaps it explicitly leaves
as "implementation defined" or "implementation dependent" behaviour.

Some times ago in this group, I talked about testing this. Now I've
come up with a few testcases. I've put the file that follows online
into the clisp CVS repository at
http://clisp.cvs.sourceforge.net/clisp/clisp/tests/unportable.tst

I also added a section about gaps (omissions?) in the CLHS,
and another about whether or not errors are actually signaled.
Depending on any of this is inherently unportable.

My findings surprised me. Did you expect (LOOP REPEAT 3.5 ...) to
exhibit differences among implementations?
Please see for yourself the examples in the file below.

I'd be happy if other cases were shown, if some documentation were
completed or if part of this were added to some implementation's
regressions tests.

Ideally, one should go through CLHS side by side with each
implementation's documentation and see whether the latter defines each
occurrence of "impl. defined" and "impl. dependent" from CLHS. I know
clisp's impnotes are quite complete in that regard, but I've not
checked any other implementation's documentation.

Ideally, results in the file (as a regression suite) should be added
only when an implementation documents a specific behaviour. I don't
consider it as something that should pin down observed behaviour in
the particular versions of cmucl (19c), sbcl (1.0.3.35), clisp (2.41)
and CormanLisp (2.0) I happened to use.

File copyright: Franz/Allegro's LLLGPL (ok with you?)
;; -*- Lisp -*-
;; Test unportable code of which some implementations specify the behaviour
;; These fall into 3 categories in ANSI-CL:
;; - "implementation defined",
;; - "implementation dependent" or
;; - "undefined consequences"
;; - none of the above, simply a gap in the spec
;; Use #-(or ...) to avoid implementations where the unportable form
;; may drop the bomb

;;;;
;;;; Implementation-defined
;;;;

;; 13.1.4.6 & 13.6
#+(and clisp unicode)
(digit-char-p #\KHMER_DIGIT_ZERO) ; #\U17e0
#+(and clisp unicode) 0

;; In CLISP, there are unicode digits beside 0-9 a-z yet they form no numbers
#+(and clisp unicode)
(type-of (read-from-string (string #\KHMER_DIGIT_ZERO)))
#+(and clisp unicode) SYMBOL


;;;;
;;;; Implementation-dependent
;;;;

;; 6.1.1.4 Whether initial value forms of for/as variables include
;; lexical environment of all loop variables or only preceding ones.
;; clisp changed its behaviour across versions

#-(or clisp)
(let ((vars '(1 2))) (loop for vars on vars collect (length vars)))
#+(or cmu sbcl cormanlisp) (2 1)

#-(or clisp)
(let ((vars '(1 2 3))) (loop for i from 0 below 5 for vars on vars collect (length vars)))
#+(or cmu sbcl cormanlisp) (3 2 1)

;; Whether the iteration constructs establish a new binding of var on
;; each iteration or whether it establishes a binding for var once at
;; the beginning and then assigns it on any subsequent iterations

;; Actually, CLISP does not guarantee the (3 3 3) or (2 2 2) result,
;; it just guarantees that it won't be (2 1 0), but rather (x x x),
;; because a single binding is assigned on each iteration.

(let (a)
(dotimes (i 3) (push (lambda () i) a))
(loop for x in a collect (funcall x)))
#+(or clisp cmu sbcl cormanlisp) (3 3 3)
#+(or) (2 1 0)

(let (a)
(dolist (i '(0 1 2)) (push (lambda () i) a))
(loop for x in a collect (funcall x)))
#+(or clisp) (2 2 2)
#+(or cmu sbcl) (2 1 0)
#+(or cormanlisp) (nil nil nil)


#|
;; 1.4.1.5 Coerce designator to function once or every time
(defun add-some (x) ; TODO not reproducible past first run
(defun add-some (x) (+ x 2))
(+ x 1))
add-some
;; ffi callback: coerce immediately, IIRC don't even accept name

#-(or)
(mapcar 'add-some '(1 2 3 4))
#+(or clisp cormanlisp) (2 4 5 6)
|#

#|
;; 3.2.5 error handler for type error in compile[-file]
(with-simple-restart (error "test handler")
(compile '(macrolet ((foo () (error "at compile-time")))
(foo))))
|#

;; 5.1.1.2 setf expander vs. setf function of standardized accessors
(fboundp '(setf car))
#+(or clisp) NIL
#+(or cmu sbcl cormanlisp) T


;;;;
;;;; Undefined Consequences
;;;;

;; 2.4.8.3
#-(or) (read-from-string "#3()")
#+(or CLISP) ERROR
#+(or sbcl cmu cormanlisp) #(nil nil nil)

;; 5.2
;; "The consequences are undefined if an attempt is made to transfer
;; control to an exit point whose dynamic extent has ended."


;;;;
;;;; Simply unspecified
;;;;

;; CLHS has a note on PROG where it is "explained" as (BLOCK (LET (TAGBODY ...))
;; whereas Mario Latendresse's paper on list comprehensions shows a macroexpansion
;; with the nesting (LET (BLOCK (TAGBODY ...))) -- what implementation was used?
;; Note that notes in ANSI-CL are not a binding part of the standard.

(block nil (prog ((x (return :outer-let))) (return :never)) (return :clhs))
#-cormanlisp :clhs
#+cormanlisp :outer-let

(dolist (i '(1 2 . 3) i))
ERROR

(loop for i in '(1 2 . 3) count t) ; for comparison, well-defined
ERROR ; 6.1.2.1.2 via ENDP

;;;;
;;;; Portable code, but care to depend on this?
;;;;

;; 6.1.9
;; "The clause repeat n is roughly equivalent to a clause such as
;; for downfrom (- n 1) to 0"
;; BTW, Iterate differs and uses ceiling instead.
(loop repeat 3.5 count t)
#+(or cmu) 3
#+(or clisp sbcl cormanlisp) 4

(loop for i downfrom (- 3.5 1) to 0 count t) ; for comparison, well-defined
3

;; "the concept [of length] does not make sense for dotted lists",
;; says ANSI-CL issue DOTTED-LIST-ARGUMENTS
(length '(1 2 . 3)) ; dotted list is not a sequence
ERROR ; how annoying

(list-length '(1 2 . 3))
ERROR ; agreed


;; Paul Dietz' ANSI testsuite (part of gcl) checks some border cases
;; http://cvs.savannah.gnu.org/viewcvs/gcl/ansi-tests/beyond-ansi/?root=gcl


Regards,
Jorg Hohle
Telekom/T-Systems Technology Center
.



Relevant Pages

  • Help choose a CL implementation!
    ... There are quite a lot of free CL implementations out there in the big ... From what I've gathered from the group, CLisp seems ... webcrawler, a data mining module, and the web interface. ...
    (comp.lang.lisp)
  • Re: Why Lisp is too hard for me to use
    ... my attempts of installing Garnet on ... Redhat led to a break of the Lispworks and CLISP installs. ... is documentation that comes with the product. ...
    (comp.lang.lisp)
  • Re: Regression test framework recommendation needed?
    ... I'm interested in this features: ... Documentation ... (might be some problems with CLisp) ... Franz Allegro 6.2 ...
    (comp.lang.lisp)
  • Re: Lisp w/out GC
    ... > commercial implementation, ... with writing a 3d game in Lisp, I doubt CLISP would be the best ... Also, to get the most out of any of the CL implementations, it's necessary ...
    (comp.lang.lisp)
  • Re: How to change peoples minds about LISP?
    ... > What you'd need is a reasonably documented system call/libc interface ... CLISP has both PCRE and POSIX regexps, ... documentation, ...
    (comp.lang.lisp)