Re: Improve `seed->random-state' in stable-2.0?
Hi Mark, On Fri 20 Jan 2012 23:45, Mark H Weaver writes: > Andy Wingo writes: > >> How about, we extend seed->random-state to operate on bytevectors, and >> have that interface do the right thing. > > I agree that it would be nice for `seed->random-state' to support > bytevectors as well, but for many (most?) purposes that would be a very > awkward interface to use. Really? My thought would be that if I have to initialize a PRNG, I need some random bits. Dunno. Deprecating the number interface does have the advantage that we can perhaps move people to use your nice new functions, instead of initializing with (getpid) or whatever it is that they are using. > Even if we keep a broken `seed->random-state', there's another problem: > our PRNG sucks rocks. If we constrain ourselves to produce the same > sequence of random numbers for a given seed, that means that we're stuck > with this very weak PRNG for the entire 2.0 series. > > Can't we just make a clean break now? 2.0 is still not widely deployed, > so now is a great time to assert our right to change the PRNG at will. > As you say, it's unlikely that anyone is relying on this anyway. > If anyone is, wouldn't it be better to deal with that now? While I agree about the badness of the PRNG -- though we shouldn't overstate that; for being so simple, MWC does well -- but I really don't think that we should change the default behavior now. OTOH, we can make seed->random-state on bytevectors return an rstate with a different implementation of scm_t_rng -- for example, we could use GMP's mersenne twister API. In any case, don't let stability concerns stop you from hacking on a fix! We'll probably get the first 2.2 preview out within a a year, and we certainly need to change the default behavior for then Andy -- http://wingolog.org/
Re: Improve `seed->random-state' in stable-2.0?
On Sat 21 Jan 2012 00:46, Mike Gran writes: > (seed->random-state (current-time)) seems to be a common idiom that > you would end up breaking. This is a common idiom that is worth deprecating. Mark's new functions that seed the random state from /dev/urandom are much better. So no, no plans to break anything -- but we should help these people write better programs. Regards, Andy -- http://wingolog.org/
Re: add-relative-load-path ?
Hi Neil, Thanks for the feedback! On Sun 22 Jan 2012 00:17, Neil Jerram writes: > Thing 1 is that (current-filename) can return a relative filename, or a > filename with a "./" in its middle [...] > > Would there be any downside from putting [canonicalize-path] inside > current-filename, so that current-filename always returns a canonical > file name? No, and I think that is the right thing to do in this case, because it avoids embedding assumptions about the current working directory into compiled .go files. I have made this change. > Thing 2 is that it remains slightly inelegant to cater for both 1.8 and > 2.0. I think the minimal complete solution is to write > > (cond-expand (guile-2 (include "setup-load-path.scm")) > (else (load "setup-load-path.scm"))) > > at top level in every uninstalled script, and then something like > > (cond-expand (guile-2 > (add-to-load-path > (dirname > (dirname >(canonicalize-path (current-filename)) >(else > ;; Less elegant code for 1.8... > (let* ((bindir (dirname (car (command-line >(absdir (cond ((string=? bindir ".") > (getcwd)) > ((string-match "^/" bindir) > bindir) > (else > (in-vicinity (getcwd) bindir) > (set! %load-path (cons (in-vicinity absdir "..") > %load-path) > > in setup-load-path.scm. > > But without a time machine I don't think anything can be done to make > either of those fragments more concise. Well, you could instead do: (cond-expand ((not guile-2) (load "guile-2.0-compat.scm"))) (add-to-load-path (dirname (dirname (current-filename Then in guile-2.0-compat.scm you have shims to make guile 1.8 offer a 2.0 interface (in this case, current-filename and add-to-load-path). >> +@code{primitive-load}, and @code{load-path} and > > Is it 'load-path' or 'load-from-path'? load-from-path. Fixed! Thanks, Andy -- http://wingolog.org/
Re: Eval, tail calls, (current-module), and backward compatibility
On Tue 17 Jan 2012 04:28, Mark H Weaver writes: > Ideally, I think that `eval' should set (current-module) during > expansion, but _not_ during evaluation. Then it can be properly tail > recursive. However, some code out there might depend on the existing > behavior, so I guess we can't change this, at least not in 2.0. > Bummer. Dunno. There are lots of instances of (current-module) in our current code, and in code from lots of external projects. I think if we changed it, it would break a lot of stuff, subtly. Andy -- http://wingolog.org/
Re: syntax-local-value patch for discussion
Hi Stefan, On Thu 19 Jan 2012 10:50, Stefan Israelsson Tampe writes: > Working on porting syntax-parse is a learning experience and I know > understand how it uses syntax-local-value as a way to lookup a syntax > object by joining the wraps together with the total wrap at the macro > call. syntax-local-binding just uses the wrap from the id that you give it, without joining it to the macro expansion environment's wrap. > I would like to have a syntax-join function that takes two syntax > objects and join them correctly and robustly in the pressense of > eventual marks or not. Why would you want to do something like this? You might try writing the documentation of the function first; it would clarify the conversation. Regards, Andy -- http://wingolog.org/
Re: syntax-locally-bound-identifiers, local-eval
Hi Mark! Thanks for your review of my patches. I would like to say, "our patches", as they are not really mine, but I understand if you don't want to claim parentage in this case :) I fixed the module-related scope issues by adding a new accessor for syntax objects, `syntax-module'. It is like Racket's `syntax-source-module'. I added your expanded test to eval.test, and it works fine. You mention versioning, but I believe that this is a non-issue. If we want to change the format of , we have two more compelling options. One would be to make a compatible change, but that's not always possible. The second would be to define another or something; new expansions of `the-environment' would embed references to this new vtable. Record type predicates could distinguish them for the purposes of local-eval/local-compile. Here are the current patches. I've manually removed the parts that patch psyntax-pp.scm, to not hurt our eyeballs :) >From 68673f7507736f9a39d2d1eac9ef2a9ad1fd80dc Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sun, 15 Jan 2012 18:39:44 +0100 Subject: [PATCH 1/3] add syntax-locally-bound-identifiers * module/ice-9/boot-9.scm (syntax-locally-bound-identifiers): Declare variable. * module/ice-9/psyntax.scm: Add locally-bound-identifiers helper, and define syntax-locally-bound-identifiers. * module/ice-9/psyntax-pp.scm: Regenerated. * doc/ref/api-macros.texi: Document the new procedure. --- doc/ref/api-macros.texi | 37 +- module/ice-9/boot-9.scm |1 + module/ice-9/psyntax-pp.scm |24438 +++ module/ice-9/psyntax.scm| 59 +- 4 files changed, 13078 insertions(+), 11457 deletions(-) diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi index 4702d2f..02b5d5c 100644 --- a/doc/ref/api-macros.texi +++ b/doc/ref/api-macros.texi @@ -744,7 +744,7 @@ information with macros: (define-syntax-rule (with-aux aux value) (let ((trans value)) (set! (aux-property trans) aux) -trans))) +trans)) (define-syntax retrieve-aux (lambda (x) (syntax-case x () @@ -768,6 +768,41 @@ information with macros: a syntax transformer; to call it otherwise will signal an error. @end deffn +@deffn {Scheme Procedure} syntax-locally-bound-identifiers id +Return a list of identifiers that were visible lexically when the +identifier @var{id} was created, in order from outermost to innermost. + +This procedure is intended to be used in specialized procedural macros, +to provide a macro with the set of bound identifiers that the macro can +reference. + +As a technical implementation detail, the identifiers returned by +@code{syntax-locally-bound-identifiers} will be anti-marked, like the +syntax object that is given as input to a macro. This is to signal to +the macro expander that these bindings were present in the original +source, and do not need to be hygienically renamed, as would be the case +with other introduced identifiers. See the discussion of hygiene in +section 12.1 of the R6RS, for more information on marks. + +@example +(define (local-lexicals id) + (filter (lambda (x) +(eq? (syntax-local-binding x) 'lexical)) + (syntax-locally-bound-identifiers id))) +(define-syntax lexicals + (lambda (x) +(syntax-case x () + ((lexicals) #'(lexicals lexicals)) + ((lexicals scope) + (with-syntax (((id ...) (local-lexicals #'scope))) + #'(list (cons 'id id) ...)) + +(let* ((x 10) (x 20)) (lexicals)) +@result{} ((x . 10) (x . 20)) +@end example +@end deffn + + @node Defmacros @subsection Lisp-style Macro Definitions diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index 2c87d13..cd55203 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -390,6 +390,7 @@ If there is no handler at all, Guile prints an error and then exits." (define bound-identifier=? #f) (define free-identifier=? #f) (define syntax-local-binding #f) +(define syntax-locally-bound-identifiers #f) ;; $sc-dispatch is an implementation detail of psyntax. It is used by ;; expanded macros, to dispatch an input against a set of patterns. diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index fd33e98..024bb85 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -791,6 +791,55 @@ id)) (else (syntax-violation 'id-var-name "invalid id" id) +;; A helper procedure for syntax-locally-bound-identifiers, which +;; itself is a helper for transformer procedures. +;; `locally-bound-identifiers' returns a list of all bindings +;; visible to a syntax object with the given wrap. They are in +;; order from outer to inner. +;; +;; The purpose of this procedure is to give a transformer procedure +;; references on bound identifiers, that the transformer can then +;; introduce some of them in its output. As such, the identifiers +;; are anti-marked, so that rebuild-macro-outp
Re: Improve `seed->random-state' in stable-2.0?
> From: Andy Wingo >> (seed->random-state (current-time)) seems to be a common idiom that >> you would end up breaking. > >This is a common idiom that is worth deprecating. Mark's new functions >that seed the random state from /dev/urandom are much better. Are you suggesting that you'll break the API in the hope that when people's code stops working, they'll reread the manual and notice that random-state-from-platform exists? It seems a rather unfriendly way to accomplish that task. Regards, Mike
Re: Improve `seed->random-state' in stable-2.0?
On Mon 23 Jan 2012 14:06, Mike Gran writes: >> From: Andy Wingo >>> (seed->random-state (current-time)) seems to be a common idiom that >>> you would end up breaking. >> >>This is a common idiom that is worth deprecating. Mark's new functions >>that seed the random state from /dev/urandom are much better. > > Are you suggesting that you'll break the API in the hope that when people's > code stops working, they'll reread the manual and notice that > random-state-from-platform exists? > > It seems a rather unfriendly way to accomplish that task. That would indeed be a mean thing to do! It's not what I'm suggesting though. Deprecation means causing Guile to emit warnings, at compile-time or at runtime, indicating that a particular interface will go away at some point, and noting the interface that should be used instead. I think it's fairly helpful, actually, but if you have any suggestions for how it could be improved, they are much welcome. Regards, Andy -- http://wingolog.org/
Re: guile-sqlite3 - patch
Pushed both of these patches; thanks! Andy -- http://wingolog.org/
Re: add-relative-load-path ?
Hello! Thanks for working on it. :-) Andy Wingo skribis: > (add-to-load-path (dirname (dirname (current-filename What about calling it ‘current-file-name’ instead? Ludo’.
Re: Compiler Warning message ideas
Hi Stefan, Stefan Israelsson Tampe skribis: > When compiling newest stable-2.0 I noticed, > > wrote `ice-9/eval.go' > GUILEC ice-9/psyntax-pp.go > GC Warning: Repeated allocation of very large block (appr. size 69632): > May lead to memory leak and poor performance. > wrote `ice-9/psyntax-pp.go' > > E.g. basically making a thread allocates a large block for the stack and > the bohem gc explicitly tells us > that doing this will probably lead to memory leak using their gc. Since it happens only when bootstrapping the compiler, I don’t think it has anything to do with thread stacks, especially since there’s only one thread at this point (plus the signal thread.) Thanks, Ludo’.
Re: syntax-local-value patch for discussion
Ok, here is a discussoin using code in syntax-parse. Let's start with the defintion of a syntax-class, str in the macro package syntax-parse: (define-syntax-class str #:attributes () #:opaque #:commit #:description "string" (pattern (~and x (~fail #:unless (string? (syntax-e #'x)) So the and patterns first match x and then on the same element match a ~fail that fails if the supplied code (string? (syntax-e #'x)) is false. The headake for me is that #'(string? (syntax-e #'x)) is stored in a struct and hence does not get wrapped correctly e.g. after the packaging of this code in a struct, say S we will then issue something like the following code in the expansion of the first match #'(with-syntax ((x stx)) (parse stx S)) and when parse is ready to unpack S we could have S = #(syntax-object # wrap-part hygiene) Now I basically solve this problem by constructing a = (vector 'syntax-object (vector-ref (struct-s-code (syntax->datum S)) 1) (un-mark wrap-part) hygiene) crossing the fingers that the "code" will be nonatomic and then the expander will use it like, (with-syntax ((code a)) #'( code)) This is the story. I do not want to rest here because this solution is not resistant to bitrot and depends on internals that I do not want to touch. The solution would be to have an interface in guile that allows to write, (with-syntax ((code (syntax-embedd (struct-s-code (syntax->datum S)) S))) ( code ...)) e.g. (syntax-embedd exp env-stx) = embedds exp in the syntax env-stx I'm much more fine with dropping env-stx and replace that with the equivalent syntax environment at the macro call I Hope that things are less foggy now! Regards Stefan On Mon, Jan 23, 2012 at 11:53 AM, Andy Wingo wrote: > Hi Stefan, > > On Thu 19 Jan 2012 10:50, Stefan Israelsson Tampe > writes: > > > Working on porting syntax-parse is a learning experience and I know > > understand how it uses syntax-local-value as a way to lookup a syntax > > object by joining the wraps together with the total wrap at the macro > > call. > > syntax-local-binding just uses the wrap from the id that you give it, > without joining it to the macro expansion environment's wrap. > > > I would like to have a syntax-join function that takes two syntax > > objects and join them correctly and robustly in the pressense of > > eventual marks or not. > > Why would you want to do something like this? > > You might try writing the documentation of the function first; it would > clarify the conversation. > > Regards, > > Andy > -- > http://wingolog.org/ >
Re: syntax-local-binding
Heya Mark, On Fri 20 Jan 2012 23:03, Mark H Weaver writes: > (let ((x 1)) > (syntax-local-binding #'x)) > > is not equivalent to: > > (let ((x 1)) > (local-eval '(syntax-local-binding #'x) (the-environment))) Indeed; bummer! I think, though, that this is simply a consequence of giving more power to macro writers. It is analogous in some ways to the changes that identifier-syntax introduce into macro writing: with identifier-syntax, one can no longer write a code walker with syntax-rules pattern matching, as single identifiers may expand out to complicated expressions, possibly even with side effects. >> Why do you think that? The procedures do carry metadata; I understood >> that that was your strategy, to use the serialization of the >> syntax-rules form in the procedure metadata. > > Well, this was in the context of a new strategy where psyntax would > include a new core form called `call-with-current-local-expander' that > calls its parameter (a procedure or macro) with a procedure that accepts > an expression and returns an expanded form. In this case, the most > straightforward implementation would simply serialize the (r w mod) > structures directly. > > Toward that end, I was thinking it would be nice to keep those > structures serializable. The only part that's not currently > serializable are the transformer procedures for local macros. > Thus the change in representation. I have been staring at this empty page here for a little while, writing and re-writing, but I can't get over a feeling that I really don't want this kind of work in psyntax itself. Who knows, maybe you have really convincing arguments here, but this particular argument should not be driving a decision about e.g. including syntax-local-binding or not. That sounds negative, and in a way of course it is -- but still, I'd much rather enable people to make powerful syntactic abstractions like local-eval outside psyntax. Syntax-parse, for example, if it ever lands, will land in the form of a module In this case there are lots of strategies you could use. We could change psyntax to embed the syntax objects in the procedure meta-data, like I said. Ice-9 local-eval could #:replace its own syntax-rules. We could (and probably should) do procedure serialization. Regards, Andy -- http://wingolog.org/
Re: add-relative-load-path ?
Hi, On Mon 23 Jan 2012 16:45, l...@gnu.org (Ludovic Courtès) writes: > Andy Wingo skribis: > >> (add-to-load-path (dirname (dirname (current-filename > > What about calling it ‘current-file-name’ instead? > (apropos "filename") (guile): set-module-filename! # (guile): module-filename # (guile): current-filename (guile): set-port-filename! # (guile): port-filename# (ice-9 readline): filename-completion-function# > (apropos "file-name") > Though I am responsible for three of those, I think I was just following established convention. Andy -- http://wingolog.org/
Re: add-relative-load-path ?
Andy Wingo writes: > Hi, > > On Mon 23 Jan 2012 16:45, l...@gnu.org (Ludovic Courtès) writes: > >> Andy Wingo skribis: >> >>> (add-to-load-path (dirname (dirname (current-filename >> >> What about calling it ‘current-file-name’ instead? I sympathise with that too, although I know I was inconsistent in my own last email in this thread. > > (apropos "filename") > (guile): set-module-filename! # ice-9/boot-9.scm:1712:2 (module val)> > (guile): module-filename# (module)> > (guile): current-filename > (guile): set-port-filename! # > (guile): port-filename # > (ice-9 readline): filename-completion-function # filename-completion-function (_ _)> > > (apropos "file-name") > > > > Though I am responsible for three of those, I think I was just following > established convention. Hmm, tricky to argue with that though. Neil
Re: add-relative-load-path ?
Andy Wingo writes: > Hi Neil, > > Thanks for the feedback! > > On Sun 22 Jan 2012 00:17, Neil Jerram writes: > >> Thing 1 is that (current-filename) can return a relative filename, or a >> filename with a "./" in its middle > [...] >> >> Would there be any downside from putting [canonicalize-path] inside >> current-filename, so that current-filename always returns a canonical >> file name? > > No, and I think that is the right thing to do in this case, because it > avoids embedding assumptions about the current working directory into > compiled .go files. I have made this change. Thanks. >> Thing 2 is that it remains slightly inelegant to cater for both 1.8 and >> 2.0. I think the minimal complete solution is to write >> >> (cond-expand (guile-2 (include "setup-load-path.scm")) >> (else (load "setup-load-path.scm"))) >> >> at top level in every uninstalled script, and then something like >> >> (cond-expand (guile-2 >>(add-to-load-path >> (dirname >> (dirname >> (canonicalize-path (current-filename)) >> (else >> ;; Less elegant code for 1.8... >>(let* ((bindir (dirname (car (command-line >> (absdir (cond ((string=? bindir ".") >> (getcwd)) >> ((string-match "^/" bindir) >> bindir) >> (else >> (in-vicinity (getcwd) bindir) >> (set! %load-path (cons (in-vicinity absdir "..") >> %load-path) >> >> in setup-load-path.scm. >> >> But without a time machine I don't think anything can be done to make >> either of those fragments more concise. > > Well, you could instead do: > > (cond-expand ((not guile-2) (load "guile-2.0-compat.scm"))) Well it seems it has to be (cond-expand (guile-2) (else (load "guile-2.0-compat.scm"))) because cond-expand errors if no clause is satisfied. > (add-to-load-path (dirname (dirname (current-filename > > Then in guile-2.0-compat.scm you have shims to make guile 1.8 offer a > 2.0 interface (in this case, current-filename and add-to-load-path). But yes, indeed that is nicer, and it obviously generalises to other compatibility issues too. Thanks for the idea! Regards, Neil
Re: syntax-local-binding
Andy Wingo writes: > On Fri 20 Jan 2012 23:03, Mark H Weaver writes: > >> (let ((x 1)) >> (syntax-local-binding #'x)) >> >> is not equivalent to: >> >> (let ((x 1)) >> (local-eval '(syntax-local-binding #'x) (the-environment))) > > Indeed; bummer! I think, though, that this is simply a consequence of > giving more power to macro writers. > > It is analogous in some ways to the changes that identifier-syntax > introduce into macro writing: with identifier-syntax, one can no longer > write a code walker with syntax-rules pattern matching, as single > identifiers may expand out to complicated expressions, possibly even > with side effects. This is false. Macros are always expanded _before_ any of their arguments are expanded. Therefore, a code walker sees the unexpanded forms, including any "simulated variables" bound by identifier-syntax. >>> Why do you think that? The procedures do carry metadata; I understood >>> that that was your strategy, to use the serialization of the >>> syntax-rules form in the procedure metadata. >> >> Well, this was in the context of a new strategy where psyntax would >> include a new core form called `call-with-current-local-expander' that >> calls its parameter (a procedure or macro) with a procedure that accepts >> an expression and returns an expanded form. In this case, the most >> straightforward implementation would simply serialize the (r w mod) >> structures directly. >> >> Toward that end, I was thinking it would be nice to keep those >> structures serializable. The only part that's not currently >> serializable are the transformer procedures for local macros. >> Thus the change in representation. > > I have been staring at this empty page here for a little while, writing > and re-writing, but I can't get over a feeling that I really don't want > this kind of work in psyntax itself. Your priorities are reversed from what they ought to be. What you _should_ be worried about is making commitments in our API that we must continue to support forever. This is a _real_ problem, since it constrains our ability to modify our implementation in the future. Putting the `the-environment' in psyntax is, at worst, a stylistic issue. Whether it belongs there is a matter of taste, but however strongly you may feel about that, it is a purely _internal_ implementation issue. The really important thing is that it commits us to _nothing_. There's nothing stopping us from radically reimplementing it later. In particular, there's nothing stopping us from moving it out of psyntax later. Guile has been in existence for a couple of decades already, and I hope that it will be actively used for many decades to come. With that in mind, please consider the long view. One of the reasons Scheme has lasted so long is because it tries exceptionally hard to hide internal implementation details. Implementations that expose too much internal detail may derive a short-term benefit from doing so, but it comes at the price of eventual calcification: there comes a time when implementations that expose too much become unable to make significant internal structural changes. Please consider this. I feel that your mind has become closed to my arguments. Mark
Re: syntax-local-binding
Hi Mark, On Mon 23 Jan 2012 22:03, Mark H Weaver writes: > Andy Wingo writes: > >> with identifier-syntax, one can no longer write a code walker with >> syntax-rules pattern matching, as single identifiers may expand out >> to complicated expressions, possibly even with side effects. > > This is false. Macros are always expanded _before_ any of their > arguments are expanded. Therefore, a code walker sees the unexpanded > forms, including any "simulated variables" bound by identifier-syntax. I'm not sure we're talking about the same thing here; do see Alex Shinn's NAK on R6RS: http://www.r6rs.org/ratification/results.html#X70 While I disagree with his assessment of the identifier-syntax tradeoff, I think he correctly identifies it as a tradeoff. Why do you think that? The procedures do carry metadata; I understood that that was your strategy, to use the serialization of the syntax-rules form in the procedure metadata. >>> >>> Well, this was in the context of a new strategy where psyntax would >>> include a new core form called `call-with-current-local-expander' that >>> calls its parameter (a procedure or macro) with a procedure that accepts >>> an expression and returns an expanded form. In this case, the most >>> straightforward implementation would simply serialize the (r w mod) >>> structures directly. >>> >>> Toward that end, I was thinking it would be nice to keep those >>> structures serializable. The only part that's not currently >>> serializable are the transformer procedures for local macros. >>> Thus the change in representation. >> >> I have been staring at this empty page here for a little while, writing >> and re-writing, but I can't get over a feeling that I really don't want >> this kind of work in psyntax itself. > > Your priorities are reversed from what they ought to be. > > What you _should_ be worried about is making commitments in our API that > we must continue to support forever. This is a _real_ problem, since it > constrains our ability to modify our implementation in the future. I know I'm going to sound like Mr. Collins in Pride and Prejudice here, but I flatter myself that I know a thing or two about managing change -- I mean, replacing the lazy-memoizing evaluator with the compiler, retrofitting psyntax into Guile, the whole subr mess, etc. There is always room to improve, of course, as in all human endeavor, but for now it does seem that Guile is getting more powerful _and_ more limpid over time. But frankly though, regarding change, while we do need the freedom to modify some things, some other practical freedoms just don't make the cost/benefit cut, for me. For example, considering replacing psyntax, which seems to be in the back of your mind here. This conservatism is preventing Guile from adding features. And we do need features -- local-eval and syntax-parse among them. > Putting the `the-environment' in psyntax is, at worst, a stylistic > issue. Whether it belongs there is a matter of taste, but however > strongly you may feel about that, it is a purely _internal_ > implementation issue. The really important thing is that it commits us > to _nothing_. There's nothing stopping us from radically reimplementing > it later. In particular, there's nothing stopping us from moving it out > of psyntax later. Apart from the fact with `the-environment' in psyntax, it's in the default environment, of course; though with autoloads one can get around that... With `the-environment' in a module, in 2.0.4 we could have three functions added to psyntax: syntax-local-binding, syntax-locally-bound-identifiers, and syntax-module. The first and the third have precedent in Racket (whose hackers have been able to do significantly awesome stuff). The second is strange, but seems OK. I'm OK with them. But what if they're the wrong interface? Well, then we use the normal deprecation mechanism to get rid of them, eventually (in the 2.2 series, for example). We learned something. Users get warned off the code. Life goes on. > Guile has been in existence for a couple of decades already, and I hope > that it will be actively used for many decades to come. Hear, hear. > With that in mind, please consider the long view. One of the reasons > Scheme has lasted so long is because it tries exceptionally hard to > hide internal implementation details. Implementations that expose too > much internal detail may derive a short-term benefit from doing so, > but it comes at the price of eventual calcification: there comes a > time when implementations that expose too much become unable to make > significant internal structural changes. > > Please consider this. I feel that your mind has become closed to my > arguments. I really do value your work, and your words, Mark. Besides that personal appreciation, I think you're doing good work for Guile. We happen to disagree here on a matter of implementation. OK. It's a feature we have worked on sufficientl
Re: syntax-local-binding
Andy Wingo writes: >> Your priorities are reversed from what they ought to be. >> >> What you _should_ be worried about is making commitments in our API that >> we must continue to support forever. This is a _real_ problem, since it >> constrains our ability to modify our implementation in the future. > > I know I'm going to sound like Mr. Collins in Pride and Prejudice here, > but I flatter myself that I know a thing or two about managing change -- > I mean, replacing the lazy-memoizing evaluator with the compiler, > retrofitting psyntax into Guile, the whole subr mess, etc. These are certainly impressive accomplishments, and I salute you for this excellent work! :) However, these accomplishments do not demonstrate that you understand the importance of hiding implementation details so that future Guile hackers can make similar transformations a decade or two from now. For example, you seem unabashedly content to lock us into using psyntax forever, despite the fact that it has known deficiencies having to do with its phase story, as well as limitations in its handling of hygiene in complex macros. (c.f. "Improved hygiene", SRFI 72). I don't mean to suggest that we should replace psyntax anytime soon, but we might want to replace it in a decade or two. Therefore, it concerns me when I see internal psyntax representations exported in our API. > But frankly though, regarding change, while we do need the freedom to > modify some things, some other practical freedoms just don't make the > cost/benefit cut, for me. I agree that sometimes practical necessity outweighs the need to hide implementation details. However, in this case, the only "benefit" is to satisfy your desire to keep `the-environment' out of psyntax. > This conservatism is preventing Guile from adding features. And we do > need features -- local-eval and syntax-parse among them. For the record, I absolutely want Stefan to have what he needs to implement `syntax-parse'. My understanding is that all he needs is a way to associate properties with syntactic keywords. Toward that end, I proposed that we should add something analogous to procedure properties for macros. This can be done without exposing internal details as you have done. > But what if they're the wrong interface? > > Well, then we use the normal deprecation mechanism to get rid of them, > eventually (in the 2.2 series, for example). We learned something. > Users get warned off the code. Life goes on. Yes, this is always an option, but it is a _painful_ option for all involved. If we can already foresee the need to deprecate an interface, wouldn't it be better not to add it in the first place? * * * * * Anyway, I can plainly see that your mind is set on this, and that all of the above words were a waste of effort, so I'm going to try to drop it. I just have one final request: please at least change the lexical environments in your `local-eval' implementation to use the future-proof `evaluator procedure' representation, as I have done in mine. FWIW, criticisms aside, I _do_ very much appreciate that you heard my plea for local-eval in 2.0.4, and that you have put so much time into this. Thanks for that, and for all the wonderful things you have done for Guile and GNU. Mark
Re: Improve `seed->random-state' in stable-2.0?
> From: Andy Wingo > That would indeed be a mean thing to do! It's not what I'm suggesting > though. Deprecation means causing Guile to emit warnings, at > compile-time or at runtime, indicating that a particular interface will > go away at some point, and noting the interface that should be used > instead. > > I think it's fairly helpful, actually, but if you have any suggestions > for how it could be improved, they are much welcome. My beef is with potentially removing the ability to use an integer seed in seed->random-state. It is useful and common. Many other languages and schemes do it the same way. Its strengths and limitations are indicated in the manual. I could make a technical argument about why this procedure's calling structure w.r.t. integers shouldn't change: but the technical argument would just be an attempt to justify my personal opinion that a documented API that I have used in scheme code that currently works fine shouldn't be broken. This is orthogonal to the bug in the procedure, though. A user should be able to expect the for each integer seed between 0 and 2^N, for some value of N, that the PRNG will return a different series. It works that way in most languages that allow integer seeds. Thanks, Mike