Re: Fixing the slib mess
Hi Mikael and welcome back! *But*, the proper implementation of syntax-toplevel? requires modification of psyntax.scm and adding it to the (system syntax) module. I didn't want to do this until I've had your comments, so the present patch has its own syntax-object accessors (which breaks abstraction and is therefore not a real solution). I should also say that I have not yet fixed the slib interface to the new Guile uniform arrays, so there's a lot of slib functionality which won't yet work. Comments? Can I add syntax-toplevel? to psyntax.scm and (system syntax)? Do you think it is reasonable to submit something along the line of guile.init.diff to slib guile.init? Best regards, Mikael Djurfeldt I can answer with some kind of suggestion here. in (system syntax) there is syntax-local-binding which you can use for example as (define-syntax f (lambda (x) (syntax-case x () ((_ x) (call-with-values (lambda () (syntax-local-binding #'x)) (lambda (x y) (pk x) (pk y))) #'#t Then, scheme@(guile-user) [1] (f +) ;;; (global) ;;; ((+ guile-user)) And, scheme@(guile-user) [1] (let ((s 1)) (f s)) ;;; (lexical) ;;; (s-490) (let ((s 1)) (define-syntax g (lambda (x) #'#f)) (f g)) ;;; (displaced-lexical) ;;; (#f) I'm not sure what exactly syntax-toplevel? does, but can you base it on syntax-local-binding? And if not is it possible to change syntax-local-binding so that you can use it? Regards Stefan
Re: Fixing the slib mess
On Mon, Oct 22, 2012 at 8:31 PM, Stefan Israelsson Tampe stefan.ita...@gmail.com wrote: Comments? Can I add syntax-toplevel? to psyntax.scm and (system syntax)? [...] I can answer with some kind of suggestion here. in (system syntax) there is syntax-local-binding which you can use for example as (define-syntax f (lambda (x) (syntax-case x () ((_ x) (call-with-values (lambda () (syntax-local-binding #'x)) (lambda (x y) (pk x) (pk y))) #'#t Then, scheme@(guile-user) [1] (f +) ;;; (global) ;;; ((+ guile-user)) And, scheme@(guile-user) [1] (let ((s 1)) (f s)) ;;; (lexical) ;;; (s-490) (let ((s 1)) (define-syntax g (lambda (x) #'#f)) (f g)) ;;; (displaced-lexical) ;;; (#f) I'm not sure what exactly syntax-toplevel? does, but can you base it on syntax-local-binding? And if not is it possible to change syntax-local-binding so that you can use it? Thanks, Stefan. (syntax-toplevel?) expands to #t if occurs in a context (position in the code if you prefer) where a (define x #f) would create/set! a global binding for x. It expands to #f otherwise. I had a look at syntax-local-binding, but decided that syntax-toplevel? was needed since the latter is not trying to determine the nature of an existing binding but rather the nature of the context. Of course oncould probe the context by first creating a new binding (with some random name) and then use syntax-local-binding to determine the nature of the context by looking at the new binding, but that seems somewhat invasive. :-)
Re: Fixing the slib mess
Yes in that case this stands on it's own! /Stefan On Mon, Oct 22, 2012 at 9:11 PM, Mikael Djurfeldt mik...@djurfeldt.comwrote: On Mon, Oct 22, 2012 at 8:31 PM, Stefan Israelsson Tampe stefan.ita...@gmail.com wrote: Comments? Can I add syntax-toplevel? to psyntax.scm and (system syntax)? [...] I can answer with some kind of suggestion here. in (system syntax) there is syntax-local-binding which you can use for example as (define-syntax f (lambda (x) (syntax-case x () ((_ x) (call-with-values (lambda () (syntax-local-binding #'x)) (lambda (x y) (pk x) (pk y))) #'#t Then, scheme@(guile-user) [1] (f +) ;;; (global) ;;; ((+ guile-user)) And, scheme@(guile-user) [1] (let ((s 1)) (f s)) ;;; (lexical) ;;; (s-490) (let ((s 1)) (define-syntax g (lambda (x) #'#f)) (f g)) ;;; (displaced-lexical) ;;; (#f) I'm not sure what exactly syntax-toplevel? does, but can you base it on syntax-local-binding? And if not is it possible to change syntax-local-binding so that you can use it? Thanks, Stefan. (syntax-toplevel?) expands to #t if occurs in a context (position in the code if you prefer) where a (define x #f) would create/set! a global binding for x. It expands to #f otherwise. I had a look at syntax-local-binding, but decided that syntax-toplevel? was needed since the latter is not trying to determine the nature of an existing binding but rather the nature of the context. Of course oncould probe the context by first creating a new binding (with some random name) and then use syntax-local-binding to determine the nature of the context by looking at the new binding, but that seems somewhat invasive. :-)
Re: Fixing the slib mess
On Mon, Oct 22, 2012 at 1:11 AM, Mikael Djurfeldt mik...@djurfeldt.com wrote: Comments? Can I add syntax-toplevel? to psyntax.scm and (system syntax)? Do you think it is reasonable to submit something along the line of guile.init.diff to slib guile.init? If I get an OK, then I would of course put some further work into this so that the full feature set of slib (including uniform arrays) gets operational. If people find my prodigious use of nested-ref ugly (but note that the original code already makes use of module system primitives), I could remove most of them as well.
Re: Fixing the slib mess
Hi Mikael! It's great to see you on guile-devel again, and it would be good to have a working slib on Guile 2. Thanks for working on this :) Mikael Djurfeldt mik...@djurfeldt.com writes: Comments? Can I add syntax-toplevel? to psyntax.scm and (system syntax)? FWIW, it sounds reasonable to add something like 'syntax-toplevel?'. However, if it's going to be added as a public API, we ought to be careful to get it right. Consider this top-level form: (let-syntax ((foo (syntax-rules () ((foo x) (quote x) (define bar (foo (a b Here, although the 'define' is expanded within a non-toplevel syntactic environment, after expansion it ends up within a top-level environment, and indeed 'bar' becomes a top-level binding. That's because the body of a 'let-syntax' or 'letrec-syntax' gets spliced into the outer context, sort of like a 'begin' but with some syntax bindings added. It looks to me like your current implementation of 'syntax-toplevel?' is actually testing for a top-level _syntactic_ environment, but what you ought to be testing for here is slightly different. I'm not sure what is the proper term, but for now I'll call it a top-level _execution_ environment. I'm also not quite sure how best to test for a top-level execution environment. I'm not sure whether the wrap contains enough information to determine that. It might be easier to handle this with 'define-syntax-parameter' and 'syntax-parameterize'. The idea would be that within slib, 'define' would be a syntax parameter. Its default expansion would turn it into 'define-public', and also parameterize 'define' to mean 'base:define' within the body. If needed, you could also define 'let' and maybe some other things to parameterize 'define' within the body. Another option would be to make 'export' a syntax parameter, and parameterize it to a no-op within lexical contours such as 'define' and 'let'. What do you think? I should also say that I have not yet fixed the slib interface to the new Guile uniform arrays, so there's a lot of slib functionality which won't yet work. I happen to be working on the reader lately. Would it help to implement SRFI-58 in our reader? Note that SRFI-58 array notation conflicts with Guile's own array notation, e.g. #1a(a b) is legal in both syntaxes and means different things. So we'd need to use a reader-directive such as #!srfi-58 to change the reader mode on that port. Would that help? Thanks for working on this! Regards, Mark