Sorry, accidentally sent this to the implementors list. Please keep any discussion on the scheme-reports list.
-- Alex ---------- Forwarded message ---------- From: Alex Shinn <[email protected]> Date: Sun, Aug 21, 2011 at 8:05 PM Subject: Re: Poll: intentions concerning the R7RS "small" language On Sat, Aug 13, 2011 at 5:04 AM, Andy Wingo <[email protected]> wrote: > > At some point I would like to consider having "unspecified values" be > generally implemented as `(values)', in the language of the R6RS. The > R7RS has currently chosen the old "an unspecified value" language, which > could make Guile incompatible with R7RS (and indeed R5RS, as you have > noted). I think that the right thing to do is to allow implementors to > consider this choice and decide on their own. Users who rely on `(if #f > #f)' producing a single value can use implementations that choose the > single-valued model. That is my opinion, but it is where I would like > to take Guile. For clarity, I assume you mean the R6RS specification, which allows an "unspecified number of unspecified values". Returning explicitly zero values was considered, but as it breaks both R5RS and R6RS compatibility didn't seem like a serious option. The concern is that there's a non-trivial amount of R5RS code which assumes a single value is returned, and it's not clear just how extensive this code is or how easily it can be changed. The specific idiom (let ((undef (if #f #f))) ...) to get at the impl's void value I've seen a lot. It doesn't even work reliably in R5RS, but in practice works in most implementations. It's arguably bad style, and the sort of thing we should discourage. There are other instances where a single value is assumed, many of which were discussed on the list. John only listed the straw-man example (define x (set! y 30)), but in a macro expansion where you are expanding only definitions (suitable for internal define) and need to use mutation, this is a natural solution. Just define x as some dummy variable. Analogously, I've often used dummy variables in let* to enable side-effects: (let* ((foo ...) (dummy (print "foo is: " foo)) (bar ...)) ...) All of these I would consider borderline cases, and assuming they aren't too extensive I wouldn't be too concerned with breaking them. The other general "class" of examples is where the programmer assumes there are no instances of multiple values in some context (such as a module or file, or perhaps their entire codebase). In this case they can write things like (define-syntax time (syntax-rules () ((time expr) (let* ((start (current-seconds)) (res expr)) (report-time start) res)))) then use this in that context (_not_ as a general utility for others to use) without worrying about the non-single value case. In short, this is a user who probably hates MV, never uses it himself, never uses any APIs which provide MV, and yet by changing the specification in the way you propose suddenly his (reasonable from his perspective) code stops working. And that's what makes a lot of people hate MV - it's not a feature you can just ignore, it pervades the whole language. But these holdouts are relatively few, and likely stick to their implementations which will continue to return a single value. In practice this change will only make their code non-portable, not break it. So we've re-opened this issue in the fourth ballot. I haven't yet decided myself how I'll vote. -- Alex _______________________________________________ Scheme-reports mailing list [email protected] http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports
