Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Register
  • Sign in
  • ansi-test ansi-test
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 17
    • Issues 17
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 1
    • Merge requests 1
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Model experiments
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar
  • ansi-test
  • ansi-testansi-test
  • Issues
  • #18

READ-SUPPRESS.17 is impossible to satisfy

(let ((*read-suppress* t)) (read-from-string "#\GARBAGE")) is unwinnable. How can the reader know that the reader macro has terminated its reading? if it encounters "#\G1((((" it cannot infer that it should stop reading when it encounters parens; maybe the reader macro just gobbles up five characters whatever they are.

An unknown reader macro can consume an arbitrary number of characters from the reader string before returning; it can read a Malbolge program and execute it. So when a read-suppressed reader encounters an unknown sharpsign macro, I guess it loses in the general case - despite the standard specifying that in the examples page for *READ-SUPPRESS*.

Also, where does it say in the spec that ";; Undefined macro dispatch characters should not signal an error"?

The best thing an implementation can do is to assume that a standard Lisp object follows the sharpsign macro I guess, but it is trivial to confuse the Lisp reader nonetheless since nothing mandates that a valid Lisp object can follow the reader macro:

(defun foo (stream dispchar char)
  (declare (ignore dispchar char))
  (loop repeat 5 do (read-char stream) finally (return nil)))

(set-dispatch-macro-character #\# #\G 'foo)

(read-from-string "(#G1(((()") ;=> (NIL)

(let ((*read-suppress* t))
  (read-from-string "(list #G1(((()")) ;=> NIL

(let ((*read-suppress* t))
  (read-from-string "(list #H1(((()")) ;=> error

Therefore I'd argue that it is impossible to win with an unknown sharpsign macro despite the specification mandating this behaviour, and the only sensible option is to signal an error, which fully invalidates test case READ-SUPPRESS.17.

Assignee
Assign to
Time tracking