In favor of explicit argument
Shiro Kawai
(09 Aug 2020 01:33 UTC)
|
Re: In favor of explicit argument
Lassi Kortela
(09 Aug 2020 06:46 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(09 Aug 2020 09:27 UTC)
|
Re: In favor of explicit argument
Adam Nelson
(10 Aug 2020 22:25 UTC)
|
Re: In favor of explicit argument
Shiro Kawai
(10 Aug 2020 23:46 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(11 Aug 2020 07:58 UTC)
|
Re: In favor of explicit argument
Alex Shinn
(11 Aug 2020 01:29 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(11 Aug 2020 07:17 UTC)
|
Re: In favor of explicit argument
Jim Rees
(11 Aug 2020 16:45 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(11 Aug 2020 16:57 UTC)
|
Re: In favor of explicit argument
Alex Shinn
(12 Aug 2020 02:20 UTC)
|
Re: In favor of explicit argument
John Cowan
(12 Aug 2020 02:49 UTC)
|
Re: In favor of explicit argument
Arthur A. Gleckler
(12 Aug 2020 03:23 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(12 Aug 2020 13:29 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(12 Aug 2020 19:46 UTC)
|
Re: In favor of explicit argument
Alex Shinn
(13 Aug 2020 00:40 UTC)
|
Re: In favor of explicit argument Marc Nieper-Wißkirchen (13 Aug 2020 07:18 UTC)
|
Re: In favor of explicit argument
Alex Shinn
(14 Aug 2020 01:24 UTC)
|
Re: In favor of explicit argument
Adam Nelson
(13 Aug 2020 01:13 UTC)
|
Re: In favor of explicit argument
John Cowan
(13 Aug 2020 01:53 UTC)
|
Re: In favor of explicit argument
Adam Nelson
(13 Aug 2020 03:09 UTC)
|
Re: In favor of explicit argument
Alex Shinn
(13 Aug 2020 03:16 UTC)
|
Re: In favor of explicit argument
John Cowan
(13 Aug 2020 03:31 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(13 Aug 2020 08:04 UTC)
|
Re: In favor of explicit argument
Jim Rees
(13 Aug 2020 18:24 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(13 Aug 2020 20:05 UTC)
|
Re: In favor of explicit argument
John Cowan
(14 Aug 2020 02:41 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(14 Aug 2020 06:34 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(14 Aug 2020 13:30 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(14 Aug 2020 14:08 UTC)
|
Re: In favor of explicit argument
Alex Shinn
(15 Aug 2020 22:56 UTC)
|
Re: In favor of explicit argument
Marc Nieper-Wißkirchen
(16 Aug 2020 07:55 UTC)
|
Re: In favor of explicit argument
Alex Shinn
(14 Aug 2020 02:29 UTC)
|
Am Do., 13. Aug. 2020 um 02:40 Uhr schrieb Alex Shinn <xxxxxx@gmail.com>: > > OK, you can leverage the internal Chibi binding renaming mechanism here, > but each implementation will need it's own low-level tricks. Note you had to > resort to C code to implement this. > > The (auto) module can be implemented in a few lines of Scheme in meta-7.scm. I hope you agree with me that you don't want to derive any general conclusions from this as this is very Chibi specific. My implementation is also no more than a few lines in Scheme code and the only C code I needed was absolutely trivial and to make a C function available through the FFI. If I did the same implementation in Chez, say, it would also only be a few lines in its syntax.ss. The same is true for any psyntax-based implementation like Guile. I don't want to say that it is less complicated to implement a new binding form, but it isn't more complicated either. There are at least two scenarios where we want to have a local binding constructs: (1) If some macro has to auto-generate an auxiliary keyword on the fly (depending on the user input), it cannot locally import an (auto) module (because we have no local imports for some good reasons), but a binding form like "define-keyword" would suffice. (2) If user code imports two modules A and B from two different sources. Say, A, defines some procedure "->", but B uses "->" as an auxiliary syntax keyword. I can only import both by renaming either "->" of A or B, which would lead locally to code using A or B that is harder to read because of the renamed identifier. With "define-keyword", I can just import B's "->" under any name and locally bring it back into scope under the original name "->". > Another advantage of the (auto) module is it can be implemented as a > normal R7RS library for any fixed set of keywords. You can have a build > target to auto-generate it, making it usable with any implementation which > doesn't support it natively. This does not work for more than one source that wants to use this trick. In any case, maybe a future SRFI on this can provide both in a compatible way: - A classical Scheme binding form like "define-keyword". - A "magic" module like "(auto)". Marc > On Thu, Aug 13, 2020 at 4:46 AM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote: >> >> At the end of this email is a patch for a quick-and-dirty >> implementation of "define-keyword" for Chibi. >> >> Please see the file lib/chibi/keyword-test.sld to see how it is used. >> >> (define-keyword <id> <name>) >> >> binds <id> to auxiliary syntax identified by the symbol <name>. >> >> -- Marc >> >> commit a61d1fe5f36e7f53f990df8eceb3dc7ad89d16cb >> Author: Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> >> Date: Wed Aug 12 21:40:40 2020 +0200 >> >> Implement define-keyword >> >> diff --git a/lib/chibi/ast.c b/lib/chibi/ast.c >> index 13d776ed..28812f37 100644 >> --- a/lib/chibi/ast.c >> +++ b/lib/chibi/ast.c >> @@ -297,6 +297,14 @@ sexp sexp_env_push_op (sexp ctx, sexp self, >> sexp_sint_t n, sexp env, sexp name, >> return SEXP_VOID; >> } >> >> +#if SEXP_USE_RENAME_BINDINGS >> +sexp sexp_env_rename_op (sexp ctx, sexp self, sexp_sint_t n, sexp >> env, sexp key, sexp value) { >> + sexp_assert_type(ctx, sexp_envp, SEXP_ENV, env); >> + sexp_assert_type(ctx, sexp_idp, SEXP_SYMBOL, key); >> + return sexp_env_rename (ctx, env, key, value); >> +} >> +#endif >> + >> sexp sexp_core_code_op (sexp ctx, sexp self, sexp_sint_t n, sexp c) { >> sexp_assert_type(ctx, sexp_corep, SEXP_CORE, c); >> return sexp_make_fixnum(sexp_core_code(c)); >> @@ -726,6 +734,9 @@ sexp sexp_init_library (sexp ctx, sexp self, >> sexp_sint_t n, sexp env, const char >> sexp_define_foreign(ctx, env, "env-syntactic?-set!", 2, >> sexp_env_syntactic_set_op); >> sexp_define_foreign(ctx, env, "env-define!", 3, sexp_env_define_op); >> sexp_define_foreign(ctx, env, "env-push!", 3, sexp_env_push_op); >> +#if SEXP_USE_RENAME_BINDINGS >> + sexp_define_foreign(ctx, env, "env-push-rename!", 3, sexp_env_rename_op); >> +#endif >> sexp_define_foreign(ctx, env, "core-code", 1, sexp_core_code_op); >> sexp_define_foreign(ctx, env, "object-size", 1, sexp_object_size); >> sexp_define_foreign(ctx, env, "immutable?", 1, sexp_immutablep_op); >> diff --git a/lib/chibi/ast.sld b/lib/chibi/ast.sld >> index 2856f656..dac80aeb 100644 >> --- a/lib/chibi/ast.sld >> +++ b/lib/chibi/ast.sld >> @@ -32,7 +32,7 @@ >> bytecode-name bytecode-literals bytecode-source >> port-line port-line-set! port-source? port-source?-set! >> extend-env env-parent env-parent-set! env-lambda env-lambda-set! >> - env-define! env-push! env-syntactic? env-syntactic?-set! core-code >> + env-define! env-push! env-push-rename! env-syntactic? >> env-syntactic?-set! core-code >> type-name type-cpl type-parent type-slots type-num-slots >> type-printer type-printer-set! >> object-size object->integer integer->immediate gc gc-usecs gc-count >> diff --git a/lib/chibi/keyword-test.sld b/lib/chibi/keyword-test.sld >> new file mode 100644 >> index 00000000..d39824ee >> --- /dev/null >> +++ b/lib/chibi/keyword-test.sld >> @@ -0,0 +1,27 @@ >> +(define-library (chibi keyword-test) >> + (export run-tests) >> + (import (scheme base) (chibi keyword) (chibi test)) >> + (begin >> + (define (run-tests) >> + (test-begin "keyword") >> + >> + (test-group "define-syntax literals" >> + (define-keyword foo foo) >> + (define-keyword bar foo) >> + (define-keyword baz bar) >> + >> + (define-syntax foo? >> + (syntax-rules (foo) >> + ((_ foo) #t) >> + ((_ _) #f))) >> + >> + (test-assert (foo? foo)) >> + (test-assert (foo? bar)) >> + (test-not (foo? baz))) >> + >> + (test-group "standard auxiliary syntax" >> + (define-keyword otherwise else) >> + (test-assert (cond >> + (otherwise #t)))) >> + >> + (test-end)))) >> diff --git a/lib/chibi/keyword.scm b/lib/chibi/keyword.scm >> new file mode 100644 >> index 00000000..fb45ac3d >> --- /dev/null >> +++ b/lib/chibi/keyword.scm >> @@ -0,0 +1,37 @@ >> +(define keywords (make-hash-table eq?)) >> + >> +(define (set-keyword! name) >> + (hash-table-set! keywords name (env-cell (current-environment) name))) >> + >> +;; Intern the keywords defined in (chibi). >> +(set-keyword! '_) >> +(set-keyword! '=>) >> +(set-keyword! '...) >> +(set-keyword! 'else) >> +(set-keyword! 'unquote) >> +(set-keyword! 'unquote-splicing) >> + >> +(define (hash-table-intern! ht key failure) >> + (hash-table-ref ht key (lambda () >> + (let ((res (failure))) >> + (hash-table-set! ht key res) >> + res)))) >> + >> +(define (intern-keyword! name mac-env) >> + (hash-table-intern! keywords name >> + (lambda () >> + (cons >> + name >> + (make-macro >> + (lambda (expr use-env mac-env) >> + (error "invalid use of auxiliary syntax" >> + name)) >> + mac-env))))) >> + >> +(%define-syntax define-keyword >> + (lambda (expr use-env mac-env) >> + (let ((_begin (make-syntactic-closure mac-env '() 'begin)) >> + (id (cadr expr)) >> + (name (strip-syntactic-closures (car (cddr expr))))) >> + (env-push-rename! use-env id (intern-keyword! name mac-env)) >> + `(,_begin)))) >> diff --git a/lib/chibi/keyword.sld b/lib/chibi/keyword.sld >> new file mode 100644 >> index 00000000..26434fbb >> --- /dev/null >> +++ b/lib/chibi/keyword.sld >> @@ -0,0 +1,6 @@ >> +(define-library (chibi keyword) >> + (export define-keyword) >> + (import (chibi) >> + (chibi ast) >> + (srfi 69)) >> + (include "keyword.scm")) >> diff --git a/tests/lib-tests.scm b/tests/lib-tests.scm >> index 8a200931..035751ab 100644 >> --- a/tests/lib-tests.scm >> +++ b/tests/lib-tests.scm >> @@ -46,6 +46,7 @@ >> (rename (chibi io-test) (run-tests run-io-tests)) >> (rename (chibi iset-test) (run-tests run-iset-tests)) >> (rename (chibi json-test) (run-tests run-json-tests)) >> + (rename (chibi keyword-test) (run-tests run-keyword-tests)) >> (rename (chibi log-test) (run-tests run-log-tests)) >> (rename (chibi loop-test) (run-tests run-loop-tests)) >> (rename (chibi match-test) (run-tests run-match-tests)) >> @@ -111,6 +112,7 @@ >> (run-io-tests) >> (run-iset-tests) >> (run-json-tests) >> +(run-keyword-tests) >> (run-log-tests) >> (run-loop-tests) >> (run-match-tests)