-
Notifications
You must be signed in to change notification settings - Fork 1k
Simplified lookup of property values #940
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
base: main
Are you sure you want to change the base?
Conversation
The property-value procedure can be used within the dynamic extent of the expander's call to a macro transformer to look up an identifier's property values.
Did you consider using In an attempt to measure the expansion overhead of
The implementation here was more than 10% slower to evaluate |
Thank you very much for your prompt and thorough review! There was no particular reason for why I used I pushed a version that uses continuation marks; it remains to make bootstrapping with an old version of Chez that does not know about continuation marks work. PS The commits below enable bootstrapping again. |
A procedure that is only allowed to be called during expansion does not seem very Chez-like. Is there anything else in Chez that has any analogous restriction? |
Well, the I changed the code so that |
In the R7RS large draft this procedure is called |
I know, but |
I'm hesitant to do something that causes macro expansion to slow down, even by 1%. It would help me to see an example where this procedure makes the macro much simpler and would justify the cost. |
For example, with the latest version, you can query identifier properties on the right-hand side of In any case, in one sense, the slowdown is negligible. Chez Scheme doesn't have a continuation barrier (à la Racket) in the expander, so reinstatiation of continuations captured in a macro transformer call long after that call has ended is possible. Through this, it becomes observable that Chez's expander uses mutable state. Moreover, one can cause the expander to produce nonsensical results. So, at one point in the future, Chez should get a continuation barrier (which would have to be placed more or less where my patch currently adds a continuation mark), and compared with the barrier, the continuation mark would be truly negligible. On the other hand, if we just declare that trying to jump back into transformer calls through |
I forgot to add that the slowdown of the macro expansion will be far less than 1% in practice. Matthew's example macro basically did nothing, so it was able to mostly measure the speed of the expander itself. Most macros encountered in practice do something non-trivial. A good measure in practice would be measuring how long it takes to expand some file with non-trivial macro use, e.g., |
The manual entry for |
No, |
A code example would help me understand what you're trying to accomplish. |
For example,
defines a property that copies the property value from another property. Replacing A different use case is that of a macro transformer helper procedure that needs to access property values. With the existing model implemented in Chez Scheme, it needs a collaborating macro transformer because that has to acquire the For example, a library API implementing some abstraction over the property facility should work seamlessly without having to ask the user code to acquire the |
Here's your example in code:
This prints:
|
Is The ultra-short explanation:
The documentation notes that:
Searching for |
Thank you for the example. If the code is part of a library, the library will at some point be expanded. At this point, the macro use This makes no difference for types like symbols, but it does make a difference when a procedure, hashtable, or some other compound type is the value of the original property. For example, imagine And this only works as long as Chez Scheme allows arbitrary objects in quoted contexts, which is not part of R6RS (there, syntax objects are only (partially) wrapped Scheme datums). Is the latter anywhere documented in CSUG, or is it just undefined behaviour? |
The Racket version of Racket may have to be stricter about the time procedures are allowed to be called because of the strictly separated phases there. Chez Scheme, with its implicit phasing model, is different, so not every Racket restriction should apply to Chez Scheme. |
Like Bob, I'm having some trouble understanding the problem this PR aims to address. It appears the aim is to avoid having to request a If so, perhaps interested parties can do this without modifying Chez Scheme by using something like the following: (library (scheme-alt)
(export property-value syntax-case)
(import (rename (scheme) (syntax-case real-syntax-case)))
(export (import (except (scheme) syntax-case)))
(define *do-lookup* (make-parameter (lambda (id key) #f)))
(define (property-value id key) ((*do-lookup*) id key))
(define-syntax syntax-case
(syntax-rules ()
[(_ expr aux clause ...)
(lambda (lookup)
(parameterize ([*do-lookup* lookup])
(real-syntax-case expr aux clause ...)))]))
) I imagine this could use Matthew's continuation mark alternative instead. Here is a pared-down example where a transformer calls a help procedure that uses the exported
|
Thank you for your code, Oscar. Of course, by importing customised versions of R6RS procedures or syntax, one can get rid of having to handle In any case, the solution you propose has (at least) two shortcomings compared to the solution this PR offers:
Let me add that I appreciate this discussion. A significant part of Chez Scheme's appeal comes from its relative conservatism, so the addition of features needs to be well-considered. In the case of |
The \scheme{property-value} procedure returns the value of the | ||
\var{key-identifier} property of \var{identifier}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The \scheme{property-value} procedure is used in macro transformers to look up the value of the
\var{key-identifier} compile-time property of \var{identifier}.
Compile-time properties are not usually available after macro expansion.
However, in the case of properties, there is a second, usually easier | ||
way, to obtain property values, namely by calling the | ||
\scheme{property-value} procedure described below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For compile-time properties, the \scheme{property-value} procedure can be used instead of the lookup procedure in macro transformers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The best wording probably depends on what the "recommended" way to retrieve property values should be. With property-value
being available, I see no reason to use the older way for new code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to avoid making a recommendation and simply present the options.
As the right-hand side of a \scheme{define-property} form is evaluated | ||
at expand-time, note that invoking \scheme{property-value} at relative | ||
run-time within the same library or top-level program won't see the | ||
property. | ||
This is the reason why the \scheme{get-property} macro wrapper around | ||
\scheme{property-value} is used below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this section. I tried to include the essence of the content in the revision above.
This is the reason why the \scheme{get-property} macro wrapper around | ||
\scheme{property-value} is used below. | ||
|
||
If \var{identifier} or \var{key-identifier} have no visible binding, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have => has
(syntax-case x () | ||
[(_ id key) | ||
#`'#,(datum->syntax #'* (property-value #'id #'key))]))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please keep the original code, because it demonstrates how to use the lookup procedure. Add a note:
This macro can also be defined without the lookup procedure using \scheme{property-value} as in the \scheme{get-info} example above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is related to my comment above; if we agree that new code probably wants to use property-value
, the primary example should be formulated with it. I could add the old version as a secondary example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine with me to have get-info use the lookup procedure and get-property use property-value. I want to have an example of each way.
@@ -116,6 +116,14 @@ Online versions of both books can be found at | |||
%----------------------------------------------------------------------------- | |||
\section{Functionality Changes}\label{section:functionality} | |||
|
|||
\subsection{Simpified lookup of property values (10.2.0)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
\subsection{Added \scheme{property-value} to look up compile-time property values (10.2.0)}
The \scheme{property-value} procedure looks up the value of a property | ||
of an identifier. This obviates the need to follow a specific | ||
transformer protocol to obtain a \scheme{lookup} procedure that | ||
returns property values and this lets macro helper functions look up | ||
property values independently. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The \scheme{property-value} procedure looks up the compile-time property value of an identifier in a macro transformer. It can be used instead of returning a procedure that binds the lookup procedure.
;; Schemes do not support continuation marks. Bootstrapping the | ||
;; expander itself doesn't make use of `property-value` and, more | ||
;; generally, continuation marks, so these mock version suffice. | ||
;; Things have to be revisited once the Nanopass framework makes use | ||
;; of `property-value` (currently, the old, less convenient | ||
;; `lookup`-procedure protocol is used). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mock version suffices for now because bootstrapping the expander does not use property-value
or continuation marks.
The
property-value
procedure, which can be used within the dynamic extent of the expander's call to a macro transformer, looks up the value of a property of an identifier in the macro's use environment. This obviates the need to follow a specific transformer protocol to obtain alookup
procedure that returns property values and lets macro helper functions look up property values independently.