Dear Marc & list,
First, the fun stuff suggested is in the *"Result, usage"* secton below - check it out first :D
This is to discuss the pull request https://github.com/feeley/gambit/pull/180 that I just made.
I hope this provides a clean and practical solution to a problem that has been discussed here on the list last years, and to which not really clean solutions have been suggested until now.
Marc, in particular can you please check out my question secton "Implementation stuff I don't remember why - Marc clarify?" right at the bottom here, and let us know so everyone will know why it needs to be exactly like this? Thanks!
*Purpose* There are times when as a user you want to enhance your s-expression format with a custom type.
E.g., sometimes you have a custom value type such as an FFI type, that you want to make serializable.
*Problem* The writer is fairly easy to extend, you just overlap Gambit's |##wr| procedure with your own (lambda (write-env obj) ...) procedure, where |obj| is the value that Gambit is serializing right now, and that procedure either does its own serialization by outputting the customs structure using (##wr-str write-env string-serialized-form), or passes on execution to the underlying (original) |##wr|.
So so far so good.
The reader is more complex to extend though.
One syntax that theoretically could have worked would have been took into gambit's #. syntax, to inline actual code to be evaluated by the reader, in the serialized form of the sexp. That is not only unsafe though, but also, Gambit namespace management is a task that is difficult to impossible - Gambit is simply not really made for that, so having your custom forms of data serialized to #.(my-data-form ...) does not scale.
*The solution I suggest* Luckily, internally Gambit has a procedure |##readtable-char-sharp-handler-set!|, which installs user-defined hash-sequence deserializer in a readtable!
E.g. install an #\X-character handler into it, and any read element #Xyour-data will have your-data readable by that custom handler.
*Implementation problem 1* The problem then is that Gambit not exports any ways to make your own custom handlers - it just exports its own handlers, such as |##read-sharp-vector| (for "#(..."), |##read-sharp-char| (for "#..."), |##read-sharp-dot| (for "#...."), |##read-sharp-bang| (for "#!..."), etc. . (All those are implemented in lib/_io.scm , and are installed in every readtable using - you guessed it - |##readtable-char-sharp-handler-set!|, in |##make-standard-readtable|.)
To implement your own handler, you need access to the lowlevel macros |macro-read-next-char-or-eof|, |macro-readenv-filepos-set!| and |macro-readenv-wrap|.
Also, perhaps, even if you had access to those macros in userland, because Gambit's IO could change at some point perhaps actually using them in userland would be a hack - and so, it would be better if Gambit exported a generalized mechanism for the user to implement his own readtable handlers, that itself takes care of the lowlevel stuff.
*Implementation problem 1 solution* To enable users to implement their own readtable handlers, I suggest the inclusion into Gambit of a procedure |##make-readtable-char-sharp-sexp-reader-transformer|, which takes the arguments (transform #!optional (read ##read-datum-or-label)) and returns a readtable hash-sequence deserializer for use with |##readtable-char-sharp-handler-set!|.
|transform| is the user-provided function that receives as only argument the data that was read out of the sexp in an ordinary format (discussed below), and performs any conversion to that to the custom format (e.g. C FFI type etc.) - the transform procedure evaluates to the conversion result to be used in the sexp.
|##make-readtable-char-sharp-sexp-reader-transformer| abstracts away the need of taking care of/takes care of all the Gambit-IO-internal macros, as discussed above.
*Implementation problem 2* The next problem is how the content of that custom hash-sequnce type is read -
The different ##read-sharp-* procedures all implement their own specific deserializer logics, to read the different hash-sequence formats e.g. "#(e1 e2)", "#\newline", "#!value", "#|| comment ||", etc. - rightly so as the formats are completely custom to the respective hash-sequence.
The ##read-sharp-* procedures frequently, but not always, implement the whole reading logic locally in themselves.
There are some instances of reading logics defined globally though -
- |##read-datum-or-label| reads a single datum (e.g. "abc", "123", "#f" or "(1 2 3)"), that one is used by |##read-sharp-ampersand|, for deserialization of the box form e.g. "#&#t", or for the datum-comment form e.g. "#;(im not read)".
- |##read-expr-from-port| reads any expression from a port, for |##eval| to be fed with it. That one is used by |##read-sharp-dot|, e.g. for "#.(+ 1 2)".
- There's a bunch of ##build- forms for reading vectors, lists, integers
- |##read-datum-or-label-or-none-or-dot| seems to read pretty much anything, and is used for instance as continuation for the whole reading process.
*Implementation problem 2 solution* Of these, it seems to me that |##read-datum-or-label| is a perfect default - in particular, the list type makes perfect sense for storing complex custom types.
*Implementation stuff I don't remember why - Marc clarify?* As of the moment of writing,
- What's the label-marker check and error handling for?
- Why is the "unwrap":ping during the call to the |read| procedure needed?
*Result, usage* The result of this addition is that you can plug in your custom serialization code as follows:
(define-type coord x y)
(##readtable-char-sharp-handler-set! (input-port-readtable (repl-input-port)) #$
(##make-readtable-char-sharp-sexp-reader-transformer (lambda (v) (apply make-coord v))))
(set! ##wr (let* ((old-wr ##wr)) (lambda (we obj) (if (coord? obj) (begin (##wr-str we "#$") (##wr-str we (object->string (list (coord-x obj) (coord-y obj))))) (old-wr we obj)))))
And it's used as follows:
*(make-coord 15 16)*
#$(15 16)
*(define c #)* *(coord-x c)*
15
*c*
#$(15 16)
*(object->string c)*
"#$(15 16)"
*(call-with-input-string # read)*
#$(15 16)
The only important catch to be aware of, is that actually typing in #$(15 16) in the REPL will evaluate to the object, which will then cause an exception:
*#$(15 16)*
*** ERROR IN (console)@19.3 -- Ill-formed expression
That's analogous to:
*(eval print)*
*** ERROR -- Ill-formed expression #<procedure #16 print> 1>
As of the time of this post, the extention consists only of the following addition to lib/_io.scm :
(define (##make-readtable-char-sharp-sexp-reader-transformer transform #!optional (read ##read-datum-or-label))
(define (read-without-wrap re) (let* ((old-wrapper (macro-readenv-wrapper re)) (old-unwrapper (macro-readenv-unwrapper re))) (macro-readenv-wrapper-set! re (lambda (re x) x)) (macro-readenv-unwrapper-set! re (lambda (re x) x)) (let ((result (read re))) (macro-readenv-wrapper-set! re old-wrapper) (macro-readenv-unwrapper-set! re old-unwrapper) result)))
(lambda (re next start-pos) (macro-read-next-char-or-eof re) ;; skip char after ## (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum (let ((args (read-without-wrap re))) (if (##label-marker? args) (begin (##raise-datum-parsing-exception 'datum-or-eof-expected re) (##void)) (let ((obj (transform args))) (macro-readenv-wrap re obj))))))
Perhaps this can be simplified further.
Looking forward to your thoughts and feedback, and I hope to finally enable Gambit with this :)
In particular if you feel any name would be more relevant than "##make-readtable-char-sharp-sexp-reader-transformer" then let me know.
Thanks!
Afficher les réponses par date
There are two things I don’t like about this extension to the reader. The implementation unconditionnaly throws away the location information (the “unwrap”) that could be useful if the form being read contains code. I understand that this is probably what you want when the form is treated as a literal constant, but this is not always the case.
Also, it opens the door to add custom syntax that may clash with future extensions to Gambit's lexical syntax. While it is good to have hooks to extend Gambit, it would be good if such extensions have some support from the community (in other words, do other people think this is the best way to extend the lexical syntax).
I remember SRFI 10, which is an extension to the lexical syntax with similar goals, and also the JazzScheme syntax for literal constants, i.e. {typename …}. Perhaps something like that would be better to avoid a proliferation of different syntaxes for the same thing. Also there are interesting “bootstrapping” issues such as the need to define the type before using the extended lexical syntax. It would be nice if literal constants could be used in the same file that defines the types (i.e. no phasing problem).
Marc
On Feb 17, 2016, at 11:48 AM, Adam adam.mlmb@gmail.com wrote:
Dear Marc & list,
First, the fun stuff suggested is in the "Result, usage" secton below - check it out first :D
This is to discuss the pull request https://github.com/feeley/gambit/pull/180 that I just made.
I hope this provides a clean and practical solution to a problem that has been discussed here on the list last years, and to which not really clean solutions have been suggested until now.
Marc, in particular can you please check out my question secton "Implementation stuff I don't remember why - Marc clarify?" right at the bottom here, and let us know so everyone will know why it needs to be exactly like this? Thanks!
Purpose There are times when as a user you want to enhance your s-expression format with a custom type.
E.g., sometimes you have a custom value type such as an FFI type, that you want to make serializable.
Problem The writer is fairly easy to extend, you just overlap Gambit's |##wr| procedure with your own (lambda (write-env obj) ...) procedure, where |obj| is the value that Gambit is serializing right now, and that procedure either does its own serialization by outputting the customs structure using (##wr-str write-env string-serialized-form), or passes on execution to the underlying (original) |##wr|.
So so far so good.
The reader is more complex to extend though.
One syntax that theoretically could have worked would have been took into gambit's #. syntax, to inline actual code to be evaluated by the reader, in the serialized form of the sexp. That is not only unsafe though, but also, Gambit namespace management is a task that is difficult to impossible - Gambit is simply not really made for that, so having your custom forms of data serialized to #.(my-data-form ...) does not scale.
The solution I suggest Luckily, internally Gambit has a procedure |##readtable-char-sharp-handler-set!|, which installs user-defined hash-sequence deserializer in a readtable!
E.g. install an #\X-character handler into it, and any read element #Xyour-data will have your-data readable by that custom handler.
Implementation problem 1 The problem then is that Gambit not exports any ways to make your own custom handlers - it just exports its own handlers, such as |##read-sharp-vector| (for "#(..."), |##read-sharp-char| (for "#..."), |##read-sharp-dot| (for "#...."), |##read-sharp-bang| (for "#!..."), etc. . (All those are implemented in lib/_io.scm , and are installed in every readtable using - you guessed it - |##readtable-char-sharp-handler-set!|, in |##make-standard-readtable|.)
To implement your own handler, you need access to the lowlevel macros |macro-read-next-char-or-eof|, |macro-readenv-filepos-set!| and |macro-readenv-wrap|.
Also, perhaps, even if you had access to those macros in userland, because Gambit's IO could change at some point perhaps actually using them in userland would be a hack - and so, it would be better if Gambit exported a generalized mechanism for the user to implement his own readtable handlers, that itself takes care of the lowlevel stuff.
Implementation problem 1 solution To enable users to implement their own readtable handlers, I suggest the inclusion into Gambit of a procedure |##make-readtable-char-sharp-sexp-reader-transformer|, which takes the arguments (transform #!optional (read ##read-datum-or-label)) and returns a readtable hash-sequence deserializer for use with |##readtable-char-sharp-handler-set!|.
|transform| is the user-provided function that receives as only argument the data that was read out of the sexp in an ordinary format (discussed below), and performs any conversion to that to the custom format (e.g. C FFI type etc.) - the transform procedure evaluates to the conversion result to be used in the sexp.
|##make-readtable-char-sharp-sexp-reader-transformer| abstracts away the need of taking care of/takes care of all the Gambit-IO-internal macros, as discussed above.
Implementation problem 2 The next problem is how the content of that custom hash-sequnce type is read -
The different ##read-sharp-* procedures all implement their own specific deserializer logics, to read the different hash-sequence formats e.g. "#(e1 e2)", "#\newline", "#!value", "#|| comment ||", etc. - rightly so as the formats are completely custom to the respective hash-sequence.
The ##read-sharp-* procedures frequently, but not always, implement the whole reading logic locally in themselves.
There are some instances of reading logics defined globally though -
• |##read-datum-or-label| reads a single datum (e.g. "abc", "123", "#f" or "(1 2 3)"), that one is used by |##read-sharp-ampersand|, for deserialization of the box form e.g. "#&#t", or for the datum-comment form e.g. "#;(im not read)".
• |##read-expr-from-port| reads any expression from a port, for |##eval| to be fed with it. That one is used by |##read-sharp-dot|, e.g. for "#.(+ 1 2)".
• There's a bunch of ##build- forms for reading vectors, lists, integers
• |##read-datum-or-label-or-none-or-dot| seems to read pretty much anything, and is used for instance as continuation for the whole reading process. Implementation problem 2 solution Of these, it seems to me that |##read-datum-or-label| is a perfect default - in particular, the list type makes perfect sense for storing complex custom types.
Implementation stuff I don't remember why - Marc clarify? As of the moment of writing, • What's the label-marker check and error handling for?
• Why is the "unwrap":ping during the call to the |read| procedure needed? Result, usage The result of this addition is that you can plug in your custom serialization code as follows:
(define-type coord x y)
(##readtable-char-sharp-handler-set! (input-port-readtable (repl-input-port)) #$ (##make-readtable-char-sharp-sexp-reader-transformer (lambda (v) (apply make-coord v))))
(set! ##wr (let* ((old-wr ##wr)) (lambda (we obj) (if (coord? obj) (begin (##wr-str we "#$") (##wr-str we (object->string (list (coord-x obj) (coord-y obj))))) (old-wr we obj)))))
And it's used as follows:
(make-coord 15 16)
#$(15 16)
(define c #) (coord-x c)
15
c
#$(15 16)
(object->string c)
"#$(15 16)"
(call-with-input-string # read)
#$(15 16)
The only important catch to be aware of, is that actually typing in #$(15 16) in the REPL will evaluate to the object, which will then cause an exception:
#$(15 16)
*** ERROR IN (console)@19.3 -- Ill-formed expression
That's analogous to:
(eval print)
*** ERROR -- Ill-formed expression #<procedure #16 print> 1>
As of the time of this post, the extention consists only of the following addition to lib/_io.scm :
(define (##make-readtable-char-sharp-sexp-reader-transformer transform #!optional (read ##read-datum-or-label))
(define (read-without-wrap re) (let* ((old-wrapper (macro-readenv-wrapper re)) (old-unwrapper (macro-readenv-unwrapper re))) (macro-readenv-wrapper-set! re (lambda (re x) x)) (macro-readenv-unwrapper-set! re (lambda (re x) x)) (let ((result (read re))) (macro-readenv-wrapper-set! re old-wrapper) (macro-readenv-unwrapper-set! re old-unwrapper) result)))
(lambda (re next start-pos) (macro-read-next-char-or-eof re) ;; skip char after ## (macro-readenv-filepos-set! re start-pos) ;; set pos to start of datum (let ((args (read-without-wrap re))) (if (##label-marker? args) (begin (##raise-datum-parsing-exception 'datum-or-eof-expected re) (##void)) (let ((obj (transform args))) (macro-readenv-wrap re obj))))))
Perhaps this can be simplified further.
Looking forward to your thoughts and feedback, and I hope to finally enable Gambit with this :)
In particular if you feel any name would be more relevant than "##make-readtable-char-sharp-sexp-reader-transformer" then let me know.
Thanks!
Marc & list,
Before getting into a specific response, I wish to re-emphasise the high priority I feel this topic has. So better something now than something slightly more perfect in couple years.
2016-02-23 2:57 GMT+07:00 Marc Feeley feeley@iro.umontreal.ca:
There are two things I don’t like about this extension to the reader. The implementation unconditionnaly throws away the location information (the “unwrap”) that could be useful if the form being read contains code. I understand that this is probably what you want when the form is treated as a literal constant, but this is not always the case.
I agree that could be useful. Perhaps unwrapping could be exposed to the user too, via an argument (do-you-want-the-value-unwrapped?) and/or traversal routines (access-this-or-that-slot-in-the-wrapped-object).
Also, it opens the door to add custom syntax that may clash with future extensions to Gambit's lexical syntax. While it is good to have hooks to extend Gambit, it would be good if such extensions have some support from the community (in other words, do other people think this is the best way to extend the lexical syntax).
Sure.
We (you+community) are the ones to make up our minds about this now.
The clashing problem shouldn't be too bad though - the sexp format is set in stone already. So I guess the worst thing would be if Gambit would introduce some extension later, that an individual user would get to a place of NOT wanting to overlap at the time then, and so hence his need to remap that new Gambit feature to another hash sequence in order to be able to use it, and that would cause suffering, confusion etc. for that particular user and all his followers, then -
That's the problem surface (and also not worse than that).
I remember SRFI 10, which is an extension to the lexical syntax with similar goals, and also the JazzScheme syntax for literal constants, i.e. {typename …}. Perhaps something like that would be better to avoid a proliferation of different syntaxes for the same thing.
What options do we have on the table?
I like the "#C(typename slot1 slot2 ...)" form (with a simpler "#Cdatum" variant).
My patch leaves the C letter to be chosen by the user, so also it could be used to implement regexp forms e.g. #/regexp/ , etc., so it has a more wide, general utility.
Also there are interesting “bootstrapping” issues such as the need to
define the type before using the extended lexical syntax. It would be nice if literal constants could be used in the same file that defines the types (i.e. no phasing problem).
Sure. But wait, can't you extract the current input port and from that in turn the readtable - so at least as long as the custom form is installed using |##readtable-char-sharp-handler-set!|, then there is in actuality no problem?
Personally I think my thought highlighted in red above creates a rather strong, wider argument for that something functionally like I suggest should be introduced, even if perhaps it won't be used primarily for custom types later on - and the blue text perhaps reinforces that additionally. So like to sum it up it has a general purpose and it's simple.
The bigger question on this topic perhaps is what I highlighted in yellow above, that is, what options do we have at hand for syntaxes for used-defined sexp extensions?
Do you feel that we should give a look at that before making up our minds about this particular?
Also, do you have any thoughts on how the wrapping aspect can be addressed (purple)?
Would be great if we could clarify this point within 3 weeks from now :D
Thanks :D
2016-02-23 4:06 GMT+07:00 Adam adam.mlmb@gmail.com:
Marc & list,
Before getting into a specific response, I wish to re-emphasise the high priority I feel this topic has. So better something now than something slightly more perfect in couple years.
...
Would be great if we could clarify this point within 3 weeks from now :D
The reason I push on this now is that the current solution (i.e. solving the problem of implementing user defined formats in the sexp reader) requires use of Gambit functionality that is not exported, and hence or a user to use it a patch to Gambit's internals are needed,
and such patches will always be a hack in some way (they're not futureproof, etc.),
and I feel this problem is of a generality high enough for some kind of solution to be devised for it (so much that the hack not will be needed),
and therefore even a practical yet imperfect solution such as the one I suggested, would be preferable to no solution at all (meaning the hack would remain => problems).
Anyhow with this said, I perfectly agree with your points, and I look forward to that we discuss and clarify this soon as to implement it.
All I need for practical purposes is a functional equivalent of "#C(user-internal-type-name [content of structure of that user internal type, as separate values])", it could look any other way that you suggest.
I'll also want to make *table* contents serializable in my usecase because I need it, e.g. "#C(table eq? ((a . b) (c . d)))", or perhaps "#T(eq? ((a . b) (c . d)))".
Guillaume is making an excellent point here. (Reposted below with his permission.)
(To paraphrase him,) I suggest that https://github.com/feeley/gambit/pull/180 should be included because *it's reasonable that users should be able to* implement their own hash-sequence extensions.
We don't need to make a bigger philosophical deal about it than that. This is low-level.
Also I think all reasonable uses will be about data and not code, and therefore they will *not* need any line numbering or similar info, so the unwrapping is fine - or easy access to an unwrapping routine (you choose). So finally perhaps the only thing would be to give it a better name, if you want that.
Please let me know if-when it can be included in Gambit :D
Thanks!!
2016-02-24 21:04 GMT+07:00 Guillaume Cartier gucartier@gmail.com:
Hi Adam,
I think the main thing I'd say is that from my experience, waiting for Marc to integrate something into Gambit so as "not to use undocumented features", you will wait a long time :) I'd say don't worry too much about using undocumented stuff. I think it is actually a wonderful feature that Gambit exposes its internal stuff, where in many languages you just don't have any access to internals. JazzScheme uses what I'd say is a "healthy" mix of mostly documented features and various undocumented features.
One reason I say you'll be waiting a long time is that a big design goal in Gambit is to *not* go into unclear how best to implement high-level features. In this Marc is really in-tune with the old R5RS philosophy, which is kinda obvious since he was on the committee :) Regarding that, I think Marc should include the low-level part of your code to implement #\ extensions even if he feels the higher level stuff is unclear.
Cheers, Guillaume
On Mon, Feb 22, 2016 at 4:29 PM, Adam adam.mlmb@gmail.com wrote:
Dear Guillaume,
I trust you are well -
if you have any thoughts about the sexp extension ML topic right now feel free to tell there,
Thanks :)
As a solution for the short term, I have moved the macro-read-next-char-or-eof and macro-peek-next-char-or-eof macros to _io#.scm so that they can be used after an (include "~~lib/_gambit#.scm").
So you should be able to easily implement the extension you want locally.
Marc
On Feb 24, 2016, at 1:04 PM, Adam adam.mlmb@gmail.com wrote:
Guillaume is making an excellent point here. (Reposted below with his permission.)
(To paraphrase him,) I suggest that https://github.com/feeley/gambit/pull/180 should be included because it's reasonable that users should be able to implement their own hash-sequence extensions.
We don't need to make a bigger philosophical deal about it than that. This is low-level.
Also I think all reasonable uses will be about data and not code, and therefore they will not need any line numbering or similar info, so the unwrapping is fine - or easy access to an unwrapping routine (you choose). So finally perhaps the only thing would be to give it a better name, if you want that.
Please let me know if-when it can be included in Gambit :D
Thanks!!
2016-02-24 21:04 GMT+07:00 Guillaume Cartier gucartier@gmail.com: Hi Adam,
I think the main thing I'd say is that from my experience, waiting for Marc to integrate something into Gambit so as "not to use undocumented features", you will wait a long time :) I'd say don't worry too much about using undocumented stuff. I think it is actually a wonderful feature that Gambit exposes its internal stuff, where in many languages you just don't have any access to internals. JazzScheme uses what I'd say is a "healthy" mix of mostly documented features and various undocumented features.
One reason I say you'll be waiting a long time is that a big design goal in Gambit is to *not* go into unclear how best to implement high-level features. In this Marc is really in-tune with the old R5RS philosophy, which is kinda obvious since he was on the committee :) Regarding that, I think Marc should include the low-level part of your code to implement #\ extensions even if he feels the higher level stuff is unclear.
Cheers, Guillaume
On Mon, Feb 22, 2016 at 4:29 PM, Adam adam.mlmb@gmail.com wrote: Dear Guillaume,
I trust you are well -
if you have any thoughts about the sexp extension ML topic right now feel free to tell there,
Thanks :)
What about macro-readenv-filepos-set!, macro-readenv-wrapper, macro-readenv-unwrapper, macro-readenv-wrapper-set!, macro-readenv-unwrapper-set!, macro-readenv-wrap?
2016-02-25 3:37 GMT+07:00 Marc Feeley feeley@iro.umontreal.ca:
As a solution for the short term, I have moved the macro-read-next-char-or-eof and macro-peek-next-char-or-eof macros to _io#.scm so that they can be used after an (include "~~lib/_gambit#.scm").
So you should be able to easily implement the extension you want locally.
Marc
On Feb 24, 2016, at 1:04 PM, Adam adam.mlmb@gmail.com wrote:
Guillaume is making an excellent point here. (Reposted below with his
permission.)
(To paraphrase him,) I suggest that
https://github.com/feeley/gambit/pull/180 should be included because it's reasonable that users should be able to implement their own hash-sequence extensions.
We don't need to make a bigger philosophical deal about it than that.
This is low-level.
Also I think all reasonable uses will be about data and not code, and
therefore they will not need any line numbering or similar info, so the unwrapping is fine - or easy access to an unwrapping routine (you choose). So finally perhaps the only thing would be to give it a better name, if you want that.
Please let me know if-when it can be included in Gambit :D
Thanks!!
2016-02-24 21:04 GMT+07:00 Guillaume Cartier gucartier@gmail.com: Hi Adam,
I think the main thing I'd say is that from my experience, waiting for
Marc to integrate something into Gambit so as "not to use undocumented features", you will wait a long time :) I'd say don't worry too much about using undocumented stuff. I think it is actually a wonderful feature that Gambit exposes its internal stuff, where in many languages you just don't have any access to internals. JazzScheme uses what I'd say is a "healthy" mix of mostly documented features and various undocumented features.
One reason I say you'll be waiting a long time is that a big design goal
in Gambit is to *not* go into unclear how best to implement high-level features. In this Marc is really in-tune with the old R5RS philosophy, which is kinda obvious since he was on the committee :) Regarding that, I think Marc should include the low-level part of your code to implement #\ extensions even if he feels the higher level stuff is unclear.
Cheers, Guillaume
On Mon, Feb 22, 2016 at 4:29 PM, Adam adam.mlmb@gmail.com wrote: Dear Guillaume,
I trust you are well -
if you have any thoughts about the sexp extension ML topic right now
feel free to tell there,
Thanks :)
Those are already exported by _io#.scm and are therefore accessible after including ~~lib/_gambit.scm .
Marc
On Feb 24, 2016, at 3:44 PM, Adam adam.mlmb@gmail.com wrote:
What about macro-readenv-filepos-set!, macro-readenv-wrapper, macro-readenv-unwrapper, macro-readenv-wrapper-set!, macro-readenv-unwrapper-set!, macro-readenv-wrap?
2016-02-25 3:37 GMT+07:00 Marc Feeley feeley@iro.umontreal.ca: As a solution for the short term, I have moved the macro-read-next-char-or-eof and macro-peek-next-char-or-eof macros to _io#.scm so that they can be used after an (include "~~lib/_gambit#.scm").
So you should be able to easily implement the extension you want locally.
Marc
On Feb 24, 2016, at 1:04 PM, Adam adam.mlmb@gmail.com wrote:
Guillaume is making an excellent point here. (Reposted below with his permission.)
(To paraphrase him,) I suggest that https://github.com/feeley/gambit/pull/180 should be included because it's reasonable that users should be able to implement their own hash-sequence extensions.
We don't need to make a bigger philosophical deal about it than that. This is low-level.
Also I think all reasonable uses will be about data and not code, and therefore they will not need any line numbering or similar info, so the unwrapping is fine - or easy access to an unwrapping routine (you choose). So finally perhaps the only thing would be to give it a better name, if you want that.
Please let me know if-when it can be included in Gambit :D
Thanks!!
2016-02-24 21:04 GMT+07:00 Guillaume Cartier gucartier@gmail.com: Hi Adam,
I think the main thing I'd say is that from my experience, waiting for Marc to integrate something into Gambit so as "not to use undocumented features", you will wait a long time :) I'd say don't worry too much about using undocumented stuff. I think it is actually a wonderful feature that Gambit exposes its internal stuff, where in many languages you just don't have any access to internals. JazzScheme uses what I'd say is a "healthy" mix of mostly documented features and various undocumented features.
One reason I say you'll be waiting a long time is that a big design goal in Gambit is to *not* go into unclear how best to implement high-level features. In this Marc is really in-tune with the old R5RS philosophy, which is kinda obvious since he was on the committee :) Regarding that, I think Marc should include the low-level part of your code to implement #\ extensions even if he feels the higher level stuff is unclear.
Cheers, Guillaume
On Mon, Feb 22, 2016 at 4:29 PM, Adam adam.mlmb@gmail.com wrote: Dear Guillaume,
I trust you are well -
if you have any thoughts about the sexp extension ML topic right now feel free to tell there,
Thanks :)
Aha cool.
Ok this would change a userland application from "acute hack" to just "hack" -
I can still feel that why it needs to work this way is a bit unclear, would you mind explaining the significance in https://github.com/feeley/gambit/pull/180/files of rows
- 11286-11287, - 11295, - 11297-11300, and - 11302
respectively?
2016-02-25 4:04 GMT+07:00 Marc Feeley feeley@iro.umontreal.ca:
Those are already exported by _io#.scm and are therefore accessible after including ~~lib/_gambit.scm .
Marc
On Feb 24, 2016, at 3:44 PM, Adam adam.mlmb@gmail.com wrote:
What about macro-readenv-filepos-set!, macro-readenv-wrapper,
macro-readenv-unwrapper, macro-readenv-wrapper-set!, macro-readenv-unwrapper-set!, macro-readenv-wrap?
2016-02-25 3:37 GMT+07:00 Marc Feeley feeley@iro.umontreal.ca: As a solution for the short term, I have moved the
macro-read-next-char-or-eof and macro-peek-next-char-or-eof macros to _io#.scm so that they can be used after an (include "~~lib/_gambit#.scm").
So you should be able to easily implement the extension you want locally.
Marc
On Feb 24, 2016, at 1:04 PM, Adam adam.mlmb@gmail.com wrote:
Guillaume is making an excellent point here. (Reposted below with his
permission.)
(To paraphrase him,) I suggest that
https://github.com/feeley/gambit/pull/180 should be included because it's reasonable that users should be able to implement their own hash-sequence extensions.
We don't need to make a bigger philosophical deal about it than that.
This is low-level.
Also I think all reasonable uses will be about data and not code, and
therefore they will not need any line numbering or similar info, so the unwrapping is fine - or easy access to an unwrapping routine (you choose). So finally perhaps the only thing would be to give it a better name, if you want that.
Please let me know if-when it can be included in Gambit :D
Thanks!!
2016-02-24 21:04 GMT+07:00 Guillaume Cartier gucartier@gmail.com: Hi Adam,
I think the main thing I'd say is that from my experience, waiting for
Marc to integrate something into Gambit so as "not to use undocumented features", you will wait a long time :) I'd say don't worry too much about using undocumented stuff. I think it is actually a wonderful feature that Gambit exposes its internal stuff, where in many languages you just don't have any access to internals. JazzScheme uses what I'd say is a "healthy" mix of mostly documented features and various undocumented features.
One reason I say you'll be waiting a long time is that a big design
goal in Gambit is to *not* go into unclear how best to implement high-level features. In this Marc is really in-tune with the old R5RS philosophy, which is kinda obvious since he was on the committee :) Regarding that, I think Marc should include the low-level part of your code to implement #\ extensions even if he feels the higher level stuff is unclear.
Cheers, Guillaume
On Mon, Feb 22, 2016 at 4:29 PM, Adam adam.mlmb@gmail.com wrote: Dear Guillaume,
I trust you are well -
if you have any thoughts about the sexp extension ML topic right now
feel free to tell there,
Thanks :)
Aha cool.
So, a user can then define his own custom Gambit with ##make-readtable-char-sharp-sexp-reader-transformer support by making a file mycustomgambit.scm that contains
(##define-macro (interpreter-or x) x) (##include "~~/lib/header.scm") (##include "~~/lib/gsi_main.scm")
and then the ##make-readtable-char-sharp-sexp-reader-transformer definition, so that's https://github.com/feeley/gambit/pull/180/files 's contents.
Sure works. And that should be IO code that changes only rarely.
2016-02-25 4:04 GMT+07:00 Marc Feeley feeley@iro.umontreal.ca:
Those are already exported by _io#.scm and are therefore accessible after including ~~lib/_gambit.scm .
Marc
On Feb 24, 2016, at 3:44 PM, Adam adam.mlmb@gmail.com wrote:
What about macro-readenv-filepos-set!, macro-readenv-wrapper,
macro-readenv-unwrapper, macro-readenv-wrapper-set!, macro-readenv-unwrapper-set!, macro-readenv-wrap?
2016-02-25 3:37 GMT+07:00 Marc Feeley feeley@iro.umontreal.ca: As a solution for the short term, I have moved the
macro-read-next-char-or-eof and macro-peek-next-char-or-eof macros to _io#.scm so that they can be used after an (include "~~lib/_gambit#.scm").
So you should be able to easily implement the extension you want locally.
Marc
On Feb 24, 2016, at 1:04 PM, Adam adam.mlmb@gmail.com wrote:
Guillaume is making an excellent point here. (Reposted below with his
permission.)
(To paraphrase him,) I suggest that
https://github.com/feeley/gambit/pull/180 should be included because it's reasonable that users should be able to implement their own hash-sequence extensions.
We don't need to make a bigger philosophical deal about it than that.
This is low-level.
Also I think all reasonable uses will be about data and not code, and
therefore they will not need any line numbering or similar info, so the unwrapping is fine - or easy access to an unwrapping routine (you choose). So finally perhaps the only thing would be to give it a better name, if you want that.
Please let me know if-when it can be included in Gambit :D
Thanks!!
2016-02-24 21:04 GMT+07:00 Guillaume Cartier gucartier@gmail.com: Hi Adam,
I think the main thing I'd say is that from my experience, waiting for
Marc to integrate something into Gambit so as "not to use undocumented features", you will wait a long time :) I'd say don't worry too much about using undocumented stuff. I think it is actually a wonderful feature that Gambit exposes its internal stuff, where in many languages you just don't have any access to internals. JazzScheme uses what I'd say is a "healthy" mix of mostly documented features and various undocumented features.
One reason I say you'll be waiting a long time is that a big design
goal in Gambit is to *not* go into unclear how best to implement high-level features. In this Marc is really in-tune with the old R5RS philosophy, which is kinda obvious since he was on the committee :) Regarding that, I think Marc should include the low-level part of your code to implement #\ extensions even if he feels the higher level stuff is unclear.
Cheers, Guillaume
On Mon, Feb 22, 2016 at 4:29 PM, Adam adam.mlmb@gmail.com wrote: Dear Guillaume,
I trust you are well -
if you have any thoughts about the sexp extension ML topic right now
feel free to tell there,
Thanks :)