Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MacLisp for LINUX?

107 views
Skip to first unread message

Felix E. Klee

unread,
Mar 19, 2002, 4:56:14 PM3/19/02
to
Hi,

is MacLisp available for LINUX?

Felix

Barry Margolin

unread,
Mar 19, 2002, 4:15:27 PM3/19/02
to
In article <3C97B3FE...@inka.de>,

Felix E. Klee <felix...@inka.de> wrote:
>is MacLisp available for LINUX?

MacLisp is a pretty dead dialect of Lisp. It was only ever available for
PDP-10 and Multics, and no work on it has been done for at least 15 years.
Are you sure this is what you're looking for? Hint: the "Mac" prefix had
nothing to do with Macintosh computers (MacLisp was in use several years
before Jobs and Wozniak constructed the first Apple computer in their
garage).

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Daniel Barlow

unread,
Mar 19, 2002, 6:55:48 PM3/19/02
to
Barry Margolin <bar...@genuity.net> writes:

> In article <3C97B3FE...@inka.de>,
> Felix E. Klee <felix...@inka.de> wrote:
> >is MacLisp available for LINUX?
>

> Are you sure this is what you're looking for? Hint: the "Mac"
> prefix had

While echoing Barry's point here, I'd point out that there are PDP-10
emulators which will run on Linux, so if you really want to try it you
could do it that way. Google

http://www.google.com/search?q=linux+pdp%2D10+its

returns more than a few relevant-looking pages


-dan

--

http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources

Erik Naggum

unread,
Mar 19, 2002, 7:02:24 PM3/19/02
to
* "Felix E. Klee" <felix...@inka.de>

| is MacLisp available for LINUX?

Somewhat tongue-in-cheek: see GNU Emacs Lisp.

///
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

Felix E. Klee

unread,
Mar 20, 2002, 3:09:23 AM3/20/02
to
Erik Naggum wrote:
> | is MacLisp available for LINUX?
>
> Somewhat tongue-in-cheek: see GNU Emacs Lisp.

Yes, I read that EMACS Lisp has its roots in MacLisp. However, it doesn't
seem to be 100% compatible. I have an old book about MacLisp here and it
says that eg. the add function is called
ADD
wheras in EMACS Lisp it is called
+

Felix

Barry Margolin

unread,
Mar 20, 2002, 10:46:07 AM3/20/02
to
In article <a79g3a$jb7b7$1...@ID-84243.news.dfncis.de>,

Felix E. Klee <felix...@inka.de> wrote:
>Erik Naggum wrote:
>> | is MacLisp available for LINUX?
>>
>> Somewhat tongue-in-cheek: see GNU Emacs Lisp.
>
>Yes, I read that EMACS Lisp has its roots in MacLisp. However, it doesn't
>seem to be 100% compatible. I have an old book about MacLisp here and it
>says that eg. the add function is called
> ADD

Actually, it was called PLUS, I believe.

>wheras in EMACS Lisp it is called
> +

Maclisp also had that, but it was for fixnums only, whereas PLUS was
generic (like Common Lisp's +).

Christopher C. Stacy

unread,
Mar 20, 2002, 5:03:15 PM3/20/02
to
>>>>> On Wed, 20 Mar 2002 15:46:07 GMT, Barry Margolin ("Barry") writes:
>> an old book about MacLisp here and it says that
>> eg. the add function is called ADD

Barry> Actually, it was called PLUS, I believe.

>> wheras in EMACS Lisp it is called +

Barry> Maclisp also had that, but it was for fixnums only,
Barry> whereas PLUS was generic (like Common Lisp's +).

Yes, as shown in this example (under RedHat Linux):

MD ITS.1647. DDT.1545.
TTY 11
You're all alone, Fair share = 9%
cstacy$0u--Mail--Postponed
*
lisp^K!
MacLISP.2149

(setq x 23409823049823094820398402938409283098234)
23409823049823094820398402938409283098234

(plus x 1)
23409823049823094820398402938409283098235

(plus x x)
46819646099646189640796805876818566196468

(+ x 1)
;23409823049823094820398402938409283098234 UNACCEPTABLE NUMERIC VALUE

;BKPT WRNG-TYPE-ARG


50074) XCT 11 :kill
*:date
THURSDAY, MARCH 20, 1902 04:56:15 PM

:KILL

Donald Fisk

unread,
Mar 20, 2002, 12:05:44 PM3/20/02
to

You and Daniel Barlow have beaten me to it -- Maclisp runs
on ITS which runs on Ken Harrenstien's PDP-10 simulator,
which runs on Linux.

I run it at home, and have written a certain well-known game,
which goes by the name of ITSTER, in Maclisp (340 lines).
Is anyone interested in my posting the source here, either
for running at home on KLH-10 or just to see what Maclisp
looks like?

--
Le Hibou
You know you've been hacking too long if, when someone
asks you if you have a son, you reply, "No, but I've
got a Symbolics 3630".

Donald Fisk

unread,
Mar 20, 2002, 12:09:55 PM3/20/02
to
Erik Naggum wrote:
>
> * "Felix E. Klee" <felix...@inka.de>
> | is MacLisp available for LINUX?
>
> Somewhat tongue-in-cheek: see GNU Emacs Lisp.

This is a reference to dynamic scoping in Maclisp and
ELisp, as opposed to the lexical scoping that Common Lisp
and Scheme have.

> ///

Thomas F. Burdick

unread,
Mar 20, 2002, 8:50:11 PM3/20/02
to
Donald Fisk <hibou000...@enterprise.net> writes:

> Erik Naggum wrote:
> >
> > * "Felix E. Klee" <felix...@inka.de>
> > | is MacLisp available for LINUX?
> >
> > Somewhat tongue-in-cheek: see GNU Emacs Lisp.
>
> This is a reference to dynamic scoping in Maclisp and
> ELisp, as opposed to the lexical scoping that Common Lisp
> and Scheme have.

Probably not /just/ that. Obarrays, too, off the top of my head.

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Dennis Marti

unread,
Mar 20, 2002, 10:35:38 PM3/20/02
to
In article <3C98C168...@enterprise.net>,
Donald Fisk <hibou000...@enterprise.net> wrote:

> Is anyone interested in my posting the source here, either
> for running at home on KLH-10 or just to see what Maclisp
> looks like?

Yes. I'm interested in seeing the source. If you don't want to post it
here, mail it to me and I'll put it on a web site. (Or not.)

Dennis

Erik Naggum

unread,
Mar 21, 2002, 5:17:43 AM3/21/02
to
* Donald Fisk

| This is a reference to dynamic scoping in Maclisp and ELisp, as opposed
| to the lexical scoping that Common Lisp and Scheme have.

No, it is not. Sheesh, some people.

Donald Fisk

unread,
Mar 21, 2002, 7:34:45 PM3/21/02
to

See below.

There's a pro-lisp point to be made here: the equivalent C code, on
Vadim Gerasimov's web site, is around 900 lines, around 3 times as long.
Mine was written independently of this, but it should do pretty much
the same thing, though not exactly. Mine is `the full monty', except
for levels (speeding up as your score goes above a threshold), the
reason
for this being that you don't get the speed necessary for them on the
simulator.

;;; -*-LISP-*-
;;;
;;; Copyright (C) 2002 Donald Fisk
;;;
;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2 of the License, or
;;; (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, write to the Free Software
;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
;;; USA

;;;; The original game was written Alexey Pajitnov, Dmitry Pavlovsky
;;;; and Vadim Gerasimov. This implementation is independent of it,
;;;; based on a specification I arrived at through playing the game
;;;; often. It is written in Maclisp for ITS. To run it, start
;;;; Maclisp `:LISP' and type `(load 'itster)' and then `(itster)' at
;;;; the prompt.

;;;; (rotation x y) contains the coordinates that the tile at (x . y) is
;;;; rotated to, relative to the top left corner of the 4x4 grid
;;;; containing the tile.

(array rotation t 4 4)

(defun init-rotation ()
(do ((x 0 (1+ x)))
((= x 4))
(do ((y 0 (1+ y)))
((= y 4))
(store (rotation x y) (cons (- 3 y) x)))))

(array shapes t 7)

(defun init-shapes ()
(store (shapes 0) '((0 . 1) (1 . 1) (2 . 1) (3 . 1)))
(store (shapes 1) '((0 . 1) (1 . 1) (2 . 1) (1 . 2)))
(store (shapes 2) '((0 . 1) (1 . 1) (2 . 1) (2 . 2)))
(store (shapes 3) '((0 . 1) (1 . 1) (1 . 2) (2 . 2)))
(store (shapes 4) '((1 . 1) (2 . 1) (1 . 2) (2 . 2)))
(store (shapes 5) '((2 . 1) (3 . 1) (1 . 2) (2 . 2)))
(store (shapes 6) '((2 . 1) (0 . 2) (1 . 2) (2 . 2))))

;;;; *current-shape* (i.e. the one currently falling) is a list of the
;;;; coordinates of its tiles. *x* and *y* are the coordinates of the
top
;;;; left corner of the 4x4 grid the shape is in. The grid is useful
when
;;;; calculating the initial position of the shape, and when rotating
it.

(defvar +grid-x+ 10.)
(defvar +grid-y+ 5)
(defvar +num-columns+ 10.)
(defvar +num-rows+ 22.)
(defvar *current-shape*)
(defvar *next-shape*)
(defvar *x*)
(defvar *y*)
(defvar *score*)

;;;; *heap* initially stores the positions of imaginary tiles at the
;;;; perimeter of the rectangle the shapes fall in. During the game,
;;;; new tiles are added to heap when shapes land, and tiles are deleted
;;;; from heap when rows are completely filled.

(defvar *heap*)

(defun init-heap ()
(setf *heap* '())
;; Push on tiles to mark the perimeter of the grid. The y coord of
;; the last tile pushed = +num-rows+. We can use this to tell which
tiles
;; fell and which tiles are perimeter markers.
(do ((y 0 (1+ y)))
((= y +num-rows+))
(push (cons -1 y) *heap*)
(push (cons +num-columns+ y) *heap*))
(do ((x 0 (1+ x)))
((= x +num-columns+))
(push (cons x +num-rows+) *heap*)))

(defun make-random-shape ()
(mapcar #'(lambda (tile)
(cons (+ *x* (car tile))
(+ *y* (cdr tile))))
(shapes (random 7))))

(defun print-next-shape ()
(cursorpos 0 (* 2 +grid-x+))
(princ "Next:")
(draw-shape (mapcar #'(lambda (tile)
(cons (car tile) (- (cdr tile) 5)))
*next-shape*)))

(defun get-new-current-shape ()
(setf *x* 3 *y* 0)
(if (boundp '*next-shape*)
(clear-shape (mapcar #'(lambda (tile)
(cons (car tile) (- (cdr tile) 5)))
*next-shape*))
(setf *next-shape* (make-random-shape)))
(setf *current-shape* *next-shape* *next-shape* (make-random-shape))
(print-next-shape)
*current-shape*)

;;; Tries to move shape one column left (x-move = -1), one column right
;;; (x-move = 1) or one row down (y-move = 1).
;;; Returns NIL on failure.
(defun move-shape (x-move y-move)
;; First, compute the new positions of the tiles.
(let ((new-shape (mapcar #'(lambda (tile)
(cons (+ x-move (car tile))
(+ y-move (cdr tile))))
*current-shape*)))
;; See if any new positions are on the heap.
(do ((tiles new-shape (cdr tiles)))
((or (null tiles)
;; New tile position already on heap?
(member (car tiles) *heap*))
(if (null tiles)
;; No new tile positions on heap -- move it (and return
;; new value of *y*).
(setf *current-shape* new-shape
*x* (+ x-move *x*) *y* (+ y-move *y*))
;; Fail -- do nothing and return NIL.
NIL)))))

;;; Tries to rotate shape. Returns NIL on failure.
(defun rotate-shape ()
(let ((new-shape (mapcar #'(lambda (tile)
;; Nasty, but might as well reuse lambda
var.
(setf tile
(rotation (- (car tile) *x*)
(- (cdr tile) *y*)))
(cons (+ (car tile) *x*)
(+ (cdr tile) *y*)))
*current-shape*)))
;; See if any new positions are on the heap.
(do ((tiles new-shape (cdr tiles)))
((or (null tiles)
;; New tile position already on heap?
(member (car tiles) *heap*))
(if (null tiles)
;; No tile positions on heap -- return new value of
;; *current-shape*.
(setf *current-shape* new-shape)
;; Fail -- do nothing and return NIL.
NIL)))))

(defun draw-tile (tile)
;; Draw new position.
(cursorpos (+ +grid-y+ (cdr tile))
(* 2 (+ +grid-x+ (car tile))))
(princ '[]))

(defun draw-shape (shape) (mapc #'draw-tile shape))

(defun clear-shape (shape)
;; Clear previous positions if it can drop.
(mapc #'(lambda (tile)
(cursorpos (+ +grid-y+ (cdr tile))
(* 2 (+ +grid-x+ (car tile))))
(princ '| |))
shape))

(defun remove-duplicates (x)
(cond ((null x) x)
((member (car x) (cdr x)) (remove-duplicates (cdr x)))
(T (cons (car x) (remove-duplicates (cdr x))))))

(defun remove-whole-rows ()
;; Get the rows *current-shape* helped to fill.
(do ((rows (remove-duplicates (mapcar #'cdr *current-shape*))
(cdr rows))
(max-row 0))
((null rows)
;; Redraw heap. First clear down to max-row.
(do ((row 0 (1+ row)))
((> row max-row))
(cursorpos (+ +grid-y+ row) (* 2 +grid-x+))
(princ " "))
;; Now redraw the tiles down to max-row.
(do ((heap *heap* (cdr heap)))
((= (cdar heap) +num-rows+))
(if (<= (cdar heap) max-row)
(draw-tile (car heap)))))
(do ((heap *heap* (cdr heap))
(count 0))
((= (cdar heap) +num-rows+) ;From here on,
it's
(if (= count +num-columns+) ; perimeter.
;; Row full. Update score.
(progn (setf *score* (1+ *score*))
;; Output new score at top of screen.
(cursorpos 0 0)
(format t "Score: ~a" *score*)
;; Update max row.
(setf max-row (max max-row (car rows)))
(do ((heap *heap* (cdr heap)))
((= (cdar heap) +num-rows+))
(cond ((< (cdar heap) (car rows))
;; Shift tile down a row.
(setf (cdar heap) (1+ (cdar heap))))
((= (cdar heap) (car rows))
;; Delete tile.
(setf *heap* (delq (car heap) *heap*)))))
;; Go through (cdr rows), shifting down rows above
;; (car rows).
(do ((remaining-rows (cdr rows) (cdr
remaining-rows)))
((null remaining-rows))
(if (< (car remaining-rows) (car rows))
(setf (car remaining-rows)
(1+ (car remaining-rows))))))))
(if (= (cdar heap) (car rows))
;; Heap tile was in row.
(setf count (1+ count))))))

;;; Lowers shape and then responds to luser specified actions.
;;; Returns NIL if the game is over (*y* = 0).
(defun redraw-shape ()
(clear-shape *current-shape*)
;; Always try to lower shape one line.
(if (or (move-shape 0 1)
;; Add shape to heap if it can't drop any further.
(progn (mapc #'(lambda (tile) (push tile *heap*))
*current-shape*)
;; Redraw the old shape.
(draw-shape *current-shape*)
(remove-whole-rows)
(if (zerop *y*)
NIL ;Fail => game
over.
;; Create a new shape.
(get-new-current-shape))))
;; Still in the game. Listen for luser specified actions.
(do ((char-to-read-p (listen) (listen))
(key))
((zerop char-to-read-p)
(draw-shape *current-shape*))
(setf key (readch))
;; These are not easy to locate and delete from screen, so use
;; unobtrusive ones.
(cond ((eq key '/,) (move-shape -1 0)) ;Left 1.
((eq key '/.) (move-shape 1 0)) ;Right 1.
((eq key '/`)
;; Lower shape.
(do ()
((null (move-shape 0 1)))))
((eq key '/') (rotate-shape))
((eq key '/
)
;; Useful if something overwrites screen.
(refresh))))))

(defun refresh ()
(cursorpos 'c) ;Clear screen.
(draw-perimeter)
(do ((heap *heap* (cdr heap)))
((= (cdar heap) +num-rows+))
(draw-tile (car heap)))
(cursorpos 0 0)
(format t "Score: ~a" *score*)
(print-next-shape))

(defun draw-perimeter ()
(cursorpos (1- +grid-y+) (1- (* 2 +grid-x+)))
(princ "+--------------------+")
(do ((line +grid-y+ (1+ line)))
((= line (+ +grid-y+ +num-rows+))
(cursorpos line (1- (* 2 +grid-x+)))
(princ "+--------------------+"))
(cursorpos line (1- (* 2 +grid-x+)))
(princ "| |")))

(defun itster ()
(cursorpos 'c) ;Clear screen.
(format t "~%To move left, press ,~%~%")
(format t "To move right, press .~%~%")
(format t "To rotate, press '~%~%")
(format t "To drop onto the heap, press `~%~%")
(format t "Enter speed (if unsure, make it 5 or 10): ")
(let ((tick-length (quotient 1.0 (read))))
(cursorpos 'c) ;Clear screen.
(draw-perimeter)
(init-heap)
(init-rotation)
(init-shapes)
(setf *score* 0)
;; Output new score at top of screen.
(cursorpos 0 0)
(format t "Score: ~a" *score*)
(get-new-current-shape)
(do ()
((null (redraw-shape)) (update-scores *score*))
(sleep tick-length))))

(defun update-scores (score)
(let* ((f (open '(itster scores) 'in))
;; Read old hall of fame.
(scores (read f)))
(close f)
(setf scores
(sort (cons (list score
(status uname)
(status dow)
(status date)
(status daytime))
scores)
#'(lambda (row1 row2) (> (car row1) (car row2)))))
(if (> (length scores) 10)
;; Remove lower score.
(rplacd (nthcdr 9 scores) '()))
(cursorpos 'c) ;Clear screen.
(format t "ITSter Hall of Fame~%===================~%")
(mapc #'(lambda (line)
(let* ((score (car line))
(uname (cadr line))
(dow (caddr line))
(date (cadddr line))
(day (caddr date))
(daytime (car (cddddr line))))
(format t
"~a ~a ~a ~a~a ~a, ~a ~a:~a:~a~%"
score uname dow
day
(if (member day '(11. 12. 13.))
"th"
(nth (remainder day 10.)
'("th" "st" "nd" "rd" "th"
"th" "th" "th" "th" "th")))
(nth (1- (cadr date))
'(Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec))
(+ 2000. (car date))
(car daytime) (cadr daytime) (caddr daytime))))
scores)
;; Save new hall of fame.
(setf f (open '(itster scores) 'out))
(print scores f)
(close f)))


>
> Dennis

Gareth McCaughan

unread,
Mar 22, 2002, 8:52:39 PM3/22/02
to
Donald Fisk wrote:

> There's a pro-lisp point to be made here: the equivalent C code, on
> Vadim Gerasimov's web site, is around 900 lines, around 3 times as long.
> Mine was written independently of this, but it should do pretty much
> the same thing, though not exactly. Mine is `the full monty', except
> for levels (speeding up as your score goes above a threshold), the
> reason
> for this being that you don't get the speed necessary for them on the
> simulator.

I would caution against using this as a maesure of language
quality. I know someone who wrote a Tetris program in *one line*
(a little under 256 bytes after tokenization) of BBC BASIC.
See http://www.helper.demon.co.uk/rheolism/
and http://www.survex.com/~olly/rheolism.html .

Aargh!

--
Gareth McCaughan Gareth.M...@pobox.com
.sig under construc

0 new messages