From: K D Rigotti
Subject: Shallow Binding
Date: 
Message-ID: <KDR.90Nov23181533@pelican.doc.ic.ac.uk>
I'm looking for a *very* small program to show shallow binding in action.
Any suggestions? 

Ideally it should work for all versions of lisp including GNU Emacs lisp 
(if that has shallow binding??)

Thanks in advance.

Kevin

----------------------------
"Information makes the world go around, money just oils the bearings"
From: Simon Leinen
Subject: Re: Shallow Binding
Date: 
Message-ID: <SIMON.90Nov26185913@lisp5.first.gmd.de>
>>>>> On 23 Nov 90 18:15:33 GMT, ···@doc.ic.ac.uk (K D Rigotti) said:

Kevin> I'm looking for a *very* small program to show shallow binding
Kevin> in action.  Any suggestions?

I don't wonder that no-one posted a reply yet.  `Shallow binding' and
`deep binding' are different implementations of special binding, but
they are supposed to be semantically equivalent.  If you want to
decide whether your particular Lisp implementation uses shallow or
deep binding, you have to look at special variable access speeds.

The following little benchmark compares the access to a (special)
variable on top of the binding stack vs. to one `covered' by many
later bindings.  In a deep binding implementation, the access to the
covered binding should be slower.  Unfortunately, all our Lisps use
shallow binding (KCL, Allegro, and Lucid Lisp).  Lisp implementations
that are designed for multiprocessing may use deep binding (I think
QLisp does) because context switching is faster.  There may be
mysterious hashing techniques for deep binding implementations that
could defeat this test.

The program follows on the next page.
-- 
Simon.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; File Name:	  binding.cl
;;; Description:  Check whether shallow or deep binding is used.
;;; Author:	  Simon Leinen (·····@lisp5)
;;; Date Created: 26-Nov-90
;;; RCS $Header$  
;;; RCS $Log$	  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#| Use this in Emacs Lisp:

(defmacro time (&rest forms)
  (` (let ((-start-time- (the-time)))
       (prog1 
	   (progn (,@ forms))
	 (let ((-end-time- (the-time)))
	   (princ (format "Real time: %s" (- -end-time- -start-time-))))))))

|#

(defvar *a* 1)
(defvar *b* 2)

(defun with-many-bindings-for-*b* (fn n-bindings n-calls)
  (with-many-bindings-for-*b*-aux fn n-bindings n-calls))

(defun with-many-bindings-for-*b*-aux (fn n-bindings n-calls)
  (if (= n-bindings 0)
      (dotimes (i n-calls)
	(funcall fn))
    (let ((*b* n-bindings))
      (with-many-bindings-for-*b*-aux fn (- n-bindings 1) n-calls))))

(defun special-ref-*a* () *a*)
(defun special-ref-*b* () *b*)

(princ "Bottom of binding stack: ")
(time (with-many-bindings-for-*b* (function special-ref-*a*) 50 100000))
(princ "Top of binding stack: ")
(time (with-many-bindings-for-*b* (function special-ref-*b*) 50 100000))
(princ "If the two timings differ SIGNIFICANTLY, your machine seems
to use deep binding.")