* Bug in eval-string? @ 2002-08-08 12:56 rm 2002-08-08 21:03 ` Marius Vollmer 2002-08-08 21:27 ` Bug in eval-string? Neil Jerram 0 siblings, 2 replies; 19+ messages in thread From: rm @ 2002-08-08 12:56 UTC (permalink / raw) Hello list, according to the documentation, 'eval-string' evaluation "... takes place in the environment returned by the procedure interaction-environment". Unfortunately this doesn't seem to work for me (see the following test case): tia Ralf Mattes ------------------------x-------------------------------- ;; File: eval-test.scm ;; create an evaluation context (define boxx (make-module)) (set-module-kind! boxx 'directory) ;; fill it with _some_ bindings (module-define! boxx 'define define) (eval '(define meaning-of-life 42) boxx) ;; test the bindings (eval 'meaning-of-life boxx) ;; => 42 (let ((interaction-environment (lambda () boxx))) (format #t "Meaning of life in a box is: ~A\n" (eval-string "meaning-of-life"))) ;; Backtrace: ;; 16: 1* (let (#) (format #t "Meaning of life in a box is: ~A " #)) ;; 17: 2 [simple-format #t "Meaning of life in a box is: ~A " ... ;; 18: 3* [eval-string "meaning-of-life"] ;; In unknown file: ;; ?: 4* meaning-of-life ;; ;; <unnamed port>: In expression meaning-of-life: ;; <unnamed port>: Unbound variable: meaning-of-life ;; ABORT: (unbound-variable) _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-08 12:56 Bug in eval-string? rm @ 2002-08-08 21:03 ` Marius Vollmer 2002-08-09 9:06 ` Matthias Koeppe 2002-08-08 21:27 ` Bug in eval-string? Neil Jerram 1 sibling, 1 reply; 19+ messages in thread From: Marius Vollmer @ 2002-08-08 21:03 UTC (permalink / raw) Cc: guile-devel rm@fabula.de writes: > (let ((interaction-environment (lambda () boxx))) > (format #t "Meaning of life in a box is: ~A\n" > (eval-string "meaning-of-life"))) Scheme 'let' creates new lexical variables, it doesn't dynamically bind existing variables like Elisp 'let' would. Your interaction-environment is a separate variable from the interaction-environment variable used by eval-string. To dynamically bind the current module (which is the same as the interaction-environment), use save-module-excursion together with set-current-module. (save-module-excursion (lambda () (set-current-module boxx) (format ...))) Yes, this could be prettier. What about adding "with" as a general dynamic scoping construct? (with ((current-module) boxx) ...) _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-08 21:03 ` Marius Vollmer @ 2002-08-09 9:06 ` Matthias Koeppe 2002-08-09 9:19 ` Marius Vollmer 0 siblings, 1 reply; 19+ messages in thread From: Matthias Koeppe @ 2002-08-09 9:06 UTC (permalink / raw) Cc: rm, guile-devel Marius Vollmer <mvo@zagadka.ping.de> writes: > What about adding "with" as a general dynamic scoping construct? > > (with ((current-module) boxx) > ...) Please don't. AFAIK, dynamic-scoping hacks of this flavor are commonly known as FLUID-LET in Scheme: - Syntax: fluid-let `(BINDINGS ...)' FORMS... (fluid-let ((VARIABLE INIT) ...) EXPRESSION EXPRESSION ...) An implementation can be found in SLIB. Due to Guile's generalized set!, FLUID-LET also carries over to places like (CURRENT-MODULE) instead of VARIABLE, if CURRENT-MODULE is a procedure-with-setter. Regards, -- Matthias Köppe -- http://www.math.uni-magdeburg.de/~mkoeppe _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-09 9:06 ` Matthias Koeppe @ 2002-08-09 9:19 ` Marius Vollmer 2002-08-09 10:24 ` Matthias Koeppe 0 siblings, 1 reply; 19+ messages in thread From: Marius Vollmer @ 2002-08-09 9:19 UTC (permalink / raw) Cc: rm, guile-devel Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > Marius Vollmer <mvo@zagadka.ping.de> writes: > > > What about adding "with" as a general dynamic scoping construct? > > > > (with ((current-module) boxx) > > ...) > > Please don't. > > AFAIK, dynamic-scoping hacks of this flavor are commonly known as > FLUID-LET in Scheme: But "with" is such a nice name compared to "fluid-let"! ;) I forgot one level of parenthesis in the code above, it was supposed to work for multiple bindings. I'd say that fluid-let should be in the core. Opinions? _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-09 9:19 ` Marius Vollmer @ 2002-08-09 10:24 ` Matthias Koeppe 2002-08-10 14:18 ` Marius Vollmer 0 siblings, 1 reply; 19+ messages in thread From: Matthias Koeppe @ 2002-08-09 10:24 UTC (permalink / raw) Cc: rm, guile-devel Marius Vollmer <mvo@zagadka.ping.de> writes: > Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > >> Marius Vollmer <mvo@zagadka.ping.de> writes: >> >> > What about adding "with" as a general dynamic scoping construct? >> > >> > (with ((current-module) boxx) >> > ...) >> >> Please don't. >> >> AFAIK, dynamic-scoping hacks of this flavor are commonly known as >> FLUID-LET in Scheme: > > But "with" is such a nice name compared to "fluid-let"! ;) The name is *too nice* for something like FLUID-LET. Remember, it uses DYNAMIC-WIND and lots of SET!s. It is inefficient if CALL/CC is used. It won't work in a threaded environment. BTW, FLUID-LET was the topic of a now-withdrawn SRFI, see http://srfi.schemers.org/srfi-15/srfi-15.html > I forgot one level of parenthesis in the code above, it was supposed > to work for multiple bindings. > > I'd say that fluid-let should be in the core. Opinions? I'd say, we should rather make SLIB integration smoother, and/or provide a SRFI-15 implementation (despite its withdrawn status). Putting it in the core won't be a good idea IMHO. 1) It creates confusion because Guile knows real fluid variables. FLUID-LET has "fluid" in its name but has no connection to fluids. 2) WITH-FLUIDS is much cleaner than FLUID-LET. People should use WITH-FLUIDS if they want (threadsafe) dynamic scoping. Moreover, for the application of switching modules by "dynamically binding" the place (CURRENT-MODULE), I think that using either your originally proposed "WITH" syntax or the FLUID-LET syntax are bad ideas because they suggest simple variable assignments, whereas changing the current module is a much heavier thing. Regards, -- Matthias Köppe -- http://www.math.uni-magdeburg.de/~mkoeppe _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-09 10:24 ` Matthias Koeppe @ 2002-08-10 14:18 ` Marius Vollmer 2002-08-12 18:20 ` Matthias Koeppe 0 siblings, 1 reply; 19+ messages in thread From: Marius Vollmer @ 2002-08-10 14:18 UTC (permalink / raw) Cc: rm, guile-devel Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > > But "with" is such a nice name compared to "fluid-let"! ;) > > The name is *too nice* for something like FLUID-LET. Remember, it > uses DYNAMIC-WIND and lots of SET!s. It is inefficient if CALL/CC > is used. Hmm, what is wrong with 'dynamic-wind' and 'set!'? > It won't work in a threaded environment. Really? Whether or not the dynamic context established by "with" or "fluid-let" is local to the current thread or gloabal to all depends on the nature of the 'variable' that you are setting. It could be a fluid, or it could be an ordinray global variable. > > I'd say that fluid-let should be in the core. Opinions? > > I'd say, we should rather make SLIB integration smoother, and/or > provide a SRFI-15 implementation (despite its withdrawn status). > > Putting it in the core won't be a good idea IMHO. > > 1) It creates confusion because Guile knows real fluid variables. > FLUID-LET has "fluid" in its name but has no connection to > fluids. That's actually one reason why I like "with". > 2) WITH-FLUIDS is much cleaner than FLUID-LET. People should use > WITH-FLUIDS if they want (threadsafe) dynamic scoping. But with-fluids is only for fluids, not for general dynamic scoping of settable things. > Moreover, for the application of switching modules by "dynamically > binding" the place (CURRENT-MODULE), I think that using either your > originally proposed "WITH" syntax or the FLUID-LET syntax are bad > ideas because they suggest simple variable assignments, whereas > changing the current module is a much heavier thing. Yes, setting the current-module can have far reaching consequences, but so could setting an ordinary variable. In fact, setting the current module is implemented by setting a variable (well, a fluid). Since "with" or "fluid-let" is distinct from "let" there is no immediate danger of someone accidentally setting the current module with it (unlike in Common Lisp (when the *special* convention isn't followed)). So I don't see how offering "fluid-let" or "with" is dangerous. It might not be 'pure', but it offers something that people want to use. having to use dynamic-wind explicitely is cumbersome and error prone compared to fluid-let, in my view. _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-10 14:18 ` Marius Vollmer @ 2002-08-12 18:20 ` Matthias Koeppe 2002-08-13 0:39 ` Marius Vollmer 0 siblings, 1 reply; 19+ messages in thread From: Matthias Koeppe @ 2002-08-12 18:20 UTC (permalink / raw) Cc: rm, guile-devel Marius Vollmer <mvo@zagadka.ping.de> writes: > Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > >> > But "with" is such a nice name compared to "fluid-let"! ;) >> >> The name is *too nice* for something like FLUID-LET. Remember, it >> uses DYNAMIC-WIND and lots of SET!s. It is inefficient if CALL/CC >> is used. > > Hmm, what is wrong with 'dynamic-wind' and 'set!'? I would like to refer you to the discussion archive of SRFI-15. http://srfi.schemers.org/srfi-15/mail-archive/maillist.html >> It won't work in a threaded environment. > > Really? Whether or not the dynamic context established by "with" or > "fluid-let" is local to the current thread or gloabal to all depends > on the nature of the 'variable' that you are setting. It could be a > fluid, or it could be an ordinray global variable. 1. If you provide an overly convenient construct named "WITH", people will write code (and libraries) using it for dynamic scoping, rather than using fluid variables with the right dynamic-scoping construct, WITH-FLUIDS. All this code will not be re-usable in a threaded environment. 2. As a side note, let us see how FLUID-LET looks if you want to use it with real fluids: (fluid-let (((fluid-ref my-fluid) value)) ...code...) Using WITH-FLUIDS would certainly be prettier here: (with-fluids ((my-fluid value)) ...code...) >> > I'd say that fluid-let should be in the core. Opinions? >> >> I'd say, we should rather make SLIB integration smoother, and/or >> provide a SRFI-15 implementation (despite its withdrawn status). >> >> Putting it in the core won't be a good idea IMHO. >> >> 1) It creates confusion because Guile knows real fluid variables. >> FLUID-LET has "fluid" in its name but has no connection to >> fluids. > > That's actually one reason why I like "with". I will comment on the name "WITH" at the end of this message. >> 2) WITH-FLUIDS is much cleaner than FLUID-LET. People should use >> WITH-FLUIDS if they want (threadsafe) dynamic scoping. > > But with-fluids is only for fluids, not for general dynamic scoping of > settable things. I don't think it is a good idea to introduce core syntax for a dynamic-scoping hack for general "settable things". I certainly don't want to see code like this: (fluid-let (((caddr l) (...)) ((list-ref l 17) (...))) ...) What "general settable things" did you have in mind? The application that the original poster had (setting the current-module for eval-string) certainly is not an example of typical use. > [...] > So I don't see how offering "fluid-let" or "with" is dangerous. It > might not be 'pure', but it offers something that people want to use. > having to use dynamic-wind explicitely is cumbersome and error prone > compared to fluid-let, in my view. It's not mainly about "purity", it's about code re-usability for a threaded environment. Guile already offers something that people want to use, and it is called WITH-FLUIDS. I guess it should simply be advertised better. In fact, in the current Guile manual, fluids currently only appear in the esoteric chapter "Threads, Mutexes, Asyncs and Dynamic Roots", which is also marked as a "FIXME" chapter. (BTW, the syntax WITH-FLUIDS is missing there, only the procedure WITH-FLUIDS* is explained.) I believe we should move the discussion of fluids to a more prominent place of the Guile manual. They should be advertised as _the_ construct in Guile for dealing with dynamical scope. * * * Users who really want to use the FLUID-LET hack can use SLIB. (Does SLIB integration work well in Guile?) Adding FLUID-LET to the core would create confusion because of Guile's fluid variables, as I mentioned. Adding it to the core under the name WITH is a bad idea because: A. Nobody else in the Scheme community seems to call FLUID-LET "WITH". B. "WITH" is a far too generic name for something like FLUID-LET. C. It does not fit at all into the Scheme naming scheme. We have WITH-INPUT-FROM-FILE, WITH-OUTPUT-TO-FILE, and some other WITH-... procedures, but their name always says with "what" the passed thunk (or body) is called. If you wanted "WITH..." syntax for FLUID-LET, it would be something like WITH-DYNAMICALLY-WOUND-VALUES. D. Because of reason 1 above. My conclusion: Adding "FLUID-LET" to the Guile core only creates problems, no matter whether it is added under its traditional name or as "WITH". (Having it in the core certainly won't help in any way to make Emacs switch to Guile, BTW.) Regards, -- Matthias Köppe -- http://www.math.uni-magdeburg.de/~mkoeppe _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-12 18:20 ` Matthias Koeppe @ 2002-08-13 0:39 ` Marius Vollmer 2002-08-14 19:07 ` Marius Vollmer ` (2 more replies) 0 siblings, 3 replies; 19+ messages in thread From: Marius Vollmer @ 2002-08-13 0:39 UTC (permalink / raw) Cc: guile-devel Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > I would like to refer you to the discussion archive of SRFI-15. Ahh, thanks. I quickly skimmed the discussion and I think I have a slightly different view of fluid-let re concurrent execution. I doesn't really make sense to me to say that fluid-let works/works not with concurrent execution. It is global lexical variables that don't work with threads, and they don't work with threads regardless of whether they are set by fluid-let or by some other construct. If using global variables is wrong, then using them together with fluid-let can't make them right. If all fluid-let can affect is lexical variables, then it is not very useful in a threaded system. You could use it to set global variables that should not be thread-local, or non-global lexical variables that are per-se thread-local. These are rather untypical things, I agree, and we should not lure people into doing them only because they are more convenient than the correct thing. But our fluid-let would be able to affect more than just variables. The extended (set! (accessor ...) ...) syntax can also used with fluid-let and with it, you can affect abstract storage locations. When you use storage locations that are themselves thread-local, then fluid-let will also work in a threaded environment. The decision that must be taken correctly is how to implement your global state, not whether to use fluid-let to twiddle it. For us, the correct way to store thread-local data is with a fluid. Thus, you might reason that one would use fluid-let mostly with fluids, but we already have a device for them, which is with-fluids. So fluid-let would be superfluous again. But fluids are by far not the only thread-local things that one might want to bind dynamically. You could also have some data structure that is pointed to by some thread-local global variable and you might want to dynamically bind a slot of this structure. Or this structure might be shared by a group of cooperating threads and setting a field in it would thus affect all of them. Also, fluids are the basis for thread-local storage, but they might not be enough. You might want to layer some notification protocol on top of them. Say the GUI thread should be signalled when you set a 'busy' flag. You could have a 'settable funtion' "busy" that knows where the GUI thread is and (set! (busy) #t) would signal it so that it can change the display. Being able to say (fluid-let (((busy) #t)) ...) looks very attractive to me (and is entirely correct because "busy" is correct, not because fluid-let is somehow thread-safe). > 1. If you provide an overly convenient construct named "WITH", people > will write code (and libraries) using it for dynamic scoping, > rather than using fluid variables with the right dynamic-scoping > construct, WITH-FLUIDS. I have more faith, it seems. I do think that they will see the light, given proper documentation. > 2. As a side note, let us see how FLUID-LET looks if you want to > use it with real fluids: > > (fluid-let (((fluid-ref my-fluid) value)) > ...code...) > > Using WITH-FLUIDS would certainly be prettier here: > > (with-fluids ((my-fluid value)) > ...code...) We can improve the former to (fluid-let (((my-fluid) value)) ...code...) when fluids are settable directly. > I don't think it is a good idea to introduce core syntax for a > dynamic-scoping hack for general "settable things". > > I certainly don't want to see code like this: > > (fluid-let (((caddr l) (...)) > ((list-ref l 17) (...))) > ...) But when that is what it takes? I would be ware of code like that myself, but do you think that people will start writing things like that just because they suddenly have fluid-let? Wouldn't they rather use eval anyway? ;) > What "general settable things" did you have in mind? Structure slots, for example. See above. > The application that the original poster had (setting the > current-module for eval-string) certainly is not an example of > typical use. No? The current module is a fluid, but it is not globally visible. You have to go thru current-module and set-current-module. Would it be better to expose the fluid or would it be better to make current-module settable and then allow people to write (fluid-let (((current-module) ...)) ...) I like the latter option better. > Guile already offers something that people want to use, and it is > called WITH-FLUIDS. > > I guess it should simply be advertised better. In fact, in the > current Guile manual, fluids currently only appear in the esoteric > chapter "Threads, Mutexes, Asyncs and Dynamic Roots", which is also > marked as a "FIXME" chapter. (BTW, the syntax WITH-FLUIDS is missing > there, only the procedure WITH-FLUIDS* is explained.) Yep, good point. I'll make me a note to look into this. > I believe we should move the discussion of fluids to a more prominent > place of the Guile manual. They should be advertised as _the_ > construct in Guile for dealing with dynamical scope. They are _the_ basic construct for thread-local storage. The simulation of dynamic scoping in Scheme is the job of dynamic-wind, or one of the syntactic-sugars for it. > Users who really want to use the FLUID-LET hack can use SLIB. (Does > SLIB integration work well in Guile?) It should. > Adding it to the core under the name WITH is a bad idea because: > > A. Nobody else in the Scheme community seems to call FLUID-LET > "WITH". To boldy go where Norman has gone before ... > B. "WITH" is a far too generic name for something like FLUID-LET. Hmm, but it _is_ is a very generic construct. The most generic one that I can imagine, actually. So it should get the most unspecific name. > My conclusion: Adding "FLUID-LET" to the Guile core only creates > problems, no matter whether it is added under its traditional name or > as "WITH". I still like it, tho... -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-13 0:39 ` Marius Vollmer @ 2002-08-14 19:07 ` Marius Vollmer 2002-08-17 11:09 ` Neil Jerram 2002-08-20 11:39 ` Matthias Koeppe 2 siblings, 0 replies; 19+ messages in thread From: Marius Vollmer @ 2002-08-14 19:07 UTC (permalink / raw) Cc: guile-devel Marius Vollmer <mvo@zagadka.ping.de> writes: > > I guess it should simply be advertised better. In fact, in the > > current Guile manual, fluids currently only appear in the esoteric > > chapter "Threads, Mutexes, Asyncs and Dynamic Roots", which is also > > marked as a "FIXME" chapter. (BTW, the syntax WITH-FLUIDS is missing > > there, only the procedure WITH-FLUIDS* is explained.) > > Yep, good point. I'll make me a note to look into this. I didn't find anything big to fix. Fluids are linked from "Other Datatypes" which I think is fine. I added "with-fluid". Do you have more specific improvements in mind? Maybe a patch? ;) -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-13 0:39 ` Marius Vollmer 2002-08-14 19:07 ` Marius Vollmer @ 2002-08-17 11:09 ` Neil Jerram 2002-08-20 11:39 ` Matthias Koeppe 2 siblings, 0 replies; 19+ messages in thread From: Neil Jerram @ 2002-08-17 11:09 UTC (permalink / raw) Cc: Matthias Koeppe, guile-devel >>>>> "Marius" == Marius Vollmer <mvo@zagadka.ping.de> writes: Marius> I doesn't really make sense to me to say that fluid-let works/works Marius> not with concurrent execution. It is global lexical variables that Marius> don't work with threads, and they don't work with threads regardless Marius> of whether they are set by fluid-let or by some other Marius> construct. [...] I agree with this argument (i.e. that the problem is not thinking about your data, not any specific setting mechanism), and I like the name `with' too. Neil _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-13 0:39 ` Marius Vollmer 2002-08-14 19:07 ` Marius Vollmer 2002-08-17 11:09 ` Neil Jerram @ 2002-08-20 11:39 ` Matthias Koeppe 2002-08-21 19:26 ` Marius Vollmer 2 siblings, 1 reply; 19+ messages in thread From: Matthias Koeppe @ 2002-08-20 11:39 UTC (permalink / raw) Cc: guile-devel Marius Vollmer <mvo@zagadka.ping.de> writes: > Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > >> I would like to refer you to the discussion archive of SRFI-15. > > Ahh, thanks. I quickly skimmed the discussion and I think I have a > slightly different view of fluid-let re concurrent execution. > > I doesn't really make sense to me to say that fluid-let works/works > not with concurrent execution. It is global lexical variables that > don't work with threads, and they don't work with threads regardless > of whether they are set by fluid-let or by some other construct. > > If using global variables is wrong, then using them together with > fluid-let can't make them right. If all fluid-let can affect is > lexical variables, then it is not very useful in a threaded system. > You could use it to set global variables that should not be > thread-local, or non-global lexical variables that are per-se > thread-local. These are rather untypical things, I agree, and we > should not lure people into doing them only because they are more > convenient than the correct thing. > > But our fluid-let would be able to affect more than just variables. > The extended (set! (accessor ...) ...) syntax can also used with > fluid-let and with it, you can affect abstract storage locations. > When you use storage locations that are themselves thread-local, then > fluid-let will also work in a threaded environment. > The decision that must be taken correctly is how to implement your > global state, not whether to use fluid-let to twiddle it. > > For us, the correct way to store thread-local data is with a fluid. > Thus, you might reason that one would use fluid-let mostly with > fluids, but we already have a device for them, which is with-fluids. > So fluid-let would be superfluous again. > > But fluids are by far not the only thread-local things that one might > want to bind dynamically. You could also have some data structure > that is pointed to by some thread-local global variable and you might > want to dynamically bind a slot of this structure. Or this structure > might be shared by a group of cooperating threads and setting a field > in it would thus affect all of them. I think it is already a very bad idea to think about temporarily mutating slots of data structures as "binding". See also below. The good thing about fluids is that they are regular Scheme values. This means that we can put them not only in global variables but also in lexical variables and other data structures. The WITH-FLUIDS syntax also deals with those fluids, not only with fluids stored in global variables. > Also, fluids are the basis for thread-local storage, but they might > not be enough. You might want to layer some notification protocol on > top of them. Say the GUI thread should be signalled when you set a > 'busy' flag. You could have a 'settable funtion' "busy" that knows > where the GUI thread is and (set! (busy) #t) would signal it so that > it can change the display. Being able to say > > (fluid-let (((busy) #t)) > ...) > > looks very attractive to me (and is entirely correct because "busy" is > correct, not because fluid-let is somehow thread-safe). It doesn't look attractive to me. I am afraid people will simulate control structures via getters and setters. BUSY is the first step into this direction. This will lead to a C++-ish overloading mess, where you never know what an operation will do unless you know exactly the type of the objects involved. The Scheme way would be to make a new control procedure (with-being-busy THUNK) or/and a macro. This is much cleaner, and much more expressive than "dynamically binding" a generalized location that executes arbitrary code when you get or set its value. >> 1. If you provide an overly convenient construct named "WITH", people >> will write code (and libraries) using it for dynamic scoping, >> rather than using fluid variables with the right dynamic-scoping >> construct, WITH-FLUIDS. > > I have more faith, it seems. I do think that they will see the light, > given proper documentation. > >> 2. As a side note, let us see how FLUID-LET looks if you want to >> use it with real fluids: >> >> (fluid-let (((fluid-ref my-fluid) value)) >> ...code...) >> >> Using WITH-FLUIDS would certainly be prettier here: >> >> (with-fluids ((my-fluid value)) >> ...code...) > > We can improve the former to > > (fluid-let (((my-fluid) value)) > ...code...) > > when fluids are settable directly. I strongly oppose the idea of making fluids "settable directly". I assume this would mean to make them "gettable directly" as well via procedure-call syntax. This is simply over-concise. We would lose expressivity of code using fluids, as only a pair of parens would distinguish it from regular variable use. >> I don't think it is a good idea to introduce core syntax for a >> dynamic-scoping hack for general "settable things". >> >> I certainly don't want to see code like this: >> >> (fluid-let (((caddr l) (...)) >> ((list-ref l 17) (...))) >> ...) > > But when that is what it takes? I would be ware of code like that > myself, but do you think that people will start writing things like > that just because they suddenly have fluid-let? Wouldn't they rather > use eval anyway? ;) > >> What "general settable things" did you have in mind? > > Structure slots, for example. See above. I was afraid you would say that. I think it is very bad style to make temporary mutations on data structures. It's not getting better if you mutate named slots rather than mutating the CADDR as in the example code I gave above. If one really has to make temporary mutations, then the dynamic-wind mess makes one think about it. Again the generalized FLUID-LET construct is simply too convenient. > [...] Marius, I have also followed the discussion on emacs-devel, which seems to be the motivation for the discussion here on guile-devel. I think that we should not get carried away by the low-level functionality (and the performance hacks) of Emacs variables, with the "swapping in-and-out" of values, and of buffer-local and frame-local variables. The only reason why I would be interested in a Guile-based implementation of Emacs is the hope for a clean, thread-safe Lisp engine, which would allow for a multi-threaded Emacs. We can't reach this goal if we copy all the inherently single-threaded stuff (swapping in and out values, as with FLUID-LET) from the Emacs Lisp engine into Guile. We should first find the right data model for Emacs "variables". Only as a second step, we should think about convenient syntax to access the variables from Scheme code (and how to translate Emacs Lisp code into Scheme code). Emacs "variables" simply aren't variables. They are functions (procedures-with-setters) depending on the "current" buffer and frame and on the "dynamic environment". Here is a possible prototype implementation. ;; pseudo-code (define-structure <emacs-variable> global-value dynamic-value-fluid ; a fluid buffer-local-values ; alist or hash table mapping buffers to values frame-local-values ; likewise ) (define* (get-emacs-variable-value emacs-variable #:optional (buffer (fluid-ref *current-buffer*)) (frame (fluid-ref *current-frame*))) (cond ((assq buffer (buffer-local-values emacs-variable)) => cdr) ((assq frame (frame-local-values emacs-variable)) => cdr) ((not (eq? (fluid-ref (dynamic-value-fluid emacs-variable))) *undefined*) (fluid-ref (dynamic-value-fluid emacs-variable))) (else (global-value emacs-variable)))) ;; setter likewise The Emacs Lisp LET syntax would translate to a WITH-FLUIDS on the dynamic-value-fluid of the Emacs variable. Regards, -- Matthias Köppe -- http://www.math.uni-magdeburg.de/~mkoeppe _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-20 11:39 ` Matthias Koeppe @ 2002-08-21 19:26 ` Marius Vollmer 2002-08-27 14:18 ` Emacs variables (was: Bug in eval-string?) Matthias Koeppe 0 siblings, 1 reply; 19+ messages in thread From: Marius Vollmer @ 2002-08-21 19:26 UTC (permalink / raw) Cc: guile-devel Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > Marius Vollmer <mvo@zagadka.ping.de> writes: > > > But fluids are by far not the only thread-local things that one might > > want to bind dynamically. You could also have some data structure > > that is pointed to by some thread-local global variable and you might > > want to dynamically bind a slot of this structure. Or this structure > > might be shared by a group of cooperating threads and setting a field > > in it would thus affect all of them. > > I think it is already a very bad idea to think about temporarily > mutating slots of data structures as "binding". See also below. Then you can't think about 'with-fluids' as performing 'bindings' as well. That is OK, and a better term would maybe be 'letting', or 'setting temporarily'. We should'nt quarrel over names too much, tho. > The good thing about fluids is that they are regular Scheme values. > This means that we can put them not only in global variables but also > in lexical variables and other data structures. The WITH-FLUIDS > syntax also deals with those fluids, not only with fluids stored in > global variables. Yes, this is a good point, one that can be used against using variables in general. fluid-let might be bad in the sense that it allows people to work with things besides fluids and doesn't force them to use fluids exclusively. But that is a weak argument in my view since I don't think that fluids are the only things that should be temporarily set. Especially things that are layered on top of fluids. > > [...] > > Being able to say > > > > (fluid-let (((busy) #t)) > > ...) > > > > looks very attractive to me (and is entirely correct because "busy" is > > correct, not because fluid-let is somehow thread-safe). > > It doesn't look attractive to me. I am afraid people will simulate > control structures via getters and setters. BUSY is the first step > into this direction. This will lead to a C++-ish overloading mess, > where you never know what an operation will do unless you know exactly > the type of the objects involved. I don't think it is that bad. The behavior of fluid-let is not changed by the things that are being 'let'. Of course you need to know what 'busy' does. > The Scheme way would be to make a new control procedure > > (with-being-busy THUNK) > > or/and a macro. How would you implement with-being-busy? Something like fluid-let would sure come in handy. Also, in addition to with-being-busy you would still need a getter to be able to find out whether you are currently busy. Factoring this into an abstract state variable that can be read and written, and a general construct that can temporarily set any abstract variable looks good to me, still. You only need to learn fluid-let once. > >> What "general settable things" did you have in mind? > > > > Structure slots, for example. See above. > > I was afraid you would say that. I think it is very bad style to make > temporary mutations on data structures. It's not getting better if > you mutate named slots rather than mutating the CADDR as in the > example code I gave above. This depends entirely on what you want to do. There are algorithms that are most efficient when you modify data structures (as opposed to coding them in a functional way). Some modifications might be temporarily (i.e., the 'dancing links' of Knuth). > The only reason why I would be interested in a Guile-based > implementation of Emacs is the hope for a clean, thread-safe Lisp > engine, which would allow for a multi-threaded Emacs. We can't reach > this goal if we copy all the inherently single-threaded stuff > (swapping in and out values, as with FLUID-LET) from the Emacs Lisp > engine into Guile. I still don't see how fluid-let ruins multi-threaded applications. The current buffer needs to be thread-local, but code like (fluid-let ((case-fold-search #f)) ...) would still need to be used. We can debate whether that should rather be (fluid-let (((buffer-local-value case-fold-search) #f)) ...) or (fluid-let (((case-fold-search) #f)) ...) or something different, but the point to discuss is the exposition of Emacs variables to Scheme, not whether we should be able to set them temporarily. A general fluid-let construct can only help with experimenting. Only allowing an unchanged with-fluids constrains the options too much, too early, I'd say. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Emacs variables (was: Bug in eval-string?) 2002-08-21 19:26 ` Marius Vollmer @ 2002-08-27 14:18 ` Matthias Koeppe 2002-08-31 13:51 ` Marius Vollmer 0 siblings, 1 reply; 19+ messages in thread From: Matthias Koeppe @ 2002-08-27 14:18 UTC (permalink / raw) Cc: guile-devel Marius Vollmer <mvo@zagadka.ping.de> writes: >[abstract part of the discussion snipped] > > Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: >> The only reason why I would be interested in a Guile-based >> implementation of Emacs is the hope for a clean, thread-safe Lisp >> engine, which would allow for a multi-threaded Emacs. We can't reach >> this goal if we copy all the inherently single-threaded stuff >> (swapping in and out values, as with FLUID-LET) from the Emacs Lisp >> engine into Guile. > > I still don't see how fluid-let ruins multi-threaded applications. > The current buffer needs to be thread-local, but code like > > (fluid-let ((case-fold-search #f)) > ...) > > would still need to be used. This example illustrates the problem with FLUID-LET, in fact. From the syntactic variations you gave below I deduce that you want to translate the common Emacs Lisp construction (let ((case-fold-search nil)) ...CODE...) to a FLUID-LET that temporarily sets the buffer-local value of the variable CASE-FOLD-SEARCH to false. But in a multi-threaded Emacs I want to have the possibility of having a user-interaction thread, where I (the user) can set CASE-FOLD-SEARCH in a buffer to some value I like, and some other thread that scans the same buffer (for instance, for creating an index) using CASE-FOLD-SEARCH = nil. Of course the other thread cannot temporarily set the buffer-local value of CASE-FOLD-SEARCH to its liking, because this would disturb the user interaction. This means that FLUID-LET cannot be used here, unless you stored the buffer-local value of a variable in fluids. However, in other cases a thread _wants_ to make a mutation of a buffer-local variable. Therefore, we cannot simply store all buffer-local values in fluids. The point is that Emacs Lisp's dynamically-binding LET binds a _symbol_ to a fresh _location_ in its dynamic environment. This is semantically very different from a value-swapping FLUID-LET (in a multithreaded environment), no matter to which generalized location FLUID-LET is applied. This is not simply about the "exposition of Emacs variables to Scheme". It's about the implementation of dynamic scoping in a multithreaded environment. The dynamic environment, of course, is thread-local, so it can be implemented in Guile with a fluid. See my pseudocode in my previous message. Regards, -- Matthias Köppe -- http://www.math.uni-magdeburg.de/~mkoeppe _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Emacs variables (was: Bug in eval-string?) 2002-08-27 14:18 ` Emacs variables (was: Bug in eval-string?) Matthias Koeppe @ 2002-08-31 13:51 ` Marius Vollmer 0 siblings, 0 replies; 19+ messages in thread From: Marius Vollmer @ 2002-08-31 13:51 UTC (permalink / raw) Cc: guile-devel Matthias Koeppe <mkoeppe@mail.Math.Uni-Magdeburg.De> writes: > The point is that Emacs Lisp's dynamically-binding LET binds a > _symbol_ to a fresh _location_ in its dynamic environment. This is > semantically very different from a value-swapping FLUID-LET (in a > multithreaded environment), no matter to which generalized location > FLUID-LET is applied. This is not simply about the "exposition of > Emacs variables to Scheme". It's about the implementation of dynamic > scoping in a multithreaded environment. I see now, thanks. I will have to think about this some more... -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-08 12:56 Bug in eval-string? rm 2002-08-08 21:03 ` Marius Vollmer @ 2002-08-08 21:27 ` Neil Jerram 2002-08-09 9:35 ` rm 1 sibling, 1 reply; 19+ messages in thread From: Neil Jerram @ 2002-08-08 21:27 UTC (permalink / raw) Cc: guile-devel >>>>> "rm" == rm <rm@fabula.de> writes: rm> Hello list, rm> according to the documentation, 'eval-string' rm> evaluation "... takes place in the environment rm> returned by the procedure interaction-environment". rm> Unfortunately this doesn't seem to work for me rm> (see the following test case): rm> (let ((interaction-environment (lambda () boxx))) rm> (format #t "Meaning of life in a box is: ~A\n" rm> (eval-string "meaning-of-life"))) This isn't Elisp! The interaction-environment variable introduced by your let has nothing to do with the builtin interaction-environment, to which the documentation refers. BTW, note that the builtin interaction-environment is (at least at the moment) identical to current-module. guile> (define boxx (make-module)) guile> (set-module-kind! boxx 'directory) directory guile> (module-define! boxx 'meaning-of-life 42) #f guile> (save-module-excursion (lambda () (set-current-module boxx) (eval-string "meaning-of-life"))) 42 guile> Neil _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-08 21:27 ` Bug in eval-string? Neil Jerram @ 2002-08-09 9:35 ` rm 2002-08-10 14:43 ` Marius Vollmer 0 siblings, 1 reply; 19+ messages in thread From: rm @ 2002-08-09 9:35 UTC (permalink / raw) Cc: rm, guile-devel First of all, thank's for all these replies. I think my problem stems partly from a missunderstanding of the documentation and from a missunderstanding of the implementation (which admittedly i could have examined myself. Sorry). On Thu, Aug 08, 2002 at 10:27:59PM +0100, Neil Jerram wrote: > [...] > rm> (let ((interaction-environment (lambda () boxx))) > rm> (format #t "Meaning of life in a box is: ~A\n" > rm> (eval-string "meaning-of-life"))) > > This isn't Elisp! The interaction-environment variable introduced by > your let has nothing to do with the builtin interaction-environment, > to which the documentation refers. I think i (wrongly) assumend that eval-string is "syntactic sugar" for eval. So my reading of the documentation made me belive that eval-string would behave like the following (pseudo)code: (use-modules (ice-9 syncase)) (define-syntax my-eval-string (syntax-rules () ((my-eval-string string) (eval (with-input-from-string string (lambda () (read))) (interaction-environment))))) maybe the documentation should be modified: "Evaluation takes place in the environment returned by the\n" "procedure @code{interaction-environment}.") to "Evaluation takes place in the same environment as \n" "returned by the procedure @code{interaction-environment}.") > BTW, note that the builtin interaction-environment is (at least at the > moment) identical to current-module. Ah, that information would have helped. > guile> (define boxx (make-module)) > guile> (set-module-kind! boxx 'directory) > directory > guile> (module-define! boxx 'meaning-of-life 42) > #f > guile> (save-module-excursion > (lambda () > (set-current-module boxx) > (eval-string "meaning-of-life"))) > 42 > guile> Where would i find documentation on save-module-excursion? And now for the RFC part: Wouldn't the 'eval*' interface be clearer and more orthogonal if eval-string would have a second, optional parameter specifying the environment/module in which evaluation should take place. If no module is specified the environment defaults to interaction-environment (this guarantees backward compatibility). The modifications to the code are minimal, see below. Ralf -- File: strports.c --------x-------------------------------------------- SCM_DEFINE (scm_eval_string, "eval-string", 1, 1, 0, (SCM string, SCM environ), "Evaluate @var{string} as the text representation of a Scheme\n" "form or forms, and return whatever value they produce.\n" "Evaluation takes place in the environment provided in the \n" "second, optional parameter @var{environ}. If none is given \n" "evalution will happen in the environment returned by the \n" "procedure @code{interaction-environment}.") #define FUNC_NAME s_scm_eval_string { SCM port = scm_mkstrport (SCM_INUM0, string, SCM_OPN | SCM_RDNG, "eval-string"); if (SCM_UNBNDP (environ)) environ = scm_interaction_environment (); return scm_c_call_with_current_module (environ, inner_eval_string, (void *)port); } #undef FUNC_NAME _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-09 9:35 ` rm @ 2002-08-10 14:43 ` Marius Vollmer 2002-08-12 10:49 ` rm 2002-08-13 20:55 ` Marius Vollmer 0 siblings, 2 replies; 19+ messages in thread From: Marius Vollmer @ 2002-08-10 14:43 UTC (permalink / raw) Cc: Neil Jerram, guile-devel rm@fabula.de writes: > I think i (wrongly) assumend that eval-string is "syntactic sugar" > for eval. There is a big difference between a macro and a function. Why did you think that eval-string is a macro? (The documentation of eval-string says that it is a procedure.) > maybe the documentation should be modified: > > "Evaluation takes place in the environment returned by the\n" > "procedure @code{interaction-environment}.") > > to > "Evaluation takes place in the same environment as \n" > "returned by the procedure @code{interaction-environment}.") I don't see the difference between the two. The question is, for both, what is "the procedure interaction-environment". The name refers to the procedure bound to the global variable that is named "interaction-environment" in the guile-core module. Most of this is implicit and applies to all of the documentation. Do we need to make this more explicit? > Wouldn't the 'eval*' interface be clearer and more orthogonal if > eval-string would have a second, optional parameter specifying the > environment/module in which evaluation should take place. Yes, this sounds good to me. I will make that change. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-10 14:43 ` Marius Vollmer @ 2002-08-12 10:49 ` rm 2002-08-13 20:55 ` Marius Vollmer 1 sibling, 0 replies; 19+ messages in thread From: rm @ 2002-08-12 10:49 UTC (permalink / raw) Cc: rm, Neil Jerram, guile-devel On Sat, Aug 10, 2002 at 04:43:36PM +0200, Marius Vollmer wrote: > rm@fabula.de writes: > > > I think i (wrongly) assumend that eval-string is "syntactic sugar" > > for eval. > > There is a big difference between a macro and a function. Why did you > think that eval-string is a macro? (The documentation of eval-string > says that it is a procedure.) Because sometimes, late at night, i tend to overlook the obvoius -- this is a sign of age, you'll experience it too ;-) > > maybe the documentation should be modified: > > > > "Evaluation takes place in the environment returned by the\n" > > "procedure @code{interaction-environment}.") > > > > to > > "Evaluation takes place in the same environment as \n" > > "returned by the procedure @code{interaction-environment}.") > > I don't see the difference between the two. The question is, for > both, what is "the procedure interaction-environment". The name > refers to the procedure bound to the global variable that is named > "interaction-environment" in the guile-core module. Hmm, my english is probably not as clear as i want it to be: from the first version i get the impression that by modifying the procedure 'interaction-environment' i have control over the environment in which 'Eval-string' takes place. The second version tries to be a bit clearer over the fact that 'interaction-environment' just returns the environment (of course, since eval-string isn't a macro this is pretty much of no importance). > Most of this is > implicit and applies to all of the documentation. Do we need to make > this more explicit? I think 'eval-string' takening an optional parameter is cleaner. > > Wouldn't the 'eval*' interface be clearer and more orthogonal if > > eval-string would have a second, optional parameter specifying the > > environment/module in which evaluation should take place. > > Yes, this sounds good to me. I will make that change. > Thanks Ralf _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: Bug in eval-string? 2002-08-10 14:43 ` Marius Vollmer 2002-08-12 10:49 ` rm @ 2002-08-13 20:55 ` Marius Vollmer 1 sibling, 0 replies; 19+ messages in thread From: Marius Vollmer @ 2002-08-13 20:55 UTC (permalink / raw) Cc: guile-devel Marius Vollmer <mvo@zagadka.ping.de> writes: > Yes, this sounds good to me. I will make that change. Done, please check. -- GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3 331E FAF8 226A D5D4 E405 _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2002-08-31 13:51 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2002-08-08 12:56 Bug in eval-string? rm 2002-08-08 21:03 ` Marius Vollmer 2002-08-09 9:06 ` Matthias Koeppe 2002-08-09 9:19 ` Marius Vollmer 2002-08-09 10:24 ` Matthias Koeppe 2002-08-10 14:18 ` Marius Vollmer 2002-08-12 18:20 ` Matthias Koeppe 2002-08-13 0:39 ` Marius Vollmer 2002-08-14 19:07 ` Marius Vollmer 2002-08-17 11:09 ` Neil Jerram 2002-08-20 11:39 ` Matthias Koeppe 2002-08-21 19:26 ` Marius Vollmer 2002-08-27 14:18 ` Emacs variables (was: Bug in eval-string?) Matthias Koeppe 2002-08-31 13:51 ` Marius Vollmer 2002-08-08 21:27 ` Bug in eval-string? Neil Jerram 2002-08-09 9:35 ` rm 2002-08-10 14:43 ` Marius Vollmer 2002-08-12 10:49 ` rm 2002-08-13 20:55 ` Marius Vollmer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).