[net.lang.lisp] Franz Lisp

bruce@godot.UUCP (Bruce Nemnich) (06/14/84)

In the 4.2bsd franz (I don't know about others), (random) has the 
extremely non-random property of alternating even and odd numbers.

To repeat, (loop for i from 1 to 20. collecting (random 2)).

I am not an expert on random-number algorithms, so if anyone has a good
fix, please let me know.
-- 
--Bruce Nemnich, Thinking Machines Corporation, Waltham, MA
  {decvax!cca,ihnp4!mit-eddie,allegra!ias}!godot!bruce, BJN@MIT-MC.ARPA

bruce@godot.UUCP (Bruce Nemnich) (06/14/84)

I just looked at the source, and (random) just calls rand(3) internally.
It is rand() which is alternating even and odd values.  random(3) doesn't
seem to have this problem, so I changed the call in 
/usr/src/ucb/lisp/franz/lam8.c to random().
-- 
--Bruce Nemnich, Thinking Machines Corporation, Waltham, MA
  {decvax!cca,ihnp4!mit-eddie,allegra!ias}!godot!bruce, BJN@MIT-MC.ARPA

ags@pucc-i (Seaman) (06/14/84)

>  In the 4.2bsd franz (I don't know about others), (random) has the 
>  extremely non-random property of alternating even and odd numbers.

Knuth (Vol. 2, Seminumerical Algorithms) makes the following observations
about random number generators of the linear congruential type:
(m = modulus, w = word size)

1. Using m = w has an enormous advantage in speed, since it avoids the
   need for a divide.

2. When m = w, the right-hand digits of the generated numbers are much less
   random than the left-hand digits (this explains the even-odd behavior).

3. A reasonable alternative is to use m = (w plus or minus 1), which makes
   the right-hand digits more random at the cost of time.

4. "In most applications, the low-order bits are insignificant, and the 
   choice m=w is quite satisfactory -- provided that the programmer using
   the random numbers does so wisely."  (this a direct quote)

The man entry for rand(3) points out that random(3) should be used in
new applications and that rand remains for compatibility.
-- 

Dave Seaman			"My hovercraft is full of eels."
..!pur-ee!pucc-i:ags

dennis@boulder.UUCP (Dennis Heimbigner) (12/21/84)

Does anyone know if Berkeley is still providing
franz lisp free of charge?  If so, who do I
contact to see about getting the latest version
(we have 38.79).

Dennis Heimbigner
dennis.boulder@csnet-relay

yuhan@ellie.UUCP (Albert Hanyong Yuhan) (12/17/85)

     We know that the function "pp" calls "pp-form" which calls again
various functions to pretty print value, propery, and/or function
definition of a symbol.  Pp or pp-form function is very important as
it is essential to converting lisp source code files into, and 
maintaining them in, human-readable forms.
     On Franz lisp, at least, running on VAX750 in Unix 4.2, currently,
"pp-form" does not work correctly if the object to be pretty printed
is a function definition whose function name contains a non-vcharacter
in it.  The bug is where the pretty printer prints the name of such a
function.  Weirdly, printing of the body of function is done correctly
if it has some special characters to be escaped.
     This bug is not trivial if a function is recursively defined, 
and its name contains a non-special character in its name, since
the head name of the function and the recursively invoked function
names of itself are now different because of this bug.


     I looked into /usr/src/lisp/pp.l , and have discovered why it
work not correctly.  The function "printdef" calls "princ" (which,
same as patom, strips off escape symbols for special characters)
rather than calling "print".  With this fix, my test showed that
it works O.K. concerning this matter.  I suppose that the system
has to be re-made.

     I am attaching a script with some comments added so that
the problem is well illustrated in a real lisp context.


==========================================================
Script started on Tue Dec 17 11:16:40 1985
{} lisp
  ** infns/load'ing of myfns/myload suppressed **
-> (load 'show.l)
[load show.l]
t
*****************************************************************
*
HERE YOU HAVE THE CONTENTS OF THE FILE
(def ident\'fun ; the function name contains an escaped quote
  (lambda (lst)
    (cond ((atom lst) lst)
          (t (cons (ident\'fun (car lst))
                   (ident\'fun (cdr lst))]
*
*****************************************************************

-> (print (getd 'ident\'fun))
(lambda (lst) (cond ((atom lst) lst) (t (cons (|ident'fun| (car lst)) (|ident'fun| (cdr lst))))))nil


-> (pp ident\'fun)
(def ident'fun
  (lambda (lst)
    (cond ((atom lst) lst)
          (t (cons (|ident'fun| (car lst)) (|ident'fun| (cdr lst)))))))

t
-> (pp-form (list 'def 'ident\'fun (getd 'ident\'fun)))
(def ident'fun
  (lambda (lst)
    (cond ((atom lst) lst)
          (t (cons (|ident'fun| (car lst)) (|ident'fun| (cdr lst)))))))nil
-> (pp-form (list 'DEF 'ident\'fun (getd 'ident\'fun)))
(DEF |ident'fun|
     (lambda (lst)
             (cond ((atom lst) lst)
                   (t (cons (|ident'fun| (car lst)) (|ident'fun| (cdr lst))))))
     )nil
*****************************************************************
*
THE ERROR IS THAT pp-form PRINTS FUNCTION NAMES WITH ESCAPE SYMBOLS
STRIPPED OFF WHEN THEY CONTAIN SOME SPECIAL CHARACTERS IN THEM.
*
*****************************************************************



*****************************************************************
*
NOW, SEE IT WORKS CORRECTLY AFTER MY FIX.
*
*****************************************************************
-> (load 'printdef.l)
[load printdef.l]
t
*****************************************************************
*
HERE YOU HAVE THE CONTENTS OF THE FILE
(def printdef
  (lambda (l lmar rmar)
    (cond ((and (zerop lmar)		; only if we're really printing a defn
                (zerop rmar)
                (cadr l)
                (atom (cadr l))
                (dtpr (caddr l))
                (null (cdddr l))
                (memq (caaddr l) '(lambda nlambda macro lexpr))
                (null (cdr (last (caddr l)))))
           (princ '|(| $outport$)
           (princ 'def $outport$)
           (princ '| | $outport$)
           (print (cadr l) $outport$)
           ******
MY FIX FROM princ INTO print TAKES CARE OF THE PROBLEM.
           (terpri $outport$)
           (princ '|  (| $outport$)
           (princ (caaddr l) $outport$)
           (princ '| | $outport$)
           (princ (cadaddr l) $outport$)
           (terpri $outport$)
           (mapc  '(lambda (x) ($prdf x 4 0)) (cddaddr l))
           (princ '|))| $outport$)
           t))))
*
*****************************************************************
-> (pp ident\'fun)
(def |ident'fun|
  (lambda (lst)
    (cond ((atom lst) lst)
          (t (cons (|ident'fun| (car lst)) (|ident'fun| (cdr lst)))))))

t
-> (pp-form (list 'def 'ident\'fun (getd 'ident\'fun)))
(def |ident'fun|
  (lambda (lst)
    (cond ((atom lst) lst)
          (t (cons (|ident'fun| (car lst)) (|ident'fun| (cdr lst)))))))nil
*****************************************************************
*
YOU SAW THAT IT WORKED CORRECTLY WITH THE FIX.
*
*****************************************************************
-> (exit)
No files updated. 
{} 

Script done on Tue Dec 17 11:22:39 1985

-- 
--------------
UUCP   : {cmc12,hao,harpo}!seismo!rochester!rocksvax!sunybcs!yuhan
         ...{allegra,decvax,watmath}!sunybcs!yuhan
CSNET  :  yuhan@buffalo
ARPA   :  yuhan%buffalo@csnet-relay
BITNET :  yuhan@sunybcs
--------------