• A Mandelbrot set generator in HG LISP

    From Stefan Ram@21:1/5 to All on Sat Apr 12 14:01:00 2025
    From my recent postings in other newsgroups: A generator for
    a Mandelbrot set image written in a LISP similar to the HG LISP
    I used in 1981 on my Pet 2001 as I remember it.

    (SETQ CADD
    (LAMBDA (Z1 Z2)
    (LIST (ADD (CAR Z1) (CAR Z2))
    (ADD (CADR Z1) (CADR Z2)))))

    (SETQ CMUL
    (LAMBDA (Z1 Z2)
    (LIST (SUB (MUL (CAR Z1) (CAR Z2)) (MUL (CADR Z1) (CADR Z2)))
    (ADD (MUL (CAR Z1) (CADR Z2)) (MUL (CADR Z1) (CAR Z2))))))

    (SETQ CABS
    (LAMBDA (Z)
    (SQRT (ADD (MUL (CAR Z) (CAR Z))
    (MUL (CADR Z) (CADR Z))))))

    (SETQ MANDELBROT
    (LAMBDA (X Y)
    (PROGN
    (SETQ C 126)
    (SETQ Z (LIST X Y))
    (SETQ A Z)
    (SETQ ITERATE
    (LAMBDA ()
    (COND ((OR (< C 32) (> (CABS Z) 2))
    (- 126 C))
    (T
    (PROGN
    (SETQ TEMP-CMUL (CMUL Z Z))
    (SETQ TEMP-CADD (CADD A TEMP-CMUL))
    (SETQ Z TEMP-CADD)
    (SETQ C (- C 1))
    (ITERATE))))))
    (ITERATE))))

    (SETQ GENERATE-MANDELBROT
    (LAMBDA ()
    (SETQ LOOP-Y
    (LAMBDA (Y)
    (COND ((> Y 1.1) NIL)
    (T
    (PROGN
    (SETQ LOOP-X
    (LAMBDA (X)
    (COND ((> X 1) NIL)
    (T
    (PROGN
    (SETQ CHAR-CODE (MANDELBROT X Y))
    (PROGN
    (COND ((< CHAR-CODE 50) (PRINT " "))
    (T (PRINT "*"))))
    (LOOP-X (ADD X 0.04)))))))
    (LOOP-X -2)
    (PRINTLN)
    (LOOP-Y (ADD Y 0.1)))))))
    (LOOP-Y -1)))

    (GENERATE-MANDELBROT)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Stefan Ram on Sun Apr 13 00:13:26 2025
    On 12 Apr 2025 14:01:00 GMT, Stefan Ram wrote:

    From my recent postings in other newsgroups: A generator for
    a Mandelbrot set image written in a LISP similar to the HG LISP I used
    in 1981 on my Pet 2001 as I remember it.

    Looks like a Lisp-1 dialect, rather than Lisp-2. But not a Scheme
    derivative?

    [extract kept as example, rest snipped]

    (SETQ MANDELBROT
    (LAMBDA (X Y)
    (PROGN
    (SETQ C 126)
    (SETQ Z (LIST X Y))
    (SETQ A Z)
    (SETQ ITERATE
    (LAMBDA ()
    (COND ((OR (< C 32) (> (CABS Z) 2))
    (- 126 C))
    (T
    (PROGN
    (SETQ TEMP-CMUL (CMUL Z Z))
    (SETQ TEMP-CADD (CADD A TEMP-CMUL))
    (SETQ Z TEMP-CADD)
    (SETQ C (- C 1))
    (ITERATE))))))
    (ITERATE))))

    I was never a fan of “parenthesis pileup” layout. Try this for comparison:

    (SETQ MANDELBROT
    (LAMBDA (X Y)
    (PROGN
    (SETQ C 126)
    (SETQ Z (LIST X Y))
    (SETQ A Z)
    (SETQ ITERATE
    (LAMBDA ()
    (COND
    ((OR (< C 32) (> (CABS Z) 2))
    (- 126 C)
    )
    (T
    (PROGN
    (SETQ TEMP-CMUL (CMUL Z Z))
    (SETQ TEMP-CADD (CADD A TEMP-CMUL))
    (SETQ Z TEMP-CADD)
    (SETQ C (- C 1))
    (ITERATE)
    ) ; PROGN
    )
    ) ; COND
    ) ; LAMBDA
    ) ; ITERATE
    (ITERATE)
    ) ; PROGN
    ) ; LAMBDA
    ) ; MANDELBROT

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Monnier@21:1/5 to All on Mon Apr 14 12:22:33 2025
    I was never a fan of “parenthesis pileup” layout. Try this for comparison:

    (SETQ MANDELBROT
    (LAMBDA (X Y)
    (PROGN
    (SETQ C 126)
    (SETQ Z (LIST X Y))
    (SETQ A Z)
    (SETQ ITERATE
    (LAMBDA ()
    (COND
    ((OR (< C 32) (> (CABS Z) 2))
    (- 126 C)
    )
    (T
    (PROGN
    (SETQ TEMP-CMUL (CMUL Z Z))
    (SETQ TEMP-CADD (CADD A TEMP-CMUL))
    (SETQ Z TEMP-CADD)
    (SETQ C (- C 1))
    (ITERATE)
    ) ; PROGN
    )
    ) ; COND
    ) ; LAMBDA
    ) ; ITERATE
    (ITERATE)
    ) ; PROGN
    ) ; LAMBDA
    ) ; MANDELBROT

    Eww!


    Stefan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Stefan Monnier on Tue Apr 15 23:20:31 2025
    On Mon, 14 Apr 2025 12:22:33 -0400, Stefan Monnier wrote:

    Eww!

    I was just checking how Emacs implements its bracket-highlighting feature.
    You know, if you position the insertion point at one opening or closing parenthesis, it will highlight the corresponding member of the pair.

    Turns out it’s a bit strange: you have to position the cursor *on* an
    opening parenthesis in order for it to highlight the corresponding closer,
    but *after* the closing parenthesis for it to highlight the corresponding opener.

    And remember, this is the editor that is famously written in Lisp.

    So you see, the “parenthesis pileup” tradition forces Emacs to implement this feature in a, shall we say, less than intuitive fashion.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Monnier@21:1/5 to All on Tue Apr 15 20:03:04 2025
    Turns out it’s a bit strange: you have to position the cursor *on* an opening parenthesis in order for it to highlight the corresponding closer, but *after* the closing parenthesis for it to highlight the corresponding opener.

    Actually, "point" is never "on" a character, it's always between characters.
    So in both cases "point" needs to be outside of the parenthesis.
    It's perfectly symmetrical.

    It's just that the cursor by default is a block drawn on the character
    that follows the actual placement of "point". Try to switch to a bar
    cursor and that should be more clear.


    Stefan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Stefan Monnier on Wed Apr 16 01:55:11 2025
    On 2025-04-16, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
    Turns out it’s a bit strange: you have to position the cursor *on* an
    opening parenthesis in order for it to highlight the corresponding closer, >> but *after* the closing parenthesis for it to highlight the corresponding
    opener.

    Actually, "point" is never "on" a character, it's always between characters. So in both cases "point" needs to be outside of the parenthesis.
    It's perfectly symmetrical.

    It's just that the cursor by default is a block drawn on the character
    that follows the actual placement of "point". Try to switch to a bar
    cursor and that should be more clear.

    Indeed, on terminals, you have an vertical bar cursor, or a block
    cursor. It may be hard-coded, but on some modern software-based
    terminal emulators it is configurable. (As well as other attributes
    like whether it blinks.)

    This is something purely local to the terminal emulator, not having
    any semantics outside of it, but it influences the perception of the
    semantics of positioning.

    In particular: selection.

    In the TXR Lisp listenter, you can set or clear this special Boolean:

    1> *listener-sel-inclusive-p*
    t

    "selection inclusive" being enabled means that the visual selection
    (Ctrl-S) includes the character that is under the cursor, when the
    cursor is considered to be a block. When the cursor is at the leftmost
    endpoint of the selection, the selection begins to the left of the
    cursor. When the cursor is at the right endpoint of the selection, the selection ends to the right of the cursor. This semantics implies that
    the selection can never be empty. When the start and end position
    coincide, one character under the block is selected.

    When you disable this flag, the selection always begins or ends to
    the left of a block cursor. This works great when the cursor is
    a vertical bar that goes down the left side of the character cell.
    This is the semantics you are describing. Many people are used to this semantics, because it's similar to how cursors and selections look
    and work in most graphical user interfaces.

    (The variable's default used to be nil, but I switched it to t, because
    it seems that block cursors, or block cursors by default, are more
    prevalent; as you note above.)

    The wretched Vim editor to only supports block semantics. I looked at
    the code to see what it would take to support a similar configuration. I
    will not be looking at that code again in hopes that my mind will one
    day unsee it.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Stefan Monnier on Wed Apr 16 07:40:13 2025
    On Tue, 15 Apr 2025 20:03:04 -0400, Stefan Monnier wrote:

    Turns out it’s a bit strange: you have to position the cursor *on* an
    opening parenthesis in order for it to highlight the corresponding
    closer, but *after* the closing parenthesis for it to highlight the
    corresponding opener.

    Actually, "point" is never "on" a character, it's always between
    characters. So in both cases "point" needs to be outside of the
    parenthesis.

    Except in one case it looks like it’s on it.

    It's just that the cursor by default is a block drawn on the character
    that follows the actual placement of "point". Try to switch to a bar
    cursor and that should be more clear.

    If it weren’t for having to deal with parenthesis pileup, it could work
    from either side.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)