Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SRFI 101: Purely Functional Random-Access Pairs and Lists #409

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

jpellegrini
Copy link
Contributor

Hi @egallesio !

One more R7RS-Large library...
This one is tricky, since it requires the redefinition of
very fundamental things like CAR and QUOTE.

Relevant points

  • Everything is defined inside the module with a prefix
    srfi101:, and exported with renaming
  • The ideal way to use this SRFI is to prefix symbols when
    importing, otherwise one'd lose the standard car, list, quote
    etc.
  • Its tests are in a separate file, and loaded as a last thing
    in do-test.stk:
(define (load-tests)
  ...
  (load "test-r5rs-pitfall.stk")
  (load "test-srfi-101.stk")
)

Issues:

  1. When not renamed, quote enters a loop
  2. Tests run fine and pass when called manually, but when inside the
    test system, they raise some kind of exception

(1) is probably because quote is not a macro in STklos, but rather a special form, so the SRFI's custom quote macro will confuse the compiler:

(define-macro (srfi101:quote x)
  (define (x->rlist obj)
    (if (scheme:pair? obj)
        (srfi101:cons (x->rlist (scheme:car obj))
                      (x->rlist (scheme:cdr obj)))
        obj))
  `(quote ,(x->rlist x)))         ;;; <== here! I can't reference "the quote symbol from Scheme",
                                  ;;; so the macro expander enters a loop when this macro is renamed to
                                  ;;; "quote"

Maybe quote and quasiquote could be turned into macros? I can take a look into that if you think it's ok.

(2) is a mystery to me.

$ src/stklos --no-init-file --utf8-encoding=yes
stklos> (load-path `("lib"   ,@(load-path)))
stklos> (load "tests/test.stk")
stklos> (load "tests/test-srfi-101.stk")
  testing srfi-101.-1 expects 5 ==> OK.
  testing srfi-101.0 expects x ==> OK.
  testing srfi-101.1 expects #t ==> OK.
  ...

(All tests pass)

But if I run the full test suite, it fails.

==== Testing R5RS pitfall  ...                                   passed
**** Error while executing file "do-test.stk"

EXIT
make[1]: *** [Makefile:483: test] Error 70
make[1]: Leaving directory '/home/jeronimo/pkg/scheme/STklos-jpellegrini/tests'
make: *** [Makefile:881: test] Error 2

@jpellegrini
Copy link
Contributor Author

jpellegrini commented Jul 27, 2022

The quote problem is really tricky. I've tried

  • making quote a macro which uses a %%quote special form;
  • having both quote and %%quote special forms, and making srfi101:quote use the second one
  • using only quasiquote in srfi101:quote (but compile-quasiquote will introduce quotes...)

This one is tricky, since it requires the redefinition of
very fundamental things like CAR and QUOTE.

- Everything is defined inside the module with a prefix
  "srfi101:", and exported with renaming
- The ideal way to use this SRFI is to prefix symbols when
  importing, otherwise one'd lose the standard car, list, quote
  etc.
- Its tests are in a separate file, and loaded as a last thing
  in do-test.stk

Issues:

- When not renamed, quote enters a loop
- Tests run fine and pass when called manually, but when inside the
  test system, they raise some kind of exception
@jpellegrini
Copy link
Contributor Author

Adapted to the new lib/scheme / lib/srfi organization. but this one needs some careful consideration, I suppose, because of the issues described.

@egallesio
Copy link
Owner

Adapted to the new lib/scheme / lib/srfi organization. but this one needs some careful consideration, I suppose, because of the issues described.

I'll have a look at this point. But as you said before, this is a more general problem with the redefinition of basic macros.

@jpellegrini
Copy link
Contributor Author

Just registering one idea:

  • Create the macro programmatically in C (the expander is easily written as a primitive, and we can build the structure in C also);
  • Then checking for quote wouldn't be necessary in the compiler! When it checks if the form is a macro usage, that "primitive" macro will be there. And it would be rebindable.
  • (Maybe this also works for other special forms)

@jpellegrini
Copy link
Contributor Author

jpellegrini commented Sep 2, 2023

Create the macro programmatically in C (the expander is easily written as a primitive, and we can build the structure in C also);

I just tried... That, by itself, doesn't help. But perhaps a new structure, [quoted-form] (or [self-eval]) would do?

  • The fundamental quote would return quoted forms;
  • The compiler would recognize that, and not try to eval them.

Maybe

  • a SELF_EVALP macro that tests a bit in the header of Scheme objects
  • %self-evaluating? that quote would set, and the compiler would check
  • %self-evaluate-set!, which quote would use to set, and perhaps other parts of STklos could use to UNset the self-evaluation flag...

@jpellegrini
Copy link
Contributor Author

jpellegrini commented Sep 2, 2023

I have this implemented, partially:

stklos> (define x '(+ 2 3))
;; x
stklos> x
(+ 2 3)
stklos> (eval x)
5
stklos> (%self-evaluating? x)
#f
stklos> (%self-evaluate-set! x #t)
stklos> (%self-evaluating? x)
#t
stklos> (eval x)
(+ 2 3)
stklos> (%self-evaluate-set! x #f)
stklos> (%self-evaluating? x)
#f
stklos>  (eval x)
5

Maybe this will make it easier to implement a redefinable quote. I'll continue in a separate PR when I get it to work.

EDIT: Not good -- quasiquote & recursive evaluation would defeat that. But a new quote structure can help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants