Re: Special variables to relax boxing
Hi Stefan, Stefan Israelsson Tampe stefan.ita...@gmail.com writes: I wouldl like to start a discussion of introducing a way to mark variables as special, and by that mean that set! variables does not nessesary get boxed. I don't think you fully understand the ramifications of what you're proposing here. In the general case, mutable variables need to be boxed because closures end up with copies of any free variables that they reference. If a free variable is mutable, that means it needs a copy of the _location_ where the value is stored. Making a copy of the _value_ of a variable at the time of closure creation would lead to very unintuitive (and IMO broken) behavior. More importantly, you are describing this proposed language feature in terms of low-level implementation details. If you're serious about proposing such a fundamental new feature to Scheme, please start by reading and understanding the denotational semantics of the R5RS, especially sections 3.1 and 3.4, and then reformulate your proposal in those terms. For such a fundamental change, I'd want to see a proposed new formal denotational semantics to replace those in section 7.2. To be honest, I'm not suggesting this to help you refine this proposal. I'm suggesting it because I think it would help you to think more clearly about these issues, and to appreciate the beautiful elegance of Scheme's minimalist semantics. Furthermore, I hope it would help you to understand what a terrible mistake it would be to muck such a beautiful language with hacks such as this. Every added bit of complexity in the core of a language has to be paid for a hundred times over, in both code (compilers, optimizers, etc) and more importantly in the mental effort required to reason about the language. Mark
Re: [PATCH] Add SRFI-41
On Thu 21 Mar 2013 01:38, Mark H Weaver m...@netris.org writes: Chris K. Jester-Young has been hard at work getting his SRFI-41 implementation ready in time for Guile 2.0.8, and I think it might be ready to push. What do you think? Needs documentation. -- http://wingolog.org/
Re: Special variables to relax boxing
Ok, This was a first step to get what I would like to have implemented in the tree il backend (Not for scheme but perhaps something useful for e.g. emacs-lisp, python etc). My main issue with the current setup is that adding undoing and redoing feature with the help of prompts will fail in 95% of the cases where the program is written in an imperative style which is not uncommmon in languages we would like to support in guile. Prompts is such a cool feature and is probably one of the main selling points of why one should use their language ontop of guile. So I've just exploring how to improve on this. I think you missundeerstood my posted semantic. It will box if you set! a variable and the same variable is located in a closure, I think that is a safe approach. But you are right that it's a very unclear semantic but my intention was to use this as a step of a better primitive. So over to the semantic I would like to have, To do it currently in guile you would need to do something like, (define-syntax with-guarded-var (lambda (x) (syntax-case x () ((_ var code) (with-syntax ((guard ...)) #'(let ((guard (make-fluid))) (with-fluids ((guard var)) (dynamic-wind (lambda () (set! var (fluid-ref guard)) (lambda () (mark-as-special var) code) (lambda x (fluid-set! guard var))) It might be improved but is really really a horrendous solution to the semantic. The semantic is pretty close to a fluid variable solution but it will mix much better with delayed computations and is a big reason for not using fluids in a more simple try. What I would like to propose is an idiom in tree-il that basicly looks like (with-special (var ...) code ...) and what it does is to put onto the stack is the following mark var1 place1 var2 place2 ... mark-end - and then execute the code just as nothing have happend. Then we could add the code to the stack copying part of the prompt cal/cc etc to when scanning the stack backwards, if it sees maek-end, then it will store the value of var1 in place 1 etc. And when reinstalling the stack it will search for the mark and place the value of place1 into the var in var1 and so on. Another solution is to add a new control ideom onto the control stack where the fluid controls and dynamic wind control lives with a pointer ti the var1 position and the number of vars. With this solution we can skip the marks and also improve the performance of the installment and savings of the stack, the drawback is that we neede to handle that we install the saved stack perhaps at another adress, but it's doable. (A good thing using this is that we can reuse this rebasing technique to improve the speed and scaleup of fluid variables at a tail call position in many cases) I actually use a clumsy version of this semantic in guile-log and I know that although it is anesoteric feature it means that you can easilly implement really cool features that I would not dare to write in e.g. kanren, If you write a prompt based logic implementation It will make a hughe difference in what you have the above semantic without going down to snail speed. To increase speed further the system would use (mark-as-special) and check if it can be unboxed, in which case tha variable will not be baxed and with-special will be a no op. I hope that this is a clearer description of what I'm aiming at! /Stefan On Thu, Mar 21, 2013 at 7:00 AM, Mark H Weaver m...@netris.org wrote: Hi Stefan, Stefan Israelsson Tampe stefan.ita...@gmail.com writes: I wouldl like to start a discussion of introducing a way to mark variables as special, and by that mean that set! variables does not nessesary get boxed. I don't think you fully understand the ramifications of what you're proposing here. In the general case, mutable variables need to be boxed because closures end up with copies of any free variables that they reference. If a free variable is mutable, that means it needs a copy of the _location_ where the value is stored. Making a copy of the _value_ of a variable at the time of closure creation would lead to very unintuitive (and IMO broken) behavior. More importantly, you are describing this proposed language feature in terms of low-level implementation details. If you're serious about proposing such a fundamental new feature to Scheme, please start by reading and understanding the denotational semantics of the R5RS, especially sections 3.1 and 3.4, and then reformulate your proposal in those terms. For such a fundamental change, I'd want to see a proposed new formal denotational semantics to replace those in section 7.2. To be honest, I'm not suggesting this to help you refine this proposal. I'm suggesting it because I think it would help you to think more clearly about these issues, and to
Re: [PATCH] Bindings for ‘sendfile’
Hi Mark, Mark H Weaver m...@netris.org skribis: l...@gnu.org (Ludovic Courtès) writes: I plan to commit the patch below, which adds bindings for ‘sendfile’. Comments? Looks great to me, modulo one comment below. Thanks for the quick review! I especially like the fact that although it can make use of the non-standard Linux syscall, it works properly on all systems. In response to suggestions by others that we create a linux module: I'd prefer to follow the good precedent set by Ludovic here. Yeah. (And experience has shown that POSIX largely follows GNU/Linux nowadays.) + size_t c_count; + off_t c_offset; + ssize_t result; + int in_fd, out_fd; + + VALIDATE_FD_OR_PORT (out_fd, out, 1); + VALIDATE_FD_OR_PORT (in_fd, in, 2); + c_count = scm_to_size_t (count); Since the code below will behave badly if 'c_count' does not fit in an 'ssize_t', we should validate here that it _does_ fit. Oops, indeed. (Note that sendfile(2) and write(2) have that problem: they take a size_t and return a ssize_t...) There was also the other issue of making sure we use the right function, depending on _FILE_OFFSET_BITS co. Here are the changes compared to the previous patch: diff --git a/libguile/filesys.c b/libguile/filesys.c index 097b03a..6804db9 100644 --- a/libguile/filesys.c +++ b/libguile/filesys.c @@ -102,6 +102,10 @@ # include sys/sendfile.h #endif +/* Glibc's `sendfile' function. */ +#define sendfile_or_sendfile64 \ + CHOOSE_LARGEFILE (sendfile, sendfile64) + #include full-read.h #include full-write.h @@ -1123,7 +1127,7 @@ SCM_DEFINE (scm_sendfile, sendfile, 3, 1, 0, } size_t c_count; - off_t c_offset; + scm_t_off c_offset; ssize_t result; int in_fd, out_fd; @@ -1133,20 +1137,20 @@ SCM_DEFINE (scm_sendfile, sendfile, 3, 1, 0, c_offset = SCM_UNBNDP (offset) ? 0 : scm_to_off_t (offset); #ifdef HAVE_SENDFILE - result = sendfile (out_fd, in_fd, + result = sendfile_or_sendfile64 (out_fd, in_fd, SCM_UNBNDP (offset) ? NULL : c_offset, c_count); /* Quoting the Linux man page: In Linux kernels before 2.6.33, out_fd must refer to a socket. Since Linux 2.6.33 it can be any file. - Fall back to read(2) and write(2) such an error happens. */ + Fall back to read(2) and write(2) when such an error occurs. */ if (result 0 errno != EINVAL errno != ENOSYS) SCM_SYSERROR; else if (result 0) #endif { char buf[8192]; -size_t left; +size_t result, left; if (!SCM_UNBNDP (offset)) { @@ -1173,6 +1177,8 @@ SCM_DEFINE (scm_sendfile, sendfile, 3, 1, 0, result += obtained; } + +return scm_from_size_t (result); } return scm_from_ssize_t (result); WDYT? Thanks, Ludo’.
Re: Core dump when throwing an exception from a resumed partial continuation
On Fri 15 Mar 2013 22:01, Brent Pinkney b...@4dst.com writes: When I resume the continuation in another thread, all works perfectly UNLESS the continued execution throws and exception. Then guile exits with a core dump. By contrast if I resume the continuation in the same thread and then throw and exception all works as expected. I think I know what this is. So, a delimited continuation should capture that part of the dynamic environment made in its extent. (See Oleg Kiselyov and Chung-Chieh Shan's Delimited Dynamic Binding paper.) That is what Guile does, for fluids, prompts, and dynamic-wind blocks. Our implementation of exception handling uses a fluid, %exception-handler (boot-9.scm:86). However that fluid references a stack of exception handlers on the heap. There is the problem: an exception in a reinstated delimited continuation continuation will walk the captured exception handler stack from the heap, not from its own dynamic environment. Therefore it could abort to a continuation that is not present on the new thread. The solution is to have the exception handler find the next handler from the dynamic environment. This will need a new primitive to walk the dynamic stack, I think. I can't look at this atm as I broke my arm (!) and so typing is tough. For now as a workaround I suggest you put a catch #t in each of your delimited continuations. This way all throws will be handled by catches established by the continuation. Regards, Andy -- http://wingolog.org/
Re: [PATCH] Bindings for ‘sendfile’
On Thu 21 Mar 2013 10:40, l...@gnu.org (Ludovic Courtès) writes: l...@gnu.org (Ludovic Courtès) writes: I plan to commit the patch below, which adds bindings for ‘sendfile’. Should probably go in gnulib at some point, no? Looks good tho :) -- http://wingolog.org/
Re: [PATCH] Bindings for ‘sendfile’
On 03/21/13 11:15, Ludovic Courtès wrote: Noah Lavine noah.b.lav...@gmail.com skribis: I've thought for a while that if I had time (which I know I won't) I would make a module called (linux) with bindings for non-POSIX Linux kernel features. What do you think of this idea? If so, what do you think of putting sendfile there and expanding it with other functions as we need them? I’ve thought about it, but ended up with making sendfile work whether or not the syscall is available (just like glibc does, after all). So for this particular case, I’d rather keep it in the global name space. There’s also the untold argument that even if sendfile(2) is unavailable, the loop written in C is going to be faster than the equivalent bytecode. Just another datapoint: Solaris 10 has sendfile. So it's not just a Linux feature. -- Andrew
Re: [PATCH] Bindings for ‘sendfile’
Andy Wingo wi...@pobox.com skribis: On Thu 21 Mar 2013 10:40, l...@gnu.org (Ludovic Courtès) writes: l...@gnu.org (Ludovic Courtès) writes: I plan to commit the patch below, which adds bindings for ‘sendfile’. Should probably go in gnulib at some point, no? Yes, you’re right. I’ll see what I can do. Ludo’.
Re: Core dump when throwing an exception from a resumed partial continuation
On 03/21/13 11:43, Andy Wingo wrote: On Fri 15 Mar 2013 22:01, Brent Pinkney b...@4dst.com writes: When I resume the continuation in another thread, all works perfectly UNLESS the continued execution throws and exception. Then guile exits with a core dump. By contrast if I resume the continuation in the same thread and then throw and exception all works as expected. I think I know what this is. So, a delimited continuation should capture that part of the dynamic environment made in its extent. (See Oleg Kiselyov and Chung-Chieh Shan's Delimited Dynamic Binding paper.) That is what Guile does, for fluids, prompts, and dynamic-wind blocks. Our implementation of exception handling uses a fluid, %exception-handler (boot-9.scm:86). However that fluid references a stack of exception handlers on the heap. There is the problem: an exception in a reinstated delimited continuation continuation will walk the captured exception handler stack from the heap, not from its own dynamic environment. Therefore it could abort to a continuation that is not present on the new thread. The solution is to have the exception handler find the next handler from the dynamic environment. This will need a new primitive to walk the dynamic stack, I think. I can't look at this atm as I broke my arm (!) and so typing is tough. For now as a workaround I suggest you put a catch #t in each of your delimited continuations. This way all throws will be handled by catches established by the continuation. Regards, Andy Andy, Thanks for giving this some thought -- sorry to hear about your arm! This does shed some light on things. If I change this: (throw 'oops) ; should not crash the vm to this: (catch #t (λ () (throw 'oops)) ; should not crash the vm (λ () (display Success!)(newline))) ; never reached the VM still cores; Success is never shown. However, you've probably spotted my mistake: the handler should be (λ (key . args) ... ). But this core shows up differently in the stack-trace in gdb: #0 scm_error (key=0x1001854c0, subr=0x0, message=0x7e7ef518 Wrong number of arguments to ~A, args=0x100db95b0, rest=0x4) at error.c:62 ... which is exactly the exception one would expect. Fixing the handler thus: (catch #t (λ () (throw 'oops)) ; should not crash the vm (λ (key . args) (display Success!)(newline))) ; works! ...solves the problem, and the VM doesn't core any more. So it seems that although we *did* have a catch around our resumption, there must have been some (different) error in its handler, which caused a second exception, which caused the VM to crash. Unfortunately, the test-case we made handles this second exception fine. It'd be great to be able to distill this problem down to a pithy test-case. (Our app is 4500 lines and still growing, so it's not really a candidate to send to the list.) The same problem happens (VM cores) if I do this: (catch 'not-oops (λ () (throw 'oops)) ; should not crash the vm (λ (key . args) (display Success!)(newline))); never reached So your answer to surround the resumption with a (catch #t ...) is a good workaround. For our code, anyway. (I'm now off to go read http://www.cs.indiana.edu/~sabry/papers/delim-dyn-bind.pdf :) -- Andrew
Re: Core dump when throwing an exception from a resumed partial continuation
On Thu 21 Mar 2013 14:53, Andrew Gaylard a...@computer.org writes: (catch #t (λ () (throw 'oops)) ; should not crash the vm (λ () (display Success!)(newline))) ; never reached the VM still cores; Success is never shown. However, you've probably spotted my mistake: the handler should be (λ (key . args) ... ). The core dump is another bug. but fixing the handler is the key thing: (catch #t (λ () (throw 'oops)) ; should not crash the vm (λ (key . args) (display Success!)(newline))) ; works! ...solves the problem, and the VM doesn't core any more. Yep Happy hacking :) A -- http://wingolog.org/
Re: [PATCH] Bindings for ‘sendfile’
Hello, Yes, you're completely right - making it work on all platforms is much better than what I had proposed. I'm glad you're doing this. Thanks, Noah On Thu, Mar 21, 2013 at 5:15 AM, Ludovic Courtès l...@gnu.org wrote: Hi Noah, Noah Lavine noah.b.lav...@gmail.com skribis: I've thought for a while that if I had time (which I know I won't) I would make a module called (linux) with bindings for non-POSIX Linux kernel features. What do you think of this idea? If so, what do you think of putting sendfile there and expanding it with other functions as we need them? I’ve thought about it, but ended up with making sendfile work whether or not the syscall is available (just like glibc does, after all). So for this particular case, I’d rather keep it in the global name space. There’s also the untold argument that even if sendfile(2) is unavailable, the loop written in C is going to be faster than the equivalent bytecode. FWIW, I plan to integrate the Linux bindings I wrote for “boot-to-Guile” eventually: http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/patches/guile-linux-syscalls.patch These are not defined in POSIX, but apart from the Linux module syscalls, they (that is, mount(2) and the networking ioctls) happen to be supported by glibc on all 3 kernels, and also by other libcs. Thus, I’d rather keep them in the global name space as well. WDYT? Thanks, Ludo’.
Re: Special variables to relax boxing
On Thursday, March 21, 2013 11:35:19 AM Noah Lavine wrote: (lambda () (let ((x 5)) (set! x (compute-1 x)) (set! x (compute-2 x)) x)) becomes (lambda () (let ((k1 (lambda (x) (k2 (compute-2 x (k2 (lambda (x) x))) (k1 (compute-1 x However, this rewriting idea runs into trouble when you try to figure out what happens to mutable variables that have been captured by closures (as Mark said). I don't know what the right solution is here. The semantic is that cpatured variables in lambdas will be restored to the value when the continuation left the guard. And this is something you want many times e.g. consider, (let ((a 0) (f (case-lambda (() a) ((b) (set! a b) (with-special (a) (for-each (lambda (x) (if (blah x) (k x f) (abort-to-prompt 'tag a))) a-list) (f))) Assume that you would like to be able to go back to the tag abort many times in a redo/undo sequence, then it is natural for the a referenced in f to be restored as well. But as you know sometimes this is not what we want. As I said, using dynwinds and fluids it's really possible to get this behavior today but it's really a bloated solution. Anyhow the good news with this semantic is as with the current behavior of assigned variables it's easy to reason with the code although one risk some severe bugs. A good question though is what we should use as default for e.g. a python implementation where prompts is not included per se, but which we might want to add as a special scheme flavour of python using an import e.g. what is the natural thing to expect for the variables that are assigned. Also in the previous email I had a suggestion to for each with variable, a, add two slots in the stack e.g. a1 val1 s2 val2 ... But there is a good reason to asign a kind to this as well e.g. a1 val kind a2 val2 kand2 ... then we could use a predicates when we rewind a continuation e.g. at rewind: (when (pred1 kind1) (set! a1 (ref-val val1))) ... and and at wind (when (pred2 kind1) (set-val val1 a1)) ... A simple version of this with a complex implementation is what I actually use in guile-log. BTW after this deep realizations of the guile variable behavior I'm ready to implement a much improved version of these special variables in guile-log that is both efficient and featureful. Cool! Have fun /Stefan
Re: makeinfo swallows page breaks
l...@gnu.org (Ludovic Courtès) skribis: Alternately, would you suggest using a different approach? Attached is a patch to use Guile’s Texinfo support [0] to build said file. Guile’s Texinfo parser is incomplete but sufficient to handle those docstrings. It solves an actual bug for anyone using Texinfo 5.x. It also seems to be the most profitable solution for us Guile hackers in the long run. And, it’s much faster: makeinfo 4.13 takes 0.1s makeinfo 5.1 takes 11.7s Guile takes 1.3s OK to commit? Thanks, Ludo’. From 84b2457ed9fdf866a354465c67e282f8fbb30eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= l...@gnu.org Date: Thu, 21 Mar 2013 19:17:13 +0100 Subject: [PATCH] Build `guile-procedures.txt' using (texinfo) instead of `makeinfo'. * Makefile.am (schemelibdir, schemelib_DATA): New variables. (libguile/guile-procedures.txt): New target. (EXTRA_DIST): Add libguile/texi-fragments-to-docstrings. * libguile/Makefile.am (guile-procedures.txt): Remove target. (schemelibdir, schemelib_DATA): Remove. * libguile/texi-fragments-to-docstrings: New file. --- Makefile.am | 17 -- libguile/Makefile.am | 16 -- libguile/texi-fragments-to-docstrings | 55 + 3 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 libguile/texi-fragments-to-docstrings diff --git a/Makefile.am b/Makefile.am index 3aa5ddd..737897b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in. ## ## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2007, -##2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +##2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. ## ## This file is part of GUILE. ## @@ -42,6 +42,18 @@ SUBDIRS = \ libguileincludedir = $(pkgincludedir)/$(GUILE_EFFECTIVE_VERSION) libguileinclude_HEADERS = libguile.h +schemelibdir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION) +schemelib_DATA = libguile/guile-procedures.txt + +# Build it from here so that all the modules are compiled by the time we +# build it. +libguile/guile-procedures.txt: libguile/guile-procedures.texi + $(AM_V_GEN) \ + $(top_builddir)/meta/guile --no-auto-compile \ + $(srcdir)/libguile/texi-fragments-to-docstrings \ + $(builddir)/libguile/guile-procedures.texi \ + libguile/guile-procedures.txt + EXTRA_DIST = LICENSE HACKING GUILE-VERSION \ m4/ChangeLog-2008 \ m4/gnulib-cache.m4 \ @@ -50,7 +62,8 @@ EXTRA_DIST = LICENSE HACKING GUILE-VERSION \ gnulib-local/lib/localcharset.h.diff \ gnulib-local/lib/localcharset.c.diff \ gnulib-local/m4/clock_time.m4.diff \ - gnulib-local/build-aux/git-version-gen.diff + gnulib-local/build-aux/git-version-gen.diff \ + libguile/texi-fragments-to-docstrings TESTS = check-guile TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ diff --git a/libguile/Makefile.am b/libguile/Makefile.am index d77bdfe..450d955 100644 --- a/libguile/Makefile.am +++ b/libguile/Makefile.am @@ -713,25 +713,9 @@ guile.texi: $(alldotdocfiles) guile$(EXEEXT) guile-procedures.texi: $(alldotdocfiles) guile$(EXEEXT) $(AM_V_GEN)$(dotdoc2texi) $@ || { rm $@; false; } -if HAVE_MAKEINFO - -guile-procedures.txt: guile-procedures.texi - rm -f $@ - makeinfo --force -o $@ guile-procedures.texi || test -f $@ - -else - -guile-procedures.txt: guile-procedures.texi - cp guile-procedures.texi $@ - -endif - c-tokenize.c: c-tokenize.lex flex -t $(srcdir)/c-tokenize.lex $@ || { rm $@; false; } -schemelibdir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION) -schemelib_DATA = guile-procedures.txt - ## Add -MG to make the .x magic work with auto-dep code. MKDEP = gcc -M -MG $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) diff --git a/libguile/texi-fragments-to-docstrings b/libguile/texi-fragments-to-docstrings new file mode 100644 index 000..b72390b --- /dev/null +++ b/libguile/texi-fragments-to-docstrings @@ -0,0 +1,55 @@ +;;; -*- mode: scheme; coding: utf-8; -*- +;;; +;;; Copyright (C) 2013 Free Software Foundation, Inc. +;;; +;;; This library is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU Lesser General Public +;;; License as published by the Free Software Foundation; either +;;; version 3 of the License, or (at your option) any later version. +;;; +;;; This library is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; Lesser General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with this library; if not, write to the Free Software +;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +;;; +;;; Read Texinfo
Re: makeinfo swallows page breaks
Hi Ludo Attached is a patch to use Guile’s Texinfo support [0] to build said file. Guile’s Texinfo parser is incomplete but sufficient to handle those docstrings. OK to commit? If Guile depends on Guile for multiple stages the build, it becomes difficult to recover from a problem when the build is failing. So maybe this commit will lead to better, more methodical hacking; maybe it will make fixing a broken Guile more annoying. Dunno. -Mike
Re: Special variables to relax boxing
Stefan, you're still describing your proposal in terms of low-level implementation details such as stacks. In the general case, we cannot store environment structures on the stack. Furthermore, in the general case *all* variables in scheme are bound to locations, not values. Only in special cases can we use stacks, and only in special cases can we avoid boxing variables. These are only _optimizations_. If you're serious about this proposal, please read sections 3.1 and 3.4 of the R5RS carefully. Explain your proposed _semantics_ (not the implementation details) in those terms, where *all* variables are bound to _locations_, and where there is no stack at all (everything is conceptually stored in a garbage-collected heap). We need to understand the *semantics* in the simplest possible terms before we even begin to think about how to implement it. Thanks, Mark
Re: Special variables to relax boxing
On Thursday, March 21, 2013 03:03:06 PM Mark H Weaver wrote: Stefan, you're still describing your proposal in terms of low-level implementation details such as stacks. In the general case, we cannot store environment structures on the stack. Furthermore, in the general case *all* variables in scheme are bound to locations, not values. Only in special cases can we use stacks, and only in special cases can we avoid boxing variables. These are only _optimizations_. If you're serious about this proposal, please read sections 3.1 and 3.4 of the R5RS carefully. Explain your proposed _semantics_ (not the implementation details) in those terms, where *all* variables are bound to _locations_, and where there is no stack at all (everything is conceptually stored in a garbage-collected heap). We need to understand the *semantics* in the simplest possible terms before we even begin to think about how to implement it. Thanks, Mark Ok, the sematics for the simple version is are, Assume k, the continuation associated with with a dynamic wind or unwind assume that there is a map from each continuation (k,id) to a value and getting and setting of this value is done through ref-get and ref-set, assume that the winder and the rewinder lambda takes a first argument k beeing the continuation under action, finally make-id will make a unique object. then the semantic would be: (define-syntax-rule (with-special (a) code) (let ((id (make-id))) (dynamic-wind (lambda (k) (set! a (ref-get k id))) (lambda () code) (lambda (k) (ref-set! k id a) A possible refinment of this is associate to k two predicates e.g. (do-wind? k kind) predicate and a (do-unwind? k kind) wich takes a parameter kind, then use the semanics (define-syntax-rule (with-special (a kind) code) (let ((id (make-id))) (dynamic-wind (lambda (k) (when (do-wind? k kind) (set! a (ref-get k id (lambda () code) (lambda (k) (when (do-unwind? k kind) (ref-set! k id a)) Hopes this helps! /Stefan
Re: makeinfo swallows page breaks
Mike Gran spk...@yahoo.com skribis: Attached is a patch to use Guile’s Texinfo support [0] to build said file. Guile’s Texinfo parser is incomplete but sufficient to handle those docstrings. OK to commit? If Guile depends on Guile for multiple stages the build, it becomes difficult to recover from a problem when the build is failing. Well, that’s nothing compared to its bootstrapping procedure. :-) So maybe this commit will lead to better, more methodical hacking; maybe it will make fixing a broken Guile more annoying. It will force us to maintain the Texinfo modules at a reasonable level, which I think it’s good. Hopefully, if something breaks, it will break deterministically. Conversely, here people with Texinfo 5.x get no docstrings (and thus failing tests), people with an older Texinfo don’t have any problems, and people without Texinfo have no problem but their docstrings include unprocessed markup. Overall, I really think it’s an improvement. Ludo’.
Re: Special variables to relax boxing
Hi, Stefan and Mark, I think you are talking past each other. Stefan is offering a very concrete definition of what he wants, and Mark is looking for a more abstract version. Here is what I think Stefan wants, in the language of R5RS' storage model: A variable is simply a name for a particular location, and each variable refers to its own unique location. When a continuation is captured, that continuation gets its own set of mirror locations, one for each variable that is in the scope of the continuation. These mirror locations are initialized with the same values that were in the locations of the corresponding variables, but they are distinct from those locations and are immutable. When a continuation is called, it is run in an environment in which each of the variables that was in scope when it was captured points to a new location, which is initialized to have the same value as the corresponding mirror location. Note that each variable name gets at least three distinct locations in this description: the original location, when the program was being run, the mirror location, when the continuation was captured, and the new location, when the continuation was called. I believe this is sufficient (and necessary?) to give the semantics that Stefan wants. Let me also give a more concrete example, which I believe captures *why* this is important. Let's say you're writing a loop with a counter that says when to terminate: (let ((count 0)) (let iter () ... do-some-stuff ... (when ( count 100) (set! count (+ count 1)) (iter Now pretend that do-some-stuff captures its continuation when count is equal to 10. Stefan wants a situation where, no matter how many times that continuation is called, *each call* to the continuation will have (= count 10). I think this is very natural if you're using an imperative style, but I'm not sure what the best way is to achieve it. Best, Noah On Thu, Mar 21, 2013 at 4:15 PM, Stefan Israelsson Tampe stefan.ita...@gmail.com wrote: On Thursday, March 21, 2013 03:03:06 PM Mark H Weaver wrote: Stefan, you're still describing your proposal in terms of low-level implementation details such as stacks. In the general case, we cannot store environment structures on the stack. Furthermore, in the general case *all* variables in scheme are bound to locations, not values. Only in special cases can we use stacks, and only in special cases can we avoid boxing variables. These are only _optimizations_. If you're serious about this proposal, please read sections 3.1 and 3.4 of the R5RS carefully. Explain your proposed _semantics_ (not the implementation details) in those terms, where *all* variables are bound to _locations_, and where there is no stack at all (everything is conceptually stored in a garbage-collected heap). We need to understand the *semantics* in the simplest possible terms before we even begin to think about how to implement it. Thanks, Mark Ok, the sematics for the simple version is are, Assume k, the continuation associated with with a dynamic wind or unwind assume that there is a map from each continuation (k,id) to a value and getting and setting of this value is done through ref-get and ref-set, assume that the winder and the rewinder lambda takes a first argument k beeing the continuation under action, finally make-id will make a unique object. then the semantic would be: (define-syntax-rule (with-special (a) code) (let ((id (make-id))) (dynamic-wind (lambda (k) (set! a (ref-get k id))) (lambda () code) (lambda (k) (ref-set! k id a) A possible refinment of this is associate to k two predicates e.g. (do-wind? k kind) predicate and a (do-unwind? k kind) wich takes a parameter kind, then use the semanics (define-syntax-rule (with-special (a kind) code) (let ((id (make-id))) (dynamic-wind (lambda (k) (when (do-wind? k kind) (set! a (ref-get k id (lambda () code) (lambda (k) (when (do-unwind? k kind) (ref-set! k id a)) Hopes this helps! /Stefan
Re: makeinfo swallows page breaks
Guileôòùs Texinfo parser Argh. The idea of a full second Texinfo parser in GNU is fundamentally wrong. If you want to call it a Guile docstring parser, whose language happens to bear some resemblance to a subset of Texinfo, fine. Anyway, your change to use more Guile in the Guile build procedures makes sense to me. k