bug#21900: map is not continuation-safe
With Guile 2.0.11: scheme@(guile-user)> (define cc #f) scheme@(guile-user)> (map (lambda (v) (if (= v 0) (call/cc (lambda (c) (set! cc c) 0)) (+ v 1))) '(10 20 30 0 40 50 60)) $1 = (11 21 31 0 41 51 61) scheme@(guile-user)> (cc 5) $2 = (61 51 41 0 31 5 41 51 61) It worked correctly in Guile 1.8. -zefram
bug#21901: bit shift wrong on maximal right shift
With Guile 2.0.11: scheme@(guile-user)> (ash 123 (ash -1 63)) $1 = 123 Correct result would of course be zero. Problem only occurs for exactly this shift distance: one bit less produces the right answer. Problem also occurs on Guile 1.8.8. Looking at the implementation, the problem is attributable to the negation of the shift distance, which in twos-complement fails to produce the expected positive result. Note the resemblance to bug #14864, fixed in 2.0.10. This bug is of very similar form, but is distinct. The test cases of #14864 pass for me on the 2.0.11 that shows the problem with a 2^63 bit shift. My bug does occur with the rnrs bitwise-arithmetic-shift-right, which was used in #14864, as well as with ash. -zefram
bug#21902: doc incorrectly describes Julian Date
The manual says, in the section "SRFI-19 Introduction", #Also, for those not familiar with the terminology, a "Julian Day" is # a real number which is a count of days and fraction of a day, in UTC, # starting from -4713-01-01T12:00:00Z, ie. midday Monday 1 Jan 4713 B.C. There are two errors in the first statement of the epoch for Julian Date, in ISO 8601 format. The JD epoch is noon on 1 January 4713 BC *in the proleptic Julian calendar*. The ISO 8601 format is properly never used on the Julian calendar: ISO 8601 specifies the use of the Gregorian calendar, including proleptically where necessary (as it most certainly is here). On the proleptic Gregorian calendar, the JD epoch is noon on 24 November 4714 BC, and so the ISO 8601 expression should have some "-11-24". The second error is in how the year is expressed in ISO 8601. The initial "-" does not mean the BC era, it means that the year number is negative. ISO 8601 specifies that the AD era is always used, with year numbers going negative where necessary; this arrangement is commonly known as "astronomical year numbering". So "" means 1 BC, "-0001" means 2 BC, and "-4713" means 4714 BC. So the "-4713" is not correct for the attempted expression of the Julian calendar date, but happens to be correct for the Gregorian calendar date. Putting it together, a correct ISO 8601 expression for the Julian Date epoch is "-4713-11-24T12:00:00Z". The word-based statement of the JD epoch is correct as far as it goes, but would benefit considerably by the addition of a clause stating that it is in the proleptic Julian calendar. (Generally, a clarification of which calendar is being used is helpful with the statement of any date prior to the UK's switch of calendar in 1752.) The description of Modified Julian Date is essentially correct. However, there's a third problem: misuse of the term "UTC" for historical times. The description of Julian Date says it's counted "in UTC", and the statement of the MJD epoch describes its 1858 time as being specified in UTC. UTC is defined entirely by its relationship to TAI, which is defined by the operation of atomic clocks. TAI is therefore only defined for the period since the operation of the first caesium atomic clock in the middle of 1955. The UTC<->TAI relationship isn't actually defined even that far back: UTC begins at the beginning of 1961 (and that was not in the modern form with leap seconds). It is therefore incorrect to apply the term "UTC" to any time prior to 1961. These two references to UTC should instead be to "UT", the wider class of closely-matching time scales of which UTC is one representative. Also, in the first sentence of this doc section, the phrase "universal time (UTC)" should be either "universal time (UT)" or (more likely) "coordinated universal time (UTC)". -zefram
bug#21903: date->string duff ISO 8601 negative years
The date->string function from (srfi srfi-19), used on ISO 8601 formats "~1", "~4" and "~5", for years preceding AD 1, has an off-by-one error: scheme@(guile-user)> (use-modules (srfi srfi-19)) scheme@(guile-user)> (date->string (julian-day->date 0 0) "~4") $1 = "-4714-11-24T12:00:00Z" The date in question, the JD epoch, is 24 November 4714 BC (in the proleptic Gregorian calendar). In ISO 8601 format, that year is properly represented as "-4713", not "-4714", because ISO 8601 uses the AD era exclusively. 4714 BC = AD -4713. -zefram
bug#21904: date->string duff ISO 8601 format for non-4-digit years
The date->string function from (srfi srfi-19), used on ISO 8601 formats "~1", "~4", and "~5", gets the formatting of year numbers wrong when the year number doesn't have exactly four digits. There are multiple cases: scheme@(guile-user)> (date->string (julian-day->date 150 0) "~1") $1 = "-607-10-04" scheme@(guile-user)> (date->string (julian-day->date 170 0) "~1") $2 = "-59-05-05" scheme@(guile-user)> (date->string (julian-day->date 172 0) "~1") $3 = "-4-02-05" For year numbers -999 to -1 inclusive, date->string is using the minimum number of digits to express the number, but ISO 8601 requires the use of at least four digits, with zero padding on the left. So one should write "-0059" rather than "-59", for example. Note that this range is also affected by the off-by-one error in the selection of the year number that I described in bug #21903, but that's not the subject of the present bug report. Here I'm concerned with how the number is represented in characters, not with how the year is represented numerically. scheme@(guile-user)> (date->string (julian-day->date 1722000 0) "~1") $4 = "2-07-29" scheme@(guile-user)> (date->string (julian-day->date 173 0) "~1") $5 = "24-06-23" scheme@(guile-user)> (date->string (julian-day->date 200 0) "~1") $6 = "763-09-18" For year numbers 1 to 999 inclusive, again date->string is using the minimum number of digits to express the number, but ISO 8601 requires the use of at least four digits. If no leading "+" sign is used then the number must be exactly four digits, and that is the appropriate format to use in this situation. So one should write "0024" rather than "24", for example. The year number 0, representing the year 1 BC, logically also falls into this group, and should be represented textually as "". Currently this case doesn't arise in the function's output, because the off-by-one bug has it erroneously emit "-1" for that year. scheme@(guile-user)> (date->string (julian-day->date 1000 0) "~1") $7 = "22666-12-20" scheme@(guile-user)> (date->string (julian-day->date 1 0) "~1") $8 = "269078-08-07" For year numbers 1 and above, it is necessary to use more than four digits for the year, and that's permitted, but ISO 8601 requires that more than four digits are preceded by a sign. For positive year numbers the sign must be "+". So one should write "+22666" rather than "22666", for example. The formatting of year numbers for ISO 8601 purposes is currently only correct for numbers -1000 and lower (though the choice of number is off by one) and for year numbers 1000 to inclusive. -zefram
bug#21906: julian-day->date negative input breakage
scheme@(guile-user)> (use-modules (srfi srfi-19)) scheme@(guile-user)> (julian-day->date 0 0) $1 = # scheme@(guile-user)> (julian-day->date -1 0) $2 = # scheme@(guile-user)> (julian-day->date -10 0) $3 = # scheme@(guile-user)> (julian-day->date -1000 0) $4 = # Observe the various erroneous field values: negative hour, negative day-of-month, zero month. These occur in general for various negative JD inputs. Not only should the conversion not produce these kinds of values, the date structure type probably ought to reject them if they get that far. -zefram
bug#21907: date->string duff ISO 8601 zone format
scheme@(guile-user)> (use-modules (srfi srfi-19)) scheme@(guile-user)> (date->string (julian-day->date 245 3600) "~4") $1 = "1995-10-09T13:00:00+0100" scheme@(guile-user)> (date->string (julian-day->date 245 3630) "~4") $2 = "1995-10-09T13:00:30+0100" There are two problems here with date->string's representation of zone offsets for the ISO 8601 formats "~2" and "~4". Firstly, because the time-of-day is represented in the extended format with colon separators, the zone offset must also be represented with colon separators. So the first "+0100" above should be "+01:00". Secondly, the offset is being truncated to an integral minute, so the output doesn't fully represent the zone offset. More importantly, because the local time-of-day isn't being adjusted to match, it's not accurately representing the point in time. ISO 8601 doesn't permit a seconds component in the zone offset, so you have a choice of three not-entirely-satisfactory options. Firstly, you could round the zone offset and adjust the represented local time accordingly, so the 3630 conversion above would yield either "1995-10-09T13:00:00+01:00" or "1995-10-09T13:01:00+01:01". Secondly, you could use the obvious extension of the ISO 8601 format to a seconds component, outputting "1995-10-09T13:00:30+01:00:30". Or finally you could signal an error when trying to represent a zone offset that's not an integral minute. Incidentally, for offsets of -1 to -59 inclusive, the truncation isn't clearing the negative sign, so is producing the invalid output "-". The zero offset is required to be represented with a "+" sign. If you take the rounding option described above, anything that rounds to a zero-minutes offset must yield "+00:00" in the output. -zefram
bug#21911: TAI-to-UTC conversion leaps at wrong time
Probing the TAI-to-UTC conversion offered by srfi-19's time-tai->date, in the minutes around the leap second in 2012: scheme@(guile-user)> (use-modules (srfi srfi-19)) scheme@(guile-user)> (for-each (lambda (d) (write (list d (date->string (time-tai->date (add-duration (julian-day->time-tai 2456109) (make-time time-duration 0 d)) 0) "~4"))) (newline)) (list 43000 43160 43164 43165 43166 43167 43199 43200 43201 43202)) (43000 "2012-06-30T23:56:40Z") (43160 "2012-06-30T23:59:20Z") (43164 "2012-06-30T23:59:24Z") (43165 "2012-06-30T23:59:25Z") (43166 "2012-06-30T23:59:25Z") (43167 "2012-06-30T23:59:26Z") (43199 "2012-06-30T23:59:58Z") (43200 "2012-06-30T23:59:59Z") (43201 "2012-06-30T23:59:60Z") (43202 "2012-07-01T00:00:01Z") The julian-day->time-tai conversion is correct (the JD refers to 2012-06-30T12:00:00 UTC, which is 2012-06-30T12:00:34 TAI), and the duration addition works in a perfectly regular manner in TAI space. All the interesting stuff happens in the TAI-to-UTC conversion, between the time-tai structure and the date structure. The same thing happens if the conversion is performed by separate time-tai->time-utc and time-utc->date calls. The date->string part is correct and uninteresting. The conversion is initially correct, minutes before midnight, but a discontinuity is seen 35 seconds before midnight. Outputs from then up to one second after midnight are one second slow. At one second after midnight it recovers. Because 35 seconds happens to be the TAI-UTC difference prevailing immediately after this leap second, I suspect that this is down to a time_t value (as used in the time-utc structure) for the moment of the leap being misinterpreted as a time-tai seconds value. The UTC-to-TAI conversion is in better shape. As a result, time-tai->time-utc and time-utc->time-tai are not inverses during the 35 second erroneous period. Round-tripping through the two conversions produces an output not matching the input. -zefram
bug#21912: TAI<->UTC conversion botches the unknown
Probing the existence of leap seconds on particular days, via srfi-19's TAI-to-UTC conversion. The methodology here is to take noon UT on the day of interest, convert to TAI, add 86400 seconds, then convert to UTC and display. The resulting time of day is 11:59:59 if there is a leap second that day, and 12:00:00 if there is not. scheme@(guile-user)> (use-modules (srfi srfi-19)) scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2455743) (make-time time-duration 0 86400)) 0) "~4") $1 = "2011-07-01T12:00:00Z" scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2456109) (make-time time-duration 0 86400)) 0) "~4") $2 = "2012-07-01T11:59:59Z" scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2457204) (make-time time-duration 0 86400)) 0) "~4") $3 = "2015-07-01T12:00:00Z" scheme@(guile-user)> (date->string (time-tai->date (add-duration (julian-day->time-tai 2457935) (make-time time-duration 0 86400)) 0) "~4") $4 = "2017-07-01T12:00:00Z" For 2011-06-30 it is correct that there was not a leap second, and for 2012-06-30 it is correct that there was. But for 2015-06-30 it says there was not a leap second, when in fact there was. For 2017-06-30 it says there will not be a leap second, when in fact it is not yet determined whether there will be. Really both of these errors come from the same cause. At the time this Guile 2.0.11 was released, the leap status of 2015-06-30 had not yet been determined. Both 2015 and 2017 fall within the future period beyond the scope of this Guile's static leap second knowledge. The bug is not that Guile doesn't know that there was a leap second in 2015. As the 2017 case illustrates, it's impossible for it to know all the leap second scheduling about which it can be asked. The bug is that Guile *thinks* it knows about all future leap seconds. It specifically thinks that there will be no leaps at all beyond the historically-scheduled ones that it knows about. Guile ought to be aware of how far its leap table extends, and signal an error when asked to perform a TAI<->UTC conversion that falls outside its scope. -zefram
bug#21915: write inconsistent about #nil
The write function is inconsistent about whether it distinguishes between #nil and (): scheme@(guile-user)> '(#nil . a) $1 = (#nil . a) scheme@(guile-user)> '(a . #nil) $2 = (a) Thee latter behaviour, emitting #nil as if it were (), breaks the usual write/read round-tripping, and the traditional correspondence between equal? and matching of written representation. Admittedly those standards are not absolute, nor is the extent to which they're expected to hold documented, but #nil is clearly sufficiently atomic to be the kind of value to which one would expect them to apply. For these reasons, if a consistent behaviour is to be chosen, I think it should be to consistently distinguish the values. I think the behaviour should be consistent. The values should be distinguished or not without regard to the context in which they arise within an s-expression. Whatever is done, even if it's to endorse the inconsistency, the behaviour should be documented, with rationale. -zefram
bug#21514: Guile 2.2: Sluggish elf calls, esp around arity / promises / statprof
Here's a fix to this bug. Tests pass, and performance appears to be back here. I've assigned copyright to the FSF for Guile so it should be fine to commit! >From 79e3b5286a2699f9b302bd3abf8a6b884b13a4f4 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 13 Nov 2015 20:42:31 -0600 Subject: [PATCH] Remove thunk / arity check in make-promise * libguile/promises.c (s_scm_make_promise): Remove arity check in make-promise. This was causing considerably slowdown with the new elf code, causing considerable number of bytevector reading calls on every call to (make-promise). Removing this check fixes a performance regression in the new compiler. --- libguile/promises.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libguile/promises.c b/libguile/promises.c index dcd0ac3..858b6f3 100644 --- a/libguile/promises.c +++ b/libguile/promises.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 +/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2015 * Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or @@ -77,7 +77,6 @@ SCM_DEFINE (scm_make_promise, "make-promise", 1, 0, 0, "@end lisp\n") #define FUNC_NAME s_scm_make_promise { - SCM_VALIDATE_THUNK (1, thunk); SCM_RETURN_NEWSMOB2 (scm_tc16_promise, SCM_UNPACK (thunk), SCM_UNPACK (scm_make_recursive_mutex ())); -- 2.1.4