* bug#14164: 'letrec' allows to refer to the values of previously bound variables @ 2013-04-09 4:41 Nikita Karetnikov 2013-04-09 5:14 ` bug#14164: letrec: detect illegal accesses to vars before entering body Mark H Weaver 0 siblings, 1 reply; 7+ messages in thread From: Nikita Karetnikov @ 2013-04-09 4:41 UTC (permalink / raw) To: 14164 [-- Attachment #1: Type: text/plain, Size: 317 bytes --] According to the manual [1], this snippet: (letrec ((a 42) (b (+ a 10))) (* a b)) should return "Error: unbound variable: a." But it returns 2184 in Guile 2.0.7. Either there is a bug in the manual or 'letrec' doesn't work properly. [1] https://gnu.org/software/guile/manual/guile.html#Local-Bindings [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#14164: letrec: detect illegal accesses to vars before entering body 2013-04-09 4:41 bug#14164: 'letrec' allows to refer to the values of previously bound variables Nikita Karetnikov @ 2013-04-09 5:14 ` Mark H Weaver 2013-04-09 6:37 ` Nikita Karetnikov 0 siblings, 1 reply; 7+ messages in thread From: Mark H Weaver @ 2013-04-09 5:14 UTC (permalink / raw) To: Nikita Karetnikov; +Cc: 14164 Nikita Karetnikov <nikita@karetnikov.org> writes: > According to the manual [1], this snippet: > > (letrec ((a 42) > (b (+ a 10))) > (* a b)) > > should return "Error: unbound variable: a." The manual doesn't say anything nearly that specific. It says "Note that while the init expressions may refer to the new variables, they may not access their values." The R5RS says "it must be possible to evaluate each <init> without assigning or referring to the value of any <variable>. If this restriction is violated, then it is an error." In general, if the manual says you "may not" do something, or if the R5RS says "it is an error", that means that if you do, the results are unspecified. It does not constitute a promise to report an error if you do. I agree that we should ideally report errors such as this, but this is not a bug, but rather a wishlist item. Note that generating code that detects programmer errors such as this may carry a non-trivial runtime cost, so we might need to provide a distinct compilation mode that inserts such debugging checks. This is on my TODO list, but I wouldn't hold your breath :) Regards, Mark ^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#14164: letrec: detect illegal accesses to vars before entering body 2013-04-09 5:14 ` bug#14164: letrec: detect illegal accesses to vars before entering body Mark H Weaver @ 2013-04-09 6:37 ` Nikita Karetnikov 2013-04-09 16:44 ` Mark H Weaver 0 siblings, 1 reply; 7+ messages in thread From: Nikita Karetnikov @ 2013-04-09 6:37 UTC (permalink / raw) To: Mark H Weaver; +Cc: 14164 [-- Attachment #1: Type: text/plain, Size: 649 bytes --] >> According to the manual [1], this snippet: >> >> (letrec ((a 42) >> (b (+ a 10))) >> (* a b)) >> >> should return "Error: unbound variable: a." > The manual doesn't say anything nearly that specific. Either you missed it or I misunderstood this sentence. So if you missed it, it can be found below 'syntax: letrec* bindings body'. > In general, if the manual says you "may not" do something, or if the > R5RS says "it is an error", that means that if you do, the results are > unspecified. Are you talking about the result of 'letrec' or 'b'? Anyway, why does it return 2184 if the results are unspecified? Could you elaborate? [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#14164: letrec: detect illegal accesses to vars before entering body 2013-04-09 6:37 ` Nikita Karetnikov @ 2013-04-09 16:44 ` Mark H Weaver 2013-04-09 17:22 ` Nikita Karetnikov 0 siblings, 1 reply; 7+ messages in thread From: Mark H Weaver @ 2013-04-09 16:44 UTC (permalink / raw) To: Nikita Karetnikov; +Cc: 14164 Nikita Karetnikov <nikita@karetnikov.org> writes: >>> According to the manual [1], this snippet: >>> >>> (letrec ((a 42) >>> (b (+ a 10))) >>> (* a b)) >>> >>> should return "Error: unbound variable: a." > >> The manual doesn't say anything nearly that specific. > > Either you missed it or I misunderstood this sentence. So if you missed > it, it can be found below 'syntax: letrec* bindings body'. Oops! You're right, of course. Apologies for saying you were wrong. I'll fix the manual. >> In general, if the manual says you "may not" do something, or if the >> R5RS says "it is an error", that means that if you do, the results are >> unspecified. > > Are you talking about the result of 'letrec' or 'b'? Anyway, why does > it return 2184 if the results are unspecified? Could you elaborate? Well, first of all, I misspoke. In this case, I should have said (as the R5RS did) that "it is an error", which in Scheme-standard-speak means "anything at all could happen". This is different from "an error is signaled" or "an error is raised" or "an exception is thrown" which consitutes a promise to report an error. When the standard (or the manual) says "the result is unspecified", that means that some value will be returned, but that value could be anything. Although Guile includes a distinguished value shown as "*unspecified*", which is often used in these cases, it is not always used. In practice, we use it when we can easily do so without imposing a runtime cost, as a debugging aid. However, it is not always used. Thanks, Mark ^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#14164: letrec: detect illegal accesses to vars before entering body 2013-04-09 16:44 ` Mark H Weaver @ 2013-04-09 17:22 ` Nikita Karetnikov 2013-04-10 9:25 ` Mark H Weaver 0 siblings, 1 reply; 7+ messages in thread From: Nikita Karetnikov @ 2013-04-09 17:22 UTC (permalink / raw) To: Mark H Weaver; +Cc: 14164 [-- Attachment #1: Type: text/plain, Size: 458 bytes --] > I'll fix the manual. Thanks. So what's the difference between 'letrec' and 'letrec*', then? I fail to grasp it. Could you add a relevant example to the manual? > When the standard (or the manual) says "the result is unspecified", that > means that some value will be returned, but that value could be > anything. Just to clarify: When the standard says "unspecified," I can read it as "it's up to the particular implementation (e.g., Guile)," right? [-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#14164: letrec: detect illegal accesses to vars before entering body 2013-04-09 17:22 ` Nikita Karetnikov @ 2013-04-10 9:25 ` Mark H Weaver 2013-04-12 8:43 ` Ludovic Courtès 0 siblings, 1 reply; 7+ messages in thread From: Mark H Weaver @ 2013-04-10 9:25 UTC (permalink / raw) To: Nikita Karetnikov; +Cc: 14164 Nikita Karetnikov <nikita@karetnikov.org> writes: >> I'll fix the manual. > > Thanks. > > So what's the difference between 'letrec' and 'letrec*', then? I fail > to grasp it. The difference is that in 'letrec*', the initializers are guaranteed to be evaluated in order, and they are allowed to access earlier bindings before entering the body. In 'letrec', the order in which the initializers are evaluated is unspecified, and they are *not* allowed to access earlier bindings. > Could you add a relevant example to the manual? The example given in the manual under 'letrec*' was basically correct. The only problem was that it shouldn't have claimed that an error would be reported to the user. Here's the change I made to the manual: --8<---------------cut here---------------start------------->8--- index 5763f36..e3a9918 100644 (file) --- a/doc/ref/api-binding.texi +++ b/doc/ref/api-binding.texi @@ -218,9 +218,9 @@ variables. @lisp (letrec ((a 42) - (b (+ a 10))) + (b (+ a 10))) ;; Illegal access (* a b)) -@result{} ;; Error: unbound variable: a +;; The behavior of the expression above is unspecified (letrec* ((a 42) (b (+ a 10))) (* a b)) @result{} 2184 @end lisp --8<---------------cut here---------------end--------------->8--- >> When the standard (or the manual) says "the result is unspecified", that >> means that some value will be returned, but that value could be >> anything. > > Just to clarify: When the standard says "unspecified," I can read it as > "it's up to the particular implementation (e.g., Guile)," right? Yes, but keep in mind that there's no guarantee that the results will be consistent from one evaluation to the next, even within a particular implementation. For example, the 'letrec' above could return a random number each time it is run, or even crash randomly, though that would clearly be undesirable and we would seek to avoid that in Guile. Regards, Mark ^ permalink raw reply related [flat|nested] 7+ messages in thread
* bug#14164: letrec: detect illegal accesses to vars before entering body 2013-04-10 9:25 ` Mark H Weaver @ 2013-04-12 8:43 ` Ludovic Courtès 0 siblings, 0 replies; 7+ messages in thread From: Ludovic Courtès @ 2013-04-12 8:43 UTC (permalink / raw) To: Mark H Weaver; +Cc: 14164 Mark H Weaver <mhw@netris.org> skribis: > @lisp > (letrec ((a 42) > - (b (+ a 10))) > + (b (+ a 10))) ;; Illegal access > (* a b)) Please change it to “invalid access”. Nothing illegal here. ;-) Ludo’. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-04-12 8:43 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-04-09 4:41 bug#14164: 'letrec' allows to refer to the values of previously bound variables Nikita Karetnikov 2013-04-09 5:14 ` bug#14164: letrec: detect illegal accesses to vars before entering body Mark H Weaver 2013-04-09 6:37 ` Nikita Karetnikov 2013-04-09 16:44 ` Mark H Weaver 2013-04-09 17:22 ` Nikita Karetnikov 2013-04-10 9:25 ` Mark H Weaver 2013-04-12 8:43 ` Ludovic Courtès
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).