The package rpms/racket.git has added or updated architecture specific content in its spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s): https://src.fedoraproject.org/cgit/rpms/racket.git/commit/?id=f241dafce90841... https://src.fedoraproject.org/cgit/rpms/racket.git/commit/?id=b8569a44d31acf....
Change: +ExcludeArch: s390x armv7hl +%ifarch %{ix86}
Thanks.
Full change: ============
commit b8569a44d31acfcec836302dff9ae178d3957c0b Author: dbenoit dbenoit@redhat.com Date: Wed Sep 5 15:37:42 2018 -0400
fix i686 and remove ppc64
diff --git a/racket.spec b/racket.spec index 5fb06c9..bb31acd 100644 --- a/racket.spec +++ b/racket.spec @@ -1,6 +1,6 @@ Name: racket Version: 7.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: General purpose programming language
License: GPLv3 and LGPLv3 and MIT @@ -21,7 +21,8 @@ Patch0: racket-7.0-remove-nonfree.patch Patch1: racket-7.0-fix-doc-open-url.patch
# Issue Building for s390x and armv7hl in koji -ExcludeArch: s390x armv7hl +#ExcludeArch: s390x armv7hl +ExcludeArch: s390x armv7hl ppc64
# To compile the program BuildRequires: gcc @@ -70,11 +71,20 @@ rm -r src/foreign/libffi
%build cd src + +# Disable SSE on i686 until fixed upstream +# https://github.com/racket/racket/issues/2245 +%ifarch %{ix86} + %set_build_flags + export CFLAGS=$(echo $CFLAGS | sed -e "s/-mfpmath=sse *//") +%endif + %configure \ --enable-pthread \ --enable-shared \ --enable-libffi \ --disable-strip + %make_build
%install @@ -231,7 +241,13 @@ A local installation of the Racket documentation system. %{_datadir}/doc/racket
%changelog -* Fri Aug 3 2018 David Benoit dbenoit@redhat.com 7.0-1 +* Wed Sep 5 2018 David Benoit dbenoit@redhat.com 7.0-2 +- Disable SSE math on i686 until issue is fixed upstream +- Exclude ppc due to issue building Racket v7.0 and + arch being deprecated in next release + +* Fri Aug 17 2018 David Benoit dbenoit@redhat.com 7.0-1 +- Update sources to Racket v7.0 - Remove 6.12 patches and add update remove nonfree srfi patch to 7.0
commit ee22cb0e92daba659fd9d9fd4855d952e21cc53f Author: dbenoit dbenoit@redhat.com Date: Fri Aug 31 15:39:51 2018 -0400
update package to v7.0
diff --git a/.gitignore b/.gitignore index d013960..4fd1ad5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/racket-6.12-src.tgz +/racket-7.0-src.tgz diff --git a/racket-6.12-fix-doc-open-url.patch b/racket-6.12-fix-doc-open-url.patch deleted file mode 100644 index 7c497f5..0000000 --- a/racket-6.12-fix-doc-open-url.patch +++ /dev/null @@ -1,69 +0,0 @@ -diff -urN racket-6.12-wbsvr/share/pkgs/scribble-lib/help/search.rkt racket-6.12/share/pkgs/scribble-lib/help/search.rkt ---- racket-6.12-wbsvr/share/pkgs/scribble-lib/help/search.rkt 2018-03-19 17:14:56.017273013 -0400 -+++ racket-6.12/share/pkgs/scribble-lib/help/search.rkt 2018-03-19 17:15:37.839113929 -0400 -@@ -17,33 +17,38 @@ - #:notify [notify void]) - (define open-url (get-doc-open-url)) - (cond -- [open-url -- (define dest-url (let ([u (string->url open-url)]) -- (combine-url/relative -- u -- (string-join -- (for/list ([s (explode-path sub)]) -- (if (path? s) -- (path-element->string s) -- (format "~a" s))) -- "/")))) -- (notify (url->string dest-url)) -- (send-url (url->string -- (struct-copy url dest-url -- [fragment (or fragment -- (url-fragment dest-url))] -- [query (append -- (url-query dest-url) -- (if query -- (url-query -- (string->url -- (format "q?~a" query))) -- null))])))] -- [else -- (let* ([path (build-path (find-user-doc-dir) sub)] -- [path (if (file-exists? path) path (build-path (find-doc-dir) sub))]) -- (notify path) -- (send-url/file path #:fragment fragment #:query query))])) -+ [open-url -+ (define dest-url (let ([u (string->url open-url)]) -+ (combine-url/relative -+ u -+ (string-join -+ (for/list ([s (explode-path sub)]) -+ (if (path? s) -+ (path-element->string s) -+ (format "~a" s))) -+ "/")))) -+ (notify (url->string dest-url)) -+ (send-url (url->string -+ (struct-copy url dest-url -+ [fragment (or fragment -+ (url-fragment dest-url))] -+ [query (append -+ (url-query dest-url) -+ (if query -+ (url-query -+ (string->url -+ (format "q?~a" query))) -+ null))])))] -+ [else -+ (let* ([path (build-path (find-user-doc-dir) sub)] -+ [path (if (file-exists? path) path (build-path (find-doc-dir) sub))]) -+ (notify path) -+ (if (file-exists? path) -+ (send-url/file path #:fragment fragment #:query query) -+ (let ([part (lambda (pfx x) (if x (string-append pfx x) ""))]) -+ (send-url (string-append -+ "https://docs.racket-lang.org/" -+ sub (part "#" fragment) (part "?" query))))))])) - - ;; This is an example of changing this code to use the online manuals. - ;; Normally, it's better to set `doc-open-url` in "etc/config.rktd", diff --git a/racket-6.12-fix-rpaths.patch b/racket-6.12-fix-rpaths.patch deleted file mode 100644 index f76730e..0000000 --- a/racket-6.12-fix-rpaths.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -urN racket-6.12-f/collects/racket/runtime-path.rkt racket-6.12/collects/racket/runtime-path.rkt ---- racket-6.12-f/collects/racket/runtime-path.rkt 2018-02-06 16:04:29.969878308 -0500 -+++ racket-6.12/collects/racket/runtime-path.rkt 2018-02-06 16:07:10.549176282 -0500 -@@ -186,7 +186,8 @@ - (path-of - #,(datum->syntax - #'orig-stx -- `(,#'this-expression-source-file)))) -+ `(,#'this-expression-source-file) -+ #'orig-stx))) - #'void)]) - (apply to-values (resolve-paths (#%variable-reference) - get-dir diff --git a/racket-6.12-fix-webserver-rpaths.patch b/racket-6.12-fix-webserver-rpaths.patch deleted file mode 100644 index 78614cf..0000000 --- a/racket-6.12-fix-webserver-rpaths.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff -urN racket-6.12-rp/share/pkgs/web-server-lib/web-server/formlets/lib.rkt racket-6.12-wbsvr/share/pkgs/web-server-lib/web-server/formlets/lib.rkt ---- racket-6.12-rp/share/pkgs/web-server-lib/web-server/formlets/lib.rkt 2018-02-22 18:42:06.131455756 -0500 -+++ racket-6.12-wbsvr/share/pkgs/web-server-lib/web-server/formlets/lib.rkt 2018-03-20 15:07:09.666222028 -0400 -@@ -7,6 +7,7 @@ - racket/function - racket/serialize - syntax/location -+ setup/collects - (for-syntax racket/base - syntax/parse)) - -@@ -70,20 +71,20 @@ - #:range-contracts (map (curry coerce-contract 'formlet/c) - contracts)))])) - (define quote-this-module-path -- (quote-module-path)) -+ (path->collects-relative (quote-module-path))) - (define-syntax formlet/c - (syntax-parser - [(_ range ...) - #:declare range (expr/c #'contract? - #:name "range contract argument") - #'(formlet/c** (-> listof-binding -- (values (coerce-contract 'formlet/c range.c) ...)))] -+ (values (coerce-contract 'formlet/c range #;.c) ...)))] - [name:id - #`(contract - (-> contract? (... ...) contract?) - dynamic-formlet/c - quote-this-module-path -- (quote-module-path) -+ (path->collects-relative (quote-module-path)) - "formlet/c" - #'name)])) - diff --git a/racket-6.12-remove-nonfree.patch b/racket-6.12-remove-nonfree.patch deleted file mode 100644 index 4e72a3e..0000000 --- a/racket-6.12-remove-nonfree.patch +++ /dev/null @@ -1,1124 +0,0 @@ -diff -urN racket-6.12-nf/share/links.rktd racket-6.12/share/links.rktd ---- racket-6.12-nf/share/links.rktd 2018-01-31 13:04:06.757393819 -0500 -+++ racket-6.12/share/links.rktd 2018-01-31 13:04:25.419309681 -0500 -@@ -133,7 +133,6 @@ - (root "pkgs/r5rs-doc") - (root "pkgs/srfi-lite-lib") - (root "pkgs/srfi-lib") -- (root "pkgs/srfi-lib-nonfree") - (root "pkgs/html-doc") - (root "pkgs/images-gui-lib") - (root "pkgs/images-doc") -@@ -177,7 +176,6 @@ - (root "pkgs/slideshow-exe") - (root "pkgs/slideshow-plugin") - (root "pkgs/srfi-doc") -- (root "pkgs/srfi-doc-nonfree") - (root "pkgs/syntax-color-doc") - (root "pkgs/web-server-lib") - (root "pkgs/unix-socket-lib") -diff -urN racket-6.12-nf/share/pkgs/srfi/info.rkt racket-6.12/share/pkgs/srfi/info.rkt ---- racket-6.12-nf/share/pkgs/srfi/info.rkt 2018-01-31 13:04:07.216391749 -0500 -+++ racket-6.12/share/pkgs/srfi/info.rkt 2018-01-31 13:05:32.601025227 -0500 -@@ -3,13 +3,9 @@ - (define collection 'multi) - - (define deps '("srfi-lib" -- "srfi-lib-nonfree" -- "srfi-doc" -- "srfi-doc-nonfree")) -+ "srfi-doc")) - (define implies '("srfi-lib" -- "srfi-lib-nonfree" -- "srfi-doc" -- "srfi-foc-nonfree")) -+ "srfi-doc")) - - (define pkg-desc "Legacy SRFI (Scheme) libraries") - -diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt ---- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/info.rkt 2018-01-31 13:04:07.221391727 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,19 +0,0 @@ --#lang info -- --(define collection 'multi) -- --(define build-deps '("mzscheme-doc" -- "scheme-lib" -- "base" -- "scribble-lib" -- "srfi-doc" -- "srfi-lib-nonfree" -- "racket-doc" -- "r5rs-doc" -- "r6rs-doc" -- "compatibility-lib")) --(define update-implies '("srfi-lib-nonfree")) -- --(define pkg-desc "documentation part of "srfi nonfree"") -- --(define pkg-authors '(mflatt noel chongkai jay)) -diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt ---- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 2018-01-31 13:04:07.221391727 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,3 +0,0 @@ --#lang info -- --(define scribblings '(("srfi-nf.scrbl" (multi-page) (library 100)))) -diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl ---- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 2018-01-31 13:04:07.221391727 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 1969-12-31 19:00:00.000000000 -0500 -@@ -1,66 +0,0 @@ --#lang scribble/doc --@(require srfi/scribblings/util -- scribble/manual -- scribble/eval -- scriblib/render-cond -- scribble/core -- scribble/html-properties -- (for-syntax scheme/base) -- (for-label scheme/base -- racket/stream)) -- --@; ---------------------------------------------------------------------- -- --@title{SRFI Nonfree Libraries and Documentation} -- --The @link[#:style srfi-std "http://srfi.schemers.org/%22%5D%7BScheme Requests for --Implementation} (a.k.a. @deftech{SRFI}) process allows individual --members of the Scheme community to propose libraries and extensions to --be supported by multiple Scheme implementations. -- --Racket is distributed with implementations of many SRFIs, most of --which can be implemented as libraries. To import the bindings of SRFI --@math{n}, use -- --@racketblock[ --(require @#,elem{@racketidfont{srfi/}@math{n}}) --] -- --This document lists the SRFIs that are supported by Racket and --provides a link to the original SRFI specification (which is also --distributed as part of Racket's documentation). -- --The following SRFI specification documents are licensed restrictively. -- --@table-of-contents[] -- -- --@; ---------------------------------------- -- --@srfi[5]{A compatible let form with signatures and rest arguments} -- --@redirect[5 '( -- (let #t "unnamed") --)] -- --Racket provides this SRFI in the @racket[srfi-lib-nonfree] package. -- --@; ---------------------------------------- -- --@srfi[29]{Localization} -- --@redirect[29 '( -- (current-language #f "current-language") -- (current-country #f "current-country") -- (current-locale-details #f "current-locale-details") -- (declare-bundle! #f "declare-bundle!") -- (store-bundle #f "store-bundle") -- (load-bundle! #f "load-bundle!") -- (localized-template #f "localized-template") --)] -- --Racket provides a free implementation of this SRFI in the @racket[srfi-lib] package. Only the SRFI specification document is nonfree. -- --@; ---------------------------------------- -- --@index-section[] -diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html ---- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 2018-01-31 13:04:07.221391727 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 1969-12-31 19:00:00.000000000 -0500 -@@ -1,507 +0,0 @@ --<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN"> --<html> -- <head> -- <meta name="generator" content="HTML Tidy, see www.w3.org"> -- <title>SRFI 29: Localization</title> -- <meta name="author" content="Scott G. Miller"> -- <meta name="description" content="Localization"> -- </head> -- <body> -- <H1>Title</H1> -- -- SRFI 29: Localization -- -- <H1>Author</H1> -- -- Scott G. Miller -- -- <H1>Abstract</H1> -- -- This document specifies an interface to retrieving and -- displaying locale sensitive messages. A Scheme program can -- register one or more translations of templated messages, and -- then write Scheme code that can transparently retrieve the -- appropriate message for the locale under which the Scheme -- system is running. <br> -- -- -- <H1>Rationale</H1> -- -- <p>As any programmer that has ever had to deal with making his -- or her code readable in more than one locale, the process of -- sufficiently abstracting program messages from their -- presentation to the user is non-trivial without help from the -- programming language. Most modern programming language -- libraries do provide some mechanism for performing this -- separation.</p> -- -- <p>A portable API that allows a piece of code to run without -- modification in different countries and under different -- languages is a must for any non-trivial software project. -- The interface should separate the logic of a program from -- the myriad of translations that may be necessary.</p> -- -- <p>The interface described in this document provides such -- functionality. The underlying implementation is also allowed to -- use whatever datastructures it likes to provide access to the -- translations in the most efficient manner possible. In -- addition, the implementation is provided with standardized -- functions that programs will use for accessing an external, -- unspecified repository of translations.</p> -- -- <p>This interface <i>does not</i> cover all aspects of -- localization, including support for non-latin characters, -- number and date formatting, etc. Such functionality is the -- scope of a future SRFI that may extend this one.</p> -- -- <H1>Dependencies</H1> -- -- An SRFI-29 conformant implementation must also implement -- SRFI-28, Basic Format Strings. Message templates are strings -- that must be processed by the <tt>format</tt> function -- specified in that SRFI. -- -- <H1>Specification</H1> -- -- <h3>Message Bundles</h3> -- -- <p>A Message Bundle is a set of message templates and their -- identifying keys. Each bundle contains one or more such -- key/value pairs. The bundle itself is associated with a -- <i>bundle specifier</i> which uniquely identifies the -- bundle.</p> -- -- <h3>Bundle Specifiers</h3> -- -- <p>A Bundle Specifier is a Scheme list that describes, in order -- of importance, the package and locale of a message bundle. -- In most cases, a locale specifier will have between one -- and three elements. The first element is a symbol denoting the -- package for which this bundle applies. The second and third -- elements denote a <i>locale</i>. The second element (first -- element of the locale) if present, is the two letter, ISO 639-1 -- language code for the bundle. The third element, if present, is -- a two letter ISO 3166-1 country code. In some cases, a -- fourth element may be present, specifying the encoding used for -- the bundle. All bundle specifier elements are Scheme -- symbols.</p> -- -- <p>If only one translation is provided, it should be designated -- only by a package name, for example <tt>(mathlib)</tt>. This -- translation is called the <i>default</i> translation.</p> -- -- <h3>Bundle Searching</h3> -- -- <p>When a message template is retrieved from a bundle, the -- Scheme implementation will provide the locale under which the -- system is currently running. When the template is retrieved, -- the package name will be specified. The Scheme system should -- construct a Bundle Specifier from the provided package name and -- the active locale. For example, when retrieving a message -- template for French Canadian, in the <tt>mathlib</tt> package, -- the bundle specifier '<tt>(mathlib fr ca)</tt>' is used. A -- program may also retrieve the elements of the current locale -- using the no-argument procedures:</p> -- -- <p><b><a name="current-language"></a><tt>current-language</tt></b> <tt>-> -- <i>symbol</i></tt><br> -- <tt><b>current-language</b> <i>symbol</i> -> -- undefined</tt><br> -- </p> -- -- <blockquote> -- When given no arguments, returns the current ISO 639-1 -- language code as a symbol. If provided with an -- argument, the current language is set to that named by the -- symbol for the currently executing Scheme thread (or for the -- entire Scheme system if such a distinction is not possible). -- -- </blockquote> -- -- <p><b><a name="current-country"></a><tt>current-country</tt></b> <tt>-> -- <i>symbol</i></tt><br> -- <tt><b>current-country</b> <i>symbol</i> -> -- undefined</tt><br> -- </p> -- -- <blockquote> -- returns the current ISO 3166-1 country code as a symbol. -- If provided with an argument, the current country is -- set to that named by the symbol for the currently executing -- Scheme thread (or for the entire Scheme system if such a -- distinction is not possible). -- </blockquote> -- -- <p><b><a name="current-locale-details"></a><tt>current-locale-details</tt></b> <tt>-> <i>list of -- symbol</i></tt>s<br> -- <tt><b>current-locale-details</b> <i>list-of-symbols</i> -> -- undefined</tt><br> -- </p> -- -- <blockquote> -- Returns a list of additional locale details as a list of -- symbols. This list may contain information about -- encodings or other more specific information. If -- provided with an argument, the current locale details are set -- to those given in the currently executing Scheme thread (or -- for the entire Scheme system if such a distinction is not -- possible). -- </blockquote> -- -- <p>The Scheme System should first check for a bundle with the -- exact name provided. If no such bundle is found, the last -- element from the list is removed and a search is tried for a -- bundle with that name. If no bundle is then found, the list is -- shortened by removing the last element again. If no message is -- found and the bundle specifier is now the empty list, an error -- should be raised.</p> -- -- <p>The reason for this search order is to provide the most -- locale sensitive template possible, but to fall back on more -- general templates if a translation has not yet been provided -- for the given locale.</p> -- -- <h3>Message Templates</h3> -- -- <p>A message template is a localized message that may or may -- not contain one of a number of formatting codes. A message -- template is a Scheme string. The string is of a form that can -- be processed by the <tt>format</tt> procedure found in many -- Scheme systems and formally specified in SRFI-28 (Basic Format -- Strings).</p> -- -- <p>This SRFI also extends SRFI-28 to provide an additional -- <tt>format</tt> escape code:</p> -- -- <blockquote> -- <tt>~[n]@*</tt> - Causes a value-requiring escape code that -- follows this code immediately to reference the [N]'th -- optional value absolutely, rather than the next unconsumed -- value. The referenced value is <i>not</i> consumed. -- </blockquote> -- This extension allows optional values to be positionally -- referenced, so that message templates can be constructed that -- can produce the proper word ordering for a language. -- -- <h3>Preparing Bundles</h3> -- Before a bundle may be used by the Scheme system to retrieve -- localized template messages, they must be made available to the -- Scheme system. This SRFI specifies a way to portably -- define the bundles, as well as store them in and retrieve them -- from an unspecified system which may be provided by resources -- outside the Scheme system.<br> -- -- -- <p><b><a name="declare-bundle!"></a><tt>declare-bundle!</tt></b> <tt><i>bundle-specifier -- association-list</i> -> undefined<br> -- </tt></p> -- -- <blockquote> -- Declares a new bundle named by the given bundle-specifier. -- The contents of the bundle are defined by the provided -- association list. The list contains associations -- between Scheme symbols and the message templates (Scheme -- strings) they name. If a bundle already exists with the -- given name, it is overwritten with the newly declared -- bundle.<br> -- </blockquote> -- <tt><a name="store-bundle"></a><b>store-bundle</b> <i>bundle-specifier</i> -> -- boolean</tt><br> -- -- -- <blockquote> -- Attempts to store a bundle named by the given bundle -- specifier, and previously made available using -- <tt>declare-bundle!</tt> or <tt>load-bundle!</tt>, in an -- unspecified mechanism that may be persistent across Scheme -- system restarts. If successful, a non-false value is -- returned. If unsuccessful, <tt>#f</tt> is returned.<br> -- </blockquote> -- <tt><a name="load-bundle!"></a><b>load-bundle!</b> <i>bundle-specifier</i> -> -- boolean</tt><br> -- -- -- <blockquote> -- Attempts to retrieve a bundle from an unspecified mechanism -- which stores bundles outside the Scheme system. If the -- bundle was retrieved successfully, the function returns a -- non-false value, and the bundle is immediately available to -- the Scheme system. If the bundle could not be found or loaded -- successfully, the function returns <tt>#f</tt>, and the -- Scheme system's bundle registry remains unaffected.<br> -- </blockquote> -- A compliant Scheme system may choose not to provide any -- external mechanism to store localized bundles. If it does -- not, it must still provide implementations for -- <tt>store-bundle</tt> and <tt>load-bundle!</tt>. In such a -- case, both functions must return <tt>#f</tt> regardless of the -- arguments given. Users of this SRFI should recognize that the -- inability to load or store a localized bundle in an external -- repository is <i>not</i> a fatal error.<br> -- -- -- <h3>Retrieving Localized Message Templates</h3> -- -- <p><a name="localized-template"></a><b><tt>localized-template</tt></b> <i><tt>package-name -- message-template-name</tt></i> <tt>-> <i>string or #f<br> -- </i></tt></p> -- -- <blockquote> -- Retrieves a localized message template for the given package -- name and the given message template name (both symbols). -- If no such message could be found, false (#f) is -- returned.<br> -- <br> -- </blockquote> -- After retrieving a template, the calling program can use -- <tt>format</tt> to produce a string that can be displayed to -- the user.<br> -- -- -- <h2>Examples</h2> -- The below example makes use of SRFI-29 to display simple, -- localized messages. It also defines its bundles in such a -- way that the Scheme system may store and retrieve the bundles -- from a more efficient system catalog, if available.<br> -- --<pre> --(let ((translations -- '(((en) . ((time . "Its ~a, ~a.") -- (goodbye . "Goodbye, ~a."))) -- ((fr) . ((time . "~1@*~a, c'est ~a.") -- (goodbye . "Au revoir, ~a.")))))) -- (for-each (lambda (translation) -- (let ((bundle-name (cons 'hello-program (car translation)))) -- (if (not (load-bundle! bundle-name)) -- (begin -- (declare-bundle! bundle-name (cdr translation)) -- (store-bundle! bundle-name))))) -- translations)) -- --(define localized-message -- (lambda (message-name . args) -- (apply format (cons (localized-template 'hello-program -- message-name) -- args)))) -- --(let ((myname "Fred")) -- (display (localized-message 'time "12:00" myname)) -- (display #\newline) -- -- (display (localized-message 'goodbye myname)) -- (display #\newline)) -- --;; Displays (English): --;; Its 12:00, Fred. --;; Goodbye, Fred. --;; --;; French: --;; Fred, c'est 12:00. --;; Au revoir, Fred. --</pre> -- -- <H1>Implementation</H1> -- -- <p>The implementation requires that the Scheme system provide a -- definition for <tt>current-language</tt> and -- <tt>current-country</tt> capable of distinguishing the correct -- locale present during a Scheme session. The definitions of -- those functions in the reference implementation are not capable -- of that distinction. Their implementation is provided only so -- that the following code can run in any R4RS scheme system. -- <br> -- </p> -- -- <p>In addition, the below implementation of a compliant -- <tt>format</tt> requires SRFI-6 (Basic String Ports) and -- SRFI-23 (Error reporting)</p> --<pre> --;; The association list in which bundles will be stored --(define *localization-bundles* '()) -- --;; The current-language and current-country functions provided --;; here must be rewritten for each Scheme system to default to the --;; actual locale of the session --(define current-language -- (let ((current-language-value 'en)) -- (lambda args -- (if (null? args) -- current-language-value -- (set! current-language-value (car args)))))) -- --(define current-country -- (let ((current-country-value 'us)) -- (lambda args -- (if (null? args) -- current-country-value -- (set! current-country-value (car args)))))) -- --;; The load-bundle! and store-bundle! both return #f in this --;; reference implementation. A compliant implementation need --;; not rewrite these procedures. --(define load-bundle! -- (lambda (bundle-specifier) -- #f)) -- --(define store-bundle! -- (lambda (bundle-specifier) -- #f)) -- --;; Declare a bundle of templates with a given bundle specifier --(define declare-bundle! -- (letrec ((remove-old-bundle -- (lambda (specifier bundle) -- (cond ((null? bundle) '()) -- ((equal? (caar bundle) specifier) -- (cdr bundle)) -- (else (cons (car bundle) -- (remove-old-bundle specifier -- (cdr bundle)))))))) -- (lambda (bundle-specifier bundle-assoc-list) -- (set! *localization-bundles* -- (cons (cons bundle-specifier bundle-assoc-list) -- (remove-old-bundle bundle-specifier -- *localization-bundles*)))))) -- --;;Retrieve a localized template given its package name and a template name --(define localized-template -- (letrec ((rdc -- (lambda (ls) -- (if (null? (cdr ls)) -- '() -- (cons (car ls) (rdc (cdr ls)))))) -- (find-bundle -- (lambda (specifier template-name) -- (cond ((assoc specifier *localization-bundles*) => -- (lambda (bundle) bundle)) -- ((null? specifier) #f) -- (else (find-bundle (rdc specifier) -- template-name)))))) -- (lambda (package-name template-name) -- (let loop ((specifier (cons package-name -- (list (current-language) -- (current-country))))) -- (and (not (null? specifier)) -- (let ((bundle (find-bundle specifier template-name))) -- (and bundle -- (cond ((assq template-name bundle) => cdr) -- ((null? (cdr specifier)) #f) -- (else (loop (rdc specifier))))))))))) -- --;;An SRFI-28 and SRFI-29 compliant version of format. It requires --;;SRFI-23 for error reporting. --(define format -- (lambda (format-string . objects) -- (let ((buffer (open-output-string))) -- (let loop ((format-list (string->list format-string)) -- (objects objects) -- (object-override #f)) -- (cond ((null? format-list) (get-output-string buffer)) -- ((char=? (car format-list) #~) -- (cond ((null? (cdr format-list)) -- (error 'format "Incomplete escape sequence")) -- ((char-numeric? (cadr format-list)) -- (let posloop ((fl (cddr format-list)) -- (pos (string->number -- (string (cadr format-list))))) -- (cond ((null? fl) -- (error 'format "Incomplete escape sequence")) -- ((and (eq? (car fl) '#@) -- (null? (cdr fl))) -- (error 'format "Incomplete escape sequence")) -- ((and (eq? (car fl) '#@) -- (eq? (cadr fl) '#*)) -- (loop (cddr fl) objects (list-ref objects pos))) -- (else -- (posloop (cdr fl) -- (+ (* 10 pos) -- (string->number -- (string (car fl))))))))) -- (else -- (case (cadr format-list) -- ((#\a) -- (cond (object-override -- (begin -- (display object-override buffer) -- (loop (cddr format-list) objects #f))) -- ((null? objects) -- (error 'format "No value for escape sequence")) -- (else -- (begin -- (display (car objects) buffer) -- (loop (cddr format-list) -- (cdr objects) #f))))) -- ((#\s) -- (cond (object-override -- (begin -- (display object-override buffer) -- (loop (cddr format-list) objects #f))) -- ((null? objects) -- (error 'format "No value for escape sequence")) -- (else -- (begin -- (write (car objects) buffer) -- (loop (cddr format-list) -- (cdr objects) #f))))) -- ((#%) -- (if object-override -- (error 'format "Escape sequence following positional override does not require a value")) -- (display #\newline buffer) -- (loop (cddr format-list) objects #f)) -- ((#~) -- (if object-override -- (error 'format "Escape sequence following positional override does not require a value")) -- (display #~ buffer) -- (loop (cddr format-list) objects #f)) -- (else -- (error 'format "Unrecognized escape sequence")))))) -- (else (display (car format-list) buffer) -- (loop (cdr format-list) objects #f))))))) -- --</pre> -- -- <H1>Copyright</H1> -- -- Copyright (C) Scott G. Miller (2002). All Rights Reserved. -- -- <p>This document and translations of it may be copied and -- furnished to others, and derivative works that comment on or -- otherwise explain it or assist in its implementation may be -- prepared, copied, published and distributed, in whole or in -- part, without restriction of any kind, provided that the above -- copyright notice and this paragraph are included on all such -- copies and derivative works. However, this document itself may -- not be modified in any way, such as by removing the copyright -- notice or references to the Scheme Request For Implementation -- process or editors, except as needed for the purpose of -- developing SRFIs in which case the procedures for copyrights -- defined in the SRFI process must be followed, or as required to -- translate it into languages other than English.</p> -- -- <p>The limited permissions granted above are perpetual and will -- not be revoked by the authors or their successors or -- assigns.</p> -- -- <p>This document and the information contained herein is -- provided on an "AS IS" basis and THE AUTHOR AND THE SRFI -- EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION -- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES -- OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> -- <hr> -- -- <address> -- Editor: <a href="mailto:srfi-editors@srfi.schemers.org">David -- Rush</a> -- </address> -- -- <address> -- Author: <a href="mailto:scgmille@freenetproject.org">Scott G. -- Miller</a> -- </address> -- <!-- Created: Tue Sep 29 19:20:08 EDT 1998 --> -- <!-- hhmts start -->Last modified: Mon Jun 17 12:00:08 Pacific -- Daylight Time 2002 <!-- hhmts end --> <br> -- </body> --</html> -- -diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html ---- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 2018-01-31 13:04:07.221391727 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 1969-12-31 19:00:00.000000000 -0500 -@@ -1,345 +0,0 @@ --<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"> --<html> --<head> -- <title>SRFI 5: A compatible let form with signatures and rest arguments</title> --</head> --<body> -- --<H1>Title</H1> -- --SRFI-5: A compatible <code>let</code> form with signatures and rest arguments -- --<H1>Author</H1> -- --Andy Gaynor -- --<H1>Status</H1> -- --This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>. --You can access the discussion on this SRFI via <A HREF="http://srfi.schemers.org/srfi-5/mail-archive/maillist.html">the archive of the mailing list</A>. --<P><UL> --<LI>Received: 1999/2/2 --<LI>Draft: 1999/2/10-1999/04/12 --<LI>Final: 1999/4/26 --<LI>Revised reference implementation: 2003/01/27 --</UL> -- --<H1>Abstract</H1> -- --The <i>named-let</i> incarnation of the <code>let</code> form has two slight --inconsistencies with the <code>define</code> form. As defined, the <code>let</code> --form makes no accommodation for rest arguments, an issue of functionality --and consistency. As defined, the <code>let</code> form does not accommodate --signature-style syntax, an issue of aesthetics and consistency. Both --issues are addressed here in a manner which is compatible with the traditional --<code>let</code> form but for minor extensions. -- --<H1>Rationale</H1> -- --<H2>Signature-style Syntax</H2> -- --Consider the following two equivalent definitions: -- --<p><pre> --(define fibonacci -- (lambda (n i f0 f1) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1))))) -- --(define (fibonacci n i f0 f1) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1)))) --</pre> -- --Although there is a named-let analog for the former form, there is none --for the latter. To wit, suppose one wished to compute the 10th element --of the Fibonacci sequence using a named let: -- --<p> --<pre> --(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1)))) --Values: 55 --</pre> -- --As it stands, one cannot equivalently write -- --<p> --<pre> --(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1)))) --</pre> -- --which is consistent with <code>define</code>'s signature-style form. --<p>Those that favor the signature style may prefer this extension. --In any case, it may be more appropriate to include all bound names within --the binding section. As presented, this straightforward extension --introduces no ambiguity or incompatibility with the existing definition --of let. -- --<H2>Rest Arguments</H2> -- --As it stands, one cannot write a named let with rest arguments, as in -- --<p> --<pre> --(let (blast (port (current-output-port)) . (x (+ 1 2) 4 5)) -- (if (null? x) -- 'just-a-silly-contrived-example -- (begin -- (write (car x) port) -- (apply blast port (cdr x))))) --</pre> -- --otherwise equivalent to -- --<p> --<pre> --(letrec ((blast (lambda (port . x) -- (if (null? x) -- 'just-a-silly-contrived-example -- (begin -- (write (car x) port) -- (apply blast port (cdr x))))))) -- (blast (current-output-port) (+ 1 2) 4 5)) --</pre> -- --While this example is rather contrived, the functionality is not. --There are several times when the author has used this construct in practice. --Regardless, there is little reason to deny the <code>let</code> form access to --all the features of lambda functionality. -- --<H2>Symbols in Binding Sections</H2> -- --Both the features above rely upon the placement of symbols in <code>let</code> --binding lists (this statement is intentially simplistic). The only --other apparent use of such symbol placement is to tersely bind variables --to unspecified values. For example, one might desire to use --<code>(let (foo bar baz) ...)</code> --to bind <code>foo</code>, <code>bar</code>, and <code>baz</code> to --unspecified values. -- --<p>This usage is considered less important in light of the rationales --presented above, and an alternate syntax is immediately apparent, as --in <code>(let ((foo) (bar) (baz)) ...)</code> This may even --be preferable, consistently parenthesizing normal binding clauses. -- --<H1>Specification</H1> -- --<H2>Syntax</H2> -- --<p> --A formal specification of the syntax follows. Below, body, expression, --and identifier are free. Each instantiation of binding-name must be --unique. --</p> -- --<p> --<pre> -- let = "(" "let" let-bindings body ")" -- expressions = nothing | expression expressions -- let-bindings = let-name bindings -- |"(" let-name "." bindings ")" -- let-name = identifier -- bindings = "(" ")" -- | rest-binding -- | "(" normal-bindings ["." rest-binding] ")" --normal-bindings = nothing -- | normal-binding normal-bindings --normal-binding = "(" binding-name expression ")" -- binding-name = identifier -- rest-binding = "(" binding-name expressions ")" --</pre> -- --<p> --For clarity and convenience, an informal specification follows. --</p> -- --<ol> --<li><a name="unnamed">Unnamed</a> -- --<p><pre> --(let ((<parameter> <argument>)...) -- <body>...) --</pre> --</li> -- --<li><a name="named-non-sig"> --Named, non-signature-style, no rest argument</a> -- --<p><pre> --(let <name> ((<parameter> <argument>)...) -- <body>...) --</pre> --</li> -- --<li><a name="named-sig">Named, signature-style, no rest argument</a> -- --<p><pre> --(let (<name> (<parameter> <argument>)...) -- <body>...) --</pre> --</li> -- --<li><a name="named-non-sig-rest">Named, non-signature-style, rest argument</a> -- --<p><pre> --(let <name> ((<parameter> <argument>)... -- --. (<rest-parameter> <rest-argument>...)) -- <body>...) --</pre> -- --<li><a name="named-sig-rest">Named, signature-style, rest argument</a> -- --<p><pre> --(let (<name> (<parameter> <argument>)... -- --. (<rest-parameter> <rest-argument>...)) -- <body>...) --</pre> --</li> --</ol> -- --<H2>Semantics</H2> -- --Let <code>$lambda</code> and <code>$letrec</code> be hygienic bindings for the <code>lambda</code> --and <code>letrec</code> forms, respectively. -- --<ul> --<li>For informal syntax 1: -- --<p><pre> --(($lambda (<parameter>...) <body>...) <argument>...) --</pre> --</li> -- --<li>For informal syntaxes 2 and 3: -- --<p> --<pre> --($letrec ((<name> ($lambda (<parameter>...) <body>...))) -- (<name> <argument>...)) --</pre> --</li> -- --<li>For informal syntaxes 4 and 5: -- --<p> --<pre> --($letrec ((<name> ($lambda (<parameter>... -- --. <rest-parameter>) <body>...))) -- (<name> <argument>... <rest-argument>...)) --</pre> --</li> --</ul> -- --<H1>Implementation</H1> -- --Here is an implementation using <code>SYNTAX-RULES</code>. -- --<p> --<pre> --;; Use your own standard let. --;; Or call a lambda. --;; (define-syntax standard-let --;; --;; (syntax-rules () --;; --;; ((let ((var val) ...) body ...) --;; ((lambda (var ...) body ...) val ...)))) -- --(define-syntax let -- -- (syntax-rules () -- -- ;; No bindings: use standard-let. -- ((let () body ...) -- (standard-let () body ...)) -- ;; Or call a lambda. -- ;; ((lambda () body ...)) -- -- ;; All standard bindings: use standard-let. -- ((let ((var val) ...) body ...) -- (standard-let ((var val) ...) body ...)) -- ;; Or call a lambda. -- ;; ((lambda (var ...) body ...) val ...) -- -- ;; One standard binding: loop. -- ;; The all-standard-bindings clause didn't match, -- ;; so there must be a rest binding. -- ((let ((var val) . bindings) body ...) -- (let-loop #f bindings (var) (val) (body ...))) -- -- ;; Signature-style name: loop. -- ((let (name binding ...) body ...) -- (let-loop name (binding ...) () () (body ...))) -- -- ;; defun-style name: loop. -- ((let name bindings body ...) -- (let-loop name bindings () () (body ...))))) -- --(define-syntax let-loop -- -- (syntax-rules () -- -- ;; Standard binding: destructure and loop. -- ((let-loop name ((var0 val0) binding ...) (var ... ) (val ... ) body) -- (let-loop name ( binding ...) (var ... var0) (val ... val0) body)) -- -- ;; Rest binding, no name: use standard-let, listing the rest values. -- ;; Because of let's first clause, there is no "no bindings, no name" clause. -- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) -- (standard-let ((var val) ... (rest-var (list rest-val ...))) . body)) -- ;; Or call a lambda with a rest parameter on all values. -- ;; ((lambda (var ... . rest-var) . body) val ... rest-val ...)) -- ;; Or use one of several other reasonable alternatives. -- -- ;; No bindings, name: call a letrec'ed lambda. -- ((let-loop name () (var ...) (val ...) body) -- ((letrec ((name (lambda (var ...) . body))) -- name) -- val ...)) -- -- ;; Rest binding, name: call a letrec'ed lambda. -- ((let-loop name (rest-var rest-val ...) (var ...) (val ...) body) -- ((letrec ((name (lambda (var ... . rest-var) . body))) -- name) -- val ... rest-val ...)))) --</pre> -- -- --<H1>Copyright</H1> -- --Copyright (C) Andy Gaynor (1999). All Rights Reserved. --<p>This document and translations of it may be copied and furnished to --others, and derivative works that comment on or otherwise explain it or --assist in its implementation may be prepared, copied, published and distributed, --in whole or in part, without restriction of any kind, provided that the --above copyright notice and this paragraph are included on all such copies --and derivative works. However, this document itself may not be modified --in any way, such as by removing the copyright notice or references to the --Scheme Request For Implementation process or editors, except as needed --for the purpose of developing SRFIs in which case the procedures for copyrights --defined in the SRFI process must be followed, or as required to translate --it into languages other than English. --<p>The limited permissions granted above are perpetual and will not be --revoked by the authors or their successors or assigns. --<p>This document and the information contained herein is provided on an --"AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, --EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE --USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED --WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -- -- <hr> -- <address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address> -- --</body> --</html> -diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/info.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt ---- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/info.rkt 2018-01-31 13:04:07.236391659 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,14 +0,0 @@ --#lang info -- --(define collection 'multi) -- --(define deps '("scheme-lib" -- "base" -- "r6rs-lib" -- "srfi-lib" -- "compatibility-lib")) -- -- --(define pkg-desc "implementation (no documentation) part of "srfi nonfree"") -- --(define pkg-authors '(mflatt noel chongkai jay)) -diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt ---- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 2018-01-31 13:04:07.236391659 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1 +0,0 @@ --#lang s-exp srfi/provider srfi/%3a5 -diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt ---- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 2018-01-31 13:04:07.236391659 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,3 +0,0 @@ --#lang s-exp srfi/provider srfi/5 -- --;; FIXME: "rest arguments" need to generate mutable lists -diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt ---- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 2018-01-31 13:04:07.236391659 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,86 +0,0 @@ --;;; --;;; <let.rkt> ---- SRFI 5 A compatible let form with signatures and rest arguments --;;; Time-stamp: <03/04/08 09:56:06 solsona> --;;; --;;; Usually, I would add a copyright notice, and the announce that --;;; this code is under the LGPL licence. Nevertheless, I only did the --;;; port to PLT Scheme v200, and here is the copyright notice, --;;; comments, and licence from the original source: --;;; --;;; Copyright (C) Andy Gaynor (1999-2003) --;;; --;;; The version of my-let here was cleaned up by: Paul Schlie schlie@attbi.com. --;;; Renamed to s:let by Eli Barzilay -- --#lang scheme/base --(provide s:let) -- --(define-syntax s:let -- (syntax-rules () -- ;; standard -- ((s:let () body ...) -- (let () body ...)) -- ((s:let ((var val) ...) body ...) -- (let ((var val) ...) body ...)) -- -- ;; rest style -- ((s:let ((var val) . bindings) body ...) -- (let-loop #f bindings (var) (val) (body ...))) -- -- ;; signature style -- ((s:let (name bindings ...) body ...) -- (let-loop name (bindings ...) () () (body ...))) -- -- ;; standard named style -- ((s:let name (bindings ...) body ...) -- (let-loop name (bindings ...) () () (body ...))) -- -- )) -- --;; A loop to walk down the list of bindings. -- --(define-syntax let-loop -- (syntax-rules () -- -- ;; No more bindings - make a LETREC. -- ((let-loop name () (vars ...) (vals ...) body) -- ((letrec ((name (lambda (vars ...) . body))) -- name) -- vals ...)) -- -- ;; Rest binding, no name -- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) -- (let ((var val) ... (rest-var (list rest-val ...))) . body)) -- -- ;; Process a (var val) pair. -- ((let-loop name ((var val) more ...) (vars ...) (vals ...) body) -- (let-loop name (more ...) (vars ... var) (vals ... val) body)) -- -- ;; End with a rest variable - make a LETREC. -- ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body) -- ((letrec ((name (lambda (vars ... . rest-var) . body))) -- name) -- vals ... rest-vals ...)))) -- --;; Four loops - normal and `signature-style', each with and without a rest --;; binding. --;; --;;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) --;; (if (= i n) --;; f0 --;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) --;; --;;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) --;; (if (= i n) --;; f0 --;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) --;; --;;(let fibonacci ((n 10) (i 0) . (f 0 1)) --;; (if (= i n) --;; (car f) --;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) --;; --;;(let (fibonacci (n 10) (i 0) . (f 0 1)) --;; (if (= i n) --;; (car f) --;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) -diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt ---- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 2018-01-31 13:04:07.236391659 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,2 +0,0 @@ --;; module loader for SRFI-5 --#lang s-exp srfi/provider srfi/5/let #:unprefix s: diff --git a/racket-6.12-update-srfi.patch b/racket-6.12-update-srfi.patch deleted file mode 100644 index 1894e32..0000000 --- a/racket-6.12-update-srfi.patch +++ /dev/null @@ -1,4369 +0,0 @@ -diff -urN racket-6.12-orig/share/links.rktd racket-6.12/share/links.rktd ---- racket-6.12-orig/share/links.rktd 2018-01-26 16:12:13.000000000 -0500 -+++ racket-6.12/share/links.rktd 2018-01-31 12:22:57.600504036 -0500 -@@ -133,6 +133,7 @@ - (root "pkgs/r5rs-doc") - (root "pkgs/srfi-lite-lib") - (root "pkgs/srfi-lib") -+ (root "pkgs/srfi-lib-nonfree") - (root "pkgs/html-doc") - (root "pkgs/images-gui-lib") - (root "pkgs/images-doc") -@@ -176,6 +177,7 @@ - (root "pkgs/slideshow-exe") - (root "pkgs/slideshow-plugin") - (root "pkgs/srfi-doc") -+ (root "pkgs/srfi-doc-nonfree") - (root "pkgs/syntax-color-doc") - (root "pkgs/web-server-lib") - (root "pkgs/unix-socket-lib") -diff -urN racket-6.12-orig/share/pkgs/srfi/info.rkt racket-6.12/share/pkgs/srfi/info.rkt ---- racket-6.12-orig/share/pkgs/srfi/info.rkt 2018-01-26 16:10:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi/info.rkt 2018-01-31 12:22:58.139502019 -0500 -@@ -1 +1,16 @@ --(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define deps (quote ("srfi-lib" "srfi-doc"))) (define implies (quote ("srfi-lib" "srfi-doc"))) (define pkg-desc "Legacy SRFI (Scheme) libraries") (define pkg-authors (quote (mflatt noel chongkai jay))))) -+#lang info -+ -+(define collection 'multi) -+ -+(define deps '("srfi-lib" -+ "srfi-lib-nonfree" -+ "srfi-doc" -+ "srfi-doc-nonfree")) -+(define implies '("srfi-lib" -+ "srfi-lib-nonfree" -+ "srfi-doc" -+ "srfi-foc-nonfree")) -+ -+(define pkg-desc "Legacy SRFI (Scheme) libraries") -+ -+(define pkg-authors '(mflatt noel chongkai jay)) -diff -urN racket-6.12-orig/share/pkgs/srfi-doc/info.rkt racket-6.12/share/pkgs/srfi-doc/info.rkt ---- racket-6.12-orig/share/pkgs/srfi-doc/info.rkt 2018-01-26 16:10:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc/info.rkt 2018-01-31 12:22:58.139502019 -0500 -@@ -1 +1,24 @@ --(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define build-deps (quote ("mzscheme-doc" "scheme-lib" "base" "scribble-lib" "srfi-lib" "racket-doc" "r5rs-doc" "r6rs-doc" "compatibility-lib"))) (define update-implies (quote ("srfi-lib"))) (define pkg-desc "documentation part of "srfi"") (define pkg-authors (quote (mflatt noel chongkai jay))))) -+#lang info -+ -+(define collection 'multi) -+ -+(define build-deps '("mzscheme-doc" -+ "scheme-lib" -+ "base" -+ "scribble-lib" -+ "srfi-lib" -+ "racket-doc" -+ "r5rs-doc" -+ "r6rs-doc" -+ "compatibility-lib")) -+ -+(define deps '("scheme-lib" -+ "base" -+ "scribble-lib" -+ "compatibility-lib")) -+ -+(define update-implies '("srfi-lib")) -+ -+(define pkg-desc "documentation part of "srfi"") -+ -+(define pkg-authors '(mflatt noel chongkai jay)) -diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl ---- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl 2018-01-31 12:22:58.144502000 -0500 -@@ -1,5 +1,6 @@ - #lang scribble/doc --@(require scribble/manual -+@(require srfi/scribblings/util -+ scribble/manual - scribble/eval - scriblib/render-cond - scribble/core -@@ -8,54 +9,6 @@ - (for-label scheme/base - racket/stream)) - --@(define-syntax (srfi stx) -- (syntax-case stx () -- [(_ num #:subdir subdir? . title) -- (with-syntax ([srfi/n (string->symbol (format "srfi/~a" (syntax-e #'num)))]) -- #'(begin -- (section #:tag (format "srfi-~a" num) -- #:style 'unnumbered -- (format "SRFI ~a: " num) -- . title) -- (defmodule srfi/n) -- "Original specification: " -- (let* ([label (format "SRFI ~a" num)] -- [sub (if subdir? (format "srfi-~a/" num) "")] -- [url ( (b) (format "~a/srfi-std/~asrfi-~a.html" b sub num))]) -- (cond-element -- [(or latex text) @link[(url "http://docs.racket-lang.org") label]] -- [else @link[(url ".") label]]))))] -- [(_ num . title) #'(srfi num #:subdir #f . title)])) -- --@;{ The `lst' argument is a list of -- (list sym syntactic-form? html-anchor) } --@(define (redirect n lst #:subdir [subdir? #f]) -- (let ([file (if subdir? -- (format "srfi-~a/srfi-~a.html" n n) -- (format "srfi-~a.html" n))] -- [mod-path (string->symbol (format "srfi/~a" n))]) -- (make-binding-redirect-elements mod-path -- (map (lambda (b) -- (list (car b) (cadr b) -- (build-path "srfi-std" file) -- (caddr b))) -- lst)))) -- --@(define in-core -- (case-lambda -- [() (in-core ".")] -- [(k) @elem{This SRFI's bindings are also available in -- @racketmodname[racket/base]@|k|}])) -- --@(begin -- (define-syntax-rule (def-mz mz-if) -- (begin -- (require (for-label mzscheme)) -- (define mz-if (racket if)))) -- (def-mz mz-if)) -- --@(define srfi-std (style #f (list (install-resource "srfi-std")))) -- - @; ---------------------------------------------------------------------- - - @title{SRFIs: Libraries} -@@ -245,14 +198,6 @@ - - @; ---------------------------------------- - --@srfi[5]{A compatible let form with signatures and rest arguments} -- --@redirect[5 '( -- (let #t "unnamed") --)] -- --@; ---------------------------------------- -- - @srfi[6]{Basic String Ports} - - @redirect[6 '( -@@ -671,20 +616,6 @@ - - @; ---------------------------------------- - --@srfi[29]{Localization} -- --@redirect[29 '( -- (current-language #f "current-language") -- (current-country #f "current-country") -- (current-locale-details #f "current-locale-details") -- (declare-bundle! #f "declare-bundle!") -- (store-bundle #f "store-bundle") -- (load-bundle! #f "load-bundle!") -- (localized-template #f "localized-template") --)] -- --@; ---------------------------------------- -- - @srfi[30]{Nested Multi-line Comments} - - This SRFI's syntax is part of Racket's default reader. -diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html ---- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html 1969-12-31 19:00:00.000000000 -0500 -@@ -1,507 +0,0 @@ --<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN"> --<html> -- <head> -- <meta name="generator" content="HTML Tidy, see www.w3.org"> -- <title>SRFI 29: Localization</title> -- <meta name="author" content="Scott G. Miller"> -- <meta name="description" content="Localization"> -- </head> -- <body> -- <H1>Title</H1> -- -- SRFI 29: Localization -- -- <H1>Author</H1> -- -- Scott G. Miller -- -- <H1>Abstract</H1> -- -- This document specifies an interface to retrieving and -- displaying locale sensitive messages. A Scheme program can -- register one or more translations of templated messages, and -- then write Scheme code that can transparently retrieve the -- appropriate message for the locale under which the Scheme -- system is running. <br> -- -- -- <H1>Rationale</H1> -- -- <p>As any programmer that has ever had to deal with making his -- or her code readable in more than one locale, the process of -- sufficiently abstracting program messages from their -- presentation to the user is non-trivial without help from the -- programming language. Most modern programming language -- libraries do provide some mechanism for performing this -- separation.</p> -- -- <p>A portable API that allows a piece of code to run without -- modification in different countries and under different -- languages is a must for any non-trivial software project. -- The interface should separate the logic of a program from -- the myriad of translations that may be necessary.</p> -- -- <p>The interface described in this document provides such -- functionality. The underlying implementation is also allowed to -- use whatever datastructures it likes to provide access to the -- translations in the most efficient manner possible. In -- addition, the implementation is provided with standardized -- functions that programs will use for accessing an external, -- unspecified repository of translations.</p> -- -- <p>This interface <i>does not</i> cover all aspects of -- localization, including support for non-latin characters, -- number and date formatting, etc. Such functionality is the -- scope of a future SRFI that may extend this one.</p> -- -- <H1>Dependencies</H1> -- -- An SRFI-29 conformant implementation must also implement -- SRFI-28, Basic Format Strings. Message templates are strings -- that must be processed by the <tt>format</tt> function -- specified in that SRFI. -- -- <H1>Specification</H1> -- -- <h3>Message Bundles</h3> -- -- <p>A Message Bundle is a set of message templates and their -- identifying keys. Each bundle contains one or more such -- key/value pairs. The bundle itself is associated with a -- <i>bundle specifier</i> which uniquely identifies the -- bundle.</p> -- -- <h3>Bundle Specifiers</h3> -- -- <p>A Bundle Specifier is a Scheme list that describes, in order -- of importance, the package and locale of a message bundle. -- In most cases, a locale specifier will have between one -- and three elements. The first element is a symbol denoting the -- package for which this bundle applies. The second and third -- elements denote a <i>locale</i>. The second element (first -- element of the locale) if present, is the two letter, ISO 639-1 -- language code for the bundle. The third element, if present, is -- a two letter ISO 3166-1 country code. In some cases, a -- fourth element may be present, specifying the encoding used for -- the bundle. All bundle specifier elements are Scheme -- symbols.</p> -- -- <p>If only one translation is provided, it should be designated -- only by a package name, for example <tt>(mathlib)</tt>. This -- translation is called the <i>default</i> translation.</p> -- -- <h3>Bundle Searching</h3> -- -- <p>When a message template is retrieved from a bundle, the -- Scheme implementation will provide the locale under which the -- system is currently running. When the template is retrieved, -- the package name will be specified. The Scheme system should -- construct a Bundle Specifier from the provided package name and -- the active locale. For example, when retrieving a message -- template for French Canadian, in the <tt>mathlib</tt> package, -- the bundle specifier '<tt>(mathlib fr ca)</tt>' is used. A -- program may also retrieve the elements of the current locale -- using the no-argument procedures:</p> -- -- <p><b><a name="current-language"></a><tt>current-language</tt></b> <tt>-> -- <i>symbol</i></tt><br> -- <tt><b>current-language</b> <i>symbol</i> -> -- undefined</tt><br> -- </p> -- -- <blockquote> -- When given no arguments, returns the current ISO 639-1 -- language code as a symbol. If provided with an -- argument, the current language is set to that named by the -- symbol for the currently executing Scheme thread (or for the -- entire Scheme system if such a distinction is not possible). -- -- </blockquote> -- -- <p><b><a name="current-country"></a><tt>current-country</tt></b> <tt>-> -- <i>symbol</i></tt><br> -- <tt><b>current-country</b> <i>symbol</i> -> -- undefined</tt><br> -- </p> -- -- <blockquote> -- returns the current ISO 3166-1 country code as a symbol. -- If provided with an argument, the current country is -- set to that named by the symbol for the currently executing -- Scheme thread (or for the entire Scheme system if such a -- distinction is not possible). -- </blockquote> -- -- <p><b><a name="current-locale-details"></a><tt>current-locale-details</tt></b> <tt>-> <i>list of -- symbol</i></tt>s<br> -- <tt><b>current-locale-details</b> <i>list-of-symbols</i> -> -- undefined</tt><br> -- </p> -- -- <blockquote> -- Returns a list of additional locale details as a list of -- symbols. This list may contain information about -- encodings or other more specific information. If -- provided with an argument, the current locale details are set -- to those given in the currently executing Scheme thread (or -- for the entire Scheme system if such a distinction is not -- possible). -- </blockquote> -- -- <p>The Scheme System should first check for a bundle with the -- exact name provided. If no such bundle is found, the last -- element from the list is removed and a search is tried for a -- bundle with that name. If no bundle is then found, the list is -- shortened by removing the last element again. If no message is -- found and the bundle specifier is now the empty list, an error -- should be raised.</p> -- -- <p>The reason for this search order is to provide the most -- locale sensitive template possible, but to fall back on more -- general templates if a translation has not yet been provided -- for the given locale.</p> -- -- <h3>Message Templates</h3> -- -- <p>A message template is a localized message that may or may -- not contain one of a number of formatting codes. A message -- template is a Scheme string. The string is of a form that can -- be processed by the <tt>format</tt> procedure found in many -- Scheme systems and formally specified in SRFI-28 (Basic Format -- Strings).</p> -- -- <p>This SRFI also extends SRFI-28 to provide an additional -- <tt>format</tt> escape code:</p> -- -- <blockquote> -- <tt>~[n]@*</tt> - Causes a value-requiring escape code that -- follows this code immediately to reference the [N]'th -- optional value absolutely, rather than the next unconsumed -- value. The referenced value is <i>not</i> consumed. -- </blockquote> -- This extension allows optional values to be positionally -- referenced, so that message templates can be constructed that -- can produce the proper word ordering for a language. -- -- <h3>Preparing Bundles</h3> -- Before a bundle may be used by the Scheme system to retrieve -- localized template messages, they must be made available to the -- Scheme system. This SRFI specifies a way to portably -- define the bundles, as well as store them in and retrieve them -- from an unspecified system which may be provided by resources -- outside the Scheme system.<br> -- -- -- <p><b><a name="declare-bundle!"></a><tt>declare-bundle!</tt></b> <tt><i>bundle-specifier -- association-list</i> -> undefined<br> -- </tt></p> -- -- <blockquote> -- Declares a new bundle named by the given bundle-specifier. -- The contents of the bundle are defined by the provided -- association list. The list contains associations -- between Scheme symbols and the message templates (Scheme -- strings) they name. If a bundle already exists with the -- given name, it is overwritten with the newly declared -- bundle.<br> -- </blockquote> -- <tt><a name="store-bundle"></a><b>store-bundle</b> <i>bundle-specifier</i> -> -- boolean</tt><br> -- -- -- <blockquote> -- Attempts to store a bundle named by the given bundle -- specifier, and previously made available using -- <tt>declare-bundle!</tt> or <tt>load-bundle!</tt>, in an -- unspecified mechanism that may be persistent across Scheme -- system restarts. If successful, a non-false value is -- returned. If unsuccessful, <tt>#f</tt> is returned.<br> -- </blockquote> -- <tt><a name="load-bundle!"></a><b>load-bundle!</b> <i>bundle-specifier</i> -> -- boolean</tt><br> -- -- -- <blockquote> -- Attempts to retrieve a bundle from an unspecified mechanism -- which stores bundles outside the Scheme system. If the -- bundle was retrieved successfully, the function returns a -- non-false value, and the bundle is immediately available to -- the Scheme system. If the bundle could not be found or loaded -- successfully, the function returns <tt>#f</tt>, and the -- Scheme system's bundle registry remains unaffected.<br> -- </blockquote> -- A compliant Scheme system may choose not to provide any -- external mechanism to store localized bundles. If it does -- not, it must still provide implementations for -- <tt>store-bundle</tt> and <tt>load-bundle!</tt>. In such a -- case, both functions must return <tt>#f</tt> regardless of the -- arguments given. Users of this SRFI should recognize that the -- inability to load or store a localized bundle in an external -- repository is <i>not</i> a fatal error.<br> -- -- -- <h3>Retrieving Localized Message Templates</h3> -- -- <p><a name="localized-template"></a><b><tt>localized-template</tt></b> <i><tt>package-name -- message-template-name</tt></i> <tt>-> <i>string or #f<br> -- </i></tt></p> -- -- <blockquote> -- Retrieves a localized message template for the given package -- name and the given message template name (both symbols). -- If no such message could be found, false (#f) is -- returned.<br> -- <br> -- </blockquote> -- After retrieving a template, the calling program can use -- <tt>format</tt> to produce a string that can be displayed to -- the user.<br> -- -- -- <h2>Examples</h2> -- The below example makes use of SRFI-29 to display simple, -- localized messages. It also defines its bundles in such a -- way that the Scheme system may store and retrieve the bundles -- from a more efficient system catalog, if available.<br> -- --<pre> --(let ((translations -- '(((en) . ((time . "Its ~a, ~a.") -- (goodbye . "Goodbye, ~a."))) -- ((fr) . ((time . "~1@*~a, c'est ~a.") -- (goodbye . "Au revoir, ~a.")))))) -- (for-each (lambda (translation) -- (let ((bundle-name (cons 'hello-program (car translation)))) -- (if (not (load-bundle! bundle-name)) -- (begin -- (declare-bundle! bundle-name (cdr translation)) -- (store-bundle! bundle-name))))) -- translations)) -- --(define localized-message -- (lambda (message-name . args) -- (apply format (cons (localized-template 'hello-program -- message-name) -- args)))) -- --(let ((myname "Fred")) -- (display (localized-message 'time "12:00" myname)) -- (display #\newline) -- -- (display (localized-message 'goodbye myname)) -- (display #\newline)) -- --;; Displays (English): --;; Its 12:00, Fred. --;; Goodbye, Fred. --;; --;; French: --;; Fred, c'est 12:00. --;; Au revoir, Fred. --</pre> -- -- <H1>Implementation</H1> -- -- <p>The implementation requires that the Scheme system provide a -- definition for <tt>current-language</tt> and -- <tt>current-country</tt> capable of distinguishing the correct -- locale present during a Scheme session. The definitions of -- those functions in the reference implementation are not capable -- of that distinction. Their implementation is provided only so -- that the following code can run in any R4RS scheme system. -- <br> -- </p> -- -- <p>In addition, the below implementation of a compliant -- <tt>format</tt> requires SRFI-6 (Basic String Ports) and -- SRFI-23 (Error reporting)</p> --<pre> --;; The association list in which bundles will be stored --(define *localization-bundles* '()) -- --;; The current-language and current-country functions provided --;; here must be rewritten for each Scheme system to default to the --;; actual locale of the session --(define current-language -- (let ((current-language-value 'en)) -- (lambda args -- (if (null? args) -- current-language-value -- (set! current-language-value (car args)))))) -- --(define current-country -- (let ((current-country-value 'us)) -- (lambda args -- (if (null? args) -- current-country-value -- (set! current-country-value (car args)))))) -- --;; The load-bundle! and store-bundle! both return #f in this --;; reference implementation. A compliant implementation need --;; not rewrite these procedures. --(define load-bundle! -- (lambda (bundle-specifier) -- #f)) -- --(define store-bundle! -- (lambda (bundle-specifier) -- #f)) -- --;; Declare a bundle of templates with a given bundle specifier --(define declare-bundle! -- (letrec ((remove-old-bundle -- (lambda (specifier bundle) -- (cond ((null? bundle) '()) -- ((equal? (caar bundle) specifier) -- (cdr bundle)) -- (else (cons (car bundle) -- (remove-old-bundle specifier -- (cdr bundle)))))))) -- (lambda (bundle-specifier bundle-assoc-list) -- (set! *localization-bundles* -- (cons (cons bundle-specifier bundle-assoc-list) -- (remove-old-bundle bundle-specifier -- *localization-bundles*)))))) -- --;;Retrieve a localized template given its package name and a template name --(define localized-template -- (letrec ((rdc -- (lambda (ls) -- (if (null? (cdr ls)) -- '() -- (cons (car ls) (rdc (cdr ls)))))) -- (find-bundle -- (lambda (specifier template-name) -- (cond ((assoc specifier *localization-bundles*) => -- (lambda (bundle) bundle)) -- ((null? specifier) #f) -- (else (find-bundle (rdc specifier) -- template-name)))))) -- (lambda (package-name template-name) -- (let loop ((specifier (cons package-name -- (list (current-language) -- (current-country))))) -- (and (not (null? specifier)) -- (let ((bundle (find-bundle specifier template-name))) -- (and bundle -- (cond ((assq template-name bundle) => cdr) -- ((null? (cdr specifier)) #f) -- (else (loop (rdc specifier))))))))))) -- --;;An SRFI-28 and SRFI-29 compliant version of format. It requires --;;SRFI-23 for error reporting. --(define format -- (lambda (format-string . objects) -- (let ((buffer (open-output-string))) -- (let loop ((format-list (string->list format-string)) -- (objects objects) -- (object-override #f)) -- (cond ((null? format-list) (get-output-string buffer)) -- ((char=? (car format-list) #~) -- (cond ((null? (cdr format-list)) -- (error 'format "Incomplete escape sequence")) -- ((char-numeric? (cadr format-list)) -- (let posloop ((fl (cddr format-list)) -- (pos (string->number -- (string (cadr format-list))))) -- (cond ((null? fl) -- (error 'format "Incomplete escape sequence")) -- ((and (eq? (car fl) '#@) -- (null? (cdr fl))) -- (error 'format "Incomplete escape sequence")) -- ((and (eq? (car fl) '#@) -- (eq? (cadr fl) '#*)) -- (loop (cddr fl) objects (list-ref objects pos))) -- (else -- (posloop (cdr fl) -- (+ (* 10 pos) -- (string->number -- (string (car fl))))))))) -- (else -- (case (cadr format-list) -- ((#\a) -- (cond (object-override -- (begin -- (display object-override buffer) -- (loop (cddr format-list) objects #f))) -- ((null? objects) -- (error 'format "No value for escape sequence")) -- (else -- (begin -- (display (car objects) buffer) -- (loop (cddr format-list) -- (cdr objects) #f))))) -- ((#\s) -- (cond (object-override -- (begin -- (display object-override buffer) -- (loop (cddr format-list) objects #f))) -- ((null? objects) -- (error 'format "No value for escape sequence")) -- (else -- (begin -- (write (car objects) buffer) -- (loop (cddr format-list) -- (cdr objects) #f))))) -- ((#%) -- (if object-override -- (error 'format "Escape sequence following positional override does not require a value")) -- (display #\newline buffer) -- (loop (cddr format-list) objects #f)) -- ((#~) -- (if object-override -- (error 'format "Escape sequence following positional override does not require a value")) -- (display #~ buffer) -- (loop (cddr format-list) objects #f)) -- (else -- (error 'format "Unrecognized escape sequence")))))) -- (else (display (car format-list) buffer) -- (loop (cdr format-list) objects #f))))))) -- --</pre> -- -- <H1>Copyright</H1> -- -- Copyright (C) Scott G. Miller (2002). All Rights Reserved. -- -- <p>This document and translations of it may be copied and -- furnished to others, and derivative works that comment on or -- otherwise explain it or assist in its implementation may be -- prepared, copied, published and distributed, in whole or in -- part, without restriction of any kind, provided that the above -- copyright notice and this paragraph are included on all such -- copies and derivative works. However, this document itself may -- not be modified in any way, such as by removing the copyright -- notice or references to the Scheme Request For Implementation -- process or editors, except as needed for the purpose of -- developing SRFIs in which case the procedures for copyrights -- defined in the SRFI process must be followed, or as required to -- translate it into languages other than English.</p> -- -- <p>The limited permissions granted above are perpetual and will -- not be revoked by the authors or their successors or -- assigns.</p> -- -- <p>This document and the information contained herein is -- provided on an "AS IS" basis and THE AUTHOR AND THE SRFI -- EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION -- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES -- OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> -- <hr> -- -- <address> -- Editor: <a href="mailto:srfi-editors@srfi.schemers.org">David -- Rush</a> -- </address> -- -- <address> -- Author: <a href="mailto:scgmille@freenetproject.org">Scott G. -- Miller</a> -- </address> -- <!-- Created: Tue Sep 29 19:20:08 EDT 1998 --> -- <!-- hhmts start -->Last modified: Mon Jun 17 12:00:08 Pacific -- Daylight Time 2002 <!-- hhmts end --> <br> -- </body> --</html> -- -diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html ---- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html 1969-12-31 19:00:00.000000000 -0500 -@@ -1,345 +0,0 @@ --<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"> --<html> --<head> -- <title>SRFI 5: A compatible let form with signatures and rest arguments</title> --</head> --<body> -- --<H1>Title</H1> -- --SRFI-5: A compatible <code>let</code> form with signatures and rest arguments -- --<H1>Author</H1> -- --Andy Gaynor -- --<H1>Status</H1> -- --This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>. --You can access the discussion on this SRFI via <A HREF="http://srfi.schemers.org/srfi-5/mail-archive/maillist.html">the archive of the mailing list</A>. --<P><UL> --<LI>Received: 1999/2/2 --<LI>Draft: 1999/2/10-1999/04/12 --<LI>Final: 1999/4/26 --<LI>Revised reference implementation: 2003/01/27 --</UL> -- --<H1>Abstract</H1> -- --The <i>named-let</i> incarnation of the <code>let</code> form has two slight --inconsistencies with the <code>define</code> form. As defined, the <code>let</code> --form makes no accommodation for rest arguments, an issue of functionality --and consistency. As defined, the <code>let</code> form does not accommodate --signature-style syntax, an issue of aesthetics and consistency. Both --issues are addressed here in a manner which is compatible with the traditional --<code>let</code> form but for minor extensions. -- --<H1>Rationale</H1> -- --<H2>Signature-style Syntax</H2> -- --Consider the following two equivalent definitions: -- --<p><pre> --(define fibonacci -- (lambda (n i f0 f1) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1))))) -- --(define (fibonacci n i f0 f1) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1)))) --</pre> -- --Although there is a named-let analog for the former form, there is none --for the latter. To wit, suppose one wished to compute the 10th element --of the Fibonacci sequence using a named let: -- --<p> --<pre> --(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1)))) --Values: 55 --</pre> -- --As it stands, one cannot equivalently write -- --<p> --<pre> --(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) -- (if (= i n) -- f0 -- (fibonacci n (+ i 1) f1 (+ f0 f1)))) --</pre> -- --which is consistent with <code>define</code>'s signature-style form. --<p>Those that favor the signature style may prefer this extension. --In any case, it may be more appropriate to include all bound names within --the binding section. As presented, this straightforward extension --introduces no ambiguity or incompatibility with the existing definition --of let. -- --<H2>Rest Arguments</H2> -- --As it stands, one cannot write a named let with rest arguments, as in -- --<p> --<pre> --(let (blast (port (current-output-port)) . (x (+ 1 2) 4 5)) -- (if (null? x) -- 'just-a-silly-contrived-example -- (begin -- (write (car x) port) -- (apply blast port (cdr x))))) --</pre> -- --otherwise equivalent to -- --<p> --<pre> --(letrec ((blast (lambda (port . x) -- (if (null? x) -- 'just-a-silly-contrived-example -- (begin -- (write (car x) port) -- (apply blast port (cdr x))))))) -- (blast (current-output-port) (+ 1 2) 4 5)) --</pre> -- --While this example is rather contrived, the functionality is not. --There are several times when the author has used this construct in practice. --Regardless, there is little reason to deny the <code>let</code> form access to --all the features of lambda functionality. -- --<H2>Symbols in Binding Sections</H2> -- --Both the features above rely upon the placement of symbols in <code>let</code> --binding lists (this statement is intentially simplistic). The only --other apparent use of such symbol placement is to tersely bind variables --to unspecified values. For example, one might desire to use --<code>(let (foo bar baz) ...)</code> --to bind <code>foo</code>, <code>bar</code>, and <code>baz</code> to --unspecified values. -- --<p>This usage is considered less important in light of the rationales --presented above, and an alternate syntax is immediately apparent, as --in <code>(let ((foo) (bar) (baz)) ...)</code> This may even --be preferable, consistently parenthesizing normal binding clauses. -- --<H1>Specification</H1> -- --<H2>Syntax</H2> -- --<p> --A formal specification of the syntax follows. Below, body, expression, --and identifier are free. Each instantiation of binding-name must be --unique. --</p> -- --<p> --<pre> -- let = "(" "let" let-bindings body ")" -- expressions = nothing | expression expressions -- let-bindings = let-name bindings -- |"(" let-name "." bindings ")" -- let-name = identifier -- bindings = "(" ")" -- | rest-binding -- | "(" normal-bindings ["." rest-binding] ")" --normal-bindings = nothing -- | normal-binding normal-bindings --normal-binding = "(" binding-name expression ")" -- binding-name = identifier -- rest-binding = "(" binding-name expressions ")" --</pre> -- --<p> --For clarity and convenience, an informal specification follows. --</p> -- --<ol> --<li><a name="unnamed">Unnamed</a> -- --<p><pre> --(let ((<parameter> <argument>)...) -- <body>...) --</pre> --</li> -- --<li><a name="named-non-sig"> --Named, non-signature-style, no rest argument</a> -- --<p><pre> --(let <name> ((<parameter> <argument>)...) -- <body>...) --</pre> --</li> -- --<li><a name="named-sig">Named, signature-style, no rest argument</a> -- --<p><pre> --(let (<name> (<parameter> <argument>)...) -- <body>...) --</pre> --</li> -- --<li><a name="named-non-sig-rest">Named, non-signature-style, rest argument</a> -- --<p><pre> --(let <name> ((<parameter> <argument>)... -- --. (<rest-parameter> <rest-argument>...)) -- <body>...) --</pre> -- --<li><a name="named-sig-rest">Named, signature-style, rest argument</a> -- --<p><pre> --(let (<name> (<parameter> <argument>)... -- --. (<rest-parameter> <rest-argument>...)) -- <body>...) --</pre> --</li> --</ol> -- --<H2>Semantics</H2> -- --Let <code>$lambda</code> and <code>$letrec</code> be hygienic bindings for the <code>lambda</code> --and <code>letrec</code> forms, respectively. -- --<ul> --<li>For informal syntax 1: -- --<p><pre> --(($lambda (<parameter>...) <body>...) <argument>...) --</pre> --</li> -- --<li>For informal syntaxes 2 and 3: -- --<p> --<pre> --($letrec ((<name> ($lambda (<parameter>...) <body>...))) -- (<name> <argument>...)) --</pre> --</li> -- --<li>For informal syntaxes 4 and 5: -- --<p> --<pre> --($letrec ((<name> ($lambda (<parameter>... -- --. <rest-parameter>) <body>...))) -- (<name> <argument>... <rest-argument>...)) --</pre> --</li> --</ul> -- --<H1>Implementation</H1> -- --Here is an implementation using <code>SYNTAX-RULES</code>. -- --<p> --<pre> --;; Use your own standard let. --;; Or call a lambda. --;; (define-syntax standard-let --;; --;; (syntax-rules () --;; --;; ((let ((var val) ...) body ...) --;; ((lambda (var ...) body ...) val ...)))) -- --(define-syntax let -- -- (syntax-rules () -- -- ;; No bindings: use standard-let. -- ((let () body ...) -- (standard-let () body ...)) -- ;; Or call a lambda. -- ;; ((lambda () body ...)) -- -- ;; All standard bindings: use standard-let. -- ((let ((var val) ...) body ...) -- (standard-let ((var val) ...) body ...)) -- ;; Or call a lambda. -- ;; ((lambda (var ...) body ...) val ...) -- -- ;; One standard binding: loop. -- ;; The all-standard-bindings clause didn't match, -- ;; so there must be a rest binding. -- ((let ((var val) . bindings) body ...) -- (let-loop #f bindings (var) (val) (body ...))) -- -- ;; Signature-style name: loop. -- ((let (name binding ...) body ...) -- (let-loop name (binding ...) () () (body ...))) -- -- ;; defun-style name: loop. -- ((let name bindings body ...) -- (let-loop name bindings () () (body ...))))) -- --(define-syntax let-loop -- -- (syntax-rules () -- -- ;; Standard binding: destructure and loop. -- ((let-loop name ((var0 val0) binding ...) (var ... ) (val ... ) body) -- (let-loop name ( binding ...) (var ... var0) (val ... val0) body)) -- -- ;; Rest binding, no name: use standard-let, listing the rest values. -- ;; Because of let's first clause, there is no "no bindings, no name" clause. -- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) -- (standard-let ((var val) ... (rest-var (list rest-val ...))) . body)) -- ;; Or call a lambda with a rest parameter on all values. -- ;; ((lambda (var ... . rest-var) . body) val ... rest-val ...)) -- ;; Or use one of several other reasonable alternatives. -- -- ;; No bindings, name: call a letrec'ed lambda. -- ((let-loop name () (var ...) (val ...) body) -- ((letrec ((name (lambda (var ...) . body))) -- name) -- val ...)) -- -- ;; Rest binding, name: call a letrec'ed lambda. -- ((let-loop name (rest-var rest-val ...) (var ...) (val ...) body) -- ((letrec ((name (lambda (var ... . rest-var) . body))) -- name) -- val ... rest-val ...)))) --</pre> -- -- --<H1>Copyright</H1> -- --Copyright (C) Andy Gaynor (1999). All Rights Reserved. --<p>This document and translations of it may be copied and furnished to --others, and derivative works that comment on or otherwise explain it or --assist in its implementation may be prepared, copied, published and distributed, --in whole or in part, without restriction of any kind, provided that the --above copyright notice and this paragraph are included on all such copies --and derivative works. However, this document itself may not be modified --in any way, such as by removing the copyright notice or references to the --Scheme Request For Implementation process or editors, except as needed --for the purpose of developing SRFIs in which case the procedures for copyrights --defined in the SRFI process must be followed, or as required to translate --it into languages other than English. --<p>The limited permissions granted above are perpetual and will not be --revoked by the authors or their successors or assigns. --<p>This document and the information contained herein is provided on an --"AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, --EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE --USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED --WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -- -- <hr> -- <address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address> -- --</body> --</html> -diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/util.rkt racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/util.rkt ---- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/util.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/util.rkt 2018-01-31 12:22:58.144502000 -0500 -@@ -0,0 +1,61 @@ -+#lang scribble/doc -+ -+@(require scribble/manual -+ scribble/eval -+ scriblib/render-cond -+ scribble/core -+ scribble/html-properties -+ (for-syntax scheme/base) -+ (for-label scheme/base -+ racket/stream)) -+ -+@(provide (all-defined-out)) -+ -+@(define-syntax (srfi stx) -+ (syntax-case stx () -+ [(_ num #:subdir subdir? . title) -+ (with-syntax ([srfi/n (string->symbol (format "srfi/~a" (syntax-e #'num)))]) -+ #'(begin -+ (section #:tag (format "srfi-~a" num) -+ #:style 'unnumbered -+ (format "SRFI ~a: " num) -+ . title) -+ (defmodule srfi/n) -+ "Original specification: " -+ (let* ([label (format "SRFI ~a" num)] -+ [sub (if subdir? (format "srfi-~a/" num) "")] -+ [url ( (b) (format "~a/srfi-std/~asrfi-~a.html" b sub num))]) -+ (cond-element -+ [(or latex text) @link[(url "http://docs.racket-lang.org") label]] -+ [else @link[(url ".") label]]))))] -+ [(_ num . title) #'(srfi num #:subdir #f . title)])) -+ -+@;{ The `lst' argument is a list of -+ (list sym syntactic-form? html-anchor) } -+@(define (redirect n lst #:subdir [subdir? #f]) -+ (let ([file (if subdir? -+ (format "srfi-~a/srfi-~a.html" n n) -+ (format "srfi-~a.html" n))] -+ [mod-path (string->symbol (format "srfi/~a" n))]) -+ (make-binding-redirect-elements mod-path -+ (map (lambda (b) -+ (list (car b) (cadr b) -+ (build-path "srfi-std" file) -+ (caddr b))) -+ lst)))) -+ -+@(define in-core -+ (case-lambda -+ [() (in-core ".")] -+ [(k) @elem{This SRFI's bindings are also available in -+ @racketmodname[racket/base]@|k|}])) -+ -+@(begin -+ (define-syntax-rule (def-mz mz-if) -+ (begin -+ (require (for-label mzscheme)) -+ (define mz-if (racket if)))) -+ (def-mz mz-if)) -+ -+@(define srfi-std (style #f (list (install-resource "srfi-std")))) -+ -diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt ---- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt 2018-01-31 12:22:58.144502000 -0500 -@@ -0,0 +1,19 @@ -+#lang info -+ -+(define collection 'multi) -+ -+(define build-deps '("mzscheme-doc" -+ "scheme-lib" -+ "base" -+ "scribble-lib" -+ "srfi-doc" -+ "srfi-lib-nonfree" -+ "racket-doc" -+ "r5rs-doc" -+ "r6rs-doc" -+ "compatibility-lib")) -+(define update-implies '("srfi-lib-nonfree")) -+ -+(define pkg-desc "documentation part of "srfi nonfree"") -+ -+(define pkg-authors '(mflatt noel chongkai jay)) -diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt ---- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 2018-01-31 12:22:58.144502000 -0500 -@@ -0,0 +1,3 @@ -+#lang info -+ -+(define scribblings '(("srfi-nf.scrbl" (multi-page) (library 100)))) -diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl ---- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 2018-01-31 12:22:58.144502000 -0500 -@@ -0,0 +1,66 @@ -+#lang scribble/doc -+@(require srfi/scribblings/util -+ scribble/manual -+ scribble/eval -+ scriblib/render-cond -+ scribble/core -+ scribble/html-properties -+ (for-syntax scheme/base) -+ (for-label scheme/base -+ racket/stream)) -+ -+@; ---------------------------------------------------------------------- -+ -+@title{SRFI Nonfree Libraries and Documentation} -+ -+The @link[#:style srfi-std "http://srfi.schemers.org/%22%5D%7BScheme Requests for -+Implementation} (a.k.a. @deftech{SRFI}) process allows individual -+members of the Scheme community to propose libraries and extensions to -+be supported by multiple Scheme implementations. -+ -+Racket is distributed with implementations of many SRFIs, most of -+which can be implemented as libraries. To import the bindings of SRFI -+@math{n}, use -+ -+@racketblock[ -+(require @#,elem{@racketidfont{srfi/}@math{n}}) -+] -+ -+This document lists the SRFIs that are supported by Racket and -+provides a link to the original SRFI specification (which is also -+distributed as part of Racket's documentation). -+ -+The following SRFI specification documents are licensed restrictively. -+ -+@table-of-contents[] -+ -+ -+@; ---------------------------------------- -+ -+@srfi[5]{A compatible let form with signatures and rest arguments} -+ -+@redirect[5 '( -+ (let #t "unnamed") -+)] -+ -+Racket provides this SRFI in the @racket[srfi-lib-nonfree] package. -+ -+@; ---------------------------------------- -+ -+@srfi[29]{Localization} -+ -+@redirect[29 '( -+ (current-language #f "current-language") -+ (current-country #f "current-country") -+ (current-locale-details #f "current-locale-details") -+ (declare-bundle! #f "declare-bundle!") -+ (store-bundle #f "store-bundle") -+ (load-bundle! #f "load-bundle!") -+ (localized-template #f "localized-template") -+)] -+ -+Racket provides a free implementation of this SRFI in the @racket[srfi-lib] package. Only the SRFI specification document is nonfree. -+ -+@; ---------------------------------------- -+ -+@index-section[] -diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html ---- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 2018-01-31 12:22:58.144502000 -0500 -@@ -0,0 +1,507 @@ -+<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN"> -+<html> -+ <head> -+ <meta name="generator" content="HTML Tidy, see www.w3.org"> -+ <title>SRFI 29: Localization</title> -+ <meta name="author" content="Scott G. Miller"> -+ <meta name="description" content="Localization"> -+ </head> -+ <body> -+ <H1>Title</H1> -+ -+ SRFI 29: Localization -+ -+ <H1>Author</H1> -+ -+ Scott G. Miller -+ -+ <H1>Abstract</H1> -+ -+ This document specifies an interface to retrieving and -+ displaying locale sensitive messages. A Scheme program can -+ register one or more translations of templated messages, and -+ then write Scheme code that can transparently retrieve the -+ appropriate message for the locale under which the Scheme -+ system is running. <br> -+ -+ -+ <H1>Rationale</H1> -+ -+ <p>As any programmer that has ever had to deal with making his -+ or her code readable in more than one locale, the process of -+ sufficiently abstracting program messages from their -+ presentation to the user is non-trivial without help from the -+ programming language. Most modern programming language -+ libraries do provide some mechanism for performing this -+ separation.</p> -+ -+ <p>A portable API that allows a piece of code to run without -+ modification in different countries and under different -+ languages is a must for any non-trivial software project. -+ The interface should separate the logic of a program from -+ the myriad of translations that may be necessary.</p> -+ -+ <p>The interface described in this document provides such -+ functionality. The underlying implementation is also allowed to -+ use whatever datastructures it likes to provide access to the -+ translations in the most efficient manner possible. In -+ addition, the implementation is provided with standardized -+ functions that programs will use for accessing an external, -+ unspecified repository of translations.</p> -+ -+ <p>This interface <i>does not</i> cover all aspects of -+ localization, including support for non-latin characters, -+ number and date formatting, etc. Such functionality is the -+ scope of a future SRFI that may extend this one.</p> -+ -+ <H1>Dependencies</H1> -+ -+ An SRFI-29 conformant implementation must also implement -+ SRFI-28, Basic Format Strings. Message templates are strings -+ that must be processed by the <tt>format</tt> function -+ specified in that SRFI. -+ -+ <H1>Specification</H1> -+ -+ <h3>Message Bundles</h3> -+ -+ <p>A Message Bundle is a set of message templates and their -+ identifying keys. Each bundle contains one or more such -+ key/value pairs. The bundle itself is associated with a -+ <i>bundle specifier</i> which uniquely identifies the -+ bundle.</p> -+ -+ <h3>Bundle Specifiers</h3> -+ -+ <p>A Bundle Specifier is a Scheme list that describes, in order -+ of importance, the package and locale of a message bundle. -+ In most cases, a locale specifier will have between one -+ and three elements. The first element is a symbol denoting the -+ package for which this bundle applies. The second and third -+ elements denote a <i>locale</i>. The second element (first -+ element of the locale) if present, is the two letter, ISO 639-1 -+ language code for the bundle. The third element, if present, is -+ a two letter ISO 3166-1 country code. In some cases, a -+ fourth element may be present, specifying the encoding used for -+ the bundle. All bundle specifier elements are Scheme -+ symbols.</p> -+ -+ <p>If only one translation is provided, it should be designated -+ only by a package name, for example <tt>(mathlib)</tt>. This -+ translation is called the <i>default</i> translation.</p> -+ -+ <h3>Bundle Searching</h3> -+ -+ <p>When a message template is retrieved from a bundle, the -+ Scheme implementation will provide the locale under which the -+ system is currently running. When the template is retrieved, -+ the package name will be specified. The Scheme system should -+ construct a Bundle Specifier from the provided package name and -+ the active locale. For example, when retrieving a message -+ template for French Canadian, in the <tt>mathlib</tt> package, -+ the bundle specifier '<tt>(mathlib fr ca)</tt>' is used. A -+ program may also retrieve the elements of the current locale -+ using the no-argument procedures:</p> -+ -+ <p><b><a name="current-language"></a><tt>current-language</tt></b> <tt>-> -+ <i>symbol</i></tt><br> -+ <tt><b>current-language</b> <i>symbol</i> -> -+ undefined</tt><br> -+ </p> -+ -+ <blockquote> -+ When given no arguments, returns the current ISO 639-1 -+ language code as a symbol. If provided with an -+ argument, the current language is set to that named by the -+ symbol for the currently executing Scheme thread (or for the -+ entire Scheme system if such a distinction is not possible). -+ -+ </blockquote> -+ -+ <p><b><a name="current-country"></a><tt>current-country</tt></b> <tt>-> -+ <i>symbol</i></tt><br> -+ <tt><b>current-country</b> <i>symbol</i> -> -+ undefined</tt><br> -+ </p> -+ -+ <blockquote> -+ returns the current ISO 3166-1 country code as a symbol. -+ If provided with an argument, the current country is -+ set to that named by the symbol for the currently executing -+ Scheme thread (or for the entire Scheme system if such a -+ distinction is not possible). -+ </blockquote> -+ -+ <p><b><a name="current-locale-details"></a><tt>current-locale-details</tt></b> <tt>-> <i>list of -+ symbol</i></tt>s<br> -+ <tt><b>current-locale-details</b> <i>list-of-symbols</i> -> -+ undefined</tt><br> -+ </p> -+ -+ <blockquote> -+ Returns a list of additional locale details as a list of -+ symbols. This list may contain information about -+ encodings or other more specific information. If -+ provided with an argument, the current locale details are set -+ to those given in the currently executing Scheme thread (or -+ for the entire Scheme system if such a distinction is not -+ possible). -+ </blockquote> -+ -+ <p>The Scheme System should first check for a bundle with the -+ exact name provided. If no such bundle is found, the last -+ element from the list is removed and a search is tried for a -+ bundle with that name. If no bundle is then found, the list is -+ shortened by removing the last element again. If no message is -+ found and the bundle specifier is now the empty list, an error -+ should be raised.</p> -+ -+ <p>The reason for this search order is to provide the most -+ locale sensitive template possible, but to fall back on more -+ general templates if a translation has not yet been provided -+ for the given locale.</p> -+ -+ <h3>Message Templates</h3> -+ -+ <p>A message template is a localized message that may or may -+ not contain one of a number of formatting codes. A message -+ template is a Scheme string. The string is of a form that can -+ be processed by the <tt>format</tt> procedure found in many -+ Scheme systems and formally specified in SRFI-28 (Basic Format -+ Strings).</p> -+ -+ <p>This SRFI also extends SRFI-28 to provide an additional -+ <tt>format</tt> escape code:</p> -+ -+ <blockquote> -+ <tt>~[n]@*</tt> - Causes a value-requiring escape code that -+ follows this code immediately to reference the [N]'th -+ optional value absolutely, rather than the next unconsumed -+ value. The referenced value is <i>not</i> consumed. -+ </blockquote> -+ This extension allows optional values to be positionally -+ referenced, so that message templates can be constructed that -+ can produce the proper word ordering for a language. -+ -+ <h3>Preparing Bundles</h3> -+ Before a bundle may be used by the Scheme system to retrieve -+ localized template messages, they must be made available to the -+ Scheme system. This SRFI specifies a way to portably -+ define the bundles, as well as store them in and retrieve them -+ from an unspecified system which may be provided by resources -+ outside the Scheme system.<br> -+ -+ -+ <p><b><a name="declare-bundle!"></a><tt>declare-bundle!</tt></b> <tt><i>bundle-specifier -+ association-list</i> -> undefined<br> -+ </tt></p> -+ -+ <blockquote> -+ Declares a new bundle named by the given bundle-specifier. -+ The contents of the bundle are defined by the provided -+ association list. The list contains associations -+ between Scheme symbols and the message templates (Scheme -+ strings) they name. If a bundle already exists with the -+ given name, it is overwritten with the newly declared -+ bundle.<br> -+ </blockquote> -+ <tt><a name="store-bundle"></a><b>store-bundle</b> <i>bundle-specifier</i> -> -+ boolean</tt><br> -+ -+ -+ <blockquote> -+ Attempts to store a bundle named by the given bundle -+ specifier, and previously made available using -+ <tt>declare-bundle!</tt> or <tt>load-bundle!</tt>, in an -+ unspecified mechanism that may be persistent across Scheme -+ system restarts. If successful, a non-false value is -+ returned. If unsuccessful, <tt>#f</tt> is returned.<br> -+ </blockquote> -+ <tt><a name="load-bundle!"></a><b>load-bundle!</b> <i>bundle-specifier</i> -> -+ boolean</tt><br> -+ -+ -+ <blockquote> -+ Attempts to retrieve a bundle from an unspecified mechanism -+ which stores bundles outside the Scheme system. If the -+ bundle was retrieved successfully, the function returns a -+ non-false value, and the bundle is immediately available to -+ the Scheme system. If the bundle could not be found or loaded -+ successfully, the function returns <tt>#f</tt>, and the -+ Scheme system's bundle registry remains unaffected.<br> -+ </blockquote> -+ A compliant Scheme system may choose not to provide any -+ external mechanism to store localized bundles. If it does -+ not, it must still provide implementations for -+ <tt>store-bundle</tt> and <tt>load-bundle!</tt>. In such a -+ case, both functions must return <tt>#f</tt> regardless of the -+ arguments given. Users of this SRFI should recognize that the -+ inability to load or store a localized bundle in an external -+ repository is <i>not</i> a fatal error.<br> -+ -+ -+ <h3>Retrieving Localized Message Templates</h3> -+ -+ <p><a name="localized-template"></a><b><tt>localized-template</tt></b> <i><tt>package-name -+ message-template-name</tt></i> <tt>-> <i>string or #f<br> -+ </i></tt></p> -+ -+ <blockquote> -+ Retrieves a localized message template for the given package -+ name and the given message template name (both symbols). -+ If no such message could be found, false (#f) is -+ returned.<br> -+ <br> -+ </blockquote> -+ After retrieving a template, the calling program can use -+ <tt>format</tt> to produce a string that can be displayed to -+ the user.<br> -+ -+ -+ <h2>Examples</h2> -+ The below example makes use of SRFI-29 to display simple, -+ localized messages. It also defines its bundles in such a -+ way that the Scheme system may store and retrieve the bundles -+ from a more efficient system catalog, if available.<br> -+ -+<pre> -+(let ((translations -+ '(((en) . ((time . "Its ~a, ~a.") -+ (goodbye . "Goodbye, ~a."))) -+ ((fr) . ((time . "~1@*~a, c'est ~a.") -+ (goodbye . "Au revoir, ~a.")))))) -+ (for-each (lambda (translation) -+ (let ((bundle-name (cons 'hello-program (car translation)))) -+ (if (not (load-bundle! bundle-name)) -+ (begin -+ (declare-bundle! bundle-name (cdr translation)) -+ (store-bundle! bundle-name))))) -+ translations)) -+ -+(define localized-message -+ (lambda (message-name . args) -+ (apply format (cons (localized-template 'hello-program -+ message-name) -+ args)))) -+ -+(let ((myname "Fred")) -+ (display (localized-message 'time "12:00" myname)) -+ (display #\newline) -+ -+ (display (localized-message 'goodbye myname)) -+ (display #\newline)) -+ -+;; Displays (English): -+;; Its 12:00, Fred. -+;; Goodbye, Fred. -+;; -+;; French: -+;; Fred, c'est 12:00. -+;; Au revoir, Fred. -+</pre> -+ -+ <H1>Implementation</H1> -+ -+ <p>The implementation requires that the Scheme system provide a -+ definition for <tt>current-language</tt> and -+ <tt>current-country</tt> capable of distinguishing the correct -+ locale present during a Scheme session. The definitions of -+ those functions in the reference implementation are not capable -+ of that distinction. Their implementation is provided only so -+ that the following code can run in any R4RS scheme system. -+ <br> -+ </p> -+ -+ <p>In addition, the below implementation of a compliant -+ <tt>format</tt> requires SRFI-6 (Basic String Ports) and -+ SRFI-23 (Error reporting)</p> -+<pre> -+;; The association list in which bundles will be stored -+(define *localization-bundles* '()) -+ -+;; The current-language and current-country functions provided -+;; here must be rewritten for each Scheme system to default to the -+;; actual locale of the session -+(define current-language -+ (let ((current-language-value 'en)) -+ (lambda args -+ (if (null? args) -+ current-language-value -+ (set! current-language-value (car args)))))) -+ -+(define current-country -+ (let ((current-country-value 'us)) -+ (lambda args -+ (if (null? args) -+ current-country-value -+ (set! current-country-value (car args)))))) -+ -+;; The load-bundle! and store-bundle! both return #f in this -+;; reference implementation. A compliant implementation need -+;; not rewrite these procedures. -+(define load-bundle! -+ (lambda (bundle-specifier) -+ #f)) -+ -+(define store-bundle! -+ (lambda (bundle-specifier) -+ #f)) -+ -+;; Declare a bundle of templates with a given bundle specifier -+(define declare-bundle! -+ (letrec ((remove-old-bundle -+ (lambda (specifier bundle) -+ (cond ((null? bundle) '()) -+ ((equal? (caar bundle) specifier) -+ (cdr bundle)) -+ (else (cons (car bundle) -+ (remove-old-bundle specifier -+ (cdr bundle)))))))) -+ (lambda (bundle-specifier bundle-assoc-list) -+ (set! *localization-bundles* -+ (cons (cons bundle-specifier bundle-assoc-list) -+ (remove-old-bundle bundle-specifier -+ *localization-bundles*)))))) -+ -+;;Retrieve a localized template given its package name and a template name -+(define localized-template -+ (letrec ((rdc -+ (lambda (ls) -+ (if (null? (cdr ls)) -+ '() -+ (cons (car ls) (rdc (cdr ls)))))) -+ (find-bundle -+ (lambda (specifier template-name) -+ (cond ((assoc specifier *localization-bundles*) => -+ (lambda (bundle) bundle)) -+ ((null? specifier) #f) -+ (else (find-bundle (rdc specifier) -+ template-name)))))) -+ (lambda (package-name template-name) -+ (let loop ((specifier (cons package-name -+ (list (current-language) -+ (current-country))))) -+ (and (not (null? specifier)) -+ (let ((bundle (find-bundle specifier template-name))) -+ (and bundle -+ (cond ((assq template-name bundle) => cdr) -+ ((null? (cdr specifier)) #f) -+ (else (loop (rdc specifier))))))))))) -+ -+;;An SRFI-28 and SRFI-29 compliant version of format. It requires -+;;SRFI-23 for error reporting. -+(define format -+ (lambda (format-string . objects) -+ (let ((buffer (open-output-string))) -+ (let loop ((format-list (string->list format-string)) -+ (objects objects) -+ (object-override #f)) -+ (cond ((null? format-list) (get-output-string buffer)) -+ ((char=? (car format-list) #~) -+ (cond ((null? (cdr format-list)) -+ (error 'format "Incomplete escape sequence")) -+ ((char-numeric? (cadr format-list)) -+ (let posloop ((fl (cddr format-list)) -+ (pos (string->number -+ (string (cadr format-list))))) -+ (cond ((null? fl) -+ (error 'format "Incomplete escape sequence")) -+ ((and (eq? (car fl) '#@) -+ (null? (cdr fl))) -+ (error 'format "Incomplete escape sequence")) -+ ((and (eq? (car fl) '#@) -+ (eq? (cadr fl) '#*)) -+ (loop (cddr fl) objects (list-ref objects pos))) -+ (else -+ (posloop (cdr fl) -+ (+ (* 10 pos) -+ (string->number -+ (string (car fl))))))))) -+ (else -+ (case (cadr format-list) -+ ((#\a) -+ (cond (object-override -+ (begin -+ (display object-override buffer) -+ (loop (cddr format-list) objects #f))) -+ ((null? objects) -+ (error 'format "No value for escape sequence")) -+ (else -+ (begin -+ (display (car objects) buffer) -+ (loop (cddr format-list) -+ (cdr objects) #f))))) -+ ((#\s) -+ (cond (object-override -+ (begin -+ (display object-override buffer) -+ (loop (cddr format-list) objects #f))) -+ ((null? objects) -+ (error 'format "No value for escape sequence")) -+ (else -+ (begin -+ (write (car objects) buffer) -+ (loop (cddr format-list) -+ (cdr objects) #f))))) -+ ((#%) -+ (if object-override -+ (error 'format "Escape sequence following positional override does not require a value")) -+ (display #\newline buffer) -+ (loop (cddr format-list) objects #f)) -+ ((#~) -+ (if object-override -+ (error 'format "Escape sequence following positional override does not require a value")) -+ (display #~ buffer) -+ (loop (cddr format-list) objects #f)) -+ (else -+ (error 'format "Unrecognized escape sequence")))))) -+ (else (display (car format-list) buffer) -+ (loop (cdr format-list) objects #f))))))) -+ -+</pre> -+ -+ <H1>Copyright</H1> -+ -+ Copyright (C) Scott G. Miller (2002). All Rights Reserved. -+ -+ <p>This document and translations of it may be copied and -+ furnished to others, and derivative works that comment on or -+ otherwise explain it or assist in its implementation may be -+ prepared, copied, published and distributed, in whole or in -+ part, without restriction of any kind, provided that the above -+ copyright notice and this paragraph are included on all such -+ copies and derivative works. However, this document itself may -+ not be modified in any way, such as by removing the copyright -+ notice or references to the Scheme Request For Implementation -+ process or editors, except as needed for the purpose of -+ developing SRFIs in which case the procedures for copyrights -+ defined in the SRFI process must be followed, or as required to -+ translate it into languages other than English.</p> -+ -+ <p>The limited permissions granted above are perpetual and will -+ not be revoked by the authors or their successors or -+ assigns.</p> -+ -+ <p>This document and the information contained herein is -+ provided on an "AS IS" basis and THE AUTHOR AND THE SRFI -+ EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION -+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES -+ OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> -+ <hr> -+ -+ <address> -+ Editor: <a href="mailto:srfi-editors@srfi.schemers.org">David -+ Rush</a> -+ </address> -+ -+ <address> -+ Author: <a href="mailto:scgmille@freenetproject.org">Scott G. -+ Miller</a> -+ </address> -+ <!-- Created: Tue Sep 29 19:20:08 EDT 1998 --> -+ <!-- hhmts start -->Last modified: Mon Jun 17 12:00:08 Pacific -+ Daylight Time 2002 <!-- hhmts end --> <br> -+ </body> -+</html> -+ -diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html ---- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 2018-01-31 12:22:58.144502000 -0500 -@@ -0,0 +1,345 @@ -+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"> -+<html> -+<head> -+ <title>SRFI 5: A compatible let form with signatures and rest arguments</title> -+</head> -+<body> -+ -+<H1>Title</H1> -+ -+SRFI-5: A compatible <code>let</code> form with signatures and rest arguments -+ -+<H1>Author</H1> -+ -+Andy Gaynor -+ -+<H1>Status</H1> -+ -+This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>. -+You can access the discussion on this SRFI via <A HREF="http://srfi.schemers.org/srfi-5/mail-archive/maillist.html">the archive of the mailing list</A>. -+<P><UL> -+<LI>Received: 1999/2/2 -+<LI>Draft: 1999/2/10-1999/04/12 -+<LI>Final: 1999/4/26 -+<LI>Revised reference implementation: 2003/01/27 -+</UL> -+ -+<H1>Abstract</H1> -+ -+The <i>named-let</i> incarnation of the <code>let</code> form has two slight -+inconsistencies with the <code>define</code> form. As defined, the <code>let</code> -+form makes no accommodation for rest arguments, an issue of functionality -+and consistency. As defined, the <code>let</code> form does not accommodate -+signature-style syntax, an issue of aesthetics and consistency. Both -+issues are addressed here in a manner which is compatible with the traditional -+<code>let</code> form but for minor extensions. -+ -+<H1>Rationale</H1> -+ -+<H2>Signature-style Syntax</H2> -+ -+Consider the following two equivalent definitions: -+ -+<p><pre> -+(define fibonacci -+ (lambda (n i f0 f1) -+ (if (= i n) -+ f0 -+ (fibonacci n (+ i 1) f1 (+ f0 f1))))) -+ -+(define (fibonacci n i f0 f1) -+ (if (= i n) -+ f0 -+ (fibonacci n (+ i 1) f1 (+ f0 f1)))) -+</pre> -+ -+Although there is a named-let analog for the former form, there is none -+for the latter. To wit, suppose one wished to compute the 10th element -+of the Fibonacci sequence using a named let: -+ -+<p> -+<pre> -+(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) -+ (if (= i n) -+ f0 -+ (fibonacci n (+ i 1) f1 (+ f0 f1)))) -+Values: 55 -+</pre> -+ -+As it stands, one cannot equivalently write -+ -+<p> -+<pre> -+(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) -+ (if (= i n) -+ f0 -+ (fibonacci n (+ i 1) f1 (+ f0 f1)))) -+</pre> -+ -+which is consistent with <code>define</code>'s signature-style form. -+<p>Those that favor the signature style may prefer this extension. -+In any case, it may be more appropriate to include all bound names within -+the binding section. As presented, this straightforward extension -+introduces no ambiguity or incompatibility with the existing definition -+of let. -+ -+<H2>Rest Arguments</H2> -+ -+As it stands, one cannot write a named let with rest arguments, as in -+ -+<p> -+<pre> -+(let (blast (port (current-output-port)) . (x (+ 1 2) 4 5)) -+ (if (null? x) -+ 'just-a-silly-contrived-example -+ (begin -+ (write (car x) port) -+ (apply blast port (cdr x))))) -+</pre> -+ -+otherwise equivalent to -+ -+<p> -+<pre> -+(letrec ((blast (lambda (port . x) -+ (if (null? x) -+ 'just-a-silly-contrived-example -+ (begin -+ (write (car x) port) -+ (apply blast port (cdr x))))))) -+ (blast (current-output-port) (+ 1 2) 4 5)) -+</pre> -+ -+While this example is rather contrived, the functionality is not. -+There are several times when the author has used this construct in practice. -+Regardless, there is little reason to deny the <code>let</code> form access to -+all the features of lambda functionality. -+ -+<H2>Symbols in Binding Sections</H2> -+ -+Both the features above rely upon the placement of symbols in <code>let</code> -+binding lists (this statement is intentially simplistic). The only -+other apparent use of such symbol placement is to tersely bind variables -+to unspecified values. For example, one might desire to use -+<code>(let (foo bar baz) ...)</code> -+to bind <code>foo</code>, <code>bar</code>, and <code>baz</code> to -+unspecified values. -+ -+<p>This usage is considered less important in light of the rationales -+presented above, and an alternate syntax is immediately apparent, as -+in <code>(let ((foo) (bar) (baz)) ...)</code> This may even -+be preferable, consistently parenthesizing normal binding clauses. -+ -+<H1>Specification</H1> -+ -+<H2>Syntax</H2> -+ -+<p> -+A formal specification of the syntax follows. Below, body, expression, -+and identifier are free. Each instantiation of binding-name must be -+unique. -+</p> -+ -+<p> -+<pre> -+ let = "(" "let" let-bindings body ")" -+ expressions = nothing | expression expressions -+ let-bindings = let-name bindings -+ |"(" let-name "." bindings ")" -+ let-name = identifier -+ bindings = "(" ")" -+ | rest-binding -+ | "(" normal-bindings ["." rest-binding] ")" -+normal-bindings = nothing -+ | normal-binding normal-bindings -+normal-binding = "(" binding-name expression ")" -+ binding-name = identifier -+ rest-binding = "(" binding-name expressions ")" -+</pre> -+ -+<p> -+For clarity and convenience, an informal specification follows. -+</p> -+ -+<ol> -+<li><a name="unnamed">Unnamed</a> -+ -+<p><pre> -+(let ((<parameter> <argument>)...) -+ <body>...) -+</pre> -+</li> -+ -+<li><a name="named-non-sig"> -+Named, non-signature-style, no rest argument</a> -+ -+<p><pre> -+(let <name> ((<parameter> <argument>)...) -+ <body>...) -+</pre> -+</li> -+ -+<li><a name="named-sig">Named, signature-style, no rest argument</a> -+ -+<p><pre> -+(let (<name> (<parameter> <argument>)...) -+ <body>...) -+</pre> -+</li> -+ -+<li><a name="named-non-sig-rest">Named, non-signature-style, rest argument</a> -+ -+<p><pre> -+(let <name> ((<parameter> <argument>)... -+ -+. (<rest-parameter> <rest-argument>...)) -+ <body>...) -+</pre> -+ -+<li><a name="named-sig-rest">Named, signature-style, rest argument</a> -+ -+<p><pre> -+(let (<name> (<parameter> <argument>)... -+ -+. (<rest-parameter> <rest-argument>...)) -+ <body>...) -+</pre> -+</li> -+</ol> -+ -+<H2>Semantics</H2> -+ -+Let <code>$lambda</code> and <code>$letrec</code> be hygienic bindings for the <code>lambda</code> -+and <code>letrec</code> forms, respectively. -+ -+<ul> -+<li>For informal syntax 1: -+ -+<p><pre> -+(($lambda (<parameter>...) <body>...) <argument>...) -+</pre> -+</li> -+ -+<li>For informal syntaxes 2 and 3: -+ -+<p> -+<pre> -+($letrec ((<name> ($lambda (<parameter>...) <body>...))) -+ (<name> <argument>...)) -+</pre> -+</li> -+ -+<li>For informal syntaxes 4 and 5: -+ -+<p> -+<pre> -+($letrec ((<name> ($lambda (<parameter>... -+ -+. <rest-parameter>) <body>...))) -+ (<name> <argument>... <rest-argument>...)) -+</pre> -+</li> -+</ul> -+ -+<H1>Implementation</H1> -+ -+Here is an implementation using <code>SYNTAX-RULES</code>. -+ -+<p> -+<pre> -+;; Use your own standard let. -+;; Or call a lambda. -+;; (define-syntax standard-let -+;; -+;; (syntax-rules () -+;; -+;; ((let ((var val) ...) body ...) -+;; ((lambda (var ...) body ...) val ...)))) -+ -+(define-syntax let -+ -+ (syntax-rules () -+ -+ ;; No bindings: use standard-let. -+ ((let () body ...) -+ (standard-let () body ...)) -+ ;; Or call a lambda. -+ ;; ((lambda () body ...)) -+ -+ ;; All standard bindings: use standard-let. -+ ((let ((var val) ...) body ...) -+ (standard-let ((var val) ...) body ...)) -+ ;; Or call a lambda. -+ ;; ((lambda (var ...) body ...) val ...) -+ -+ ;; One standard binding: loop. -+ ;; The all-standard-bindings clause didn't match, -+ ;; so there must be a rest binding. -+ ((let ((var val) . bindings) body ...) -+ (let-loop #f bindings (var) (val) (body ...))) -+ -+ ;; Signature-style name: loop. -+ ((let (name binding ...) body ...) -+ (let-loop name (binding ...) () () (body ...))) -+ -+ ;; defun-style name: loop. -+ ((let name bindings body ...) -+ (let-loop name bindings () () (body ...))))) -+ -+(define-syntax let-loop -+ -+ (syntax-rules () -+ -+ ;; Standard binding: destructure and loop. -+ ((let-loop name ((var0 val0) binding ...) (var ... ) (val ... ) body) -+ (let-loop name ( binding ...) (var ... var0) (val ... val0) body)) -+ -+ ;; Rest binding, no name: use standard-let, listing the rest values. -+ ;; Because of let's first clause, there is no "no bindings, no name" clause. -+ ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) -+ (standard-let ((var val) ... (rest-var (list rest-val ...))) . body)) -+ ;; Or call a lambda with a rest parameter on all values. -+ ;; ((lambda (var ... . rest-var) . body) val ... rest-val ...)) -+ ;; Or use one of several other reasonable alternatives. -+ -+ ;; No bindings, name: call a letrec'ed lambda. -+ ((let-loop name () (var ...) (val ...) body) -+ ((letrec ((name (lambda (var ...) . body))) -+ name) -+ val ...)) -+ -+ ;; Rest binding, name: call a letrec'ed lambda. -+ ((let-loop name (rest-var rest-val ...) (var ...) (val ...) body) -+ ((letrec ((name (lambda (var ... . rest-var) . body))) -+ name) -+ val ... rest-val ...)))) -+</pre> -+ -+ -+<H1>Copyright</H1> -+ -+Copyright (C) Andy Gaynor (1999). All Rights Reserved. -+<p>This document and translations of it may be copied and furnished to -+others, and derivative works that comment on or otherwise explain it or -+assist in its implementation may be prepared, copied, published and distributed, -+in whole or in part, without restriction of any kind, provided that the -+above copyright notice and this paragraph are included on all such copies -+and derivative works. However, this document itself may not be modified -+in any way, such as by removing the copyright notice or references to the -+Scheme Request For Implementation process or editors, except as needed -+for the purpose of developing SRFIs in which case the procedures for copyrights -+defined in the SRFI process must be followed, or as required to translate -+it into languages other than English. -+<p>The limited permissions granted above are perpetual and will not be -+revoked by the authors or their successors or assigns. -+<p>This document and the information contained herein is provided on an -+"AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, -+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE -+USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED -+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -+ -+ <hr> -+ <address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address> -+ -+</body> -+</html> -diff -urN racket-6.12-orig/share/pkgs/srfi-lib/info.rkt racket-6.12/share/pkgs/srfi-lib/info.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib/info.rkt 2018-01-26 16:10:02.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib/info.rkt 2018-01-31 12:22:58.144502000 -0500 -@@ -1 +1,15 @@ --(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define deps (quote ("scheme-lib" "base" "srfi-lite-lib" "r6rs-lib" "compatibility-lib"))) (define implies (quote ("srfi-lite-lib"))) (define pkg-desc "implementation (no documentation) part of "srfi"") (define pkg-authors (quote (mflatt noel chongkai jay))))) -+#lang info -+ -+(define collection 'multi) -+ -+(define deps '("scheme-lib" -+ "base" -+ "srfi-lite-lib" -+ "r6rs-lib" -+ "compatibility-lib")) -+ -+(define implies '("srfi-lite-lib")) -+ -+(define pkg-desc "implementation (no documentation) part of "srfi"") -+ -+(define pkg-authors '(mflatt noel chongkai jay)) -diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/sort.txt racket-6.12/share/pkgs/srfi-lib/srfi/32/sort.txt ---- racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/sort.txt 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib/srfi/32/sort.txt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,1069 +0,0 @@ --The SRFI-32 sort libraries -*- outline -*- --Olin Shivers --First draft: 1998/10/19 --Last update: 2002/7/21 -- --[Todo: del-list-neighbor-dups! -- vector-copy -> subvector -- use srfi-23 for reporting errors -- use srfi-16 for n-aries? -- --Emacs should display this document in outline mode. Say c-h m for --instructions on how to move through it by sections (e.g., c-c c-n, c-c c-p). -- --* Table of contents --------------------- --Abstract --Procedure index --Introduction --What's wrong with the current state of affairs? --Design rules -- What vs. how -- Consistency across function signatures -- Data parameter first, less-than parameter after -- Ordering, comparison functions & stability -- All vector operations accept optional subrange parameters -- Required vs. allowed side-effects --Procedure specification -- Procedure naming and functionality -- Types of parameters and return values -- sort-lib - general sorting package -- Algorithm-specific sorting packages --Algorithmic properties --Topics to be resolved during discussion phase --Porting and optimisation --References & Links --Acknowledgements --Copyright -- -- --* Abstract ------------ --Current Scheme sorting packages are, every one of them, surprisingly bad. I've --designed the API for a full-featured sort toolkit, which I propose as a SRFI. -- --The spec comes with 1200 lines of high-quality reference code: tightly --written, highly commented, portable code, available for free. Implementors --want this code. It's better than what you have. -- --------------------------------------------------------------------------------- --* Procedure index ------------------- --list-sorted? vector-sorted? -- --list-merge vector-merge --list-sort vector-sort --list-stable-sort vector-stable-sort --list-delete-neighbor-dups vector-delete-neighbor-dups -- --list-merge! vector-merge! --list-sort! vector-sort! --list-stable-sort! vector-stable-sort! --list-delete-neighbor-dups! vector-delete-neighbor-dups! -- --quick-sort heap-sort insert-sort list-merge-sort vector-merge-sort --quick-sort! heap-sort! insert-sort! list-merge-sort! vector-merge-sort! --quick-sort3! -- --vector-binary-search --vector-binary-search3 -- --------------------------------------------------------------------------------- --* Introduction ---------------- --As I'll detail below, I wasn't very happy with the state of the Scheme --world for sorting and merging lists and vectors. So I have designed and --written a fairly comprehensive sorting & merging toolkit. It is -- -- - very portable, -- -- - much better code than what is currently in Elk, Gambit, Bigloo, -- Scheme->C, MzScheme, RScheme, Scheme48, MIT Scheme, or slib, and -- -- - priced to move: free code. -- --The package includes -- - Vector insert sort (stable) -- - Vector heap sort -- - Vector quick sort (with median-of-3 pivot picking) -- - Vector merge sort (stable) -- - Pure and destructive list merge sort (stable) -- - Stable vector and list merge -- - Miscellaneous sort-related procedures: Vector and list merging, -- sorted? predicates, vector binary search, vector and list -- delete-equal-neighbor procedures. -- - A general, non-algorithmic set of procedure names for general sorting -- and merging. -- --Scheme programmers may want to adopt this package. I'd like Scheme --implementors to adopt this code and its API -- in fact, the code is a bribe to --make it easy for implementors to converge on the suggested API. I mean, you'd --really have to be a boor to take this free code I wrote and mutate its --interface over to your incompatible, unportable API, wouldn't you? But you --could, of course -- it's freely available. More in the spirit of the offering, --you could make this API available, and then also write a little module --providing your old interface that is defined in terms of this API. "Scheme --implementors," in this context, includes slib, which is not a standalone --implementation of Scheme, but rather an influential collection of API's and --code. -- --The code is tightly bummed. It is clearly written, and commented in my usual --voluminous style. This includes notes on porting and implementation-specific --optimisations. -- -- --------------------------------------------------------------------------------- --* What's wrong with the current state of affairs? --------------------------------------------------- -- --It's just amazing to me that in 2002, sorting and merging hasn't been --completely put to bed. These are well-understood algorithms, each of them well --under a page of code. The straightforward algorithms are basic, core stuff -- --sophomore-level. But if you tour the major Scheme implementations out there on --the Net, you find badly written code that provides extremely spotty coverage --of the algorithm space. One implementation even has a buggy implementation --that has been in use for about 20 years. Another has an O(n^2) algorithm... --implemented in C for speed. -- --Open source-code is a wonderful thing. In a couple of hours, I was able to --download and check the sources of 9 Scheme systems. Here are my notes from the --systems I checked. You can skip to the next section if you aren't morbidly --curious. -- --slib -- sorted? vector-or-list < -- merge list1 list2 < -- merge! list1 list2 < -- sort vector-or-list < -- sort! vector-or-list < -- -- Richard O'Keefe's stable list merge sort is right idea, but implemented -- using gratuitous variable side effects. It also does redundant SET-CDR!s. -- The vector sort converts to list, merge sorts, then reconverts -- to vector. This is a bad idea -- non-local pointer chasing bad; vector -- shuffling good. If you must allocate temp storage, might as well allocate -- a temp vector and use vector merge sort. -- --MIT Scheme -- sort! vector < -- merge-sort! vector < -- quick-sort! vector < -- -- sort vector-or-list < -- merge-sort vector-or-list < -- quick-sort vector-or-list < -- -- Naive vector quicksort: loser, for worst-case performance reasons. -- List sort by "list->vector; quicksort; vector->list," hence also loser. -- A clever stable vector merge sort, albeit not very bummed. -- --Scheme 48 & T -- sort-list list < -- sort-list! list < -- list-merge! list1 list2 < -- -- Bob Nix's implementation of online merge-sort, written in the early 80's. -- Conses unnecessary bookkeeping structure, which isn't necessary with a -- proper recursive formulation. Also, does redundant SET-CDR!s. No vector -- sort. Also, has a bug -- is claimed to be a stable sort, but isn't! To see -- this, get the S48 code, and try -- (define (my< x y) (< (abs x) (abs y))) -- (list-merge! (list 0 2) (list -2) my<) ; -> (0 2 -2) -- (list-merge! (list 2) (list 0 -2) my<) ; -> (0 -2 2) -- This could be fixed very easily, but it isn't worth it given the -- other problems with the algorithm. -- --RScheme -- vector-sort! vector < -- sort collection < -- -- Good basic implementation of vector heapsort, which has O(n lg n) -- worst-case time. Code ugly, needs tuning. List sort by "list->vector; -- sort; vector->list." Nothing for stable sorting. -- --MzScheme -- quicksort lis < -- mergesort alox < -- -- Sorts lists with (list->vector; quicksort; vector->list) -- but the core -- quicksort is not available for vector sorting. Nothing for stable sorting. -- Quicksort picks pivot naively, inducing O(n^2) worse-case behaviour on a -- fairly common case: an already-sorted list. -- --Bigloo, STK -- sort vector-or-list < -- Uses an O(n^2) algorithm... implemented in C for speed. Hmm. -- (See runtime/Ieee/vector.scm and runtime/Clib/cvector.c) -- --Gambit -- sort-list list < -- Nothing for vectors. Simple, slow, unstable merge sort for lists. -- --Elk -- Another naive quicksort. Lists handled by converting to vector. -- sort vector-or-list < -- sort! vector-or-list < -- --Chez Scheme -- merge < list1 list2 -- merge! < list1 list2 -- sort < list -- sort! < list -- -- These are stable. I have not seen the source code. -- --Common Lisp -- sort sequence < [key] -- stable-sort sequence < [key] -- merge result-type sequence1 sequence2 < [key] -- -- The sort procedures are allowed, but not required, to be destructive. -- --SML/NJ -- sort: ('a*'a -> bool) -> 'a list -> 'a list -- "Smooth applicative merge sort," which is stable. -- There is also a highly bummed quicksort for vectors. -- --The right solution: Implement a full toolbox of carefully written standard sort --routines. -- --Having the source of all these above-cited Schemes available for study made --life a lot easier writing this code. I appreciate the authors making their --source available under such open terms. -- -- --------------------------------------------------------------------------------- --* Design rules ---------------- -- --** What vs. how --=============== --There are two different interfaces: "what" (simple) & "how" (detailed). -- -- - Simple: you specify semantics: datatype (list or vector), -- mutability, and stability. -- -- - Detailed: you specify the actual algorithm (quick, heap, -- insert, merge). Different algorithms have different properties, -- both semantic & pragmatic, so these exports are necessary. -- -- It is necessarily the case that the specifications of these procedures -- make statements about execution "pragmatics." For example, the sole -- distinction between heap sort and quick sort -- both of which are -- provided by this library -- is one of execution time, which is not a -- "semantic" distinction. Similar resource-use statements are made about -- "iterative" procedures, meaning that they can execute on input of -- arbitrary size in a constant number of stack frames. -- --** Consistency across function signatures --========================================= --The two interfaces share common function signatures wherever --possible, to facilitate switching a given call from one procedure --to another. -- --** Less-than parameter first, data parameter after --================================================== --These procedures uniformly observe the following parameter order: --the data to be sorted comes after the comparison function. --That is, we write -- (sort < lis) --not -- (sort lis <). -- --With the sole exception of Chez Scheme, this is the exact opposite of --every sort function out there in current use in the Scheme world. (See --the summary of related APIs above.) However, it is consistent with common --practice across Scheme libraries in general to put the ordering function --first -- the "operation currying" convention. (E.g., consider FOR-EACH or --MAP or FIND.) -- --The original draft of this SRFI used the data-first/comparison-last convention --for backwards compatibility -- a decision I made with internal misgivings. --Happily, however, the overwhelming response from the discussion phase --supported "cleaning up" this issue and re-converging the parameter order with --the general Scheme "op currying" convention. So the original decision was --inverted in favor of the comparison-first/data-last convention. -- --** Ordering, comparison functions & stability --============================================= --These routines take a < comparison function, not a <= comparison --function, and they sort into increasing order. The difference between --a < spec and a <= spec comes up in three places: -- - the definition of an ordered or sorted data set, -- - the definition of a stable sorting algorithm, and -- - correctness of quicksort. -- --+ We say that a data set (a list or vector) is *sorted* or *ordered* -- if it contains no adjacent pair of values ... X Y ... such that Y < X. -- -- In other words, scanning across the data never takes a "downwards" step. -- -- If you use a <= procedure where these algorithms expect a < -- procedure, you may not get the answers you expect. For example, -- the LIST-SORTED? function will return false if you pass it a <= comparison -- function and an ordered list containing adjacent equal elements. -- --+ A "stable" sort is one that preserves the pre-existing order of equal -- elements. Suppose, for example, that we sort a list of numbers by -- comparing their absolute values, i.e., using comparison function -- (lambda (x y) (< (abs x) (abs y))) -- If we sort a list that contains both 3 and -3: -- ... 3 ... -3 ... -- then a stable sort is an algorithm that will not swap the order -- of these two elements, that is, the answer is guaranteed to to look like -- ... 3 -3 ... -- not -- ... -3 3 ... -- -- Choosing < for the comparison function instead of <= affects how stability -- is coded. Given an adjacent pair X Y, (< y x) means "Y should be moved in -- front of X" -- otherwise, leave things as they are. So using a <= function -- where a < function is expected will *invert* stability. -- -- This is due to the definition of equality, given a < comparator: -- (and (not (< x y)) -- (not (< y x))) -- The definition is rather different, given a <= comparator: -- (and (<= x y) -- (<= y x)) -- --+ A "stable" merge is one that reliably favors one of its data sets -- when equal items appear in both data sets. *All merge operations in -- this library are stable*, breaking ties between data sets in favor -- of the first data set -- elements of the first list come before equal -- elements in the second list. -- -- So, if we are merging two lists of numbers ordered by absolute value, -- the stable merge operation LIST-MERGE -- (list-merge (lambda (x y) (< (abs x) (abs y))) -- '(0 -2 4 8 -10) '(-1 3 -4 7)) -- reliably places the 4 of the first list before the equal-comparing -4 -- of the second list: -- (0 -1 -2 4 -4 7 8 -10) -- --+ Some sort algorithms will *not work correctly* if given a <= when they -- expect a < comparison (or vice-versa). For example, violating quicksort's -- spec may cause it to produce wrong answers, diverge, raise an error, or do -- some fourth thing. To see why, consider the left-scan part of the standard -- quicksort partition step: -- (let ((i (let scan ((i i)) (if (elt< (vector-ref v i) pivot) -- (scan (+ i 1)) -- i)))) -- ...) -- Consider applying this loop to a vector of all zeroes (hence, PIVOT, as -- well, is zero), but erroneously using <= for the ELT< function. The loop -- will scan right off the end of the vector, producing a vector-index error. -- The guarantee that the scan loop will terminate before running off the end -- of the vector depends critically upon ELT< performing as a true, irreflexive -- < relation. Running off the end of the vector is only one of a variety of -- possibly ways to lose -- other, variant implementations of quicksort can, -- instead, loop forever on some data sets if ELT< is a <= predicate. -- --In short, if your comparison function F answers true to (F x x), then -- - using a stable sorting or merging algorithm will not give you a -- stable sort or merge, -- - LIST-SORTED? may surprise you, and -- - quicksort may fail in a variety of possible ways. --Note that you can synthesize a < function from a <= function with -- (lambda (x y) (not (<= y x))) --if need be. -- --Precise definitions give sharp edges to tools, but require care in use. --"Measure twice, cut once." -- --I have adopted the choice of < from Common Lisp. One would assume the definers --of Common Lisp had a good reason for adopting < instead of <=, but canvassing --several of the principal actors in the definition process has turned up no --better reason than "an arbitrary but consistent choice." At minimum, then, --this SRFI extends the coverage of that consistent choice. -- --** All vector operations accept optional subrange parameters --============================================================ --The vector operations specified below all take optional START/END arguments --indicating a selected subrange of a vector's elements. If a START parameter or --START/END parameter pair is given to such a procedure, they must be exact, --non-negative integers, such that -- 0 <= START <= END <= (VECTOR-LENGTH V) --where V is the related vector parameter. If not specified, they default to 0 --and the length of the vector, respectively. They are interpreted to select the --range [START,END), that is, all elements from index START (inclusive) up to, --but not including, index END. -- --** Required vs. allowed side-effects --==================================== --LIST-SORT! and LIST-STABLE-SORT! are allowed, but not required, --to alter their arguments' cons cells to construct the result list. This is --consistent with the what-not-how character of the group of procedures --to which they belong (the "sort-lib" package). -- --The LIST-DELETE-NEIGHBOR-DUPS!, LIST-MERGE! and LIST-MERGE-SORT! procedures, --on the other hand, provide specific algorithms, and, as such, explicitly --commit to the use of side-effects on their input lists in order to guarantee --their key algorithmic properties (e.g., linear-time operation, constant-space --stack use). -- --------------------------------------------------------------------------------- --* Procedure specification --------------------------- --The procedures are split into several packages. In a Scheme system that has a --module or package system, these procedures should be contained in modules --named as follows: -- Package name Functionality -- ------------ ------------- -- sort-lib General sorting for lists & vectors -- sorted?-lib Sorted predicates for lists & vectors -- list-merge-sort-lib List merge sort -- vector-merge-sort-lib Vector merge sort -- vector-heap-sort-lib Vector heap sort -- vector-quick-sort-lib Vector quick sort -- vector-insert-sort-lib Vector insertion sort -- delndup-lib List and vector delete neighbor duplicates -- binsearch-lib Vector binary search -- --A Scheme system without a module system should provide all of the bindings --defined in all of these modules as components of the "SRFI-32" package. -- --Note that there is no "list insert sort" package, as you might as well always --use list merge sort. The reference implementation's destructive list merge --sort will do fewer SET-CDR!s than a destructive insert sort. -- --** Procedure naming and functionality --===================================== --Almost all of the procedures described below are variants of two basic --operations: sorting and merging. These procedures are consistently named --by composing a set of basic lexemes to indicate what they do. -- --Lexeme Meaning -------- ------- --"sort" The procedure sorts its input data set by some < comparison function. -- --"merge" The procedure merges two ordered data sets into a single ordered -- result. -- --"stable" This lexeme indicates that the sort is a stable one. -- --"vector" The procedure operates upon vectors. -- --"list" The procedure operates upon lists. -- --"!" Procedures that end in "!" are allowed, and sometimes required, -- to reuse their input storage to construct their answer. -- --** Types of parameters and return values --======================================== --In the procedures specified below, -- - A LIS parameter is a list; -- -- - A V parameter is a vector; -- -- - A < or = parameter is a procedure accepting two arguments taken from the -- specified procedure's data set(s), and returning a boolean; -- -- - START and END parameters are exact, non-negative integers that -- serve as vector indices selecting a subrange of some associated vector. -- When specified, they must satisfy the relation -- 0 <= start <= end <= (vector-length v) -- where V is the associated vector. -- --Passing values to procedures with these parameters that do not satisfy these --types is an error. -- --If a procedure is said to return "unspecified," this means that nothing at all --is said about what the procedure returns, not even the number of return --values. Such a procedure is not even required to be consistent from call to --call in the nature or number of its return values. It is simply required to --return a value (or values) that may be passed to a command continuation, e.g. --as the value of an expression appearing as a non-terminal subform of a BEGIN --expression. Note that in R5RS, this restricts such a procedure to returning a --single value; non-R5RS systems may not even provide this restriction. -- --** sort-lib - general sorting package --===================================== --This library provides basic sorting and merging functionality suitable for --general programming. The procedures are named by their semantic properties, --i.e., what they do to the data (sort, stable sort, merge, and so forth). -- -- Procedure Suggested algorithm -- ------------------------------------------------------------------------- -- list-sorted? < lis -> boolean -- list-merge < lis1 lis2 -> list -- list-merge! < lis1 lis2 -> list -- list-sort < lis -> list (vector heap or quick) -- list-sort! < lis -> list (list merge sort) -- list-stable-sort < lis -> list (vector merge sort) -- list-stable-sort! < lis -> list (list merge sort) -- list-delete-neighbor-dups = lis -> list -- list-delete-neighbor-dups! = lis -> list -- -- vector-sorted? < v [start end] -> boolean -- vector-merge < v1 v2 [start1 end1 start2 end2] -> vector -- vector-merge! < v v1 v2 [start start1 end1 start2 end2] -> unspecified -- vector-sort < v [start end] -> vector (heap or quick sort) -- vector-sort! < v [start end] -> unspecified (heap or quick sort) -- vector-stable-sort < v [start end] -> vector (vector merge sort) -- vector-stable-sort! < v [start end] -> unspecified (vector merge sort) -- vector-delete-neighbor-dups = v [start end] -> vector -- vector-delete-neighbor-dups! = target source [t-start s-start s-end] -> t-end -- -- LIST-SORTED? and VECTOR-SORTED? return true if their input list or vector -- is in sorted order, as determined by their < comparison parameter. -- -- All four merge operations are stable: an element of the initial list LIS1 -- or vector V1 will come before an equal-comparing element in the second -- list LIS2 or vector V2 in the result. -- -- The procedures -- LIST-MERGE -- LIST-SORT -- LIST-STABLE-SORT -- LIST-DELETE-NEIGHBOR-DUPS -- do not alter their inputs and are allowed to return a value that shares -- a common tail with a list argument. -- -- The procedures -- LIST-SORT! -- LIST-STABLE-SORT! -- are "linear update" operators -- they are allowed, but not required, to -- alter the cons cells of their arguments to produce their results. -- -- On the other hand, the procedures -- LIST-DELETE-NEIGHBOR-DUPS! -- LIST-MERGE! -- make only a single, iterative, linear-time pass over their argument lists, -- using SET-CDR!s to rearrange the cells of the lists into the final result -- -- they work "in place." Hence, any cons cell appearing in the result must -- have originally appeared in an input. The intent of this -- iterative-algorithm commitment is to allow the programmer to be sure that -- if, for example, LIST-MERGE! is asked to merge two ten-million-element -- lists, the operation will complete without performing some extremely -- (possibly twenty-million) deep recursion. -- -- The vector procedures -- VECTOR-SORT -- VECTOR-STABLE-SORT -- VECTOR-DELETE-NEIGHBOR-DUPS -- do not alter their inputs, but allocate a fresh vector for their result, -- of length END - START. -- -- The vector procedures -- VECTOR-SORT! -- VECTOR-STABLE-SORT! -- sort their data in-place. (But note that VECTOR-STABLE-SORT! may -- allocate temporary storage proportional to the size of the input -- -- I am not aware of O(n lg n) stable vector-sorting algorithms that -- run in constant space.) -- -- VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). -- -- VECTOR-MERGE! writes its result into vector V, beginning at index START, -- for indices less than END = START + (END1-START1) + (END2-START2). The -- target subvector -- V[start,end) -- may not overlap either source subvector -- V1[start1,end1) -- V2[start2,end2). -- -- The ...-DELETE-NEIGHBOR-DUPS-... procedures: -- These procedures delete adjacent duplicate elements from a list or a -- vector, using a given element-equality procedure. The first/leftmost -- element of a run of equal elements is the one that survives. The list or -- vector is not otherwise disordered. -- -- These procedures are linear time -- much faster than the O(n^2) general -- duplicate-element deletors that do not assume any "bunching" of elements -- (such as the ones provided by SRFI-1). If you want to delete duplicate -- elements from a large list or vector, you can sort the elements to bring -- equal items together, then use one of these procedures, for a total time -- of O(n lg n). -- -- The comparison function = passed to these procedures is always applied -- (= x y) -- where X comes before Y in the containing list or vector. -- -- - LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer -- may share storage with the input list. -- -- - VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but -- rather allocates a fresh vector to hold the result. -- -- - LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to -- mutate its input list in order to construct its answer. -- -- - VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the -- answer, packing its answer into the index range [start,end'), where -- END' is the non-negative exact integer returned as its value. It -- returns END' as its result. The vector is not altered outside the range -- [start,end'). -- -- - VECTOR-DELETE-NEIGHBOR-DUPS! scans vector SOURCE in range -- [S-START,S-END), writing its result to vector TARGET beginning at index -- T-START. It returns exact, non-negative integer T-END, which indicates -- that the results of the operation are found in index range -- [T-START,T-END) of TARGET; elements of TARGET outside this range -- are unaltered. -- -- It is an error for memory cell TARGET[T-START] to be a memory cell in -- the region SOURCE[1 + S-START, S-END). In a Scheme implementation -- that does not allow distinct vectors to share storage, this means -- that one of the following must be true: -- 1. (not (eq? source target)) -- 2. t-start not-in [s-start + 1, s-end) -- -- - Examples: -- (list-delete-neighbor-dups = '(1 1 2 7 7 7 0 -2 -2)) -- => (1 2 7 0 -2) -- -- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2)) -- => #(1 2 7 0 -2) -- -- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2) 3 7) -- => #(7 0 -2) -- -- ;; Result left in v[3,9): -- (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) -- (cons (vector-delete-neighbor-dups! = v 3) -- v)) -- => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) -- -- --** Algorithm-specific sorting packages --====================================== --These packages provide more specific sorting functionality, that is, --specific commitment to particular algorithms that have particular --pragmatic consequences (such as memory locality, asymptotic running time) --beyond their semantic behaviour (sorting, stable sorting, merging, etc.). --Programmers that need a particular algorithm can use one of these packages. -- --sorted?-lib - sorted predicates -- list-sorted? < lis -> boolean -- vector-sorted? < v [start end] -> boolean -- -- Return #f iff there is an adjacent pair ... X Y ... in the input -- list or vector such that Y < X. The optional START/END range -- arguments restrict VECTOR-SORTED? to the indicated subvector. -- --list-merge-sort-lib - list merge sort -- list-merge-sort < lis -> list -- list-merge-sort! < lis -> list -- list-merge lis1 < lis2 -> list -- list-merge! lis1 < lis2 -> list -- -- The sort procedures sort their data using a list merge sort, which is -- stable. (The reference implementation is, additionally, a "natural" sort. -- See below for the properties of this algorithm.) -- -- The ! procedures are destructive -- they use SET-CDR!s to rearrange the -- cells of the lists into the proper order. As such, they do not allocate -- any extra cons cells -- they are "in place" sorts. Additionally, -- LIST-MERGE! is iterative -- it can operate on arguments of arbitrary size -- with a constant number of stack frames. -- -- The merge operations are stable: an element of LIS1 will come before an -- equal-comparing element in LIS2 in the result list. -- --vector-merge-sort-lib - vector merge sort -- vector-merge-sort < v [start end temp] -> vector -- vector-merge-sort! < v [start end temp] -> unspecified -- vector-merge < v1 v2 [start1 end1 start2 end2] -> vector -- vector-merge! < v v1 v2 [start start1 end1 start2 end2] -> unspecified -- -- The sort procedures sort their data using vector merge sort, which is -- stable. (The reference implementation is, additionally, a "natural" sort. -- See below for the properties of this algorithm.) -- -- The optional START/END arguments provide for sorting of subranges, and -- default to 0 and the length of the corresponding vector. -- -- Merge-sorting a vector requires the allocation of a temporary "scratch" -- work vector for the duration of the sort. This scratch vector can be -- passed in by the client as the optional TEMP argument; if so, the supplied -- vector must be of size >= END, and will not be altered outside the range -- [start,end). If not supplied, the sort routines allocate one themselves. -- -- The merge operations are stable: an element of V1 will come before an -- equal-comparing element in V2 in the result vector. -- -- VECTOR-MERGE-SORT! leaves its result in V[start,end). -- -- VECTOR-MERGE-SORT returns a vector of length END-START. -- -- VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). -- -- VECTOR-MERGE! writes its result into vector V, beginning at index START, -- for indices less than END = START + (END1-START1) + (END2-START2). The -- target subvector -- V[start,end) -- may not overlap either source subvector -- V1[start1,end1) -- V2[start2,end2). -- --vector-heap-sort-lib - vector heap sort -- heap-sort < v [start end] -> vector -- heap-sort! < v [start end] -> unspecified -- -- These procedures sort their data using heap sort, -- which is not a stable sorting algorithm. -- -- HEAP-SORT returns a vector of length END-START. -- HEAP-SORT! is in-place, leaving its result in V[start,end). -- --vector-quick-sort-lib - vector quick sort -- quick-sort < v [start end] -> vector -- quick-sort! < v [start end] -> unspecified -- quick-sort3! c v [start end] -> unspecified -- -- These procedures sort their data using quick sort, -- which is not a stable sorting algorithm. -- -- QUICK-SORT returns a vector of length END-START. -- QUICK-SORT! is in-place, leaving its result in V[start,end). -- -- QUICK-SORT3! is a variant of quick-sort that takes a three-way -- comparison function C. C compares a pair of elements and returns -- an exact integer whose sign indicates their relationship: -- (c x y) < 0 => x<y -- (c x y) = 0 => x=y -- (c x y) > 0 => x>y -- To help remember the relationship between the sign of the result and -- the relation, use the function - as the model for C: (- x y) < 0 -- means that x < y; (- x y) > 0 means that x > y. -- -- The extra discrimination provided by the three-way comparison can -- provide significant speedups when sorting data sets with many duplicates, -- especially when the comparison function is relatively expensive (e.g., -- comparing long strings). -- -- WARNING: Some sort algorithms, such as insertion sort or heap sort, -- can tolerate being passed a <= comparison function when they expect a < -- function -- insertion and merge sort may simply invert stability; and -- heap sort will run a bit slower, but otherwise produce a correct answer. -- -- Quicksort, however, is much more critically sensitive to the distinction -- between a < and a <= comparison. If QUICK-SORT or QUICK-SORT! expect a < -- comparison function, and are erroneously given a <= function, they may, -- depending on implementation, produce an unsorted result, go into an -- infinite loop, cause a run-time error, occasionally produce a correct -- result, or do some fifth thing. -- -- Implementors may wish to write QUICKSORT3! so that it (a) tests the -- comparison function (by checking that (c v[start] v[start]) produces -- false), or (b) is tolerant of an erroneous <= function, or (c) both. -- Clients of this function, however, should not count on this. -- --vector-insert-sort-lib - vector insertion sort -- insert-sort < v [start end] -> vector -- insert-sort! < v [start end] -> unspecified -- -- These procedures stably sort their data using insertion sort. -- -- INSERT-SORT returns a vector of length END-START. -- INSERT-SORT! is in-place, leaving its result in V[start,end). -- --delndup-lib - list and vector delete neighbor duplicates -- list-delete-neighbor-dups = lis -> list -- list-delete-neighbor-dups! = lis -> list -- -- vector-delete-neighbor-dups = v [start end] -> vector -- vector-delete-neighbor-dups! = v [start end] -> end' -- -- These procedures delete adjacent duplicate elements from a list or -- a vector, using a given element-equality procedure =. The first/leftmost -- element of a run of equal elements is the one that survives. The list -- or vector is not otherwise disordered. -- -- These procedures are linear time -- much faster than the O(n^2) general -- duplicate-element deletors that do not assume any "bunching" of elements -- (such as the ones provided by SRFI-1). If you want to delete duplicate -- elements from a large list or vector, you can sort the elements to bring -- equal items together, then use one of these procedures, for a total time -- of O(n lg n). -- -- The comparison function = passed to these procedures is always applied -- (= x y) -- where X comes before Y in the containing list or vector. -- -- LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer -- may share storage with the input list. -- -- VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but -- rather allocates a fresh vector to hold the result. -- -- LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to -- mutate its input list in order to construct its answer. -- -- VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the -- answer, packing its answer into the index range [start,end'), where -- END' is the non-negative exact integer returned as its value. It -- returns END' as its result. The vector is not altered outside the range -- [start,end'). -- -- Examples: -- (list-delete-neighbor-dups = '(1 1 2 7 7 7 0 -2 -2)) -- => (1 2 7 0 -2) -- -- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2)) -- => #(1 2 7 0 -2) -- -- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2) 3 7) -- => #(7 0 -2) -- -- ;; Result left in v[3,9): -- (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) -- (cons (vector-delete-neighbor-dups! = v 3) -- v)) -- => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) -- --binsearch-lib - vector binary search lib -- vector-binary-search elt< elt->key key v [start end] -> integer-or-false -- vector-binary-search3 c v [start end] -> integer-or-false -- -- VECTOR-BINARY-SEARCH searches vector V in range [START,END) (which -- default to 0 and the length of V, respectively) for an element whose -- associated key is equal to KEY. The procedure ELT->KEY is used to map -- an element to its associated key. The elements of the vector are assumed -- to be ordered by the ELT< relation on these keys. That is, -- (vector-sorted? (lambda (x y) (elt< (elt->key x) (elt->key y))) -- v start end) => true -- An element E of V is a match for KEY if it's neither less nor greater -- than the key: -- (and (not (elt< (elt->key e) key)) -- (not (elt< key (elt->key e)))) -- If there is such an element, the procedure returns its index in the -- vector as an exact integer. If there is no such element in the searched -- range, the procedure returns false. -- -- (vector-binary-search < car 4 '#((1 . one) (3 . three) -- (4 . four) (25 . twenty-five))) -- => 2 -- -- (vector-binary-search < car 7 '#((1 . one) (3 . three) -- (4 . four) (25 . twenty-five))) -- => #f -- -- VECTOR-BINARY-SEARCH3 is a variant that uses a three-way comparison -- function C. C compares its parameter to the search key, and returns an -- exact integer whose sign indicates its relationship to the search key. -- (c x) < 0 => x < search-key -- (c x) = 0 => x = search-key -- (c x) > 0 => x > search-key -- -- (vector-binary-search3 (lambda (elt) (- (car elt) 4)) -- '#((1 . one) (3 . three) -- (4 . four) (25 . twenty-five))) -- => 2 -- -- Rationale: -- - Why isn't VECTOR-BINARY-SEARCH's ELT->KEY computation simply absorbed -- into the < function? It is separated out because the < function is -- applied twice inside the binary-search inner loop, once with the search -- key for the first argument and the element key for the second argument, -- and once, with the reverse argument order. This is not necessary for -- VECTOR-BINARY-SEARCH3. -- -- - When a comparison operation is able to produce a three-way -- discrimination, the inner loop of the binary search can trim the number -- of per-iteration comparisons from an average of 1.5 to a guaranteed -- single comparison per iteration. This can be a significant savings when -- searching with an expensive comparison operation (e.g., one that -- uses string compare, sends email, references a database, or queries -- a network service such as a web server). -- -- - Failure is signaled by false (rather than, say, -1) so that searches -- can be used in conditional forms such as -- (or (vector-binary-search ...) ...) -- or -- (cond ((vector-binary-search ...) => index-consumer) -- ...) -- --------------------------------------------------------------------------------- --* Algorithmic properties -------------------------- --Different sort and merge algorithms have different properties. --Choose the algorithm that matches your needs: -- --Vector insert sort -- Stable, but only suitable for small vectors -- O(n^2). -- --Vector quick sort -- Not stable. Is fast on average -- O(n lg n) -- but has bad worst-case -- behaviour. Has good memory locality for big vectors (unlike heap sort). -- A clever pivot-picking trick (median of three samples) helps avoid -- worst-case behaviour, but pathological cases can still blow up. -- --Vector heap sort -- Not stable. Guaranteed fast -- O(n lg n) *worst* case. Poor locality -- on large vectors. A very reliable workhorse. -- --Vector merge sort -- Stable. Not in-place -- requires a temporary buffer of equal size. -- Fast -- O(n lg n) -- and has good memory locality for large vectors. -- -- The implementation of vector merge sort provided by this SRFI's reference -- implementation is, additionally, a "natural" sort, meaning that it -- exploits existing order in the input data, providing O(n) best case. -- --Destructive list merge sort -- Stable, fast and in-place (i.e., allocates no new cons cells). "Fast" -- means O(n lg n) worse-case, and substantially better if the data -- is already mostly ordered, all the way down to linear time for -- a completely-ordered input list (i.e., it is a "natural" sort). -- -- Note that sorting lists involves chasing pointers through memory, which -- can be a loser on modern machine architectures because of poor cache & -- page locality. Pointer *writing*, which is what the SET-CDR!s of a -- destructive list-sort algorithm do, is even worse, especially if your -- Scheme has a generational GC -- the writes will thrash the write-barrier. -- Sorting vectors has inherently better locality. -- -- This SRFI's destructive list merge and merge sort implementations are -- opportunistic -- they avoid redundant SET-CDR!s, and try to take long -- already-ordered runs of list structure as-is when doing the merges. -- --Pure list merge sort -- Stable and fast -- O(n lg n) worst-case, and possibly O(n), depending -- upon the input list (see discussion above). -- -- --Algorithm Stable? Worst case Average case In-place -------------------------------------------------------- --Vector insert Yes O(n^2) O(n^2) Yes --Vector quick No O(n^2) O(n lg n) Yes --Vector heap No O(n lg n) O(n lg n) Yes --Vector merge Yes O(n lg n) O(n lg n) No --List merge Yes O(n lg n) O(n lg n) Either -- -- --------------------------------------------------------------------------------- --* Porting and optimisation ---------------------------- --This package should be trivial to port. There are only four non-R4RS bits --in the code: --- Use of multiple-value return, with the R5RS VALUES procedure, and the -- simple (RECEIVE (var ...) mv-exp body ...) multiple-value binding macro -- of SRFI-8. -- --- A VECTOR-COPY procedure. This is a tiny little procedure: -- (vector-copy v [start end]) -- --- Use of the LET-OPTIONALS macro from scsh to parse and default optional -- arguments to three routines. Again, easy to port the macro or rewrite -- the code to parse, default, and error check the args by hand. -- --- Calls to an ERROR function for complaining about bad arguments. -- --This code is tightly bummed, as far as I can go in portable Scheme. -- --You could speed up the vector code a lot by error-checking the procedure --parameters and then shifting over to fixnum-specific arithmetic and dangerous --vector-indexing and vector-setting primitives. The comments in the code --indicate where the initial error checks would have to be added. There are --several (QUOTIENT N 2)'s that could be changed to a fixnum right-shift, as --well, in both the list and vector code (SRFI 33 provides such an operator). --The code is designed to enable this -- each file usually exports one or two --"safe" procedures that end up calling an internal "dangerous" primitive. The --little exported cover procedures are where you move the error checks. -- --This should provide *big* speedups. In fact, all the code bumming I've done --pretty much disappears in the noise unless you have a good compiler and also --can dump the vector-index checks and generic arithmetic -- so I've really just --set things up for you to exploit. -- --The optional-arg parsing, defaulting, and error checking is done with a --portable R4RS macro. But if your Scheme has a faster mechanism (e.g., Chez), --you should definitely port over to it. Note that argument defaulting and --error-checking are interleaved -- you don't have to error-check defaulted --START/END args to see if they are fixnums that are legal vector indices for --the corresponding vector, etc. -- -- --------------------------------------------------------------------------------- --* References & Links ---------------------- -- --This document, in HTML: -- http://srfi.schemers.org/srfi-32/srfi-32.html -- [This link may not be valid while the SRFI is in draft form.] -- --This document, in simple text format: -- http://srfi.schemers.org/srfi-32/srfi-32.txt -- --Archive of SRFI-32 discussion-list email: -- http://srfi.schemers.org/srfi-32/mail-archive/maillist.html -- --SRFI web site: -- http://srfi.schemers.org/ -- --[CommonLisp] -- Common Lisp: the Language -- Guy L. Steele Jr. (editor). -- Digital Press, Maynard, Mass., second edition 1990. -- Available at http://www.elwood.com/alu/table/references.htm#cltl2 -- -- The Common Lisp "HyperSpec," produced by Kent Pitman, is essentially -- the ANSI spec for Common Lisp: -- http://www.xanalys.com/software_tools/reference/HyperSpec/ -- --[R5RS] -- Revised^5 Report on the Algorithmic Language Scheme, -- R. Kelsey, W. Clinger, J. Rees (editors). -- Higher-Order and Symbolic Computation, Vol. 11, No. 1, September, 1998. -- and ACM SIGPLAN Notices, Vol. 33, No. 9, October, 1998. -- -- Available at http://www.schemers.org/Documents/Standards/ -- -- --------------------------------------------------------------------------------- --* Acknowledgements -------------------- -- --I thank the authors of the open source I consulted when designing this --library, particularly Richard O'Keefe, Donovan Kolby and the MIT Scheme Team. -- -- --------------------------------------------------------------------------------- --* Copyright ------------- -- --** SRFI text --============ --This document is copyright (C) Olin Shivers (1998, 1999). --All Rights Reserved. -- --This document and translations of it may be copied and furnished to others, --and derivative works that comment on or otherwise explain it or assist in its --implementation may be prepared, copied, published and distributed, in whole or --in part, without restriction of any kind, provided that the above copyright --notice and this paragraph are included on all such copies and derivative --works. However, this document itself may not be modified in any way, such as --by removing the copyright notice or references to the Scheme Request For --Implementation process or editors, except as needed for the purpose of --developing SRFIs in which case the procedures for copyrights defined in the --SRFI process must be followed, or as required to translate it into languages --other than English. -- --The limited permissions granted above are perpetual and will not be revoked by --the authors or their successors or assigns. -- --This document and the information contained herein is provided on an "AS IS" --basis and THE AUTHORS AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR --IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE --INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF --MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -- --** Reference implementation --=========================== --Short summary: no restrictions. -- --While I wrote all of this code myself, I read a lot of code before I began --writing. However, all such code is, itself, either open source or public --domain, rendering irrelevant any issue of "copyright taint." -- --The natural merge sorts (pure list, destructive list, and vector) are not only --my own code, but are implementations of an algorithm of my own devising. They --run in O(n lg n) worst case, O(n) best case, and require only a logarithmic --number of stack frames. And they are stable. And the destructive-list variant --allocates zero cons cells; it simply rearranges the cells of the input list. -- --Hence the reference implementation is -- Copyright (c) 1998 by Olin Shivers. --and made available under the same copyright as the SRFI text (see above). -diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/srfi-32.txt racket-6.12/share/pkgs/srfi-lib/srfi/32/srfi-32.txt ---- racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/srfi-32.txt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib/srfi/32/srfi-32.txt 2018-01-31 12:22:58.152501970 -0500 -@@ -0,0 +1,938 @@ -+The SRFI-32 sort libraries -*- outline -*- -+Olin Shivers -+First draft: 1998/10/19 -+Last update: 2002/7/21 -+ -+Emacs should display this document in outline mode. Say c-h m for -+instructions on how to move through it by sections (e.g., c-c c-n, c-c c-p). -+ -+* Table of contents -+------------------- -+Abstract -+Procedure index -+Introduction -+What's wrong with the current state of affairs? -+Design rules -+ What vs. how -+ Consistency across function signatures -+ Data parameter first, less-than parameter after -+ Ordering, comparison functions & stability -+ All vector operations accept optional subrange parameters -+ Required vs. allowed side-effects -+Procedure specification -+ Procedure naming and functionality -+ Types of parameters and return values -+ sort-lib - general sorting package -+ Algorithm-specific sorting packages -+Algorithmic properties -+Topics to be resolved during discussion phase -+Porting and optimisation -+References & Links -+Acknowledgements -+Copyright -+ -+ -+* Abstract -+---------- -+Current Scheme sorting packages are, every one of them, surprisingly bad. I've -+designed the API for a full-featured sort toolkit, which I propose as an SRFI. -+The spec comes with 1200 lines of high-quality reference code: tightly -+written, highly commented, portable code, available for free. Implementors -+want this code. It's better than what you have. -+ -+------------------------------------------------------------------------------- -+* Procedure index -+----------------- -+list-sorted? vector-sorted? -+ -+list-merge vector-merge -+list-sort vector-sort -+list-stable-sort vector-stable-sort -+list-delete-neighbor-dups vector-delete-neighbor-dups -+ -+list-merge! vector-merge! -+list-sort! vector-sort! -+list-stable-sort! vector-stable-sort! -+list-delete-neighbor-dups! vector-delete-neighbor-dups! -+ -+heap-sort quick-sort insert-sort list-merge-sort vector-merge-sort -+heap-sort! quick-sort! insert-sort! list-merge-sort! vector-merge-sort! -+ -+------------------------------------------------------------------------------- -+* Introduction -+-------------- -+As I'll detail bewlow, I wasn't very happy with the state of the Scheme -+world for sorting and merging lists and vectors. So I have designed and -+written a fairly comprehensive sorting & merging toolkit. It is -+ -+ - very portable, -+ -+ - much better code than what is currently in Elk, Gambit, Bigloo, -+ Scheme->C, MzScheme, RScheme, Scheme48, MIT Scheme, or slib, and -+ -+ - priced to move: free code. -+ -+The package includes -+ - Vector insert sort (stable) -+ - Vector heap sort -+ - Vector quick sort (with median-of-3 pivot picking) -+ - Vector merge sort (stable) -+ - Pure and destructive list merge sort (stable) -+ - Stable vector and list merge -+ - Miscellaneous sort-related procedures: Vector and list merging, -+ sorted? predicates, vector binary search, vector and list -+ delete-equal-neighbor procedures. -+ - A general, non-algorithmic set of procedure names for general sorting -+ and merging. -+ -+Scheme programmers may want to adopt this package. I'd like Scheme -+implementors to adopt this code and its API -- in fact, the code is a bribe to -+make it easy for implementors to converge on the suggested API. I mean, you'd -+really have to be a boor to take this free code I wrote and mutate its -+interface over to your incompatible, unportable API, wouldn't you? But you -+could, of course -- it's freely available. More in the spirit of the offering, -+you could make this API available, and then also write a little module -+providing your old interface that is defined in terms of this API. "Scheme -+implementors," in this context, includes slib, which isn't really a standalone -+implementation of Scheme, but is an influential collection of API's and code. -+ -+The code is tightly bummed. It is clearly written, and commented in my usual -+voluminous style. This includes notes on porting and implementation-specific -+optimisations. -+ -+ -+------------------------------------------------------------------------------- -+* What's wrong with the current state of affairs? -+------------------------------------------------- -+ -+It's just amazing to me that in 2002, sorting and merging hasn't been -+completely put to bed. These are well-understood algorithms, each of them well -+under a page of code. The straightforward algorithms are basic, core stuff -- -+sophomore-level. But if you tour the major Scheme implementations out there on -+the Net, you find badly written code that provides extremely spotty coverage -+of the algorithm space. One implementation even has a buggy implementation -+that has been in use for about 20 years! -+ -+Open source-code is a wonderful thing. In a couple of hours, I was able to -+download and check the sources of 9 Scheme systems. Here are my notes from the -+systems I checked. You can skip to the next section if you aren't morbidly -+curious. -+ -+slib -+ sorted? vector-or-list < -+ merge list1 list2 < -+ merge! list1 list2 < -+ sort vector-or-list < -+ sort! vector-or-list < -+ -+ Richard O'Keefe's stable list merge sort is right idea, but implemented -+ using gratuitous variable side effects. It also does redundant SET-CDR!s. -+ The vector sort converts to list, merge sorts, then reconverts -+ to vector. This is a bad idea -- non-local pointer chasing bad; vector -+ shuffling good. -+ -+MIT Scheme -+ sort! vector < -+ merge-sort! vector < -+ quick-sort! vector < -+ -+ sort vector-or-list < -+ merge-sort vector-or-list < -+ quick-sort vector-or-list < -+ -+ Naive vector quicksort: loser, for worst-case performance reasons. -+ List sort by "list->vector; quicksort; vector->list," hence also loser. -+ A clever stable vector merge sort, albeit not very bummed. -+ -+Scheme 48 & T -+ sort-list list < -+ sort-list! list < -+ list-merge! list1 list2 < -+ -+ Bob Nix's implementation of online merge-sort, written in the early 80's. -+ Conses unnecessary bookkeeping structure, which isn't necessary with a -+ proper recursive formulation. Also, does redundant SET-CDR!s. No vector -+ sort. Also, has a bug -- is claimed to be a stable sort, but isn't! To see -+ this, get the S48 code, and try -+ (define (my< x y) (< (quotient x 2) (quotient y 2))) -+ (list-merge! (list 0 2) (list 3) my<) ; -> (0 2 3) -+ (list-merge! (list 2) (list 0 3) my<) ; -> (0 3 2) -+ This could be fixed very easily, but it isn't worth it given the -+ other problems with the algorithm. -+ -+RScheme -+ vector-sort! vector < -+ sort collection < -+ -+ Good basic implementation of vector heapsort, which has O(n lg n) -+ worst-case time. Code ugly, needs tuning. List sort by "list->vector; -+ sort; vector->list", which allocates unneeded temp storage. Nothing -+ for stable sorting. -+ -+MzScheme -+ Naive quicksort -- but not available for vector sorting, even -+ though it internally uses a vector. Nothing for stable sorting, -+ and naive quicksort has bad worst-case behaviour. -+ -+Bigloo, Scheme->C -+ Couldn't find anything -- but maybe I didn't search for the right -+ thing, since the Bigloo names are French. (I invite correction from -+ the Bigloo implementors.) -+ -+Gambit -+ sort-list list < -+ Nothing for vectors. Simple, slow, unstable merge sort for lists. -+ -+Elk -+ Another naive quicksort. Lists handled by converting to vector. -+ sort vector-or-list < -+ sort! vector-or-list < -+ -+Chez Scheme -+ merge < list1 list2 -+ merge! < list1 list2 -+ sort < list -+ sort! < list -+ -+ These are stable. I have not seen the source code. -+ -+Common Lisp -+ sort sequence < [key] -+ stable-sort sequence < [key] -+ merge result-type sequence1 sequence2 < [key] -+ -+ The sort procedures are allowed, but not required, to be destructive. -+ -+SML/NJ -+ sort: ('a*'a -> bool) -> 'a list -> 'a list -+ "Smooth applicative merge sort," which is stable. -+ There is also a highly bummed quicksort for vectors. -+ -+The right solution: Implement a full toolbox of carefully written standard sort -+routines. -+ -+Having the source available for all of these above-cited Schemes made -+life a lot easier writing this code. I appreciate the authors making their -+source available under such open terms. -+ -+ -+------------------------------------------------------------------------------- -+* Design rules -+-------------- -+ -+** What vs. how -+=============== -+There are two different interfaces: "what" (simple) & "how" (detailed). -+ -+ - Simple: you specify semantics: datatype (list or vector), -+ mutability, and stability. -+ -+ - Detailed: you specify the actual algorithm (quick, heap, -+ insert, merge). Different algorithms have different properties, -+ both semantic & pragmatic, so these exports are necessary. -+ -+ It is necessarily the case that the specifications of these procedures -+ make statements about execution "pragmatics." For example, the sole -+ distinction between heap sort and quick sort -- both of which are -+ provided by this library -- is one of execution time, which is not a -+ "semantic" distinction. Similar resource-use statements are made about -+ "iterative" procedures, meaning that they can execute on input of -+ arbitrary size without needing to allocate an unbounded number of stack -+ frames. -+ -+** Consistency across function signatures -+========================================= -+The two interfaces share common function signatures wherever -+possible, to facilitate switching a given call from one procedure -+to another. -+ -+** Data parameter first, less-than parameter after -+================================================== -+These procedures uniformly observe the following parameter order: -+the data to be sorted come before the the comparison function. -+That is, we write -+ (sort lis <) -+not -+ (sort < lis). -+This is consistent with every single implementation out there, with -+the sole exception of Chez Scheme. -+ -+In my opinion, it would be more consistent with other Scheme libraries -+to put the ordering function first -- the "operation currying" convention. -+(E.g., consider FOR-EACH or MAP or FIND.) I decided to leave things as they -+are in favor of near-total backwards compatibility with existing practice. -+ -+[Perhaps this should be discussed.] -+ -+** Ordering, comparison functions & stability -+============================================= -+These routines take a < comparison function, not a <= comparison -+function, and they sort into increasing order. The difference between -+a < spec and a <= spec comes up in two places: -+ - the definition of an ordered or sorted data set, and -+ - the definition of a stable sorting algorithm. -+ -++ We say that a data set (a list or vector) is *sorted* or *ordered* -+ if it contains no adjacent pair of values ... X Y ... such that Y < X. -+ -+ In other words, scanning across the data never takes a "downwards" step. -+ -+ If you use a <= procedure where these algorithms expect a < -+ procedure, you may not get the answers you expect. For example, -+ the LIST-SORTED? function will return false if you pass it a <= comparison -+ function and an ordered list containing adjacent equal elements. -+ -++ A "stable" sort is one that preserves the pre-existing order of equal -+ elements. Suppose, for example, that we sort a list of numbers by -+ comparing their absolute values, i.e., using comparison function -+ (lambda (x y) (< (abs x) (abs y))) -+ If we sort a list that contains both 3 and -3: -+ ... 3 ... -3 ... -+ then a stable sort is an algorithm that will not swap the order -+ of these two elements, that is, the answer will look like -+ ... 3 -3 ... -+ not -+ ... -3 3 ... -+ -+ Choosing < for the comparison function instead of <= affects how stability -+ is coded. Given an adjacent pair X Y, (< y x) means "Y should be moved in -+ front of X" -- otherwise, leave things as they are. So using a <= function -+ where a < function is expected will *invert* stability. -+ -+ This is due to the definition of equality, given a < comparator: -+ (and (not (< x y)) -+ (not (< y x))) -+ The definition is rather different, given a <= comparator: -+ (and (<= x y) -+ (<= x y)) -+ -++ A "stable" merge is one that reliably favors one of its data sets -+ when equal items appear in both data sets. *All merge operations in -+ this library are stable*, breaking ties between data sets in favor -+ of the first data set -- elements of the first list come before equal -+ elements in the second list. -+ -+ So, if we are merging two lists of numbers ordered by absolute value -+ using the stable merge operation LIST-MERGE -+ (list-merge '(0 -2 4 8 -10) '(-1 3 -4 7) -+ (lambda (x y) (< (abs x) (abs y)))) -+ reliably places the 4 of the first list before the equal-comparing -4 -+ of the second list: -+ (0 -1 -2 4 -4 7 8 -10) -+ -+In short, if your comparison function F answers true to (F x x), then -+using a stable sorting or merging algorithm will not give you a stable sort -+or merge, and LIST-SORTED? may surprise you. Note that you can synthesize a < -+function from a <= function with -+ (lambda (x y) (not (<= y x))) -+if need be. -+ -+Precise definitions give sharp edges to tools, but require care -+in use. "Measure twice, cut once." -+ -+I have adopted the choice of < from Common Lisp. I assume they -+had a good reason for adopting < instead of <=. I'd love to know -+what this reason is; send me email if you can explain it, please. -+ -+** All vector operations accept optional subrange parameters -+============================================================ -+The vector operations specified below all take optional START/END arguments -+indicating a selected subrange of a vector's elements. If a START parameter or -+START/END parameter pair is given to such a procedure, they must be exact, -+non-negative integers, such that -+ 0 <= START <= END <= (VECTOR-LENGTH V) -+where V is the related vector parameter. If not specified, they default to 0 -+and the length of the vector, respectively. They are interpreted to select the -+range [START,END), that is, all elements from index START (inclusive) up to, -+but not including, index END. -+ -+** Required vs. allowed side-effects -+==================================== -+LIST-SORT! and LIST-STABLE-SORT! are allowed, but not required, -+to alter their arguments' cons cells to construct the result list. This is -+consistent with the what-not-how character of the group of procedures -+to which they belong (the "sort-lib" package). -+ -+The LIST-DELETE-NEIGHBOR-DUPS!, LIST-MERGE! and LIST-MERGE-SORT! procedures, -+on the other hand, provide specific algorithms, and, as such, explicitly -+commit to the use of side-effects on their input lists in order to guarantee -+their key algorithmic properties (e.g., linear-time operation, constant-space -+stack use). -+ -+------------------------------------------------------------------------------- -+* Procedure specification -+------------------------- -+The procedures are split into several packages. In a Scheme system that has a -+module or package system, these procedures should be contained in modules -+named as follows: -+ Package name Functionality -+ ------------ ------------- -+ sort-lib General sorting for lists & vectors -+ sorted?-lib Sorted predicates for lists & vectors -+ list-merge-sort-lib List merge sort -+ vector-merge-sort-lib Vector merge sort -+ vector-heap-sort-lib Vector heap sort -+ vector-quick-sort-lib Vector quick sort -+ vector-insert-sort-lib Vector insertion sort -+ delndup-lib List and vector delete neighbor duplicates -+ -+A Scheme system without a module system should provide all of the bindings -+defined in all of these modules as components of the "SRFI-32" package. -+ -+Note that there is no list insert sort package, as you might as well always -+use list merge sort. The reference implementation's destructive list merge -+sort will do fewer SET-CDR!s than a destructive insert sort. -+ -+** Procedure naming and functionality -+===================================== -+Almost all of the procedures described below are variants of two basic -+operations: sorting and merging. These procedures are consistently named -+by composing a set of basic lexemes to indicate what they do. -+ -+Lexeme Meaning -+------ ------- -+"sort" The procedure sorts its input data set by some < comparison function. -+ -+"merge" The procedure merges two ordered data sets into a single ordered -+ result. -+ -+"stable" This lexeme indicates that the sort is a stable one. -+ -+"vector" The procedure operates upon vectors. -+ -+"list" The procedure operates upon lists. -+ -+"!" Procedures that end in "!" are allowed, and sometimes required, -+ to reuse their input storage to construct their answer. -+ -+** Types of parameters and return values -+======================================== -+In the procedures specified below, -+ - A LIS parameter is a list; -+ -+ - A V parameter is a vector; -+ -+ - A < or = parameter is a procedure accepting two arguments taken from the -+ specified procedure's data set(s), and returning a boolean; -+ -+ - START and END parameters are exact, non-negative integers that -+ serve as vector indices selecting a subrange of some associated vector. -+ When specified, they must satisfy the relation -+ 0 <= start <= end <= (vector-length v) -+ where V is the associated vector. -+ -+Passing values to procedures with these parameters that do not satisfy these -+types is an error. -+ -+If a procedure is said to return "unspecified," this means that nothing at all -+is said about what the procedure returns, not even the number of return -+values. Such a procedure is not even required to be consistent from call to -+call in the nature or number of its return values. It is simply required to -+return a value (or values) that may be passed to a command continuation, e.g. -+as the value of an expression appearing as a non-terminal subform of a BEGIN -+expression. Note that in R5RS, this restricts such a procedure to returning a -+single value; non-R5RS systems may not even provide this restriction. -+ -+** sort-lib - general sorting package -+===================================== -+This library provides basic sorting and merging functionality suitable for -+general programming. The procedures are named by their semantic properties, -+i.e., what they do to the data (sort, stable sort, merge, and so forth). -+ -+ Procedure Suggested algorithm -+ ------------------------------------------------------------------------- -+ list-sorted? lis < -> boolean -+ list-merge lis1 lis2 < -> list -+ list-merge! lis1 lis2 < -> list -+ list-sort lis < -> list (vector heap or quick) -+ list-sort! lis < -> list (list merge sort) -+ list-stable-sort lis < -> list (vector merge sort) -+ list-stable-sort! lis < -> list (list merge sort) -+ list-delete-neighbor-dups lis = -> list -+ list-delete-neighbor-dups! lis = -> list -+ -+ vector-sorted? v < [start end] -> boolean -+ vector-merge v1 v2 < [start1 end1 start2 end2] -> vector -+ vector-merge! v v1 v2 < [start start1 end1 start2 end2] -> unspecific -+ vector-sort v < [start end] -> vector (heap or quick sort) -+ vector-sort! v < [start end] -> unspecific (heap or quick sort) -+ vector-stable-sort v < [start end] -> vector (vector merge sort) -+ vector-stable-sort! v < [start end] -> unspecific (vector merge sort) -+ vector-delete-neighbor-dups v = [start end] -> vector -+ vector-delete-neighbor-dups! v = [start end] -> end' -+ -+ LIST-SORTED? and VECTOR-SORTED? return true if their input list or vector -+ is in sorted order, as determined by their < comparison parameter. -+ -+ All four merge operations are stable: an element of the initial list LIS1 -+ or vector V1 will come before an equal-comparing element in the second -+ list LIS2 or vector V2 in the result. -+ -+ The procedures -+ LIST-MERGE -+ LIST-SORT -+ LIST-STABLE-SORT -+ LIST-DELETE-NEIGHBOR-DUPS -+ do not alter their inputs and are allowed to return a value that shares -+ a common tail with a list argument. -+ -+ The procedures -+ LIST-SORT! -+ LIST-STABLE-SORT! -+ are "linear update" operators -- they are allowed, but not required, to -+ alter the cons cells of their arguments to produce their results. -+ -+ On the other hand, the procedures -+ LIST-DELETE-NEIGHBOR-DUPS! -+ LIST-MERGE! -+ make only a single, iterative, linear-time pass over their argument lists, -+ using SET-CDR!s to rearrange the cells of the lists into the final result -+ -- they work "in place." Hence, any cons cell appearing in the result must -+ have originally appeared in an input. The intent of this -+ iterative-algorithm commitment is to allow the programmer to be sure that -+ if, for example, LIST-MERGE! is asked to merge two ten-million-element -+ lists, the operation will complete without performing some extremely -+ (possibly twenty-million) deep recursion. -+ -+ The vector procedures -+ VECTOR-SORT -+ VECTOR-STABLE-SORT -+ VECTOR-DELETE-NEIGHBOR-DUPS -+ do not alter their inputs, but allocate a fresh vector for their result, -+ of length END-START. -+ -+ The vector procedures -+ VECTOR-SORT! -+ VECTOR-STABLE-SORT! -+ sort their data in-place. (But note that VECTOR-STABLE-SORT! may -+ allocate temporary storage proportional to the size of the input -- -+ I am not aware of O(n lg n) stable vector sorting algorithms that -+ run in constant space.) -+ -+ VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). -+ -+ VECTOR-MERGE! writes its result into vector V, beginning at index START0, -+ for indices less than END0 = START0 + (END1-START1) + (END2-START2). The -+ target subvector -+ V[start0,end0) -+ may not overlap either source subvector -+ V1[start1,end1) -+ V2[start2,end2). -+ -+ The DELETE-NEIGHBOR-DUP-... procedures: -+ These procedures delete adjacent duplicate elements from a list or a -+ vector, using a given element-equality procedure. The first/leftmost -+ element of a run of equal elements is the one that survives. The list or -+ vector is not otherwise disordered. -+ -+ These procedures are linear time -- much faster than the O(n^2) general -+ duplicate-element deletors that do not assume any "bunching" of elements -+ (such as the ones provided by SRFI-1). If you want to delete duplicate -+ elements from a large list or vector, sort the elements to bring equal -+ items together, then use one of these procedures, for a total time of -+ O(n lg n). -+ -+ The comparison function = passed to these procedures is always applied -+ (= x y) -+ where X comes before Y in the containing list or vector. -+ -+ - LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer -+ may share storage with the input list. -+ -+ - VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but -+ rather allocates a fresh vector to hold the result. -+ -+ - LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to -+ mutate its input list in order to construct its answer. -+ -+ - VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the -+ answer, packing its answer into the index range [start,end'), where -+ END' is the non-negative exact integer returned as its value. It -+ returns END' as its result. The vector is not altered outside the range -+ [start,end'). -+ -+ [Maybe this procedure should take a "target" vector to write?] -+ -+ - Examples: -+ (list-delete-neighbor-dups '(1 1 2 7 7 7 0 -2 -2) =) -+ => (1 2 7 0 -2) -+ -+ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) =) -+ => #(1 2 7 0 -2) -+ -+ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) = 3 7) -+ => #(7 0 -2) -+ -+ ;; Result left in v[3,9): -+ (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) -+ (cons (vector-delete-neighbor-dups! v = 3) -+ v)) -+ => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) -+ -+ -+** Algorithm-specific sorting packages -+====================================== -+These packages provide more specific sorting functionality, that is, -+specific committment to particular algorithms that have particular -+pragmatic consequences (such as memory locality, asymptotic running time) -+beyond their semantic behaviour (sorting, stable sorting, merging, etc.). -+Programmers that need a particular algorithm can use one of these packages. -+ -+sorted?-lib - sorted predicates -+ list-sorted? lis < -> boolean -+ vector-sorted? v < [start end] -> boolean -+ -+ Return #f iff there is an adjacent pair ... X Y ... in the input -+ list or vector such that Y < X. The optional START/END range -+ arguments restrict VECTOR-SORTED? to the indicated subvector. -+ -+list-merge-sort-lib - list merge sort -+ list-merge-sort lis < -> list -+ list-merge-sort! lis < -> list -+ list-merge lis1 lis2 < -> list -+ list-merge! lis1 lis2 < -> list -+ -+ The sort procedures sort their data using a list merge sort, which is -+ stable. (The reference implementation is, additionally, a "natural" sort. -+ See below for the properties of this algorithm.) -+ -+ The ! procedures are destructive -- they use SET-CDR!s to rearrange the -+ cells of the lists into the proper order. As such, they do not allocate -+ any extra cons cells -- they are "in place" sorts. Additionally, -+ LIST-MERGE! is iterative, not recursive -- it can operate on arguments of -+ arbitrary size without requiring an unbounded amount of stack space. -+ -+ The merge operations are stable: an element of LIS1 will come before an -+ equal-comparing element in LIS2 in the result list. -+ -+vector-merge-sort-lib - vector merge sort -+ vector-merge-sort v < [start end temp] -> vector -+ vector-merge-sort! v < [start end temp] -> unspecific -+ vector-merge v1 v2 < [start1 end1 start2 end2] -> vector -+ vector-merge! v v1 v2 < [start0 start1 end1 start2 end2] -> unspecific -+ -+ The sort procedures sort their data using vector merge sort, which is -+ stable. (The reference implementation is, additionally, a "natural" sort. -+ See below for the properties of this algorithm.) -+ -+ The optional START/END arguments provide for sorting of subranges, and -+ default to 0 and the length of the corresponding vector. -+ -+ Merge-sorting a vector requires the allocation of a temporary "scratch" -+ work vector for the duration of the sort. This scratch vector can be -+ passed in by the client as the optional TEMP argument; if so, the supplied -+ vector must be of size >= END, and will not be altered outside the range -+ [start,end). If not supplied, the sort routines allocate one themselves. -+ -+ The merge operations are stable: an element of V1 will come before an -+ equal-comparing element in V2 in the result vector. -+ -+ VECTOR-MERGE-SORT! leaves its result in V[start,end). -+ -+ VECTOR-MERGE-SORT returns a vector of length END-START. -+ -+ VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). -+ -+ VECTOR-MERGE! writes its result into vector V, beginning at index START0, -+ for indices less than END0 = START0 + (END1-START1) + (END2-START2). The -+ target subvector -+ V[start0,end0) -+ may not overlap either source subvector -+ V1[start1,end1) -+ V2[start2,end2). -+ -+vector-heap-sort-lib - vector heap sort -+ heap-sort v < [start end] -> vector -+ heap-sort! v < [start end] -> unspecific -+ -+ These procedures sort their data using heap sort, -+ which is not a stable sorting algorithm. -+ -+ HEAP-SORT returns a vector of length END-START. -+ HEAP-SORT! is in-place, leaving its result in V[start,end). -+ -+vector-quick-sort-lib - vector quick sort -+ quick-sort v < [start end] -> vector -+ quick-sort! v < [start end] -> unspecific -+ -+ These procedures sort their data using quick sort, -+ which is not a stable sorting algorithm. -+ -+ QUICK-SORT returns a vector of length END-START. -+ QUICK-SORT! is in-place, leaving its result in V[start,end). -+ -+vector-insert-sort-lib - vector insertion sort -+ insert-sort v < [start end] -> vector -+ insert-sort! v < [start end] -> unspecific -+ -+ These procedures stably sort their data using insertion sort. -+ -+ INSERT-SORT returns a vector of length END-START. -+ INSERT-SORT! is in-place, leaving its result in V[start,end). -+ -+delndup-lib - list and vector delete neighbor duplicates -+ list-delete-neighbor-dups lis = -> list -+ list-delete-neighbor-dups! lis = -> list -+ -+ vector-delete-neighbor-dups v = [start end] -> vector -+ vector-delete-neighbor-dups! v = [start end] -> end' -+ -+ These procedures delete adjacent duplicate elements from a list or -+ a vector, using a given element-equality procedure =. The first/leftmost -+ element of a run of equal elements is the one that survives. The list -+ or vector is not otherwise disordered. -+ -+ These procedures are linear time -- much faster than the O(n^2) general -+ duplicate-element deletors that do not assume any "bunching" of elements -+ (such as the ones provided by SRFI-1). If you want to delete duplicate -+ elements from a large list or vector, sort the elements to bring equal -+ items together, then use one of these procedures, for a total time of -+ O(n lg n). -+ -+ The comparison function = passed to these procedures is always applied -+ (= x y) -+ where X comes before Y in the containing list or vector. -+ -+ LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer -+ may share storage with the input list. -+ -+ VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but -+ rather allocates a fresh vector to hold the result. -+ -+ LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to -+ mutate its input list in order to construct its answer. -+ -+ VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the -+ answer, packing its answer into the index range [start,end'), where -+ END' is the non-negative exact integer returned as its value. It -+ returns END' as its result. The vector is not altered outside the range -+ [start,end'). -+ -+ Examples: -+ (list-delete-neighbor-dups '(1 1 2 7 7 7 0 -2 -2) =) -+ => (1 2 7 0 -2) -+ -+ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) =) -+ => #(1 2 7 0 -2) -+ -+ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) = 3 7) -+ => #(7 0 -2) -+ -+ ;; Result left in v[3,9): -+ (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) -+ (cons (vector-delete-neighbor-dups! v = 3) -+ v)) -+ => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) -+ -+ -+------------------------------------------------------------------------------- -+* Algorithmic properties -+------------------------ -+Different sort and merge algorithms have different properties. -+Choose the algorithm that matches your needs: -+ -+Vector insert sort -+ Stable, but only suitable for small vectors -- O(n^2). -+ -+Vector quick sort -+ Not stable. Is fast on average -- O(n lg n) -- but has bad worst-case -+ behaviour. Has good memory locality for big vectors (unlike heap sort). -+ A clever pivot-picking trick (median of three samples) helps avoid -+ worst-case behaviour, but pathological cases can still blow up. -+ -+Vector heap sort -+ Not stable. Guaranteed fast -- O(n lg n) *worst* case. Poor locality -+ on large vectors. A very reliable workhorse. -+ -+Vector merge sort -+ Stable. Not in-place -- requires a temporary buffer of equal size. -+ Fast -- O(n lg n) -- and has good memory locality for large vectors. -+ -+ The implementation of vector merge sort provided by this SRFI's reference -+ implementation is, additionally, a "natural" sort, meaning that it -+ exploits existing order in the input data, providing O(n) best case. -+ -+Destructive list merge sort -+ Stable, fast and in-place (i.e., allocates no new cons cells). "Fast" -+ means O(n lg n) worse-case, and substantially better if the data -+ is already mostly ordered, all the way down to linear time for -+ a completely-ordered input list (i.e., it is a "natural" sort). -+ -+ Note that sorting lists involves chasing pointers through memory, which -+ can be a loser on modern machine architectures because of poor cache & -+ page locality. Pointer *writing*, which is what the SET-CDR!s of a -+ destructive list-sort algorithm do, is even worse, especially if your -+ Scheme has a generational GC -- the writes will thrash the write-barrier. -+ Sorting vectors has inherently better locality. -+ -+ This SRFIs destructive list merge and merge sort implementations are -+ opportunistic -- they avoid redundant SET-CDR!s, and try to take long -+ already-ordered runs of list structure as-is when doing the merges. -+ -+Pure list merge sort -+ Stable and fast -- O(n lg n) worst-case, and possibly better, depending -+ upon the input list (see above). -+ -+ -+Algorithm Stable? Worst case Average case In-place -+------------------------------------------------------ -+V insert Yes O(n^2) O(n^2) Yes -+V quick No O(n^2) O(n lg n) Yes -+V heap No O(n lg n) O(n lg n) Yes -+V merge Yes O(n lg n) O(n lg n) No -+L merge Yes O(n lg n) O(n lg n) Either -+ -+ -+------------------------------------------------------------------------------- -+* Topics to be resolved during discussion phase -+----------------------------------------------- -+I particularly solicit comments about the following topics. -+ -+- Include VECTOR-BINARY-SEARCH ? -+ Should we include -+ (VECTOR-BINARY-SEARCH v key< elt->key key [start end]) -+ in the SRFI? It sort of goes with sorting; it's exactly ten lines of code. -+ -+- Comparison function before or after the list/vector argument? -+ Should it be -+ (list-sort < lis) -+ or -+ (list-sort lis <) -+ There is overwhelming consistency among the implementations: data first, -+ < after. Only Chez does it differently. -+ -+ I have done it in the backwards-compatible way. But I prefer the < first, -+ data after way. -+ -+ -+------------------------------------------------------------------------------- -+* Porting and optimisation -+-------------------------- -+This package should be trivial to port. There are only four non-R4RS bits -+in the code: -+- Use of multiple-value return, with the R5RS VALUES procedure, and the -+ simple (RECEIVE (var ...) mv-exp body ...) multiple-value binding macro. -+ -+- A VECTOR-COPY procedure. This is a tiny little procedure: -+ (vector-copy v [start end]) -+ -+- Use of the LET-OPTIONALS macro from scsh to parse and default optional -+ arguments to three routines. Again, easy to port the macro or rewrite -+ the code to parse, default, and error check the args by hand. -+ -+- Calls to an ERROR function for complaining about bad arguments. -+ -+This code is tightly bummed, as far as I can go in portable Scheme. -+ -+You could speed up the vector code a lot by error-checking the procedure -+parameters and then shifting over to fixnum-specific arithmetic and -+dangerous vector-indexing and vector-setting primitives. The comments -+in the code indicate where the initial error checks would have to be -+added. There are several (QUOTIENT N 2)'s that could be changed to a -+fixnum right-shift, as well, in both the list and vector code. The code -+is designed to enable this -- each file usually exports one or two "safe" -+procedures that end up calling an internal "dangerous" primitive. The -+little exported cover procedures are where you move the error checks. -+ -+This should provide *big* speedups. In fact, all the code bumming I've done -+pretty much disappears in the noise unless you have a good compiler and also -+can dump the vector-index checks and generic arithmetic -- so I've really just -+set things up for you to exploit. -+ -+The optional-arg parsing, defaulting, and error checking is done with a -+portable R4RS macro. But if your Scheme has a faster mechanism (e.g., Chez), -+you should definitely port over to it. Note that argument defaulting and -+error-checking are interleaved -- you don't have to error-check defaulted -+START/END args to see if they are fixnums that are legal vector indices for -+the corresponding vector, etc. -+ -+ -+------------------------------------------------------------------------------- -+* References & Links -+-------------------- -+ -+This document, in HTML: -+ http://srfi.schemers.org/srfi-32/srfi-32.html -+ [This link may not be valid while the SRFI is in draft form.] -+ -+This document, in simple text format: -+ http://srfi.schemers.org/srfi-32/srfi-32.txt -+ -+Archive of SRFI-32 discussion-list email: -+ http://srfi.schemers.org/srfi-32/mail-archive/maillist.html -+ -+SRFI web site: -+ http://srfi.schemers.org/ -+ -+[CommonLisp] -+ Common Lisp: the Language -+ Guy L. Steele Jr. (editor). -+ Digital Press, Maynard, Mass., second edition 1990. -+ Available at http://www.elwood.com/alu/table/references.htm#cltl2 -+ -+ The Common Lisp "HyperSpec," produced by Kent Pitman, is essentially -+ the ANSI spec for Common Lisp: -+ http://www.xanalys.com/software_tools/reference/HyperSpec/ -+ -+[R5RS] -+ Revised^5 Report on the Algorithmic Language Scheme, -+ R. Kelsey, W. Clinger, J. Rees (editors). -+ Higher-Order and Symbolic Computation, Vol. 11, No. 1, September, 1998. -+ and ACM SIGPLAN Notices, Vol. 33, No. 9, October, 1998. -+ -+ Available at http://www.schemers.org/Documents/Standards/ -+ -+ -+------------------------------------------------------------------------------- -+* Acknowledgements -+------------------ -+ -+I thank the authors of the open source I consulted when designing this -+library, particularly Richard O'Keefe, Donovan Kolby and the MIT Scheme Team. -+ -+ -+------------------------------------------------------------------------------- -+* Copyright -+----------- -+ -+** SRFI text -+============ -+This document is copyright (C) Olin Shivers (1998, 1999). -+All Rights Reserved. -+ -+Permission is hereby granted, free of charge, to any person obtaining -+a copy of this software and associated documentation files (the -+"Software"), to deal in the Software without restriction, including -+without limitation the rights to use, copy, modify, merge, publish, -+distribute, sublicense, and/or sell copies of the Software, and to -+permit persons to whom the Software is furnished to do so, subject to -+the following conditions: -+ -+The above copyright notice and this permission notice shall be -+included in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+** Reference implementation -+=========================== -+Short summary: no restrictions. -+ -+While I wrote all of this code myself, I read a lot of code before I began -+writing. However, all such code is, itself, either open source or public -+domain, rendering irrelevant any issue of "copyright taint." -+ -+The natural merge sorts (pure list, destructive list, and vector) are not only -+my own code, but are implementations of an algorithm of my own devising. They -+run in O(n lg n) worst case, O(n) best case, and require only a logarithmic -+number of stack frames. And they are stable. And the destructive-list variant -+allocates zero cons cells; it simply rearranges the cells of the input list. -+ -+Hence the reference implementation is -+ Copyright (c) 1998 by Olin Shivers. -+and made available under the same copyright as the SRFI text (see above). -diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5/let.rkt racket-6.12/share/pkgs/srfi-lib/srfi/%3a5/let.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5/let.rkt 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib/srfi/%3a5/let.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1 +0,0 @@ --#lang s-exp srfi/provider srfi/%3a5 -diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5.rkt racket-6.12/share/pkgs/srfi-lib/srfi/%3a5.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5.rkt 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib/srfi/%3a5.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,3 +0,0 @@ --#lang s-exp srfi/provider srfi/5 -- --;; FIXME: "rest arguments" need to generate mutable lists -diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/5/let.rkt racket-6.12/share/pkgs/srfi-lib/srfi/5/let.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib/srfi/5/let.rkt 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib/srfi/5/let.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,86 +0,0 @@ --;;; --;;; <let.rkt> ---- SRFI 5 A compatible let form with signatures and rest arguments --;;; Time-stamp: <03/04/08 09:56:06 solsona> --;;; --;;; Usually, I would add a copyright notice, and the announce that --;;; this code is under the LGPL licence. Nevertheless, I only did the --;;; port to PLT Scheme v200, and here is the copyright notice, --;;; comments, and licence from the original source: --;;; --;;; Copyright (C) Andy Gaynor (1999-2003) --;;; --;;; The version of my-let here was cleaned up by: Paul Schlie schlie@attbi.com. --;;; Renamed to s:let by Eli Barzilay -- --#lang scheme/base --(provide s:let) -- --(define-syntax s:let -- (syntax-rules () -- ;; standard -- ((s:let () body ...) -- (let () body ...)) -- ((s:let ((var val) ...) body ...) -- (let ((var val) ...) body ...)) -- -- ;; rest style -- ((s:let ((var val) . bindings) body ...) -- (let-loop #f bindings (var) (val) (body ...))) -- -- ;; signature style -- ((s:let (name bindings ...) body ...) -- (let-loop name (bindings ...) () () (body ...))) -- -- ;; standard named style -- ((s:let name (bindings ...) body ...) -- (let-loop name (bindings ...) () () (body ...))) -- -- )) -- --;; A loop to walk down the list of bindings. -- --(define-syntax let-loop -- (syntax-rules () -- -- ;; No more bindings - make a LETREC. -- ((let-loop name () (vars ...) (vals ...) body) -- ((letrec ((name (lambda (vars ...) . body))) -- name) -- vals ...)) -- -- ;; Rest binding, no name -- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) -- (let ((var val) ... (rest-var (list rest-val ...))) . body)) -- -- ;; Process a (var val) pair. -- ((let-loop name ((var val) more ...) (vars ...) (vals ...) body) -- (let-loop name (more ...) (vars ... var) (vals ... val) body)) -- -- ;; End with a rest variable - make a LETREC. -- ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body) -- ((letrec ((name (lambda (vars ... . rest-var) . body))) -- name) -- vals ... rest-vals ...)))) -- --;; Four loops - normal and `signature-style', each with and without a rest --;; binding. --;; --;;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) --;; (if (= i n) --;; f0 --;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) --;; --;;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) --;; (if (= i n) --;; f0 --;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) --;; --;;(let fibonacci ((n 10) (i 0) . (f 0 1)) --;; (if (= i n) --;; (car f) --;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) --;; --;;(let (fibonacci (n 10) (i 0) . (f 0 1)) --;; (if (= i n) --;; (car f) --;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) -diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/5.rkt racket-6.12/share/pkgs/srfi-lib/srfi/5.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib/srfi/5.rkt 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib/srfi/5.rkt 1969-12-31 19:00:00.000000000 -0500 -@@ -1,2 +0,0 @@ --;; module loader for SRFI-5 --#lang s-exp srfi/provider srfi/5/let #:unprefix s: -diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/info.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt 2018-01-31 12:22:58.159501944 -0500 -@@ -0,0 +1,14 @@ -+#lang info -+ -+(define collection 'multi) -+ -+(define deps '("scheme-lib" -+ "base" -+ "r6rs-lib" -+ "srfi-lib" -+ "compatibility-lib")) -+ -+ -+(define pkg-desc "implementation (no documentation) part of "srfi nonfree"") -+ -+(define pkg-authors '(mflatt noel chongkai jay)) -diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 2018-01-31 12:22:58.159501944 -0500 -@@ -0,0 +1 @@ -+#lang s-exp srfi/provider srfi/%3a5 -diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 2018-01-31 12:22:58.159501944 -0500 -@@ -0,0 +1,3 @@ -+#lang s-exp srfi/provider srfi/5 -+ -+;; FIXME: "rest arguments" need to generate mutable lists -diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 2018-01-31 12:22:58.159501944 -0500 -@@ -0,0 +1,86 @@ -+;;; -+;;; <let.rkt> ---- SRFI 5 A compatible let form with signatures and rest arguments -+;;; Time-stamp: <03/04/08 09:56:06 solsona> -+;;; -+;;; Usually, I would add a copyright notice, and the announce that -+;;; this code is under the LGPL licence. Nevertheless, I only did the -+;;; port to PLT Scheme v200, and here is the copyright notice, -+;;; comments, and licence from the original source: -+;;; -+;;; Copyright (C) Andy Gaynor (1999-2003) -+;;; -+;;; The version of my-let here was cleaned up by: Paul Schlie schlie@attbi.com. -+;;; Renamed to s:let by Eli Barzilay -+ -+#lang scheme/base -+(provide s:let) -+ -+(define-syntax s:let -+ (syntax-rules () -+ ;; standard -+ ((s:let () body ...) -+ (let () body ...)) -+ ((s:let ((var val) ...) body ...) -+ (let ((var val) ...) body ...)) -+ -+ ;; rest style -+ ((s:let ((var val) . bindings) body ...) -+ (let-loop #f bindings (var) (val) (body ...))) -+ -+ ;; signature style -+ ((s:let (name bindings ...) body ...) -+ (let-loop name (bindings ...) () () (body ...))) -+ -+ ;; standard named style -+ ((s:let name (bindings ...) body ...) -+ (let-loop name (bindings ...) () () (body ...))) -+ -+ )) -+ -+;; A loop to walk down the list of bindings. -+ -+(define-syntax let-loop -+ (syntax-rules () -+ -+ ;; No more bindings - make a LETREC. -+ ((let-loop name () (vars ...) (vals ...) body) -+ ((letrec ((name (lambda (vars ...) . body))) -+ name) -+ vals ...)) -+ -+ ;; Rest binding, no name -+ ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) -+ (let ((var val) ... (rest-var (list rest-val ...))) . body)) -+ -+ ;; Process a (var val) pair. -+ ((let-loop name ((var val) more ...) (vars ...) (vals ...) body) -+ (let-loop name (more ...) (vars ... var) (vals ... val) body)) -+ -+ ;; End with a rest variable - make a LETREC. -+ ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body) -+ ((letrec ((name (lambda (vars ... . rest-var) . body))) -+ name) -+ vals ... rest-vals ...)))) -+ -+;; Four loops - normal and `signature-style', each with and without a rest -+;; binding. -+;; -+;;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) -+;; (if (= i n) -+;; f0 -+;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) -+;; -+;;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) -+;; (if (= i n) -+;; f0 -+;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) -+;; -+;;(let fibonacci ((n 10) (i 0) . (f 0 1)) -+;; (if (= i n) -+;; (car f) -+;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) -+;; -+;;(let (fibonacci (n 10) (i 0) . (f 0 1)) -+;; (if (= i n) -+;; (car f) -+;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) -diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt ---- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 1969-12-31 19:00:00.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 2018-01-31 12:22:58.159501944 -0500 -@@ -0,0 +1,2 @@ -+;; module loader for SRFI-5 -+#lang s-exp srfi/provider srfi/5/let #:unprefix s: -diff -urN racket-6.12-orig/share/pkgs/srfi-lite-lib/info.rkt racket-6.12/share/pkgs/srfi-lite-lib/info.rkt ---- racket-6.12-orig/share/pkgs/srfi-lite-lib/info.rkt 2018-01-26 16:10:04.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lite-lib/info.rkt 2018-01-31 12:22:58.160501940 -0500 -@@ -1 +1,9 @@ --(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define deps (quote ("base"))) (define pkg-desc "implementation of the most widely used "srfi" libraries") (define pkg-authors (quote (mflatt))))) -+#lang info -+ -+(define collection 'multi) -+ -+(define deps '("base")) -+ -+(define pkg-desc "implementation of the most widely used "srfi" libraries") -+ -+(define pkg-authors '(mflatt)) -Binary files racket-6.12-orig/share/pkgs/srfi-lite-lib/.info.rkt.swp and racket-6.12/share/pkgs/srfi-lite-lib/.info.rkt.swp differ -diff -urN racket-6.12-orig/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt racket-6.12/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt ---- racket-6.12-orig/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt 2018-01-26 15:34:52.000000000 -0500 -+++ racket-6.12/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt 2018-01-31 12:22:58.162501933 -0500 -@@ -2,6 +2,7 @@ - - (require racket/contract/base - racket/file -+ racket/list - (only-in racket/runtime-path define-runtime-path) - racket/string racket/format - syntax/modread -@@ -113,10 +114,6 @@ - (lambda () - (with-input-from-file path read)))) - #t)))) -- (define (rdc ls) -- (if (null? (cdr ls)) -- '() -- (cons (car ls) (rdc (cdr ls))))) - - ;;Retrieve a localized template given its package name and a template name - (define (localized-template package-name template-name) -@@ -127,5 +124,5 @@ - (let ((bundle (hash-ref *localization-bundles* specifier #f))) - (cond ((and bundle (assq template-name bundle)) => cdr) - ((null? (cdr specifier)) #f) -- (else (loop (rdc specifier)))))))) -+ (else (loop (drop-right specifier 1)))))))) - ) diff --git a/racket-7.0-fix-doc-open-url.patch b/racket-7.0-fix-doc-open-url.patch new file mode 100644 index 0000000..7c497f5 --- /dev/null +++ b/racket-7.0-fix-doc-open-url.patch @@ -0,0 +1,69 @@ +diff -urN racket-6.12-wbsvr/share/pkgs/scribble-lib/help/search.rkt racket-6.12/share/pkgs/scribble-lib/help/search.rkt +--- racket-6.12-wbsvr/share/pkgs/scribble-lib/help/search.rkt 2018-03-19 17:14:56.017273013 -0400 ++++ racket-6.12/share/pkgs/scribble-lib/help/search.rkt 2018-03-19 17:15:37.839113929 -0400 +@@ -17,33 +17,38 @@ + #:notify [notify void]) + (define open-url (get-doc-open-url)) + (cond +- [open-url +- (define dest-url (let ([u (string->url open-url)]) +- (combine-url/relative +- u +- (string-join +- (for/list ([s (explode-path sub)]) +- (if (path? s) +- (path-element->string s) +- (format "~a" s))) +- "/")))) +- (notify (url->string dest-url)) +- (send-url (url->string +- (struct-copy url dest-url +- [fragment (or fragment +- (url-fragment dest-url))] +- [query (append +- (url-query dest-url) +- (if query +- (url-query +- (string->url +- (format "q?~a" query))) +- null))])))] +- [else +- (let* ([path (build-path (find-user-doc-dir) sub)] +- [path (if (file-exists? path) path (build-path (find-doc-dir) sub))]) +- (notify path) +- (send-url/file path #:fragment fragment #:query query))])) ++ [open-url ++ (define dest-url (let ([u (string->url open-url)]) ++ (combine-url/relative ++ u ++ (string-join ++ (for/list ([s (explode-path sub)]) ++ (if (path? s) ++ (path-element->string s) ++ (format "~a" s))) ++ "/")))) ++ (notify (url->string dest-url)) ++ (send-url (url->string ++ (struct-copy url dest-url ++ [fragment (or fragment ++ (url-fragment dest-url))] ++ [query (append ++ (url-query dest-url) ++ (if query ++ (url-query ++ (string->url ++ (format "q?~a" query))) ++ null))])))] ++ [else ++ (let* ([path (build-path (find-user-doc-dir) sub)] ++ [path (if (file-exists? path) path (build-path (find-doc-dir) sub))]) ++ (notify path) ++ (if (file-exists? path) ++ (send-url/file path #:fragment fragment #:query query) ++ (let ([part (lambda (pfx x) (if x (string-append pfx x) ""))]) ++ (send-url (string-append ++ "https://docs.racket-lang.org/" ++ sub (part "#" fragment) (part "?" query))))))])) + + ;; This is an example of changing this code to use the online manuals. + ;; Normally, it's better to set `doc-open-url` in "etc/config.rktd", diff --git a/racket-7.0-remove-nonfree.patch b/racket-7.0-remove-nonfree.patch new file mode 100644 index 0000000..778001a --- /dev/null +++ b/racket-7.0-remove-nonfree.patch @@ -0,0 +1,1074 @@ +diff -urN racket-7.0.orig/share/links.rktd racket-7.0/share/links.rktd +--- racket-7.0.orig/share/links.rktd 2018-08-03 15:23:48.604561727 -0400 ++++ racket-7.0/share/links.rktd 2018-08-03 15:23:45.481540939 -0400 +@@ -175,9 +175,7 @@ + ("sasl" "pkgs/sasl-doc") + (root "pkgs/slideshow-exe") + (root "pkgs/slideshow-plugin") +- (root "pkgs/srfi-lib-nonfree") + (root "pkgs/srfi-doc") +- (root "pkgs/srfi-doc-nonfree") + (root "pkgs/syntax-color-doc") + (root "pkgs/web-server-lib") + (root "pkgs/unix-socket-lib") +diff -urN racket-7.0.orig/share/pkgs/srfi/info.rkt racket-7.0/share/pkgs/srfi/info.rkt +--- racket-7.0.orig/share/pkgs/srfi/info.rkt 2018-08-03 15:23:48.891563638 -0400 ++++ racket-7.0/share/pkgs/srfi/info.rkt 2018-08-03 15:23:45.424540559 -0400 +@@ -1 +1 @@ +-(module info setup/infotab (#%module-begin (define package-content-state (quote (built "7.0"))) (define collection (quote multi)) (define deps (quote ("srfi-lib" "srfi-lib-nonfree" "srfi-doc" "srfi-doc-nonfree"))) (define implies (quote ("srfi-lib" "srfi-lib-nonfree" "srfi-doc" "srfi-doc-nonfree"))) (define pkg-desc "Legacy SRFI (Scheme) libraries") (define pkg-authors (quote (mflatt noel chongkai jay))))) ++(module info setup/infotab (#%module-begin (define package-content-state (quote (built "7.0"))) (define collection (quote multi)) (define deps (quote ("srfi-lib" "srfi-doc"))) (define implies (quote ("srfi-lib" "srfi-doc"))) (define pkg-desc "Legacy SRFI (Scheme) libraries") (define pkg-authors (quote (mflatt noel chongkai jay))))) +diff -urN racket-7.0.orig/share/pkgs/srfi-doc-nonfree/info.rkt racket-7.0/share/pkgs/srfi-doc-nonfree/info.rkt +--- racket-7.0.orig/share/pkgs/srfi-doc-nonfree/info.rkt 2018-08-03 15:23:48.895563664 -0400 ++++ racket-7.0/share/pkgs/srfi-doc-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1 +0,0 @@ +-(module info setup/infotab (#%module-begin (define package-content-state (quote (built "7.0"))) (define collection (quote multi)) (define build-deps (quote ("mzscheme-doc" "scheme-lib" "base" "scribble-lib" "srfi-doc" "srfi-lib-nonfree" "racket-doc" "r5rs-doc" "r6rs-doc" "compatibility-lib"))) (define update-implies (quote ("srfi-lib-nonfree"))) (define pkg-desc "documentation part of "srfi nonfree"") (define pkg-authors (quote (mflatt noel chongkai jay))))) +diff -urN racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt +--- racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 2018-08-03 15:23:48.895563664 -0400 ++++ racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,3 +0,0 @@ +-#lang info +- +-(define scribblings '(("srfi-nf.scrbl" (multi-page) (library 100)))) +diff -urN racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl +--- racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 2018-08-03 15:23:48.895563664 -0400 ++++ racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 1969-12-31 19:00:00.000000000 -0500 +@@ -1,66 +0,0 @@ +-#lang scribble/doc +-@(require srfi/scribblings/util +- scribble/manual +- scribble/eval +- scriblib/render-cond +- scribble/core +- scribble/html-properties +- (for-syntax scheme/base) +- (for-label scheme/base +- racket/stream)) +- +-@; ---------------------------------------------------------------------- +- +-@title{SRFI Nonfree Libraries and Documentation} +- +-The @link[#:style srfi-std "http://srfi.schemers.org/%22%5D%7BScheme Requests for +-Implementation} (a.k.a. @deftech{SRFI}) process allows individual +-members of the Scheme community to propose libraries and extensions to +-be supported by multiple Scheme implementations. +- +-Racket is distributed with implementations of many SRFIs, most of +-which can be implemented as libraries. To import the bindings of SRFI +-@math{n}, use +- +-@racketblock[ +-(require @#,elem{@racketidfont{srfi/}@math{n}}) +-] +- +-This document lists the SRFIs that are supported by Racket and +-provides a link to the original SRFI specification (which is also +-distributed as part of Racket's documentation). +- +-The following SRFI specification documents are licensed restrictively. +- +-@table-of-contents[] +- +- +-@; ---------------------------------------- +- +-@srfi[5]{A compatible let form with signatures and rest arguments} +- +-@redirect[5 '( +- (let #t "unnamed") +-)] +- +-Racket provides this SRFI in the @racket[srfi-lib-nonfree] package. +- +-@; ---------------------------------------- +- +-@srfi[29]{Localization} +- +-@redirect[29 '( +- (current-language #f "current-language") +- (current-country #f "current-country") +- (current-locale-details #f "current-locale-details") +- (declare-bundle! #f "declare-bundle!") +- (store-bundle #f "store-bundle") +- (load-bundle! #f "load-bundle!") +- (localized-template #f "localized-template") +-)] +- +-Racket provides a free implementation of this SRFI in the @racket[srfi-lib] package. Only the SRFI specification document is nonfree. +- +-@; ---------------------------------------- +- +-@index-section[] +diff -urN racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html +--- racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 2018-08-03 15:23:48.895563664 -0400 ++++ racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 1969-12-31 19:00:00.000000000 -0500 +@@ -1,507 +0,0 @@ +-<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN"> +-<html> +- <head> +- <meta name="generator" content="HTML Tidy, see www.w3.org"> +- <title>SRFI 29: Localization</title> +- <meta name="author" content="Scott G. Miller"> +- <meta name="description" content="Localization"> +- </head> +- <body> +- <H1>Title</H1> +- +- SRFI 29: Localization +- +- <H1>Author</H1> +- +- Scott G. Miller +- +- <H1>Abstract</H1> +- +- This document specifies an interface to retrieving and +- displaying locale sensitive messages. A Scheme program can +- register one or more translations of templated messages, and +- then write Scheme code that can transparently retrieve the +- appropriate message for the locale under which the Scheme +- system is running. <br> +- +- +- <H1>Rationale</H1> +- +- <p>As any programmer that has ever had to deal with making his +- or her code readable in more than one locale, the process of +- sufficiently abstracting program messages from their +- presentation to the user is non-trivial without help from the +- programming language. Most modern programming language +- libraries do provide some mechanism for performing this +- separation.</p> +- +- <p>A portable API that allows a piece of code to run without +- modification in different countries and under different +- languages is a must for any non-trivial software project. +- The interface should separate the logic of a program from +- the myriad of translations that may be necessary.</p> +- +- <p>The interface described in this document provides such +- functionality. The underlying implementation is also allowed to +- use whatever datastructures it likes to provide access to the +- translations in the most efficient manner possible. In +- addition, the implementation is provided with standardized +- functions that programs will use for accessing an external, +- unspecified repository of translations.</p> +- +- <p>This interface <i>does not</i> cover all aspects of +- localization, including support for non-latin characters, +- number and date formatting, etc. Such functionality is the +- scope of a future SRFI that may extend this one.</p> +- +- <H1>Dependencies</H1> +- +- An SRFI-29 conformant implementation must also implement +- SRFI-28, Basic Format Strings. Message templates are strings +- that must be processed by the <tt>format</tt> function +- specified in that SRFI. +- +- <H1>Specification</H1> +- +- <h3>Message Bundles</h3> +- +- <p>A Message Bundle is a set of message templates and their +- identifying keys. Each bundle contains one or more such +- key/value pairs. The bundle itself is associated with a +- <i>bundle specifier</i> which uniquely identifies the +- bundle.</p> +- +- <h3>Bundle Specifiers</h3> +- +- <p>A Bundle Specifier is a Scheme list that describes, in order +- of importance, the package and locale of a message bundle. +- In most cases, a locale specifier will have between one +- and three elements. The first element is a symbol denoting the +- package for which this bundle applies. The second and third +- elements denote a <i>locale</i>. The second element (first +- element of the locale) if present, is the two letter, ISO 639-1 +- language code for the bundle. The third element, if present, is +- a two letter ISO 3166-1 country code. In some cases, a +- fourth element may be present, specifying the encoding used for +- the bundle. All bundle specifier elements are Scheme +- symbols.</p> +- +- <p>If only one translation is provided, it should be designated +- only by a package name, for example <tt>(mathlib)</tt>. This +- translation is called the <i>default</i> translation.</p> +- +- <h3>Bundle Searching</h3> +- +- <p>When a message template is retrieved from a bundle, the +- Scheme implementation will provide the locale under which the +- system is currently running. When the template is retrieved, +- the package name will be specified. The Scheme system should +- construct a Bundle Specifier from the provided package name and +- the active locale. For example, when retrieving a message +- template for French Canadian, in the <tt>mathlib</tt> package, +- the bundle specifier '<tt>(mathlib fr ca)</tt>' is used. A +- program may also retrieve the elements of the current locale +- using the no-argument procedures:</p> +- +- <p><b><a name="current-language"></a><tt>current-language</tt></b> <tt>-> +- <i>symbol</i></tt><br> +- <tt><b>current-language</b> <i>symbol</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- When given no arguments, returns the current ISO 639-1 +- language code as a symbol. If provided with an +- argument, the current language is set to that named by the +- symbol for the currently executing Scheme thread (or for the +- entire Scheme system if such a distinction is not possible). +- +- </blockquote> +- +- <p><b><a name="current-country"></a><tt>current-country</tt></b> <tt>-> +- <i>symbol</i></tt><br> +- <tt><b>current-country</b> <i>symbol</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- returns the current ISO 3166-1 country code as a symbol. +- If provided with an argument, the current country is +- set to that named by the symbol for the currently executing +- Scheme thread (or for the entire Scheme system if such a +- distinction is not possible). +- </blockquote> +- +- <p><b><a name="current-locale-details"></a><tt>current-locale-details</tt></b> <tt>-> <i>list of +- symbol</i></tt>s<br> +- <tt><b>current-locale-details</b> <i>list-of-symbols</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- Returns a list of additional locale details as a list of +- symbols. This list may contain information about +- encodings or other more specific information. If +- provided with an argument, the current locale details are set +- to those given in the currently executing Scheme thread (or +- for the entire Scheme system if such a distinction is not +- possible). +- </blockquote> +- +- <p>The Scheme System should first check for a bundle with the +- exact name provided. If no such bundle is found, the last +- element from the list is removed and a search is tried for a +- bundle with that name. If no bundle is then found, the list is +- shortened by removing the last element again. If no message is +- found and the bundle specifier is now the empty list, an error +- should be raised.</p> +- +- <p>The reason for this search order is to provide the most +- locale sensitive template possible, but to fall back on more +- general templates if a translation has not yet been provided +- for the given locale.</p> +- +- <h3>Message Templates</h3> +- +- <p>A message template is a localized message that may or may +- not contain one of a number of formatting codes. A message +- template is a Scheme string. The string is of a form that can +- be processed by the <tt>format</tt> procedure found in many +- Scheme systems and formally specified in SRFI-28 (Basic Format +- Strings).</p> +- +- <p>This SRFI also extends SRFI-28 to provide an additional +- <tt>format</tt> escape code:</p> +- +- <blockquote> +- <tt>~[n]@*</tt> - Causes a value-requiring escape code that +- follows this code immediately to reference the [N]'th +- optional value absolutely, rather than the next unconsumed +- value. The referenced value is <i>not</i> consumed. +- </blockquote> +- This extension allows optional values to be positionally +- referenced, so that message templates can be constructed that +- can produce the proper word ordering for a language. +- +- <h3>Preparing Bundles</h3> +- Before a bundle may be used by the Scheme system to retrieve +- localized template messages, they must be made available to the +- Scheme system. This SRFI specifies a way to portably +- define the bundles, as well as store them in and retrieve them +- from an unspecified system which may be provided by resources +- outside the Scheme system.<br> +- +- +- <p><b><a name="declare-bundle!"></a><tt>declare-bundle!</tt></b> <tt><i>bundle-specifier +- association-list</i> -> undefined<br> +- </tt></p> +- +- <blockquote> +- Declares a new bundle named by the given bundle-specifier. +- The contents of the bundle are defined by the provided +- association list. The list contains associations +- between Scheme symbols and the message templates (Scheme +- strings) they name. If a bundle already exists with the +- given name, it is overwritten with the newly declared +- bundle.<br> +- </blockquote> +- <tt><a name="store-bundle"></a><b>store-bundle</b> <i>bundle-specifier</i> -> +- boolean</tt><br> +- +- +- <blockquote> +- Attempts to store a bundle named by the given bundle +- specifier, and previously made available using +- <tt>declare-bundle!</tt> or <tt>load-bundle!</tt>, in an +- unspecified mechanism that may be persistent across Scheme +- system restarts. If successful, a non-false value is +- returned. If unsuccessful, <tt>#f</tt> is returned.<br> +- </blockquote> +- <tt><a name="load-bundle!"></a><b>load-bundle!</b> <i>bundle-specifier</i> -> +- boolean</tt><br> +- +- +- <blockquote> +- Attempts to retrieve a bundle from an unspecified mechanism +- which stores bundles outside the Scheme system. If the +- bundle was retrieved successfully, the function returns a +- non-false value, and the bundle is immediately available to +- the Scheme system. If the bundle could not be found or loaded +- successfully, the function returns <tt>#f</tt>, and the +- Scheme system's bundle registry remains unaffected.<br> +- </blockquote> +- A compliant Scheme system may choose not to provide any +- external mechanism to store localized bundles. If it does +- not, it must still provide implementations for +- <tt>store-bundle</tt> and <tt>load-bundle!</tt>. In such a +- case, both functions must return <tt>#f</tt> regardless of the +- arguments given. Users of this SRFI should recognize that the +- inability to load or store a localized bundle in an external +- repository is <i>not</i> a fatal error.<br> +- +- +- <h3>Retrieving Localized Message Templates</h3> +- +- <p><a name="localized-template"></a><b><tt>localized-template</tt></b> <i><tt>package-name +- message-template-name</tt></i> <tt>-> <i>string or #f<br> +- </i></tt></p> +- +- <blockquote> +- Retrieves a localized message template for the given package +- name and the given message template name (both symbols). +- If no such message could be found, false (#f) is +- returned.<br> +- <br> +- </blockquote> +- After retrieving a template, the calling program can use +- <tt>format</tt> to produce a string that can be displayed to +- the user.<br> +- +- +- <h2>Examples</h2> +- The below example makes use of SRFI-29 to display simple, +- localized messages. It also defines its bundles in such a +- way that the Scheme system may store and retrieve the bundles +- from a more efficient system catalog, if available.<br> +- +-<pre> +-(let ((translations +- '(((en) . ((time . "Its ~a, ~a.") +- (goodbye . "Goodbye, ~a."))) +- ((fr) . ((time . "~1@*~a, c'est ~a.") +- (goodbye . "Au revoir, ~a.")))))) +- (for-each (lambda (translation) +- (let ((bundle-name (cons 'hello-program (car translation)))) +- (if (not (load-bundle! bundle-name)) +- (begin +- (declare-bundle! bundle-name (cdr translation)) +- (store-bundle! bundle-name))))) +- translations)) +- +-(define localized-message +- (lambda (message-name . args) +- (apply format (cons (localized-template 'hello-program +- message-name) +- args)))) +- +-(let ((myname "Fred")) +- (display (localized-message 'time "12:00" myname)) +- (display #\newline) +- +- (display (localized-message 'goodbye myname)) +- (display #\newline)) +- +-;; Displays (English): +-;; Its 12:00, Fred. +-;; Goodbye, Fred. +-;; +-;; French: +-;; Fred, c'est 12:00. +-;; Au revoir, Fred. +-</pre> +- +- <H1>Implementation</H1> +- +- <p>The implementation requires that the Scheme system provide a +- definition for <tt>current-language</tt> and +- <tt>current-country</tt> capable of distinguishing the correct +- locale present during a Scheme session. The definitions of +- those functions in the reference implementation are not capable +- of that distinction. Their implementation is provided only so +- that the following code can run in any R4RS scheme system. +- <br> +- </p> +- +- <p>In addition, the below implementation of a compliant +- <tt>format</tt> requires SRFI-6 (Basic String Ports) and +- SRFI-23 (Error reporting)</p> +-<pre> +-;; The association list in which bundles will be stored +-(define *localization-bundles* '()) +- +-;; The current-language and current-country functions provided +-;; here must be rewritten for each Scheme system to default to the +-;; actual locale of the session +-(define current-language +- (let ((current-language-value 'en)) +- (lambda args +- (if (null? args) +- current-language-value +- (set! current-language-value (car args)))))) +- +-(define current-country +- (let ((current-country-value 'us)) +- (lambda args +- (if (null? args) +- current-country-value +- (set! current-country-value (car args)))))) +- +-;; The load-bundle! and store-bundle! both return #f in this +-;; reference implementation. A compliant implementation need +-;; not rewrite these procedures. +-(define load-bundle! +- (lambda (bundle-specifier) +- #f)) +- +-(define store-bundle! +- (lambda (bundle-specifier) +- #f)) +- +-;; Declare a bundle of templates with a given bundle specifier +-(define declare-bundle! +- (letrec ((remove-old-bundle +- (lambda (specifier bundle) +- (cond ((null? bundle) '()) +- ((equal? (caar bundle) specifier) +- (cdr bundle)) +- (else (cons (car bundle) +- (remove-old-bundle specifier +- (cdr bundle)))))))) +- (lambda (bundle-specifier bundle-assoc-list) +- (set! *localization-bundles* +- (cons (cons bundle-specifier bundle-assoc-list) +- (remove-old-bundle bundle-specifier +- *localization-bundles*)))))) +- +-;;Retrieve a localized template given its package name and a template name +-(define localized-template +- (letrec ((rdc +- (lambda (ls) +- (if (null? (cdr ls)) +- '() +- (cons (car ls) (rdc (cdr ls)))))) +- (find-bundle +- (lambda (specifier template-name) +- (cond ((assoc specifier *localization-bundles*) => +- (lambda (bundle) bundle)) +- ((null? specifier) #f) +- (else (find-bundle (rdc specifier) +- template-name)))))) +- (lambda (package-name template-name) +- (let loop ((specifier (cons package-name +- (list (current-language) +- (current-country))))) +- (and (not (null? specifier)) +- (let ((bundle (find-bundle specifier template-name))) +- (and bundle +- (cond ((assq template-name bundle) => cdr) +- ((null? (cdr specifier)) #f) +- (else (loop (rdc specifier))))))))))) +- +-;;An SRFI-28 and SRFI-29 compliant version of format. It requires +-;;SRFI-23 for error reporting. +-(define format +- (lambda (format-string . objects) +- (let ((buffer (open-output-string))) +- (let loop ((format-list (string->list format-string)) +- (objects objects) +- (object-override #f)) +- (cond ((null? format-list) (get-output-string buffer)) +- ((char=? (car format-list) #~) +- (cond ((null? (cdr format-list)) +- (error 'format "Incomplete escape sequence")) +- ((char-numeric? (cadr format-list)) +- (let posloop ((fl (cddr format-list)) +- (pos (string->number +- (string (cadr format-list))))) +- (cond ((null? fl) +- (error 'format "Incomplete escape sequence")) +- ((and (eq? (car fl) '#@) +- (null? (cdr fl))) +- (error 'format "Incomplete escape sequence")) +- ((and (eq? (car fl) '#@) +- (eq? (cadr fl) '#*)) +- (loop (cddr fl) objects (list-ref objects pos))) +- (else +- (posloop (cdr fl) +- (+ (* 10 pos) +- (string->number +- (string (car fl))))))))) +- (else +- (case (cadr format-list) +- ((#\a) +- (cond (object-override +- (begin +- (display object-override buffer) +- (loop (cddr format-list) objects #f))) +- ((null? objects) +- (error 'format "No value for escape sequence")) +- (else +- (begin +- (display (car objects) buffer) +- (loop (cddr format-list) +- (cdr objects) #f))))) +- ((#\s) +- (cond (object-override +- (begin +- (display object-override buffer) +- (loop (cddr format-list) objects #f))) +- ((null? objects) +- (error 'format "No value for escape sequence")) +- (else +- (begin +- (write (car objects) buffer) +- (loop (cddr format-list) +- (cdr objects) #f))))) +- ((#%) +- (if object-override +- (error 'format "Escape sequence following positional override does not require a value")) +- (display #\newline buffer) +- (loop (cddr format-list) objects #f)) +- ((#~) +- (if object-override +- (error 'format "Escape sequence following positional override does not require a value")) +- (display #~ buffer) +- (loop (cddr format-list) objects #f)) +- (else +- (error 'format "Unrecognized escape sequence")))))) +- (else (display (car format-list) buffer) +- (loop (cdr format-list) objects #f))))))) +- +-</pre> +- +- <H1>Copyright</H1> +- +- Copyright (C) Scott G. Miller (2002). All Rights Reserved. +- +- <p>This document and translations of it may be copied and +- furnished to others, and derivative works that comment on or +- otherwise explain it or assist in its implementation may be +- prepared, copied, published and distributed, in whole or in +- part, without restriction of any kind, provided that the above +- copyright notice and this paragraph are included on all such +- copies and derivative works. However, this document itself may +- not be modified in any way, such as by removing the copyright +- notice or references to the Scheme Request For Implementation +- process or editors, except as needed for the purpose of +- developing SRFIs in which case the procedures for copyrights +- defined in the SRFI process must be followed, or as required to +- translate it into languages other than English.</p> +- +- <p>The limited permissions granted above are perpetual and will +- not be revoked by the authors or their successors or +- assigns.</p> +- +- <p>This document and the information contained herein is +- provided on an "AS IS" basis and THE AUTHOR AND THE SRFI +- EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION +- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES +- OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> +- <hr> +- +- <address> +- Editor: <a href="mailto:srfi-editors@srfi.schemers.org">David +- Rush</a> +- </address> +- +- <address> +- Author: <a href="mailto:scgmille@freenetproject.org">Scott G. +- Miller</a> +- </address> +- <!-- Created: Tue Sep 29 19:20:08 EDT 1998 --> +- <!-- hhmts start -->Last modified: Mon Jun 17 12:00:08 Pacific +- Daylight Time 2002 <!-- hhmts end --> <br> +- </body> +-</html> +- +diff -urN racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html +--- racket-7.0.orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 2018-08-03 15:23:48.895563664 -0400 ++++ racket-7.0/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 1969-12-31 19:00:00.000000000 -0500 +@@ -1,345 +0,0 @@ +-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"> +-<html> +-<head> +- <title>SRFI 5: A compatible let form with signatures and rest arguments</title> +-</head> +-<body> +- +-<H1>Title</H1> +- +-SRFI-5: A compatible <code>let</code> form with signatures and rest arguments +- +-<H1>Author</H1> +- +-Andy Gaynor +- +-<H1>Status</H1> +- +-This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>. +-You can access the discussion on this SRFI via <A HREF="http://srfi.schemers.org/srfi-5/mail-archive/maillist.html">the archive of the mailing list</A>. +-<P><UL> +-<LI>Received: 1999/2/2 +-<LI>Draft: 1999/2/10-1999/04/12 +-<LI>Final: 1999/4/26 +-<LI>Revised reference implementation: 2003/01/27 +-</UL> +- +-<H1>Abstract</H1> +- +-The <i>named-let</i> incarnation of the <code>let</code> form has two slight +-inconsistencies with the <code>define</code> form. As defined, the <code>let</code> +-form makes no accommodation for rest arguments, an issue of functionality +-and consistency. As defined, the <code>let</code> form does not accommodate +-signature-style syntax, an issue of aesthetics and consistency. Both +-issues are addressed here in a manner which is compatible with the traditional +-<code>let</code> form but for minor extensions. +- +-<H1>Rationale</H1> +- +-<H2>Signature-style Syntax</H2> +- +-Consider the following two equivalent definitions: +- +-<p><pre> +-(define fibonacci +- (lambda (n i f0 f1) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1))))) +- +-(define (fibonacci n i f0 f1) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-</pre> +- +-Although there is a named-let analog for the former form, there is none +-for the latter. To wit, suppose one wished to compute the 10th element +-of the Fibonacci sequence using a named let: +- +-<p> +-<pre> +-(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-Values: 55 +-</pre> +- +-As it stands, one cannot equivalently write +- +-<p> +-<pre> +-(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-</pre> +- +-which is consistent with <code>define</code>'s signature-style form. +-<p>Those that favor the signature style may prefer this extension. +-In any case, it may be more appropriate to include all bound names within +-the binding section. As presented, this straightforward extension +-introduces no ambiguity or incompatibility with the existing definition +-of let. +- +-<H2>Rest Arguments</H2> +- +-As it stands, one cannot write a named let with rest arguments, as in +- +-<p> +-<pre> +-(let (blast (port (current-output-port)) . (x (+ 1 2) 4 5)) +- (if (null? x) +- 'just-a-silly-contrived-example +- (begin +- (write (car x) port) +- (apply blast port (cdr x))))) +-</pre> +- +-otherwise equivalent to +- +-<p> +-<pre> +-(letrec ((blast (lambda (port . x) +- (if (null? x) +- 'just-a-silly-contrived-example +- (begin +- (write (car x) port) +- (apply blast port (cdr x))))))) +- (blast (current-output-port) (+ 1 2) 4 5)) +-</pre> +- +-While this example is rather contrived, the functionality is not. +-There are several times when the author has used this construct in practice. +-Regardless, there is little reason to deny the <code>let</code> form access to +-all the features of lambda functionality. +- +-<H2>Symbols in Binding Sections</H2> +- +-Both the features above rely upon the placement of symbols in <code>let</code> +-binding lists (this statement is intentially simplistic). The only +-other apparent use of such symbol placement is to tersely bind variables +-to unspecified values. For example, one might desire to use +-<code>(let (foo bar baz) ...)</code> +-to bind <code>foo</code>, <code>bar</code>, and <code>baz</code> to +-unspecified values. +- +-<p>This usage is considered less important in light of the rationales +-presented above, and an alternate syntax is immediately apparent, as +-in <code>(let ((foo) (bar) (baz)) ...)</code> This may even +-be preferable, consistently parenthesizing normal binding clauses. +- +-<H1>Specification</H1> +- +-<H2>Syntax</H2> +- +-<p> +-A formal specification of the syntax follows. Below, body, expression, +-and identifier are free. Each instantiation of binding-name must be +-unique. +-</p> +- +-<p> +-<pre> +- let = "(" "let" let-bindings body ")" +- expressions = nothing | expression expressions +- let-bindings = let-name bindings +- |"(" let-name "." bindings ")" +- let-name = identifier +- bindings = "(" ")" +- | rest-binding +- | "(" normal-bindings ["." rest-binding] ")" +-normal-bindings = nothing +- | normal-binding normal-bindings +-normal-binding = "(" binding-name expression ")" +- binding-name = identifier +- rest-binding = "(" binding-name expressions ")" +-</pre> +- +-<p> +-For clarity and convenience, an informal specification follows. +-</p> +- +-<ol> +-<li><a name="unnamed">Unnamed</a> +- +-<p><pre> +-(let ((<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-non-sig"> +-Named, non-signature-style, no rest argument</a> +- +-<p><pre> +-(let <name> ((<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-sig">Named, signature-style, no rest argument</a> +- +-<p><pre> +-(let (<name> (<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-non-sig-rest">Named, non-signature-style, rest argument</a> +- +-<p><pre> +-(let <name> ((<parameter> <argument>)... +- +-. (<rest-parameter> <rest-argument>...)) +- <body>...) +-</pre> +- +-<li><a name="named-sig-rest">Named, signature-style, rest argument</a> +- +-<p><pre> +-(let (<name> (<parameter> <argument>)... +- +-. (<rest-parameter> <rest-argument>...)) +- <body>...) +-</pre> +-</li> +-</ol> +- +-<H2>Semantics</H2> +- +-Let <code>$lambda</code> and <code>$letrec</code> be hygienic bindings for the <code>lambda</code> +-and <code>letrec</code> forms, respectively. +- +-<ul> +-<li>For informal syntax 1: +- +-<p><pre> +-(($lambda (<parameter>...) <body>...) <argument>...) +-</pre> +-</li> +- +-<li>For informal syntaxes 2 and 3: +- +-<p> +-<pre> +-($letrec ((<name> ($lambda (<parameter>...) <body>...))) +- (<name> <argument>...)) +-</pre> +-</li> +- +-<li>For informal syntaxes 4 and 5: +- +-<p> +-<pre> +-($letrec ((<name> ($lambda (<parameter>... +- +-. <rest-parameter>) <body>...))) +- (<name> <argument>... <rest-argument>...)) +-</pre> +-</li> +-</ul> +- +-<H1>Implementation</H1> +- +-Here is an implementation using <code>SYNTAX-RULES</code>. +- +-<p> +-<pre> +-;; Use your own standard let. +-;; Or call a lambda. +-;; (define-syntax standard-let +-;; +-;; (syntax-rules () +-;; +-;; ((let ((var val) ...) body ...) +-;; ((lambda (var ...) body ...) val ...)))) +- +-(define-syntax let +- +- (syntax-rules () +- +- ;; No bindings: use standard-let. +- ((let () body ...) +- (standard-let () body ...)) +- ;; Or call a lambda. +- ;; ((lambda () body ...)) +- +- ;; All standard bindings: use standard-let. +- ((let ((var val) ...) body ...) +- (standard-let ((var val) ...) body ...)) +- ;; Or call a lambda. +- ;; ((lambda (var ...) body ...) val ...) +- +- ;; One standard binding: loop. +- ;; The all-standard-bindings clause didn't match, +- ;; so there must be a rest binding. +- ((let ((var val) . bindings) body ...) +- (let-loop #f bindings (var) (val) (body ...))) +- +- ;; Signature-style name: loop. +- ((let (name binding ...) body ...) +- (let-loop name (binding ...) () () (body ...))) +- +- ;; defun-style name: loop. +- ((let name bindings body ...) +- (let-loop name bindings () () (body ...))))) +- +-(define-syntax let-loop +- +- (syntax-rules () +- +- ;; Standard binding: destructure and loop. +- ((let-loop name ((var0 val0) binding ...) (var ... ) (val ... ) body) +- (let-loop name ( binding ...) (var ... var0) (val ... val0) body)) +- +- ;; Rest binding, no name: use standard-let, listing the rest values. +- ;; Because of let's first clause, there is no "no bindings, no name" clause. +- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) +- (standard-let ((var val) ... (rest-var (list rest-val ...))) . body)) +- ;; Or call a lambda with a rest parameter on all values. +- ;; ((lambda (var ... . rest-var) . body) val ... rest-val ...)) +- ;; Or use one of several other reasonable alternatives. +- +- ;; No bindings, name: call a letrec'ed lambda. +- ((let-loop name () (var ...) (val ...) body) +- ((letrec ((name (lambda (var ...) . body))) +- name) +- val ...)) +- +- ;; Rest binding, name: call a letrec'ed lambda. +- ((let-loop name (rest-var rest-val ...) (var ...) (val ...) body) +- ((letrec ((name (lambda (var ... . rest-var) . body))) +- name) +- val ... rest-val ...)))) +-</pre> +- +- +-<H1>Copyright</H1> +- +-Copyright (C) Andy Gaynor (1999). All Rights Reserved. +-<p>This document and translations of it may be copied and furnished to +-others, and derivative works that comment on or otherwise explain it or +-assist in its implementation may be prepared, copied, published and distributed, +-in whole or in part, without restriction of any kind, provided that the +-above copyright notice and this paragraph are included on all such copies +-and derivative works. However, this document itself may not be modified +-in any way, such as by removing the copyright notice or references to the +-Scheme Request For Implementation process or editors, except as needed +-for the purpose of developing SRFIs in which case the procedures for copyrights +-defined in the SRFI process must be followed, or as required to translate +-it into languages other than English. +-<p>The limited permissions granted above are perpetual and will not be +-revoked by the authors or their successors or assigns. +-<p>This document and the information contained herein is provided on an +-"AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE +-USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +-WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +- <hr> +- <address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address> +- +-</body> +-</html> +diff -urN racket-7.0.orig/share/pkgs/srfi-lib-nonfree/info.rkt racket-7.0/share/pkgs/srfi-lib-nonfree/info.rkt +--- racket-7.0.orig/share/pkgs/srfi-lib-nonfree/info.rkt 2018-08-03 15:23:48.906563738 -0400 ++++ racket-7.0/share/pkgs/srfi-lib-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1 +0,0 @@ +-(module info setup/infotab (#%module-begin (define package-content-state (quote (built "7.0"))) (define collection (quote multi)) (define deps (quote ("scheme-lib" "base" "r6rs-lib" "srfi-lib" "compatibility-lib"))) (define pkg-desc "implementation (no documentation) part of "srfi nonfree"") (define pkg-authors (quote (mflatt noel chongkai jay))))) +diff -urN racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt +--- racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 2018-08-03 15:23:48.906563738 -0400 ++++ racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1 +0,0 @@ +-#lang s-exp srfi/provider srfi/%3a5 +diff -urN racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt +--- racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 2018-08-03 15:23:48.906563738 -0400 ++++ racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,3 +0,0 @@ +-#lang s-exp srfi/provider srfi/5 +- +-;; FIXME: "rest arguments" need to generate mutable lists +diff -urN racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt +--- racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 2018-08-03 15:23:48.906563738 -0400 ++++ racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,86 +0,0 @@ +-;;; +-;;; <let.rkt> ---- SRFI 5 A compatible let form with signatures and rest arguments +-;;; Time-stamp: <03/04/08 09:56:06 solsona> +-;;; +-;;; Usually, I would add a copyright notice, and the announce that +-;;; this code is under the LGPL licence. Nevertheless, I only did the +-;;; port to PLT Scheme v200, and here is the copyright notice, +-;;; comments, and licence from the original source: +-;;; +-;;; Copyright (C) Andy Gaynor (1999-2003) +-;;; +-;;; The version of my-let here was cleaned up by: Paul Schlie schlie@attbi.com. +-;;; Renamed to s:let by Eli Barzilay +- +-#lang scheme/base +-(provide s:let) +- +-(define-syntax s:let +- (syntax-rules () +- ;; standard +- ((s:let () body ...) +- (let () body ...)) +- ((s:let ((var val) ...) body ...) +- (let ((var val) ...) body ...)) +- +- ;; rest style +- ((s:let ((var val) . bindings) body ...) +- (let-loop #f bindings (var) (val) (body ...))) +- +- ;; signature style +- ((s:let (name bindings ...) body ...) +- (let-loop name (bindings ...) () () (body ...))) +- +- ;; standard named style +- ((s:let name (bindings ...) body ...) +- (let-loop name (bindings ...) () () (body ...))) +- +- )) +- +-;; A loop to walk down the list of bindings. +- +-(define-syntax let-loop +- (syntax-rules () +- +- ;; No more bindings - make a LETREC. +- ((let-loop name () (vars ...) (vals ...) body) +- ((letrec ((name (lambda (vars ...) . body))) +- name) +- vals ...)) +- +- ;; Rest binding, no name +- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) +- (let ((var val) ... (rest-var (list rest-val ...))) . body)) +- +- ;; Process a (var val) pair. +- ((let-loop name ((var val) more ...) (vars ...) (vals ...) body) +- (let-loop name (more ...) (vars ... var) (vals ... val) body)) +- +- ;; End with a rest variable - make a LETREC. +- ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body) +- ((letrec ((name (lambda (vars ... . rest-var) . body))) +- name) +- vals ... rest-vals ...)))) +- +-;; Four loops - normal and `signature-style', each with and without a rest +-;; binding. +-;; +-;;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) +-;; (if (= i n) +-;; f0 +-;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-;; +-;;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) +-;; (if (= i n) +-;; f0 +-;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-;; +-;;(let fibonacci ((n 10) (i 0) . (f 0 1)) +-;; (if (= i n) +-;; (car f) +-;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) +-;; +-;;(let (fibonacci (n 10) (i 0) . (f 0 1)) +-;; (if (= i n) +-;; (car f) +-;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) +diff -urN racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/5.rkt racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/5.rkt +--- racket-7.0.orig/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 2018-08-03 15:23:48.906563738 -0400 ++++ racket-7.0/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,2 +0,0 @@ +-;; module loader for SRFI-5 +-#lang s-exp srfi/provider srfi/5/let #:unprefix s: diff --git a/racket.spec b/racket.spec index d3dc907..5fb06c9 100644 --- a/racket.spec +++ b/racket.spec @@ -1,38 +1,24 @@ Name: racket -Version: 6.12 -Release: 8%{?dist} +Version: 7.0 +Release: 1%{?dist} Summary: General purpose programming language
License: GPLv3 and LGPLv3 and MIT URL: https://racket-lang.org Source0: https://mirror.racket-lang.org/installers/%%7Bversion%7D/%%7Bname%7D-%%7Bver...
-# Update SRFI libraries to include upstream PR 5. -# See: https://github.com/racket/srfi/pull/5 (merged) -Patch0: racket-6.12-update-srfi.patch - # Remove SRFI library and docs with restrictive licensing. # See: https://github.com/racket/srfi/issues/4 (open) # Note: Upstream maintainers have confirmed this # is safe, since the removed components are # extra elements which nothing else in the # package depends on. -Patch1: racket-6.12-remove-nonfree.patch - -# Backport upstream fix of rpaths in racket/racket -# which break check-buildroot -# https://github.com/racket/racket/pull/1947 (merged) -Patch2: racket-6.12-fix-rpaths.patch - -# Backport upstream fix of rpaths in racket/web-server -# which break check-buildroot -# https://github.com/racket/web-server/issues/36 (closed) -Patch3: racket-6.12-fix-webserver-rpaths.patch +Patch0: racket-7.0-remove-nonfree.patch
# Update racket-doc/search to use https://docs.racket-lang.org # when no docs exist locally # https://github.com/racket/scribble/pull/164 (open) -Patch4: racket-6.12-fix-doc-open-url.patch +Patch1: racket-7.0-fix-doc-open-url.patch
# Issue Building for s390x and armv7hl in koji ExcludeArch: s390x armv7hl @@ -131,6 +117,7 @@ for i in $DOCS_TO_FIX; do ${RPM_BUILD_ROOT}/%{_datadir}/doc/racket/$i done
+# Remove the executable bit on legacy template file chmod -x ${RPM_BUILD_ROOT}%{_libdir}/racket/starter-sh
%ldconfig_scriptlets @@ -244,6 +231,10 @@ A local installation of the Racket documentation system. %{_datadir}/doc/racket
%changelog +* Fri Aug 3 2018 David Benoit dbenoit@redhat.com 7.0-1 +- Remove 6.12 patches and add update remove nonfree + srfi patch to 7.0 + * Mon Jul 30 2018 David Benoit dbenoit@redhat.com 6.12-8 - Annotate dependencies with links to source code - Move dependencies to racket-pkgs, since they are only used diff --git a/sources b/sources index 0fa455a..e43e6a3 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (racket-6.12-src.tgz) = e373cc1dd94f98d84dd2a105dad1cc2f2068118777b455af3f30ea3d190e6d601392bf17337652eeb84fa86d9c60aaa17563599b1772dc312211a8ac6e2c7060 +SHA512 (racket-7.0-src.tgz) = 98be3a7f0fbe38ae5febd2a9a3c81baede7dd7b3f3a9ed3ce68321389a68f74c6a8e24170013f7ca4fd725a79a3d5cfbda2e26f0f75163076e3b98f43094507f
commit 1b0a0799af2a5acee95845192bd3a772fd4a0f55 Author: dbenoit dbenoit@redhat.com Date: Fri Aug 31 14:54:24 2018 -0400
fix sources file
diff --git a/.gitignore b/.gitignore index e69de29..d013960 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/racket-6.12-src.tgz diff --git a/sources b/sources index 452da4f..0fa455a 100644 --- a/sources +++ b/sources @@ -1,6 +1 @@ -SHA512 (racket-6.12-fix-doc-open-url.patch) = 66a6a7f0f005a0da7acaf1ffbd53831eb796171994aa033bae5a2a973a79bb1c65212eaf4bf7ec02dfae5a186efcfa3e2a06b08bc31ff162cd4e08ab5b97bb94 -SHA512 (racket-6.12-fix-rpaths.patch) = d844d4d174b1cd92c61d16912aaf48afddbc9010acb2e5950d2d277d3110fc9256b68cbc38f06f69f6e2009f34085b32690a535049934d46d820e5b1491434e1 -SHA512 (racket-6.12-fix-webserver-rpaths.patch) = 807e356726dff3087bbcf505835082bcd2f0cdfb1d45e899d98bdf9b23715586b5c2a4a5703fff9ff2af9e46feb9936eaf685b6fb331388cd77dcc57389fbd76 -SHA512 (racket-6.12-remove-nonfree.patch) = 76e24e03728742073bdf4dc927da734195ddb6400cbcdaedecc09d94e7eac4168de4c9d30423bfd293b5fcd3580b0147b38c9061bded1205ec91e24f4868be2c -SHA512 (racket-6.12-update-srfi.patch) = cfa97cc312ec3a40ad3dd4c4d662c949274325d6acc991c0d9b2327fc03b6c532cec0aa6e7f9a5563d0c23526742177367264f601f8e92055a1d6c3347e763a4 -SHA512 (racket.spec) = 5c53ad1906aa228848f7cabd72f377dd6da8f711669af515650d35fb40b5d3cb627c0b3daaf347cd2066ed250ce7fbcced7192e24f1aea7509eba1ceee487f49 +SHA512 (racket-6.12-src.tgz) = e373cc1dd94f98d84dd2a105dad1cc2f2068118777b455af3f30ea3d190e6d601392bf17337652eeb84fa86d9c60aaa17563599b1772dc312211a8ac6e2c7060
commit 335d72219631d93c3f29c29fd82070c0af593ef4 Author: dbenoit dbenoit@redhat.com Date: Fri Aug 31 14:44:26 2018 -0400
fix gitignore
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/sources b/sources new file mode 100644 index 0000000..452da4f --- /dev/null +++ b/sources @@ -0,0 +1,6 @@ +SHA512 (racket-6.12-fix-doc-open-url.patch) = 66a6a7f0f005a0da7acaf1ffbd53831eb796171994aa033bae5a2a973a79bb1c65212eaf4bf7ec02dfae5a186efcfa3e2a06b08bc31ff162cd4e08ab5b97bb94 +SHA512 (racket-6.12-fix-rpaths.patch) = d844d4d174b1cd92c61d16912aaf48afddbc9010acb2e5950d2d277d3110fc9256b68cbc38f06f69f6e2009f34085b32690a535049934d46d820e5b1491434e1 +SHA512 (racket-6.12-fix-webserver-rpaths.patch) = 807e356726dff3087bbcf505835082bcd2f0cdfb1d45e899d98bdf9b23715586b5c2a4a5703fff9ff2af9e46feb9936eaf685b6fb331388cd77dcc57389fbd76 +SHA512 (racket-6.12-remove-nonfree.patch) = 76e24e03728742073bdf4dc927da734195ddb6400cbcdaedecc09d94e7eac4168de4c9d30423bfd293b5fcd3580b0147b38c9061bded1205ec91e24f4868be2c +SHA512 (racket-6.12-update-srfi.patch) = cfa97cc312ec3a40ad3dd4c4d662c949274325d6acc991c0d9b2327fc03b6c532cec0aa6e7f9a5563d0c23526742177367264f601f8e92055a1d6c3347e763a4 +SHA512 (racket.spec) = 5c53ad1906aa228848f7cabd72f377dd6da8f711669af515650d35fb40b5d3cb627c0b3daaf347cd2066ed250ce7fbcced7192e24f1aea7509eba1ceee487f49
commit f241dafce908418595fbb717060cbbefb6867e61 Author: dbenoit dbenoit@redhat.com Date: Fri Aug 31 14:25:40 2018 -0400
add spec and patches
diff --git a/racket-6.12-fix-doc-open-url.patch b/racket-6.12-fix-doc-open-url.patch new file mode 100644 index 0000000..7c497f5 --- /dev/null +++ b/racket-6.12-fix-doc-open-url.patch @@ -0,0 +1,69 @@ +diff -urN racket-6.12-wbsvr/share/pkgs/scribble-lib/help/search.rkt racket-6.12/share/pkgs/scribble-lib/help/search.rkt +--- racket-6.12-wbsvr/share/pkgs/scribble-lib/help/search.rkt 2018-03-19 17:14:56.017273013 -0400 ++++ racket-6.12/share/pkgs/scribble-lib/help/search.rkt 2018-03-19 17:15:37.839113929 -0400 +@@ -17,33 +17,38 @@ + #:notify [notify void]) + (define open-url (get-doc-open-url)) + (cond +- [open-url +- (define dest-url (let ([u (string->url open-url)]) +- (combine-url/relative +- u +- (string-join +- (for/list ([s (explode-path sub)]) +- (if (path? s) +- (path-element->string s) +- (format "~a" s))) +- "/")))) +- (notify (url->string dest-url)) +- (send-url (url->string +- (struct-copy url dest-url +- [fragment (or fragment +- (url-fragment dest-url))] +- [query (append +- (url-query dest-url) +- (if query +- (url-query +- (string->url +- (format "q?~a" query))) +- null))])))] +- [else +- (let* ([path (build-path (find-user-doc-dir) sub)] +- [path (if (file-exists? path) path (build-path (find-doc-dir) sub))]) +- (notify path) +- (send-url/file path #:fragment fragment #:query query))])) ++ [open-url ++ (define dest-url (let ([u (string->url open-url)]) ++ (combine-url/relative ++ u ++ (string-join ++ (for/list ([s (explode-path sub)]) ++ (if (path? s) ++ (path-element->string s) ++ (format "~a" s))) ++ "/")))) ++ (notify (url->string dest-url)) ++ (send-url (url->string ++ (struct-copy url dest-url ++ [fragment (or fragment ++ (url-fragment dest-url))] ++ [query (append ++ (url-query dest-url) ++ (if query ++ (url-query ++ (string->url ++ (format "q?~a" query))) ++ null))])))] ++ [else ++ (let* ([path (build-path (find-user-doc-dir) sub)] ++ [path (if (file-exists? path) path (build-path (find-doc-dir) sub))]) ++ (notify path) ++ (if (file-exists? path) ++ (send-url/file path #:fragment fragment #:query query) ++ (let ([part (lambda (pfx x) (if x (string-append pfx x) ""))]) ++ (send-url (string-append ++ "https://docs.racket-lang.org/" ++ sub (part "#" fragment) (part "?" query))))))])) + + ;; This is an example of changing this code to use the online manuals. + ;; Normally, it's better to set `doc-open-url` in "etc/config.rktd", diff --git a/racket-6.12-fix-rpaths.patch b/racket-6.12-fix-rpaths.patch new file mode 100644 index 0000000..f76730e --- /dev/null +++ b/racket-6.12-fix-rpaths.patch @@ -0,0 +1,13 @@ +diff -urN racket-6.12-f/collects/racket/runtime-path.rkt racket-6.12/collects/racket/runtime-path.rkt +--- racket-6.12-f/collects/racket/runtime-path.rkt 2018-02-06 16:04:29.969878308 -0500 ++++ racket-6.12/collects/racket/runtime-path.rkt 2018-02-06 16:07:10.549176282 -0500 +@@ -186,7 +186,8 @@ + (path-of + #,(datum->syntax + #'orig-stx +- `(,#'this-expression-source-file)))) ++ `(,#'this-expression-source-file) ++ #'orig-stx))) + #'void)]) + (apply to-values (resolve-paths (#%variable-reference) + get-dir diff --git a/racket-6.12-fix-webserver-rpaths.patch b/racket-6.12-fix-webserver-rpaths.patch new file mode 100644 index 0000000..78614cf --- /dev/null +++ b/racket-6.12-fix-webserver-rpaths.patch @@ -0,0 +1,35 @@ +diff -urN racket-6.12-rp/share/pkgs/web-server-lib/web-server/formlets/lib.rkt racket-6.12-wbsvr/share/pkgs/web-server-lib/web-server/formlets/lib.rkt +--- racket-6.12-rp/share/pkgs/web-server-lib/web-server/formlets/lib.rkt 2018-02-22 18:42:06.131455756 -0500 ++++ racket-6.12-wbsvr/share/pkgs/web-server-lib/web-server/formlets/lib.rkt 2018-03-20 15:07:09.666222028 -0400 +@@ -7,6 +7,7 @@ + racket/function + racket/serialize + syntax/location ++ setup/collects + (for-syntax racket/base + syntax/parse)) + +@@ -70,20 +71,20 @@ + #:range-contracts (map (curry coerce-contract 'formlet/c) + contracts)))])) + (define quote-this-module-path +- (quote-module-path)) ++ (path->collects-relative (quote-module-path))) + (define-syntax formlet/c + (syntax-parser + [(_ range ...) + #:declare range (expr/c #'contract? + #:name "range contract argument") + #'(formlet/c** (-> listof-binding +- (values (coerce-contract 'formlet/c range.c) ...)))] ++ (values (coerce-contract 'formlet/c range #;.c) ...)))] + [name:id + #`(contract + (-> contract? (... ...) contract?) + dynamic-formlet/c + quote-this-module-path +- (quote-module-path) ++ (path->collects-relative (quote-module-path)) + "formlet/c" + #'name)])) + diff --git a/racket-6.12-remove-nonfree.patch b/racket-6.12-remove-nonfree.patch new file mode 100644 index 0000000..4e72a3e --- /dev/null +++ b/racket-6.12-remove-nonfree.patch @@ -0,0 +1,1124 @@ +diff -urN racket-6.12-nf/share/links.rktd racket-6.12/share/links.rktd +--- racket-6.12-nf/share/links.rktd 2018-01-31 13:04:06.757393819 -0500 ++++ racket-6.12/share/links.rktd 2018-01-31 13:04:25.419309681 -0500 +@@ -133,7 +133,6 @@ + (root "pkgs/r5rs-doc") + (root "pkgs/srfi-lite-lib") + (root "pkgs/srfi-lib") +- (root "pkgs/srfi-lib-nonfree") + (root "pkgs/html-doc") + (root "pkgs/images-gui-lib") + (root "pkgs/images-doc") +@@ -177,7 +176,6 @@ + (root "pkgs/slideshow-exe") + (root "pkgs/slideshow-plugin") + (root "pkgs/srfi-doc") +- (root "pkgs/srfi-doc-nonfree") + (root "pkgs/syntax-color-doc") + (root "pkgs/web-server-lib") + (root "pkgs/unix-socket-lib") +diff -urN racket-6.12-nf/share/pkgs/srfi/info.rkt racket-6.12/share/pkgs/srfi/info.rkt +--- racket-6.12-nf/share/pkgs/srfi/info.rkt 2018-01-31 13:04:07.216391749 -0500 ++++ racket-6.12/share/pkgs/srfi/info.rkt 2018-01-31 13:05:32.601025227 -0500 +@@ -3,13 +3,9 @@ + (define collection 'multi) + + (define deps '("srfi-lib" +- "srfi-lib-nonfree" +- "srfi-doc" +- "srfi-doc-nonfree")) ++ "srfi-doc")) + (define implies '("srfi-lib" +- "srfi-lib-nonfree" +- "srfi-doc" +- "srfi-foc-nonfree")) ++ "srfi-doc")) + + (define pkg-desc "Legacy SRFI (Scheme) libraries") + +diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt +--- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/info.rkt 2018-01-31 13:04:07.221391727 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,19 +0,0 @@ +-#lang info +- +-(define collection 'multi) +- +-(define build-deps '("mzscheme-doc" +- "scheme-lib" +- "base" +- "scribble-lib" +- "srfi-doc" +- "srfi-lib-nonfree" +- "racket-doc" +- "r5rs-doc" +- "r6rs-doc" +- "compatibility-lib")) +-(define update-implies '("srfi-lib-nonfree")) +- +-(define pkg-desc "documentation part of "srfi nonfree"") +- +-(define pkg-authors '(mflatt noel chongkai jay)) +diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt +--- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 2018-01-31 13:04:07.221391727 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,3 +0,0 @@ +-#lang info +- +-(define scribblings '(("srfi-nf.scrbl" (multi-page) (library 100)))) +diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl +--- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 2018-01-31 13:04:07.221391727 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 1969-12-31 19:00:00.000000000 -0500 +@@ -1,66 +0,0 @@ +-#lang scribble/doc +-@(require srfi/scribblings/util +- scribble/manual +- scribble/eval +- scriblib/render-cond +- scribble/core +- scribble/html-properties +- (for-syntax scheme/base) +- (for-label scheme/base +- racket/stream)) +- +-@; ---------------------------------------------------------------------- +- +-@title{SRFI Nonfree Libraries and Documentation} +- +-The @link[#:style srfi-std "http://srfi.schemers.org/%22%5D%7BScheme Requests for +-Implementation} (a.k.a. @deftech{SRFI}) process allows individual +-members of the Scheme community to propose libraries and extensions to +-be supported by multiple Scheme implementations. +- +-Racket is distributed with implementations of many SRFIs, most of +-which can be implemented as libraries. To import the bindings of SRFI +-@math{n}, use +- +-@racketblock[ +-(require @#,elem{@racketidfont{srfi/}@math{n}}) +-] +- +-This document lists the SRFIs that are supported by Racket and +-provides a link to the original SRFI specification (which is also +-distributed as part of Racket's documentation). +- +-The following SRFI specification documents are licensed restrictively. +- +-@table-of-contents[] +- +- +-@; ---------------------------------------- +- +-@srfi[5]{A compatible let form with signatures and rest arguments} +- +-@redirect[5 '( +- (let #t "unnamed") +-)] +- +-Racket provides this SRFI in the @racket[srfi-lib-nonfree] package. +- +-@; ---------------------------------------- +- +-@srfi[29]{Localization} +- +-@redirect[29 '( +- (current-language #f "current-language") +- (current-country #f "current-country") +- (current-locale-details #f "current-locale-details") +- (declare-bundle! #f "declare-bundle!") +- (store-bundle #f "store-bundle") +- (load-bundle! #f "load-bundle!") +- (localized-template #f "localized-template") +-)] +- +-Racket provides a free implementation of this SRFI in the @racket[srfi-lib] package. Only the SRFI specification document is nonfree. +- +-@; ---------------------------------------- +- +-@index-section[] +diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html +--- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 2018-01-31 13:04:07.221391727 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 1969-12-31 19:00:00.000000000 -0500 +@@ -1,507 +0,0 @@ +-<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN"> +-<html> +- <head> +- <meta name="generator" content="HTML Tidy, see www.w3.org"> +- <title>SRFI 29: Localization</title> +- <meta name="author" content="Scott G. Miller"> +- <meta name="description" content="Localization"> +- </head> +- <body> +- <H1>Title</H1> +- +- SRFI 29: Localization +- +- <H1>Author</H1> +- +- Scott G. Miller +- +- <H1>Abstract</H1> +- +- This document specifies an interface to retrieving and +- displaying locale sensitive messages. A Scheme program can +- register one or more translations of templated messages, and +- then write Scheme code that can transparently retrieve the +- appropriate message for the locale under which the Scheme +- system is running. <br> +- +- +- <H1>Rationale</H1> +- +- <p>As any programmer that has ever had to deal with making his +- or her code readable in more than one locale, the process of +- sufficiently abstracting program messages from their +- presentation to the user is non-trivial without help from the +- programming language. Most modern programming language +- libraries do provide some mechanism for performing this +- separation.</p> +- +- <p>A portable API that allows a piece of code to run without +- modification in different countries and under different +- languages is a must for any non-trivial software project. +- The interface should separate the logic of a program from +- the myriad of translations that may be necessary.</p> +- +- <p>The interface described in this document provides such +- functionality. The underlying implementation is also allowed to +- use whatever datastructures it likes to provide access to the +- translations in the most efficient manner possible. In +- addition, the implementation is provided with standardized +- functions that programs will use for accessing an external, +- unspecified repository of translations.</p> +- +- <p>This interface <i>does not</i> cover all aspects of +- localization, including support for non-latin characters, +- number and date formatting, etc. Such functionality is the +- scope of a future SRFI that may extend this one.</p> +- +- <H1>Dependencies</H1> +- +- An SRFI-29 conformant implementation must also implement +- SRFI-28, Basic Format Strings. Message templates are strings +- that must be processed by the <tt>format</tt> function +- specified in that SRFI. +- +- <H1>Specification</H1> +- +- <h3>Message Bundles</h3> +- +- <p>A Message Bundle is a set of message templates and their +- identifying keys. Each bundle contains one or more such +- key/value pairs. The bundle itself is associated with a +- <i>bundle specifier</i> which uniquely identifies the +- bundle.</p> +- +- <h3>Bundle Specifiers</h3> +- +- <p>A Bundle Specifier is a Scheme list that describes, in order +- of importance, the package and locale of a message bundle. +- In most cases, a locale specifier will have between one +- and three elements. The first element is a symbol denoting the +- package for which this bundle applies. The second and third +- elements denote a <i>locale</i>. The second element (first +- element of the locale) if present, is the two letter, ISO 639-1 +- language code for the bundle. The third element, if present, is +- a two letter ISO 3166-1 country code. In some cases, a +- fourth element may be present, specifying the encoding used for +- the bundle. All bundle specifier elements are Scheme +- symbols.</p> +- +- <p>If only one translation is provided, it should be designated +- only by a package name, for example <tt>(mathlib)</tt>. This +- translation is called the <i>default</i> translation.</p> +- +- <h3>Bundle Searching</h3> +- +- <p>When a message template is retrieved from a bundle, the +- Scheme implementation will provide the locale under which the +- system is currently running. When the template is retrieved, +- the package name will be specified. The Scheme system should +- construct a Bundle Specifier from the provided package name and +- the active locale. For example, when retrieving a message +- template for French Canadian, in the <tt>mathlib</tt> package, +- the bundle specifier '<tt>(mathlib fr ca)</tt>' is used. A +- program may also retrieve the elements of the current locale +- using the no-argument procedures:</p> +- +- <p><b><a name="current-language"></a><tt>current-language</tt></b> <tt>-> +- <i>symbol</i></tt><br> +- <tt><b>current-language</b> <i>symbol</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- When given no arguments, returns the current ISO 639-1 +- language code as a symbol. If provided with an +- argument, the current language is set to that named by the +- symbol for the currently executing Scheme thread (or for the +- entire Scheme system if such a distinction is not possible). +- +- </blockquote> +- +- <p><b><a name="current-country"></a><tt>current-country</tt></b> <tt>-> +- <i>symbol</i></tt><br> +- <tt><b>current-country</b> <i>symbol</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- returns the current ISO 3166-1 country code as a symbol. +- If provided with an argument, the current country is +- set to that named by the symbol for the currently executing +- Scheme thread (or for the entire Scheme system if such a +- distinction is not possible). +- </blockquote> +- +- <p><b><a name="current-locale-details"></a><tt>current-locale-details</tt></b> <tt>-> <i>list of +- symbol</i></tt>s<br> +- <tt><b>current-locale-details</b> <i>list-of-symbols</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- Returns a list of additional locale details as a list of +- symbols. This list may contain information about +- encodings or other more specific information. If +- provided with an argument, the current locale details are set +- to those given in the currently executing Scheme thread (or +- for the entire Scheme system if such a distinction is not +- possible). +- </blockquote> +- +- <p>The Scheme System should first check for a bundle with the +- exact name provided. If no such bundle is found, the last +- element from the list is removed and a search is tried for a +- bundle with that name. If no bundle is then found, the list is +- shortened by removing the last element again. If no message is +- found and the bundle specifier is now the empty list, an error +- should be raised.</p> +- +- <p>The reason for this search order is to provide the most +- locale sensitive template possible, but to fall back on more +- general templates if a translation has not yet been provided +- for the given locale.</p> +- +- <h3>Message Templates</h3> +- +- <p>A message template is a localized message that may or may +- not contain one of a number of formatting codes. A message +- template is a Scheme string. The string is of a form that can +- be processed by the <tt>format</tt> procedure found in many +- Scheme systems and formally specified in SRFI-28 (Basic Format +- Strings).</p> +- +- <p>This SRFI also extends SRFI-28 to provide an additional +- <tt>format</tt> escape code:</p> +- +- <blockquote> +- <tt>~[n]@*</tt> - Causes a value-requiring escape code that +- follows this code immediately to reference the [N]'th +- optional value absolutely, rather than the next unconsumed +- value. The referenced value is <i>not</i> consumed. +- </blockquote> +- This extension allows optional values to be positionally +- referenced, so that message templates can be constructed that +- can produce the proper word ordering for a language. +- +- <h3>Preparing Bundles</h3> +- Before a bundle may be used by the Scheme system to retrieve +- localized template messages, they must be made available to the +- Scheme system. This SRFI specifies a way to portably +- define the bundles, as well as store them in and retrieve them +- from an unspecified system which may be provided by resources +- outside the Scheme system.<br> +- +- +- <p><b><a name="declare-bundle!"></a><tt>declare-bundle!</tt></b> <tt><i>bundle-specifier +- association-list</i> -> undefined<br> +- </tt></p> +- +- <blockquote> +- Declares a new bundle named by the given bundle-specifier. +- The contents of the bundle are defined by the provided +- association list. The list contains associations +- between Scheme symbols and the message templates (Scheme +- strings) they name. If a bundle already exists with the +- given name, it is overwritten with the newly declared +- bundle.<br> +- </blockquote> +- <tt><a name="store-bundle"></a><b>store-bundle</b> <i>bundle-specifier</i> -> +- boolean</tt><br> +- +- +- <blockquote> +- Attempts to store a bundle named by the given bundle +- specifier, and previously made available using +- <tt>declare-bundle!</tt> or <tt>load-bundle!</tt>, in an +- unspecified mechanism that may be persistent across Scheme +- system restarts. If successful, a non-false value is +- returned. If unsuccessful, <tt>#f</tt> is returned.<br> +- </blockquote> +- <tt><a name="load-bundle!"></a><b>load-bundle!</b> <i>bundle-specifier</i> -> +- boolean</tt><br> +- +- +- <blockquote> +- Attempts to retrieve a bundle from an unspecified mechanism +- which stores bundles outside the Scheme system. If the +- bundle was retrieved successfully, the function returns a +- non-false value, and the bundle is immediately available to +- the Scheme system. If the bundle could not be found or loaded +- successfully, the function returns <tt>#f</tt>, and the +- Scheme system's bundle registry remains unaffected.<br> +- </blockquote> +- A compliant Scheme system may choose not to provide any +- external mechanism to store localized bundles. If it does +- not, it must still provide implementations for +- <tt>store-bundle</tt> and <tt>load-bundle!</tt>. In such a +- case, both functions must return <tt>#f</tt> regardless of the +- arguments given. Users of this SRFI should recognize that the +- inability to load or store a localized bundle in an external +- repository is <i>not</i> a fatal error.<br> +- +- +- <h3>Retrieving Localized Message Templates</h3> +- +- <p><a name="localized-template"></a><b><tt>localized-template</tt></b> <i><tt>package-name +- message-template-name</tt></i> <tt>-> <i>string or #f<br> +- </i></tt></p> +- +- <blockquote> +- Retrieves a localized message template for the given package +- name and the given message template name (both symbols). +- If no such message could be found, false (#f) is +- returned.<br> +- <br> +- </blockquote> +- After retrieving a template, the calling program can use +- <tt>format</tt> to produce a string that can be displayed to +- the user.<br> +- +- +- <h2>Examples</h2> +- The below example makes use of SRFI-29 to display simple, +- localized messages. It also defines its bundles in such a +- way that the Scheme system may store and retrieve the bundles +- from a more efficient system catalog, if available.<br> +- +-<pre> +-(let ((translations +- '(((en) . ((time . "Its ~a, ~a.") +- (goodbye . "Goodbye, ~a."))) +- ((fr) . ((time . "~1@*~a, c'est ~a.") +- (goodbye . "Au revoir, ~a.")))))) +- (for-each (lambda (translation) +- (let ((bundle-name (cons 'hello-program (car translation)))) +- (if (not (load-bundle! bundle-name)) +- (begin +- (declare-bundle! bundle-name (cdr translation)) +- (store-bundle! bundle-name))))) +- translations)) +- +-(define localized-message +- (lambda (message-name . args) +- (apply format (cons (localized-template 'hello-program +- message-name) +- args)))) +- +-(let ((myname "Fred")) +- (display (localized-message 'time "12:00" myname)) +- (display #\newline) +- +- (display (localized-message 'goodbye myname)) +- (display #\newline)) +- +-;; Displays (English): +-;; Its 12:00, Fred. +-;; Goodbye, Fred. +-;; +-;; French: +-;; Fred, c'est 12:00. +-;; Au revoir, Fred. +-</pre> +- +- <H1>Implementation</H1> +- +- <p>The implementation requires that the Scheme system provide a +- definition for <tt>current-language</tt> and +- <tt>current-country</tt> capable of distinguishing the correct +- locale present during a Scheme session. The definitions of +- those functions in the reference implementation are not capable +- of that distinction. Their implementation is provided only so +- that the following code can run in any R4RS scheme system. +- <br> +- </p> +- +- <p>In addition, the below implementation of a compliant +- <tt>format</tt> requires SRFI-6 (Basic String Ports) and +- SRFI-23 (Error reporting)</p> +-<pre> +-;; The association list in which bundles will be stored +-(define *localization-bundles* '()) +- +-;; The current-language and current-country functions provided +-;; here must be rewritten for each Scheme system to default to the +-;; actual locale of the session +-(define current-language +- (let ((current-language-value 'en)) +- (lambda args +- (if (null? args) +- current-language-value +- (set! current-language-value (car args)))))) +- +-(define current-country +- (let ((current-country-value 'us)) +- (lambda args +- (if (null? args) +- current-country-value +- (set! current-country-value (car args)))))) +- +-;; The load-bundle! and store-bundle! both return #f in this +-;; reference implementation. A compliant implementation need +-;; not rewrite these procedures. +-(define load-bundle! +- (lambda (bundle-specifier) +- #f)) +- +-(define store-bundle! +- (lambda (bundle-specifier) +- #f)) +- +-;; Declare a bundle of templates with a given bundle specifier +-(define declare-bundle! +- (letrec ((remove-old-bundle +- (lambda (specifier bundle) +- (cond ((null? bundle) '()) +- ((equal? (caar bundle) specifier) +- (cdr bundle)) +- (else (cons (car bundle) +- (remove-old-bundle specifier +- (cdr bundle)))))))) +- (lambda (bundle-specifier bundle-assoc-list) +- (set! *localization-bundles* +- (cons (cons bundle-specifier bundle-assoc-list) +- (remove-old-bundle bundle-specifier +- *localization-bundles*)))))) +- +-;;Retrieve a localized template given its package name and a template name +-(define localized-template +- (letrec ((rdc +- (lambda (ls) +- (if (null? (cdr ls)) +- '() +- (cons (car ls) (rdc (cdr ls)))))) +- (find-bundle +- (lambda (specifier template-name) +- (cond ((assoc specifier *localization-bundles*) => +- (lambda (bundle) bundle)) +- ((null? specifier) #f) +- (else (find-bundle (rdc specifier) +- template-name)))))) +- (lambda (package-name template-name) +- (let loop ((specifier (cons package-name +- (list (current-language) +- (current-country))))) +- (and (not (null? specifier)) +- (let ((bundle (find-bundle specifier template-name))) +- (and bundle +- (cond ((assq template-name bundle) => cdr) +- ((null? (cdr specifier)) #f) +- (else (loop (rdc specifier))))))))))) +- +-;;An SRFI-28 and SRFI-29 compliant version of format. It requires +-;;SRFI-23 for error reporting. +-(define format +- (lambda (format-string . objects) +- (let ((buffer (open-output-string))) +- (let loop ((format-list (string->list format-string)) +- (objects objects) +- (object-override #f)) +- (cond ((null? format-list) (get-output-string buffer)) +- ((char=? (car format-list) #~) +- (cond ((null? (cdr format-list)) +- (error 'format "Incomplete escape sequence")) +- ((char-numeric? (cadr format-list)) +- (let posloop ((fl (cddr format-list)) +- (pos (string->number +- (string (cadr format-list))))) +- (cond ((null? fl) +- (error 'format "Incomplete escape sequence")) +- ((and (eq? (car fl) '#@) +- (null? (cdr fl))) +- (error 'format "Incomplete escape sequence")) +- ((and (eq? (car fl) '#@) +- (eq? (cadr fl) '#*)) +- (loop (cddr fl) objects (list-ref objects pos))) +- (else +- (posloop (cdr fl) +- (+ (* 10 pos) +- (string->number +- (string (car fl))))))))) +- (else +- (case (cadr format-list) +- ((#\a) +- (cond (object-override +- (begin +- (display object-override buffer) +- (loop (cddr format-list) objects #f))) +- ((null? objects) +- (error 'format "No value for escape sequence")) +- (else +- (begin +- (display (car objects) buffer) +- (loop (cddr format-list) +- (cdr objects) #f))))) +- ((#\s) +- (cond (object-override +- (begin +- (display object-override buffer) +- (loop (cddr format-list) objects #f))) +- ((null? objects) +- (error 'format "No value for escape sequence")) +- (else +- (begin +- (write (car objects) buffer) +- (loop (cddr format-list) +- (cdr objects) #f))))) +- ((#%) +- (if object-override +- (error 'format "Escape sequence following positional override does not require a value")) +- (display #\newline buffer) +- (loop (cddr format-list) objects #f)) +- ((#~) +- (if object-override +- (error 'format "Escape sequence following positional override does not require a value")) +- (display #~ buffer) +- (loop (cddr format-list) objects #f)) +- (else +- (error 'format "Unrecognized escape sequence")))))) +- (else (display (car format-list) buffer) +- (loop (cdr format-list) objects #f))))))) +- +-</pre> +- +- <H1>Copyright</H1> +- +- Copyright (C) Scott G. Miller (2002). All Rights Reserved. +- +- <p>This document and translations of it may be copied and +- furnished to others, and derivative works that comment on or +- otherwise explain it or assist in its implementation may be +- prepared, copied, published and distributed, in whole or in +- part, without restriction of any kind, provided that the above +- copyright notice and this paragraph are included on all such +- copies and derivative works. However, this document itself may +- not be modified in any way, such as by removing the copyright +- notice or references to the Scheme Request For Implementation +- process or editors, except as needed for the purpose of +- developing SRFIs in which case the procedures for copyrights +- defined in the SRFI process must be followed, or as required to +- translate it into languages other than English.</p> +- +- <p>The limited permissions granted above are perpetual and will +- not be revoked by the authors or their successors or +- assigns.</p> +- +- <p>This document and the information contained herein is +- provided on an "AS IS" basis and THE AUTHOR AND THE SRFI +- EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION +- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES +- OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> +- <hr> +- +- <address> +- Editor: <a href="mailto:srfi-editors@srfi.schemers.org">David +- Rush</a> +- </address> +- +- <address> +- Author: <a href="mailto:scgmille@freenetproject.org">Scott G. +- Miller</a> +- </address> +- <!-- Created: Tue Sep 29 19:20:08 EDT 1998 --> +- <!-- hhmts start -->Last modified: Mon Jun 17 12:00:08 Pacific +- Daylight Time 2002 <!-- hhmts end --> <br> +- </body> +-</html> +- +diff -urN racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html +--- racket-6.12-nf/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 2018-01-31 13:04:07.221391727 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 1969-12-31 19:00:00.000000000 -0500 +@@ -1,345 +0,0 @@ +-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"> +-<html> +-<head> +- <title>SRFI 5: A compatible let form with signatures and rest arguments</title> +-</head> +-<body> +- +-<H1>Title</H1> +- +-SRFI-5: A compatible <code>let</code> form with signatures and rest arguments +- +-<H1>Author</H1> +- +-Andy Gaynor +- +-<H1>Status</H1> +- +-This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>. +-You can access the discussion on this SRFI via <A HREF="http://srfi.schemers.org/srfi-5/mail-archive/maillist.html">the archive of the mailing list</A>. +-<P><UL> +-<LI>Received: 1999/2/2 +-<LI>Draft: 1999/2/10-1999/04/12 +-<LI>Final: 1999/4/26 +-<LI>Revised reference implementation: 2003/01/27 +-</UL> +- +-<H1>Abstract</H1> +- +-The <i>named-let</i> incarnation of the <code>let</code> form has two slight +-inconsistencies with the <code>define</code> form. As defined, the <code>let</code> +-form makes no accommodation for rest arguments, an issue of functionality +-and consistency. As defined, the <code>let</code> form does not accommodate +-signature-style syntax, an issue of aesthetics and consistency. Both +-issues are addressed here in a manner which is compatible with the traditional +-<code>let</code> form but for minor extensions. +- +-<H1>Rationale</H1> +- +-<H2>Signature-style Syntax</H2> +- +-Consider the following two equivalent definitions: +- +-<p><pre> +-(define fibonacci +- (lambda (n i f0 f1) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1))))) +- +-(define (fibonacci n i f0 f1) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-</pre> +- +-Although there is a named-let analog for the former form, there is none +-for the latter. To wit, suppose one wished to compute the 10th element +-of the Fibonacci sequence using a named let: +- +-<p> +-<pre> +-(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-Values: 55 +-</pre> +- +-As it stands, one cannot equivalently write +- +-<p> +-<pre> +-(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-</pre> +- +-which is consistent with <code>define</code>'s signature-style form. +-<p>Those that favor the signature style may prefer this extension. +-In any case, it may be more appropriate to include all bound names within +-the binding section. As presented, this straightforward extension +-introduces no ambiguity or incompatibility with the existing definition +-of let. +- +-<H2>Rest Arguments</H2> +- +-As it stands, one cannot write a named let with rest arguments, as in +- +-<p> +-<pre> +-(let (blast (port (current-output-port)) . (x (+ 1 2) 4 5)) +- (if (null? x) +- 'just-a-silly-contrived-example +- (begin +- (write (car x) port) +- (apply blast port (cdr x))))) +-</pre> +- +-otherwise equivalent to +- +-<p> +-<pre> +-(letrec ((blast (lambda (port . x) +- (if (null? x) +- 'just-a-silly-contrived-example +- (begin +- (write (car x) port) +- (apply blast port (cdr x))))))) +- (blast (current-output-port) (+ 1 2) 4 5)) +-</pre> +- +-While this example is rather contrived, the functionality is not. +-There are several times when the author has used this construct in practice. +-Regardless, there is little reason to deny the <code>let</code> form access to +-all the features of lambda functionality. +- +-<H2>Symbols in Binding Sections</H2> +- +-Both the features above rely upon the placement of symbols in <code>let</code> +-binding lists (this statement is intentially simplistic). The only +-other apparent use of such symbol placement is to tersely bind variables +-to unspecified values. For example, one might desire to use +-<code>(let (foo bar baz) ...)</code> +-to bind <code>foo</code>, <code>bar</code>, and <code>baz</code> to +-unspecified values. +- +-<p>This usage is considered less important in light of the rationales +-presented above, and an alternate syntax is immediately apparent, as +-in <code>(let ((foo) (bar) (baz)) ...)</code> This may even +-be preferable, consistently parenthesizing normal binding clauses. +- +-<H1>Specification</H1> +- +-<H2>Syntax</H2> +- +-<p> +-A formal specification of the syntax follows. Below, body, expression, +-and identifier are free. Each instantiation of binding-name must be +-unique. +-</p> +- +-<p> +-<pre> +- let = "(" "let" let-bindings body ")" +- expressions = nothing | expression expressions +- let-bindings = let-name bindings +- |"(" let-name "." bindings ")" +- let-name = identifier +- bindings = "(" ")" +- | rest-binding +- | "(" normal-bindings ["." rest-binding] ")" +-normal-bindings = nothing +- | normal-binding normal-bindings +-normal-binding = "(" binding-name expression ")" +- binding-name = identifier +- rest-binding = "(" binding-name expressions ")" +-</pre> +- +-<p> +-For clarity and convenience, an informal specification follows. +-</p> +- +-<ol> +-<li><a name="unnamed">Unnamed</a> +- +-<p><pre> +-(let ((<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-non-sig"> +-Named, non-signature-style, no rest argument</a> +- +-<p><pre> +-(let <name> ((<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-sig">Named, signature-style, no rest argument</a> +- +-<p><pre> +-(let (<name> (<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-non-sig-rest">Named, non-signature-style, rest argument</a> +- +-<p><pre> +-(let <name> ((<parameter> <argument>)... +- +-. (<rest-parameter> <rest-argument>...)) +- <body>...) +-</pre> +- +-<li><a name="named-sig-rest">Named, signature-style, rest argument</a> +- +-<p><pre> +-(let (<name> (<parameter> <argument>)... +- +-. (<rest-parameter> <rest-argument>...)) +- <body>...) +-</pre> +-</li> +-</ol> +- +-<H2>Semantics</H2> +- +-Let <code>$lambda</code> and <code>$letrec</code> be hygienic bindings for the <code>lambda</code> +-and <code>letrec</code> forms, respectively. +- +-<ul> +-<li>For informal syntax 1: +- +-<p><pre> +-(($lambda (<parameter>...) <body>...) <argument>...) +-</pre> +-</li> +- +-<li>For informal syntaxes 2 and 3: +- +-<p> +-<pre> +-($letrec ((<name> ($lambda (<parameter>...) <body>...))) +- (<name> <argument>...)) +-</pre> +-</li> +- +-<li>For informal syntaxes 4 and 5: +- +-<p> +-<pre> +-($letrec ((<name> ($lambda (<parameter>... +- +-. <rest-parameter>) <body>...))) +- (<name> <argument>... <rest-argument>...)) +-</pre> +-</li> +-</ul> +- +-<H1>Implementation</H1> +- +-Here is an implementation using <code>SYNTAX-RULES</code>. +- +-<p> +-<pre> +-;; Use your own standard let. +-;; Or call a lambda. +-;; (define-syntax standard-let +-;; +-;; (syntax-rules () +-;; +-;; ((let ((var val) ...) body ...) +-;; ((lambda (var ...) body ...) val ...)))) +- +-(define-syntax let +- +- (syntax-rules () +- +- ;; No bindings: use standard-let. +- ((let () body ...) +- (standard-let () body ...)) +- ;; Or call a lambda. +- ;; ((lambda () body ...)) +- +- ;; All standard bindings: use standard-let. +- ((let ((var val) ...) body ...) +- (standard-let ((var val) ...) body ...)) +- ;; Or call a lambda. +- ;; ((lambda (var ...) body ...) val ...) +- +- ;; One standard binding: loop. +- ;; The all-standard-bindings clause didn't match, +- ;; so there must be a rest binding. +- ((let ((var val) . bindings) body ...) +- (let-loop #f bindings (var) (val) (body ...))) +- +- ;; Signature-style name: loop. +- ((let (name binding ...) body ...) +- (let-loop name (binding ...) () () (body ...))) +- +- ;; defun-style name: loop. +- ((let name bindings body ...) +- (let-loop name bindings () () (body ...))))) +- +-(define-syntax let-loop +- +- (syntax-rules () +- +- ;; Standard binding: destructure and loop. +- ((let-loop name ((var0 val0) binding ...) (var ... ) (val ... ) body) +- (let-loop name ( binding ...) (var ... var0) (val ... val0) body)) +- +- ;; Rest binding, no name: use standard-let, listing the rest values. +- ;; Because of let's first clause, there is no "no bindings, no name" clause. +- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) +- (standard-let ((var val) ... (rest-var (list rest-val ...))) . body)) +- ;; Or call a lambda with a rest parameter on all values. +- ;; ((lambda (var ... . rest-var) . body) val ... rest-val ...)) +- ;; Or use one of several other reasonable alternatives. +- +- ;; No bindings, name: call a letrec'ed lambda. +- ((let-loop name () (var ...) (val ...) body) +- ((letrec ((name (lambda (var ...) . body))) +- name) +- val ...)) +- +- ;; Rest binding, name: call a letrec'ed lambda. +- ((let-loop name (rest-var rest-val ...) (var ...) (val ...) body) +- ((letrec ((name (lambda (var ... . rest-var) . body))) +- name) +- val ... rest-val ...)))) +-</pre> +- +- +-<H1>Copyright</H1> +- +-Copyright (C) Andy Gaynor (1999). All Rights Reserved. +-<p>This document and translations of it may be copied and furnished to +-others, and derivative works that comment on or otherwise explain it or +-assist in its implementation may be prepared, copied, published and distributed, +-in whole or in part, without restriction of any kind, provided that the +-above copyright notice and this paragraph are included on all such copies +-and derivative works. However, this document itself may not be modified +-in any way, such as by removing the copyright notice or references to the +-Scheme Request For Implementation process or editors, except as needed +-for the purpose of developing SRFIs in which case the procedures for copyrights +-defined in the SRFI process must be followed, or as required to translate +-it into languages other than English. +-<p>The limited permissions granted above are perpetual and will not be +-revoked by the authors or their successors or assigns. +-<p>This document and the information contained herein is provided on an +-"AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE +-USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +-WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +- <hr> +- <address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address> +- +-</body> +-</html> +diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/info.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt +--- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/info.rkt 2018-01-31 13:04:07.236391659 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,14 +0,0 @@ +-#lang info +- +-(define collection 'multi) +- +-(define deps '("scheme-lib" +- "base" +- "r6rs-lib" +- "srfi-lib" +- "compatibility-lib")) +- +- +-(define pkg-desc "implementation (no documentation) part of "srfi nonfree"") +- +-(define pkg-authors '(mflatt noel chongkai jay)) +diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt +--- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 2018-01-31 13:04:07.236391659 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1 +0,0 @@ +-#lang s-exp srfi/provider srfi/%3a5 +diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt +--- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 2018-01-31 13:04:07.236391659 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,3 +0,0 @@ +-#lang s-exp srfi/provider srfi/5 +- +-;; FIXME: "rest arguments" need to generate mutable lists +diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt +--- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 2018-01-31 13:04:07.236391659 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,86 +0,0 @@ +-;;; +-;;; <let.rkt> ---- SRFI 5 A compatible let form with signatures and rest arguments +-;;; Time-stamp: <03/04/08 09:56:06 solsona> +-;;; +-;;; Usually, I would add a copyright notice, and the announce that +-;;; this code is under the LGPL licence. Nevertheless, I only did the +-;;; port to PLT Scheme v200, and here is the copyright notice, +-;;; comments, and licence from the original source: +-;;; +-;;; Copyright (C) Andy Gaynor (1999-2003) +-;;; +-;;; The version of my-let here was cleaned up by: Paul Schlie schlie@attbi.com. +-;;; Renamed to s:let by Eli Barzilay +- +-#lang scheme/base +-(provide s:let) +- +-(define-syntax s:let +- (syntax-rules () +- ;; standard +- ((s:let () body ...) +- (let () body ...)) +- ((s:let ((var val) ...) body ...) +- (let ((var val) ...) body ...)) +- +- ;; rest style +- ((s:let ((var val) . bindings) body ...) +- (let-loop #f bindings (var) (val) (body ...))) +- +- ;; signature style +- ((s:let (name bindings ...) body ...) +- (let-loop name (bindings ...) () () (body ...))) +- +- ;; standard named style +- ((s:let name (bindings ...) body ...) +- (let-loop name (bindings ...) () () (body ...))) +- +- )) +- +-;; A loop to walk down the list of bindings. +- +-(define-syntax let-loop +- (syntax-rules () +- +- ;; No more bindings - make a LETREC. +- ((let-loop name () (vars ...) (vals ...) body) +- ((letrec ((name (lambda (vars ...) . body))) +- name) +- vals ...)) +- +- ;; Rest binding, no name +- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) +- (let ((var val) ... (rest-var (list rest-val ...))) . body)) +- +- ;; Process a (var val) pair. +- ((let-loop name ((var val) more ...) (vars ...) (vals ...) body) +- (let-loop name (more ...) (vars ... var) (vals ... val) body)) +- +- ;; End with a rest variable - make a LETREC. +- ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body) +- ((letrec ((name (lambda (vars ... . rest-var) . body))) +- name) +- vals ... rest-vals ...)))) +- +-;; Four loops - normal and `signature-style', each with and without a rest +-;; binding. +-;; +-;;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) +-;; (if (= i n) +-;; f0 +-;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-;; +-;;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) +-;; (if (= i n) +-;; f0 +-;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-;; +-;;(let fibonacci ((n 10) (i 0) . (f 0 1)) +-;; (if (= i n) +-;; (car f) +-;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) +-;; +-;;(let (fibonacci (n 10) (i 0) . (f 0 1)) +-;; (if (= i n) +-;; (car f) +-;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) +diff -urN racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt +--- racket-6.12-nf/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 2018-01-31 13:04:07.236391659 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,2 +0,0 @@ +-;; module loader for SRFI-5 +-#lang s-exp srfi/provider srfi/5/let #:unprefix s: diff --git a/racket-6.12-update-srfi.patch b/racket-6.12-update-srfi.patch new file mode 100644 index 0000000..1894e32 --- /dev/null +++ b/racket-6.12-update-srfi.patch @@ -0,0 +1,4369 @@ +diff -urN racket-6.12-orig/share/links.rktd racket-6.12/share/links.rktd +--- racket-6.12-orig/share/links.rktd 2018-01-26 16:12:13.000000000 -0500 ++++ racket-6.12/share/links.rktd 2018-01-31 12:22:57.600504036 -0500 +@@ -133,6 +133,7 @@ + (root "pkgs/r5rs-doc") + (root "pkgs/srfi-lite-lib") + (root "pkgs/srfi-lib") ++ (root "pkgs/srfi-lib-nonfree") + (root "pkgs/html-doc") + (root "pkgs/images-gui-lib") + (root "pkgs/images-doc") +@@ -176,6 +177,7 @@ + (root "pkgs/slideshow-exe") + (root "pkgs/slideshow-plugin") + (root "pkgs/srfi-doc") ++ (root "pkgs/srfi-doc-nonfree") + (root "pkgs/syntax-color-doc") + (root "pkgs/web-server-lib") + (root "pkgs/unix-socket-lib") +diff -urN racket-6.12-orig/share/pkgs/srfi/info.rkt racket-6.12/share/pkgs/srfi/info.rkt +--- racket-6.12-orig/share/pkgs/srfi/info.rkt 2018-01-26 16:10:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi/info.rkt 2018-01-31 12:22:58.139502019 -0500 +@@ -1 +1,16 @@ +-(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define deps (quote ("srfi-lib" "srfi-doc"))) (define implies (quote ("srfi-lib" "srfi-doc"))) (define pkg-desc "Legacy SRFI (Scheme) libraries") (define pkg-authors (quote (mflatt noel chongkai jay))))) ++#lang info ++ ++(define collection 'multi) ++ ++(define deps '("srfi-lib" ++ "srfi-lib-nonfree" ++ "srfi-doc" ++ "srfi-doc-nonfree")) ++(define implies '("srfi-lib" ++ "srfi-lib-nonfree" ++ "srfi-doc" ++ "srfi-foc-nonfree")) ++ ++(define pkg-desc "Legacy SRFI (Scheme) libraries") ++ ++(define pkg-authors '(mflatt noel chongkai jay)) +diff -urN racket-6.12-orig/share/pkgs/srfi-doc/info.rkt racket-6.12/share/pkgs/srfi-doc/info.rkt +--- racket-6.12-orig/share/pkgs/srfi-doc/info.rkt 2018-01-26 16:10:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc/info.rkt 2018-01-31 12:22:58.139502019 -0500 +@@ -1 +1,24 @@ +-(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define build-deps (quote ("mzscheme-doc" "scheme-lib" "base" "scribble-lib" "srfi-lib" "racket-doc" "r5rs-doc" "r6rs-doc" "compatibility-lib"))) (define update-implies (quote ("srfi-lib"))) (define pkg-desc "documentation part of "srfi"") (define pkg-authors (quote (mflatt noel chongkai jay))))) ++#lang info ++ ++(define collection 'multi) ++ ++(define build-deps '("mzscheme-doc" ++ "scheme-lib" ++ "base" ++ "scribble-lib" ++ "srfi-lib" ++ "racket-doc" ++ "r5rs-doc" ++ "r6rs-doc" ++ "compatibility-lib")) ++ ++(define deps '("scheme-lib" ++ "base" ++ "scribble-lib" ++ "compatibility-lib")) ++ ++(define update-implies '("srfi-lib")) ++ ++(define pkg-desc "documentation part of "srfi"") ++ ++(define pkg-authors '(mflatt noel chongkai jay)) +diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl +--- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi.scrbl 2018-01-31 12:22:58.144502000 -0500 +@@ -1,5 +1,6 @@ + #lang scribble/doc +-@(require scribble/manual ++@(require srfi/scribblings/util ++ scribble/manual + scribble/eval + scriblib/render-cond + scribble/core +@@ -8,54 +9,6 @@ + (for-label scheme/base + racket/stream)) + +-@(define-syntax (srfi stx) +- (syntax-case stx () +- [(_ num #:subdir subdir? . title) +- (with-syntax ([srfi/n (string->symbol (format "srfi/~a" (syntax-e #'num)))]) +- #'(begin +- (section #:tag (format "srfi-~a" num) +- #:style 'unnumbered +- (format "SRFI ~a: " num) +- . title) +- (defmodule srfi/n) +- "Original specification: " +- (let* ([label (format "SRFI ~a" num)] +- [sub (if subdir? (format "srfi-~a/" num) "")] +- [url ( (b) (format "~a/srfi-std/~asrfi-~a.html" b sub num))]) +- (cond-element +- [(or latex text) @link[(url "http://docs.racket-lang.org") label]] +- [else @link[(url ".") label]]))))] +- [(_ num . title) #'(srfi num #:subdir #f . title)])) +- +-@;{ The `lst' argument is a list of +- (list sym syntactic-form? html-anchor) } +-@(define (redirect n lst #:subdir [subdir? #f]) +- (let ([file (if subdir? +- (format "srfi-~a/srfi-~a.html" n n) +- (format "srfi-~a.html" n))] +- [mod-path (string->symbol (format "srfi/~a" n))]) +- (make-binding-redirect-elements mod-path +- (map (lambda (b) +- (list (car b) (cadr b) +- (build-path "srfi-std" file) +- (caddr b))) +- lst)))) +- +-@(define in-core +- (case-lambda +- [() (in-core ".")] +- [(k) @elem{This SRFI's bindings are also available in +- @racketmodname[racket/base]@|k|}])) +- +-@(begin +- (define-syntax-rule (def-mz mz-if) +- (begin +- (require (for-label mzscheme)) +- (define mz-if (racket if)))) +- (def-mz mz-if)) +- +-@(define srfi-std (style #f (list (install-resource "srfi-std")))) +- + @; ---------------------------------------------------------------------- + + @title{SRFIs: Libraries} +@@ -245,14 +198,6 @@ + + @; ---------------------------------------- + +-@srfi[5]{A compatible let form with signatures and rest arguments} +- +-@redirect[5 '( +- (let #t "unnamed") +-)] +- +-@; ---------------------------------------- +- + @srfi[6]{Basic String Ports} + + @redirect[6 '( +@@ -671,20 +616,6 @@ + + @; ---------------------------------------- + +-@srfi[29]{Localization} +- +-@redirect[29 '( +- (current-language #f "current-language") +- (current-country #f "current-country") +- (current-locale-details #f "current-locale-details") +- (declare-bundle! #f "declare-bundle!") +- (store-bundle #f "store-bundle") +- (load-bundle! #f "load-bundle!") +- (localized-template #f "localized-template") +-)] +- +-@; ---------------------------------------- +- + @srfi[30]{Nested Multi-line Comments} + + This SRFI's syntax is part of Racket's default reader. +diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html +--- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-29.html 1969-12-31 19:00:00.000000000 -0500 +@@ -1,507 +0,0 @@ +-<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN"> +-<html> +- <head> +- <meta name="generator" content="HTML Tidy, see www.w3.org"> +- <title>SRFI 29: Localization</title> +- <meta name="author" content="Scott G. Miller"> +- <meta name="description" content="Localization"> +- </head> +- <body> +- <H1>Title</H1> +- +- SRFI 29: Localization +- +- <H1>Author</H1> +- +- Scott G. Miller +- +- <H1>Abstract</H1> +- +- This document specifies an interface to retrieving and +- displaying locale sensitive messages. A Scheme program can +- register one or more translations of templated messages, and +- then write Scheme code that can transparently retrieve the +- appropriate message for the locale under which the Scheme +- system is running. <br> +- +- +- <H1>Rationale</H1> +- +- <p>As any programmer that has ever had to deal with making his +- or her code readable in more than one locale, the process of +- sufficiently abstracting program messages from their +- presentation to the user is non-trivial without help from the +- programming language. Most modern programming language +- libraries do provide some mechanism for performing this +- separation.</p> +- +- <p>A portable API that allows a piece of code to run without +- modification in different countries and under different +- languages is a must for any non-trivial software project. +- The interface should separate the logic of a program from +- the myriad of translations that may be necessary.</p> +- +- <p>The interface described in this document provides such +- functionality. The underlying implementation is also allowed to +- use whatever datastructures it likes to provide access to the +- translations in the most efficient manner possible. In +- addition, the implementation is provided with standardized +- functions that programs will use for accessing an external, +- unspecified repository of translations.</p> +- +- <p>This interface <i>does not</i> cover all aspects of +- localization, including support for non-latin characters, +- number and date formatting, etc. Such functionality is the +- scope of a future SRFI that may extend this one.</p> +- +- <H1>Dependencies</H1> +- +- An SRFI-29 conformant implementation must also implement +- SRFI-28, Basic Format Strings. Message templates are strings +- that must be processed by the <tt>format</tt> function +- specified in that SRFI. +- +- <H1>Specification</H1> +- +- <h3>Message Bundles</h3> +- +- <p>A Message Bundle is a set of message templates and their +- identifying keys. Each bundle contains one or more such +- key/value pairs. The bundle itself is associated with a +- <i>bundle specifier</i> which uniquely identifies the +- bundle.</p> +- +- <h3>Bundle Specifiers</h3> +- +- <p>A Bundle Specifier is a Scheme list that describes, in order +- of importance, the package and locale of a message bundle. +- In most cases, a locale specifier will have between one +- and three elements. The first element is a symbol denoting the +- package for which this bundle applies. The second and third +- elements denote a <i>locale</i>. The second element (first +- element of the locale) if present, is the two letter, ISO 639-1 +- language code for the bundle. The third element, if present, is +- a two letter ISO 3166-1 country code. In some cases, a +- fourth element may be present, specifying the encoding used for +- the bundle. All bundle specifier elements are Scheme +- symbols.</p> +- +- <p>If only one translation is provided, it should be designated +- only by a package name, for example <tt>(mathlib)</tt>. This +- translation is called the <i>default</i> translation.</p> +- +- <h3>Bundle Searching</h3> +- +- <p>When a message template is retrieved from a bundle, the +- Scheme implementation will provide the locale under which the +- system is currently running. When the template is retrieved, +- the package name will be specified. The Scheme system should +- construct a Bundle Specifier from the provided package name and +- the active locale. For example, when retrieving a message +- template for French Canadian, in the <tt>mathlib</tt> package, +- the bundle specifier '<tt>(mathlib fr ca)</tt>' is used. A +- program may also retrieve the elements of the current locale +- using the no-argument procedures:</p> +- +- <p><b><a name="current-language"></a><tt>current-language</tt></b> <tt>-> +- <i>symbol</i></tt><br> +- <tt><b>current-language</b> <i>symbol</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- When given no arguments, returns the current ISO 639-1 +- language code as a symbol. If provided with an +- argument, the current language is set to that named by the +- symbol for the currently executing Scheme thread (or for the +- entire Scheme system if such a distinction is not possible). +- +- </blockquote> +- +- <p><b><a name="current-country"></a><tt>current-country</tt></b> <tt>-> +- <i>symbol</i></tt><br> +- <tt><b>current-country</b> <i>symbol</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- returns the current ISO 3166-1 country code as a symbol. +- If provided with an argument, the current country is +- set to that named by the symbol for the currently executing +- Scheme thread (or for the entire Scheme system if such a +- distinction is not possible). +- </blockquote> +- +- <p><b><a name="current-locale-details"></a><tt>current-locale-details</tt></b> <tt>-> <i>list of +- symbol</i></tt>s<br> +- <tt><b>current-locale-details</b> <i>list-of-symbols</i> -> +- undefined</tt><br> +- </p> +- +- <blockquote> +- Returns a list of additional locale details as a list of +- symbols. This list may contain information about +- encodings or other more specific information. If +- provided with an argument, the current locale details are set +- to those given in the currently executing Scheme thread (or +- for the entire Scheme system if such a distinction is not +- possible). +- </blockquote> +- +- <p>The Scheme System should first check for a bundle with the +- exact name provided. If no such bundle is found, the last +- element from the list is removed and a search is tried for a +- bundle with that name. If no bundle is then found, the list is +- shortened by removing the last element again. If no message is +- found and the bundle specifier is now the empty list, an error +- should be raised.</p> +- +- <p>The reason for this search order is to provide the most +- locale sensitive template possible, but to fall back on more +- general templates if a translation has not yet been provided +- for the given locale.</p> +- +- <h3>Message Templates</h3> +- +- <p>A message template is a localized message that may or may +- not contain one of a number of formatting codes. A message +- template is a Scheme string. The string is of a form that can +- be processed by the <tt>format</tt> procedure found in many +- Scheme systems and formally specified in SRFI-28 (Basic Format +- Strings).</p> +- +- <p>This SRFI also extends SRFI-28 to provide an additional +- <tt>format</tt> escape code:</p> +- +- <blockquote> +- <tt>~[n]@*</tt> - Causes a value-requiring escape code that +- follows this code immediately to reference the [N]'th +- optional value absolutely, rather than the next unconsumed +- value. The referenced value is <i>not</i> consumed. +- </blockquote> +- This extension allows optional values to be positionally +- referenced, so that message templates can be constructed that +- can produce the proper word ordering for a language. +- +- <h3>Preparing Bundles</h3> +- Before a bundle may be used by the Scheme system to retrieve +- localized template messages, they must be made available to the +- Scheme system. This SRFI specifies a way to portably +- define the bundles, as well as store them in and retrieve them +- from an unspecified system which may be provided by resources +- outside the Scheme system.<br> +- +- +- <p><b><a name="declare-bundle!"></a><tt>declare-bundle!</tt></b> <tt><i>bundle-specifier +- association-list</i> -> undefined<br> +- </tt></p> +- +- <blockquote> +- Declares a new bundle named by the given bundle-specifier. +- The contents of the bundle are defined by the provided +- association list. The list contains associations +- between Scheme symbols and the message templates (Scheme +- strings) they name. If a bundle already exists with the +- given name, it is overwritten with the newly declared +- bundle.<br> +- </blockquote> +- <tt><a name="store-bundle"></a><b>store-bundle</b> <i>bundle-specifier</i> -> +- boolean</tt><br> +- +- +- <blockquote> +- Attempts to store a bundle named by the given bundle +- specifier, and previously made available using +- <tt>declare-bundle!</tt> or <tt>load-bundle!</tt>, in an +- unspecified mechanism that may be persistent across Scheme +- system restarts. If successful, a non-false value is +- returned. If unsuccessful, <tt>#f</tt> is returned.<br> +- </blockquote> +- <tt><a name="load-bundle!"></a><b>load-bundle!</b> <i>bundle-specifier</i> -> +- boolean</tt><br> +- +- +- <blockquote> +- Attempts to retrieve a bundle from an unspecified mechanism +- which stores bundles outside the Scheme system. If the +- bundle was retrieved successfully, the function returns a +- non-false value, and the bundle is immediately available to +- the Scheme system. If the bundle could not be found or loaded +- successfully, the function returns <tt>#f</tt>, and the +- Scheme system's bundle registry remains unaffected.<br> +- </blockquote> +- A compliant Scheme system may choose not to provide any +- external mechanism to store localized bundles. If it does +- not, it must still provide implementations for +- <tt>store-bundle</tt> and <tt>load-bundle!</tt>. In such a +- case, both functions must return <tt>#f</tt> regardless of the +- arguments given. Users of this SRFI should recognize that the +- inability to load or store a localized bundle in an external +- repository is <i>not</i> a fatal error.<br> +- +- +- <h3>Retrieving Localized Message Templates</h3> +- +- <p><a name="localized-template"></a><b><tt>localized-template</tt></b> <i><tt>package-name +- message-template-name</tt></i> <tt>-> <i>string or #f<br> +- </i></tt></p> +- +- <blockquote> +- Retrieves a localized message template for the given package +- name and the given message template name (both symbols). +- If no such message could be found, false (#f) is +- returned.<br> +- <br> +- </blockquote> +- After retrieving a template, the calling program can use +- <tt>format</tt> to produce a string that can be displayed to +- the user.<br> +- +- +- <h2>Examples</h2> +- The below example makes use of SRFI-29 to display simple, +- localized messages. It also defines its bundles in such a +- way that the Scheme system may store and retrieve the bundles +- from a more efficient system catalog, if available.<br> +- +-<pre> +-(let ((translations +- '(((en) . ((time . "Its ~a, ~a.") +- (goodbye . "Goodbye, ~a."))) +- ((fr) . ((time . "~1@*~a, c'est ~a.") +- (goodbye . "Au revoir, ~a.")))))) +- (for-each (lambda (translation) +- (let ((bundle-name (cons 'hello-program (car translation)))) +- (if (not (load-bundle! bundle-name)) +- (begin +- (declare-bundle! bundle-name (cdr translation)) +- (store-bundle! bundle-name))))) +- translations)) +- +-(define localized-message +- (lambda (message-name . args) +- (apply format (cons (localized-template 'hello-program +- message-name) +- args)))) +- +-(let ((myname "Fred")) +- (display (localized-message 'time "12:00" myname)) +- (display #\newline) +- +- (display (localized-message 'goodbye myname)) +- (display #\newline)) +- +-;; Displays (English): +-;; Its 12:00, Fred. +-;; Goodbye, Fred. +-;; +-;; French: +-;; Fred, c'est 12:00. +-;; Au revoir, Fred. +-</pre> +- +- <H1>Implementation</H1> +- +- <p>The implementation requires that the Scheme system provide a +- definition for <tt>current-language</tt> and +- <tt>current-country</tt> capable of distinguishing the correct +- locale present during a Scheme session. The definitions of +- those functions in the reference implementation are not capable +- of that distinction. Their implementation is provided only so +- that the following code can run in any R4RS scheme system. +- <br> +- </p> +- +- <p>In addition, the below implementation of a compliant +- <tt>format</tt> requires SRFI-6 (Basic String Ports) and +- SRFI-23 (Error reporting)</p> +-<pre> +-;; The association list in which bundles will be stored +-(define *localization-bundles* '()) +- +-;; The current-language and current-country functions provided +-;; here must be rewritten for each Scheme system to default to the +-;; actual locale of the session +-(define current-language +- (let ((current-language-value 'en)) +- (lambda args +- (if (null? args) +- current-language-value +- (set! current-language-value (car args)))))) +- +-(define current-country +- (let ((current-country-value 'us)) +- (lambda args +- (if (null? args) +- current-country-value +- (set! current-country-value (car args)))))) +- +-;; The load-bundle! and store-bundle! both return #f in this +-;; reference implementation. A compliant implementation need +-;; not rewrite these procedures. +-(define load-bundle! +- (lambda (bundle-specifier) +- #f)) +- +-(define store-bundle! +- (lambda (bundle-specifier) +- #f)) +- +-;; Declare a bundle of templates with a given bundle specifier +-(define declare-bundle! +- (letrec ((remove-old-bundle +- (lambda (specifier bundle) +- (cond ((null? bundle) '()) +- ((equal? (caar bundle) specifier) +- (cdr bundle)) +- (else (cons (car bundle) +- (remove-old-bundle specifier +- (cdr bundle)))))))) +- (lambda (bundle-specifier bundle-assoc-list) +- (set! *localization-bundles* +- (cons (cons bundle-specifier bundle-assoc-list) +- (remove-old-bundle bundle-specifier +- *localization-bundles*)))))) +- +-;;Retrieve a localized template given its package name and a template name +-(define localized-template +- (letrec ((rdc +- (lambda (ls) +- (if (null? (cdr ls)) +- '() +- (cons (car ls) (rdc (cdr ls)))))) +- (find-bundle +- (lambda (specifier template-name) +- (cond ((assoc specifier *localization-bundles*) => +- (lambda (bundle) bundle)) +- ((null? specifier) #f) +- (else (find-bundle (rdc specifier) +- template-name)))))) +- (lambda (package-name template-name) +- (let loop ((specifier (cons package-name +- (list (current-language) +- (current-country))))) +- (and (not (null? specifier)) +- (let ((bundle (find-bundle specifier template-name))) +- (and bundle +- (cond ((assq template-name bundle) => cdr) +- ((null? (cdr specifier)) #f) +- (else (loop (rdc specifier))))))))))) +- +-;;An SRFI-28 and SRFI-29 compliant version of format. It requires +-;;SRFI-23 for error reporting. +-(define format +- (lambda (format-string . objects) +- (let ((buffer (open-output-string))) +- (let loop ((format-list (string->list format-string)) +- (objects objects) +- (object-override #f)) +- (cond ((null? format-list) (get-output-string buffer)) +- ((char=? (car format-list) #~) +- (cond ((null? (cdr format-list)) +- (error 'format "Incomplete escape sequence")) +- ((char-numeric? (cadr format-list)) +- (let posloop ((fl (cddr format-list)) +- (pos (string->number +- (string (cadr format-list))))) +- (cond ((null? fl) +- (error 'format "Incomplete escape sequence")) +- ((and (eq? (car fl) '#@) +- (null? (cdr fl))) +- (error 'format "Incomplete escape sequence")) +- ((and (eq? (car fl) '#@) +- (eq? (cadr fl) '#*)) +- (loop (cddr fl) objects (list-ref objects pos))) +- (else +- (posloop (cdr fl) +- (+ (* 10 pos) +- (string->number +- (string (car fl))))))))) +- (else +- (case (cadr format-list) +- ((#\a) +- (cond (object-override +- (begin +- (display object-override buffer) +- (loop (cddr format-list) objects #f))) +- ((null? objects) +- (error 'format "No value for escape sequence")) +- (else +- (begin +- (display (car objects) buffer) +- (loop (cddr format-list) +- (cdr objects) #f))))) +- ((#\s) +- (cond (object-override +- (begin +- (display object-override buffer) +- (loop (cddr format-list) objects #f))) +- ((null? objects) +- (error 'format "No value for escape sequence")) +- (else +- (begin +- (write (car objects) buffer) +- (loop (cddr format-list) +- (cdr objects) #f))))) +- ((#%) +- (if object-override +- (error 'format "Escape sequence following positional override does not require a value")) +- (display #\newline buffer) +- (loop (cddr format-list) objects #f)) +- ((#~) +- (if object-override +- (error 'format "Escape sequence following positional override does not require a value")) +- (display #~ buffer) +- (loop (cddr format-list) objects #f)) +- (else +- (error 'format "Unrecognized escape sequence")))))) +- (else (display (car format-list) buffer) +- (loop (cdr format-list) objects #f))))))) +- +-</pre> +- +- <H1>Copyright</H1> +- +- Copyright (C) Scott G. Miller (2002). All Rights Reserved. +- +- <p>This document and translations of it may be copied and +- furnished to others, and derivative works that comment on or +- otherwise explain it or assist in its implementation may be +- prepared, copied, published and distributed, in whole or in +- part, without restriction of any kind, provided that the above +- copyright notice and this paragraph are included on all such +- copies and derivative works. However, this document itself may +- not be modified in any way, such as by removing the copyright +- notice or references to the Scheme Request For Implementation +- process or editors, except as needed for the purpose of +- developing SRFIs in which case the procedures for copyrights +- defined in the SRFI process must be followed, or as required to +- translate it into languages other than English.</p> +- +- <p>The limited permissions granted above are perpetual and will +- not be revoked by the authors or their successors or +- assigns.</p> +- +- <p>This document and the information contained herein is +- provided on an "AS IS" basis and THE AUTHOR AND THE SRFI +- EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION +- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES +- OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> +- <hr> +- +- <address> +- Editor: <a href="mailto:srfi-editors@srfi.schemers.org">David +- Rush</a> +- </address> +- +- <address> +- Author: <a href="mailto:scgmille@freenetproject.org">Scott G. +- Miller</a> +- </address> +- <!-- Created: Tue Sep 29 19:20:08 EDT 1998 --> +- <!-- hhmts start -->Last modified: Mon Jun 17 12:00:08 Pacific +- Daylight Time 2002 <!-- hhmts end --> <br> +- </body> +-</html> +- +diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html +--- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/srfi-std/srfi-5.html 1969-12-31 19:00:00.000000000 -0500 +@@ -1,345 +0,0 @@ +-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"> +-<html> +-<head> +- <title>SRFI 5: A compatible let form with signatures and rest arguments</title> +-</head> +-<body> +- +-<H1>Title</H1> +- +-SRFI-5: A compatible <code>let</code> form with signatures and rest arguments +- +-<H1>Author</H1> +- +-Andy Gaynor +- +-<H1>Status</H1> +- +-This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>. +-You can access the discussion on this SRFI via <A HREF="http://srfi.schemers.org/srfi-5/mail-archive/maillist.html">the archive of the mailing list</A>. +-<P><UL> +-<LI>Received: 1999/2/2 +-<LI>Draft: 1999/2/10-1999/04/12 +-<LI>Final: 1999/4/26 +-<LI>Revised reference implementation: 2003/01/27 +-</UL> +- +-<H1>Abstract</H1> +- +-The <i>named-let</i> incarnation of the <code>let</code> form has two slight +-inconsistencies with the <code>define</code> form. As defined, the <code>let</code> +-form makes no accommodation for rest arguments, an issue of functionality +-and consistency. As defined, the <code>let</code> form does not accommodate +-signature-style syntax, an issue of aesthetics and consistency. Both +-issues are addressed here in a manner which is compatible with the traditional +-<code>let</code> form but for minor extensions. +- +-<H1>Rationale</H1> +- +-<H2>Signature-style Syntax</H2> +- +-Consider the following two equivalent definitions: +- +-<p><pre> +-(define fibonacci +- (lambda (n i f0 f1) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1))))) +- +-(define (fibonacci n i f0 f1) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-</pre> +- +-Although there is a named-let analog for the former form, there is none +-for the latter. To wit, suppose one wished to compute the 10th element +-of the Fibonacci sequence using a named let: +- +-<p> +-<pre> +-(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-Values: 55 +-</pre> +- +-As it stands, one cannot equivalently write +- +-<p> +-<pre> +-(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) +- (if (= i n) +- f0 +- (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-</pre> +- +-which is consistent with <code>define</code>'s signature-style form. +-<p>Those that favor the signature style may prefer this extension. +-In any case, it may be more appropriate to include all bound names within +-the binding section. As presented, this straightforward extension +-introduces no ambiguity or incompatibility with the existing definition +-of let. +- +-<H2>Rest Arguments</H2> +- +-As it stands, one cannot write a named let with rest arguments, as in +- +-<p> +-<pre> +-(let (blast (port (current-output-port)) . (x (+ 1 2) 4 5)) +- (if (null? x) +- 'just-a-silly-contrived-example +- (begin +- (write (car x) port) +- (apply blast port (cdr x))))) +-</pre> +- +-otherwise equivalent to +- +-<p> +-<pre> +-(letrec ((blast (lambda (port . x) +- (if (null? x) +- 'just-a-silly-contrived-example +- (begin +- (write (car x) port) +- (apply blast port (cdr x))))))) +- (blast (current-output-port) (+ 1 2) 4 5)) +-</pre> +- +-While this example is rather contrived, the functionality is not. +-There are several times when the author has used this construct in practice. +-Regardless, there is little reason to deny the <code>let</code> form access to +-all the features of lambda functionality. +- +-<H2>Symbols in Binding Sections</H2> +- +-Both the features above rely upon the placement of symbols in <code>let</code> +-binding lists (this statement is intentially simplistic). The only +-other apparent use of such symbol placement is to tersely bind variables +-to unspecified values. For example, one might desire to use +-<code>(let (foo bar baz) ...)</code> +-to bind <code>foo</code>, <code>bar</code>, and <code>baz</code> to +-unspecified values. +- +-<p>This usage is considered less important in light of the rationales +-presented above, and an alternate syntax is immediately apparent, as +-in <code>(let ((foo) (bar) (baz)) ...)</code> This may even +-be preferable, consistently parenthesizing normal binding clauses. +- +-<H1>Specification</H1> +- +-<H2>Syntax</H2> +- +-<p> +-A formal specification of the syntax follows. Below, body, expression, +-and identifier are free. Each instantiation of binding-name must be +-unique. +-</p> +- +-<p> +-<pre> +- let = "(" "let" let-bindings body ")" +- expressions = nothing | expression expressions +- let-bindings = let-name bindings +- |"(" let-name "." bindings ")" +- let-name = identifier +- bindings = "(" ")" +- | rest-binding +- | "(" normal-bindings ["." rest-binding] ")" +-normal-bindings = nothing +- | normal-binding normal-bindings +-normal-binding = "(" binding-name expression ")" +- binding-name = identifier +- rest-binding = "(" binding-name expressions ")" +-</pre> +- +-<p> +-For clarity and convenience, an informal specification follows. +-</p> +- +-<ol> +-<li><a name="unnamed">Unnamed</a> +- +-<p><pre> +-(let ((<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-non-sig"> +-Named, non-signature-style, no rest argument</a> +- +-<p><pre> +-(let <name> ((<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-sig">Named, signature-style, no rest argument</a> +- +-<p><pre> +-(let (<name> (<parameter> <argument>)...) +- <body>...) +-</pre> +-</li> +- +-<li><a name="named-non-sig-rest">Named, non-signature-style, rest argument</a> +- +-<p><pre> +-(let <name> ((<parameter> <argument>)... +- +-. (<rest-parameter> <rest-argument>...)) +- <body>...) +-</pre> +- +-<li><a name="named-sig-rest">Named, signature-style, rest argument</a> +- +-<p><pre> +-(let (<name> (<parameter> <argument>)... +- +-. (<rest-parameter> <rest-argument>...)) +- <body>...) +-</pre> +-</li> +-</ol> +- +-<H2>Semantics</H2> +- +-Let <code>$lambda</code> and <code>$letrec</code> be hygienic bindings for the <code>lambda</code> +-and <code>letrec</code> forms, respectively. +- +-<ul> +-<li>For informal syntax 1: +- +-<p><pre> +-(($lambda (<parameter>...) <body>...) <argument>...) +-</pre> +-</li> +- +-<li>For informal syntaxes 2 and 3: +- +-<p> +-<pre> +-($letrec ((<name> ($lambda (<parameter>...) <body>...))) +- (<name> <argument>...)) +-</pre> +-</li> +- +-<li>For informal syntaxes 4 and 5: +- +-<p> +-<pre> +-($letrec ((<name> ($lambda (<parameter>... +- +-. <rest-parameter>) <body>...))) +- (<name> <argument>... <rest-argument>...)) +-</pre> +-</li> +-</ul> +- +-<H1>Implementation</H1> +- +-Here is an implementation using <code>SYNTAX-RULES</code>. +- +-<p> +-<pre> +-;; Use your own standard let. +-;; Or call a lambda. +-;; (define-syntax standard-let +-;; +-;; (syntax-rules () +-;; +-;; ((let ((var val) ...) body ...) +-;; ((lambda (var ...) body ...) val ...)))) +- +-(define-syntax let +- +- (syntax-rules () +- +- ;; No bindings: use standard-let. +- ((let () body ...) +- (standard-let () body ...)) +- ;; Or call a lambda. +- ;; ((lambda () body ...)) +- +- ;; All standard bindings: use standard-let. +- ((let ((var val) ...) body ...) +- (standard-let ((var val) ...) body ...)) +- ;; Or call a lambda. +- ;; ((lambda (var ...) body ...) val ...) +- +- ;; One standard binding: loop. +- ;; The all-standard-bindings clause didn't match, +- ;; so there must be a rest binding. +- ((let ((var val) . bindings) body ...) +- (let-loop #f bindings (var) (val) (body ...))) +- +- ;; Signature-style name: loop. +- ((let (name binding ...) body ...) +- (let-loop name (binding ...) () () (body ...))) +- +- ;; defun-style name: loop. +- ((let name bindings body ...) +- (let-loop name bindings () () (body ...))))) +- +-(define-syntax let-loop +- +- (syntax-rules () +- +- ;; Standard binding: destructure and loop. +- ((let-loop name ((var0 val0) binding ...) (var ... ) (val ... ) body) +- (let-loop name ( binding ...) (var ... var0) (val ... val0) body)) +- +- ;; Rest binding, no name: use standard-let, listing the rest values. +- ;; Because of let's first clause, there is no "no bindings, no name" clause. +- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) +- (standard-let ((var val) ... (rest-var (list rest-val ...))) . body)) +- ;; Or call a lambda with a rest parameter on all values. +- ;; ((lambda (var ... . rest-var) . body) val ... rest-val ...)) +- ;; Or use one of several other reasonable alternatives. +- +- ;; No bindings, name: call a letrec'ed lambda. +- ((let-loop name () (var ...) (val ...) body) +- ((letrec ((name (lambda (var ...) . body))) +- name) +- val ...)) +- +- ;; Rest binding, name: call a letrec'ed lambda. +- ((let-loop name (rest-var rest-val ...) (var ...) (val ...) body) +- ((letrec ((name (lambda (var ... . rest-var) . body))) +- name) +- val ... rest-val ...)))) +-</pre> +- +- +-<H1>Copyright</H1> +- +-Copyright (C) Andy Gaynor (1999). All Rights Reserved. +-<p>This document and translations of it may be copied and furnished to +-others, and derivative works that comment on or otherwise explain it or +-assist in its implementation may be prepared, copied, published and distributed, +-in whole or in part, without restriction of any kind, provided that the +-above copyright notice and this paragraph are included on all such copies +-and derivative works. However, this document itself may not be modified +-in any way, such as by removing the copyright notice or references to the +-Scheme Request For Implementation process or editors, except as needed +-for the purpose of developing SRFIs in which case the procedures for copyrights +-defined in the SRFI process must be followed, or as required to translate +-it into languages other than English. +-<p>The limited permissions granted above are perpetual and will not be +-revoked by the authors or their successors or assigns. +-<p>This document and the information contained herein is provided on an +-"AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, +-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE +-USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +-WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +- <hr> +- <address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address> +- +-</body> +-</html> +diff -urN racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/util.rkt racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/util.rkt +--- racket-6.12-orig/share/pkgs/srfi-doc/srfi/scribblings/util.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc/srfi/scribblings/util.rkt 2018-01-31 12:22:58.144502000 -0500 +@@ -0,0 +1,61 @@ ++#lang scribble/doc ++ ++@(require scribble/manual ++ scribble/eval ++ scriblib/render-cond ++ scribble/core ++ scribble/html-properties ++ (for-syntax scheme/base) ++ (for-label scheme/base ++ racket/stream)) ++ ++@(provide (all-defined-out)) ++ ++@(define-syntax (srfi stx) ++ (syntax-case stx () ++ [(_ num #:subdir subdir? . title) ++ (with-syntax ([srfi/n (string->symbol (format "srfi/~a" (syntax-e #'num)))]) ++ #'(begin ++ (section #:tag (format "srfi-~a" num) ++ #:style 'unnumbered ++ (format "SRFI ~a: " num) ++ . title) ++ (defmodule srfi/n) ++ "Original specification: " ++ (let* ([label (format "SRFI ~a" num)] ++ [sub (if subdir? (format "srfi-~a/" num) "")] ++ [url ( (b) (format "~a/srfi-std/~asrfi-~a.html" b sub num))]) ++ (cond-element ++ [(or latex text) @link[(url "http://docs.racket-lang.org") label]] ++ [else @link[(url ".") label]]))))] ++ [(_ num . title) #'(srfi num #:subdir #f . title)])) ++ ++@;{ The `lst' argument is a list of ++ (list sym syntactic-form? html-anchor) } ++@(define (redirect n lst #:subdir [subdir? #f]) ++ (let ([file (if subdir? ++ (format "srfi-~a/srfi-~a.html" n n) ++ (format "srfi-~a.html" n))] ++ [mod-path (string->symbol (format "srfi/~a" n))]) ++ (make-binding-redirect-elements mod-path ++ (map (lambda (b) ++ (list (car b) (cadr b) ++ (build-path "srfi-std" file) ++ (caddr b))) ++ lst)))) ++ ++@(define in-core ++ (case-lambda ++ [() (in-core ".")] ++ [(k) @elem{This SRFI's bindings are also available in ++ @racketmodname[racket/base]@|k|}])) ++ ++@(begin ++ (define-syntax-rule (def-mz mz-if) ++ (begin ++ (require (for-label mzscheme)) ++ (define mz-if (racket if)))) ++ (def-mz mz-if)) ++ ++@(define srfi-std (style #f (list (install-resource "srfi-std")))) ++ +diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt +--- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/info.rkt 2018-01-31 12:22:58.144502000 -0500 +@@ -0,0 +1,19 @@ ++#lang info ++ ++(define collection 'multi) ++ ++(define build-deps '("mzscheme-doc" ++ "scheme-lib" ++ "base" ++ "scribble-lib" ++ "srfi-doc" ++ "srfi-lib-nonfree" ++ "racket-doc" ++ "r5rs-doc" ++ "r6rs-doc" ++ "compatibility-lib")) ++(define update-implies '("srfi-lib-nonfree")) ++ ++(define pkg-desc "documentation part of "srfi nonfree"") ++ ++(define pkg-authors '(mflatt noel chongkai jay)) +diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt +--- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/info.rkt 2018-01-31 12:22:58.144502000 -0500 +@@ -0,0 +1,3 @@ ++#lang info ++ ++(define scribblings '(("srfi-nf.scrbl" (multi-page) (library 100)))) +diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl +--- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-nf.scrbl 2018-01-31 12:22:58.144502000 -0500 +@@ -0,0 +1,66 @@ ++#lang scribble/doc ++@(require srfi/scribblings/util ++ scribble/manual ++ scribble/eval ++ scriblib/render-cond ++ scribble/core ++ scribble/html-properties ++ (for-syntax scheme/base) ++ (for-label scheme/base ++ racket/stream)) ++ ++@; ---------------------------------------------------------------------- ++ ++@title{SRFI Nonfree Libraries and Documentation} ++ ++The @link[#:style srfi-std "http://srfi.schemers.org/%22%5D%7BScheme Requests for ++Implementation} (a.k.a. @deftech{SRFI}) process allows individual ++members of the Scheme community to propose libraries and extensions to ++be supported by multiple Scheme implementations. ++ ++Racket is distributed with implementations of many SRFIs, most of ++which can be implemented as libraries. To import the bindings of SRFI ++@math{n}, use ++ ++@racketblock[ ++(require @#,elem{@racketidfont{srfi/}@math{n}}) ++] ++ ++This document lists the SRFIs that are supported by Racket and ++provides a link to the original SRFI specification (which is also ++distributed as part of Racket's documentation). ++ ++The following SRFI specification documents are licensed restrictively. ++ ++@table-of-contents[] ++ ++ ++@; ---------------------------------------- ++ ++@srfi[5]{A compatible let form with signatures and rest arguments} ++ ++@redirect[5 '( ++ (let #t "unnamed") ++)] ++ ++Racket provides this SRFI in the @racket[srfi-lib-nonfree] package. ++ ++@; ---------------------------------------- ++ ++@srfi[29]{Localization} ++ ++@redirect[29 '( ++ (current-language #f "current-language") ++ (current-country #f "current-country") ++ (current-locale-details #f "current-locale-details") ++ (declare-bundle! #f "declare-bundle!") ++ (store-bundle #f "store-bundle") ++ (load-bundle! #f "load-bundle!") ++ (localized-template #f "localized-template") ++)] ++ ++Racket provides a free implementation of this SRFI in the @racket[srfi-lib] package. Only the SRFI specification document is nonfree. ++ ++@; ---------------------------------------- ++ ++@index-section[] +diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html +--- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-29.html 2018-01-31 12:22:58.144502000 -0500 +@@ -0,0 +1,507 @@ ++<!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN"> ++<html> ++ <head> ++ <meta name="generator" content="HTML Tidy, see www.w3.org"> ++ <title>SRFI 29: Localization</title> ++ <meta name="author" content="Scott G. Miller"> ++ <meta name="description" content="Localization"> ++ </head> ++ <body> ++ <H1>Title</H1> ++ ++ SRFI 29: Localization ++ ++ <H1>Author</H1> ++ ++ Scott G. Miller ++ ++ <H1>Abstract</H1> ++ ++ This document specifies an interface to retrieving and ++ displaying locale sensitive messages. A Scheme program can ++ register one or more translations of templated messages, and ++ then write Scheme code that can transparently retrieve the ++ appropriate message for the locale under which the Scheme ++ system is running. <br> ++ ++ ++ <H1>Rationale</H1> ++ ++ <p>As any programmer that has ever had to deal with making his ++ or her code readable in more than one locale, the process of ++ sufficiently abstracting program messages from their ++ presentation to the user is non-trivial without help from the ++ programming language. Most modern programming language ++ libraries do provide some mechanism for performing this ++ separation.</p> ++ ++ <p>A portable API that allows a piece of code to run without ++ modification in different countries and under different ++ languages is a must for any non-trivial software project. ++ The interface should separate the logic of a program from ++ the myriad of translations that may be necessary.</p> ++ ++ <p>The interface described in this document provides such ++ functionality. The underlying implementation is also allowed to ++ use whatever datastructures it likes to provide access to the ++ translations in the most efficient manner possible. In ++ addition, the implementation is provided with standardized ++ functions that programs will use for accessing an external, ++ unspecified repository of translations.</p> ++ ++ <p>This interface <i>does not</i> cover all aspects of ++ localization, including support for non-latin characters, ++ number and date formatting, etc. Such functionality is the ++ scope of a future SRFI that may extend this one.</p> ++ ++ <H1>Dependencies</H1> ++ ++ An SRFI-29 conformant implementation must also implement ++ SRFI-28, Basic Format Strings. Message templates are strings ++ that must be processed by the <tt>format</tt> function ++ specified in that SRFI. ++ ++ <H1>Specification</H1> ++ ++ <h3>Message Bundles</h3> ++ ++ <p>A Message Bundle is a set of message templates and their ++ identifying keys. Each bundle contains one or more such ++ key/value pairs. The bundle itself is associated with a ++ <i>bundle specifier</i> which uniquely identifies the ++ bundle.</p> ++ ++ <h3>Bundle Specifiers</h3> ++ ++ <p>A Bundle Specifier is a Scheme list that describes, in order ++ of importance, the package and locale of a message bundle. ++ In most cases, a locale specifier will have between one ++ and three elements. The first element is a symbol denoting the ++ package for which this bundle applies. The second and third ++ elements denote a <i>locale</i>. The second element (first ++ element of the locale) if present, is the two letter, ISO 639-1 ++ language code for the bundle. The third element, if present, is ++ a two letter ISO 3166-1 country code. In some cases, a ++ fourth element may be present, specifying the encoding used for ++ the bundle. All bundle specifier elements are Scheme ++ symbols.</p> ++ ++ <p>If only one translation is provided, it should be designated ++ only by a package name, for example <tt>(mathlib)</tt>. This ++ translation is called the <i>default</i> translation.</p> ++ ++ <h3>Bundle Searching</h3> ++ ++ <p>When a message template is retrieved from a bundle, the ++ Scheme implementation will provide the locale under which the ++ system is currently running. When the template is retrieved, ++ the package name will be specified. The Scheme system should ++ construct a Bundle Specifier from the provided package name and ++ the active locale. For example, when retrieving a message ++ template for French Canadian, in the <tt>mathlib</tt> package, ++ the bundle specifier '<tt>(mathlib fr ca)</tt>' is used. A ++ program may also retrieve the elements of the current locale ++ using the no-argument procedures:</p> ++ ++ <p><b><a name="current-language"></a><tt>current-language</tt></b> <tt>-> ++ <i>symbol</i></tt><br> ++ <tt><b>current-language</b> <i>symbol</i> -> ++ undefined</tt><br> ++ </p> ++ ++ <blockquote> ++ When given no arguments, returns the current ISO 639-1 ++ language code as a symbol. If provided with an ++ argument, the current language is set to that named by the ++ symbol for the currently executing Scheme thread (or for the ++ entire Scheme system if such a distinction is not possible). ++ ++ </blockquote> ++ ++ <p><b><a name="current-country"></a><tt>current-country</tt></b> <tt>-> ++ <i>symbol</i></tt><br> ++ <tt><b>current-country</b> <i>symbol</i> -> ++ undefined</tt><br> ++ </p> ++ ++ <blockquote> ++ returns the current ISO 3166-1 country code as a symbol. ++ If provided with an argument, the current country is ++ set to that named by the symbol for the currently executing ++ Scheme thread (or for the entire Scheme system if such a ++ distinction is not possible). ++ </blockquote> ++ ++ <p><b><a name="current-locale-details"></a><tt>current-locale-details</tt></b> <tt>-> <i>list of ++ symbol</i></tt>s<br> ++ <tt><b>current-locale-details</b> <i>list-of-symbols</i> -> ++ undefined</tt><br> ++ </p> ++ ++ <blockquote> ++ Returns a list of additional locale details as a list of ++ symbols. This list may contain information about ++ encodings or other more specific information. If ++ provided with an argument, the current locale details are set ++ to those given in the currently executing Scheme thread (or ++ for the entire Scheme system if such a distinction is not ++ possible). ++ </blockquote> ++ ++ <p>The Scheme System should first check for a bundle with the ++ exact name provided. If no such bundle is found, the last ++ element from the list is removed and a search is tried for a ++ bundle with that name. If no bundle is then found, the list is ++ shortened by removing the last element again. If no message is ++ found and the bundle specifier is now the empty list, an error ++ should be raised.</p> ++ ++ <p>The reason for this search order is to provide the most ++ locale sensitive template possible, but to fall back on more ++ general templates if a translation has not yet been provided ++ for the given locale.</p> ++ ++ <h3>Message Templates</h3> ++ ++ <p>A message template is a localized message that may or may ++ not contain one of a number of formatting codes. A message ++ template is a Scheme string. The string is of a form that can ++ be processed by the <tt>format</tt> procedure found in many ++ Scheme systems and formally specified in SRFI-28 (Basic Format ++ Strings).</p> ++ ++ <p>This SRFI also extends SRFI-28 to provide an additional ++ <tt>format</tt> escape code:</p> ++ ++ <blockquote> ++ <tt>~[n]@*</tt> - Causes a value-requiring escape code that ++ follows this code immediately to reference the [N]'th ++ optional value absolutely, rather than the next unconsumed ++ value. The referenced value is <i>not</i> consumed. ++ </blockquote> ++ This extension allows optional values to be positionally ++ referenced, so that message templates can be constructed that ++ can produce the proper word ordering for a language. ++ ++ <h3>Preparing Bundles</h3> ++ Before a bundle may be used by the Scheme system to retrieve ++ localized template messages, they must be made available to the ++ Scheme system. This SRFI specifies a way to portably ++ define the bundles, as well as store them in and retrieve them ++ from an unspecified system which may be provided by resources ++ outside the Scheme system.<br> ++ ++ ++ <p><b><a name="declare-bundle!"></a><tt>declare-bundle!</tt></b> <tt><i>bundle-specifier ++ association-list</i> -> undefined<br> ++ </tt></p> ++ ++ <blockquote> ++ Declares a new bundle named by the given bundle-specifier. ++ The contents of the bundle are defined by the provided ++ association list. The list contains associations ++ between Scheme symbols and the message templates (Scheme ++ strings) they name. If a bundle already exists with the ++ given name, it is overwritten with the newly declared ++ bundle.<br> ++ </blockquote> ++ <tt><a name="store-bundle"></a><b>store-bundle</b> <i>bundle-specifier</i> -> ++ boolean</tt><br> ++ ++ ++ <blockquote> ++ Attempts to store a bundle named by the given bundle ++ specifier, and previously made available using ++ <tt>declare-bundle!</tt> or <tt>load-bundle!</tt>, in an ++ unspecified mechanism that may be persistent across Scheme ++ system restarts. If successful, a non-false value is ++ returned. If unsuccessful, <tt>#f</tt> is returned.<br> ++ </blockquote> ++ <tt><a name="load-bundle!"></a><b>load-bundle!</b> <i>bundle-specifier</i> -> ++ boolean</tt><br> ++ ++ ++ <blockquote> ++ Attempts to retrieve a bundle from an unspecified mechanism ++ which stores bundles outside the Scheme system. If the ++ bundle was retrieved successfully, the function returns a ++ non-false value, and the bundle is immediately available to ++ the Scheme system. If the bundle could not be found or loaded ++ successfully, the function returns <tt>#f</tt>, and the ++ Scheme system's bundle registry remains unaffected.<br> ++ </blockquote> ++ A compliant Scheme system may choose not to provide any ++ external mechanism to store localized bundles. If it does ++ not, it must still provide implementations for ++ <tt>store-bundle</tt> and <tt>load-bundle!</tt>. In such a ++ case, both functions must return <tt>#f</tt> regardless of the ++ arguments given. Users of this SRFI should recognize that the ++ inability to load or store a localized bundle in an external ++ repository is <i>not</i> a fatal error.<br> ++ ++ ++ <h3>Retrieving Localized Message Templates</h3> ++ ++ <p><a name="localized-template"></a><b><tt>localized-template</tt></b> <i><tt>package-name ++ message-template-name</tt></i> <tt>-> <i>string or #f<br> ++ </i></tt></p> ++ ++ <blockquote> ++ Retrieves a localized message template for the given package ++ name and the given message template name (both symbols). ++ If no such message could be found, false (#f) is ++ returned.<br> ++ <br> ++ </blockquote> ++ After retrieving a template, the calling program can use ++ <tt>format</tt> to produce a string that can be displayed to ++ the user.<br> ++ ++ ++ <h2>Examples</h2> ++ The below example makes use of SRFI-29 to display simple, ++ localized messages. It also defines its bundles in such a ++ way that the Scheme system may store and retrieve the bundles ++ from a more efficient system catalog, if available.<br> ++ ++<pre> ++(let ((translations ++ '(((en) . ((time . "Its ~a, ~a.") ++ (goodbye . "Goodbye, ~a."))) ++ ((fr) . ((time . "~1@*~a, c'est ~a.") ++ (goodbye . "Au revoir, ~a.")))))) ++ (for-each (lambda (translation) ++ (let ((bundle-name (cons 'hello-program (car translation)))) ++ (if (not (load-bundle! bundle-name)) ++ (begin ++ (declare-bundle! bundle-name (cdr translation)) ++ (store-bundle! bundle-name))))) ++ translations)) ++ ++(define localized-message ++ (lambda (message-name . args) ++ (apply format (cons (localized-template 'hello-program ++ message-name) ++ args)))) ++ ++(let ((myname "Fred")) ++ (display (localized-message 'time "12:00" myname)) ++ (display #\newline) ++ ++ (display (localized-message 'goodbye myname)) ++ (display #\newline)) ++ ++;; Displays (English): ++;; Its 12:00, Fred. ++;; Goodbye, Fred. ++;; ++;; French: ++;; Fred, c'est 12:00. ++;; Au revoir, Fred. ++</pre> ++ ++ <H1>Implementation</H1> ++ ++ <p>The implementation requires that the Scheme system provide a ++ definition for <tt>current-language</tt> and ++ <tt>current-country</tt> capable of distinguishing the correct ++ locale present during a Scheme session. The definitions of ++ those functions in the reference implementation are not capable ++ of that distinction. Their implementation is provided only so ++ that the following code can run in any R4RS scheme system. ++ <br> ++ </p> ++ ++ <p>In addition, the below implementation of a compliant ++ <tt>format</tt> requires SRFI-6 (Basic String Ports) and ++ SRFI-23 (Error reporting)</p> ++<pre> ++;; The association list in which bundles will be stored ++(define *localization-bundles* '()) ++ ++;; The current-language and current-country functions provided ++;; here must be rewritten for each Scheme system to default to the ++;; actual locale of the session ++(define current-language ++ (let ((current-language-value 'en)) ++ (lambda args ++ (if (null? args) ++ current-language-value ++ (set! current-language-value (car args)))))) ++ ++(define current-country ++ (let ((current-country-value 'us)) ++ (lambda args ++ (if (null? args) ++ current-country-value ++ (set! current-country-value (car args)))))) ++ ++;; The load-bundle! and store-bundle! both return #f in this ++;; reference implementation. A compliant implementation need ++;; not rewrite these procedures. ++(define load-bundle! ++ (lambda (bundle-specifier) ++ #f)) ++ ++(define store-bundle! ++ (lambda (bundle-specifier) ++ #f)) ++ ++;; Declare a bundle of templates with a given bundle specifier ++(define declare-bundle! ++ (letrec ((remove-old-bundle ++ (lambda (specifier bundle) ++ (cond ((null? bundle) '()) ++ ((equal? (caar bundle) specifier) ++ (cdr bundle)) ++ (else (cons (car bundle) ++ (remove-old-bundle specifier ++ (cdr bundle)))))))) ++ (lambda (bundle-specifier bundle-assoc-list) ++ (set! *localization-bundles* ++ (cons (cons bundle-specifier bundle-assoc-list) ++ (remove-old-bundle bundle-specifier ++ *localization-bundles*)))))) ++ ++;;Retrieve a localized template given its package name and a template name ++(define localized-template ++ (letrec ((rdc ++ (lambda (ls) ++ (if (null? (cdr ls)) ++ '() ++ (cons (car ls) (rdc (cdr ls)))))) ++ (find-bundle ++ (lambda (specifier template-name) ++ (cond ((assoc specifier *localization-bundles*) => ++ (lambda (bundle) bundle)) ++ ((null? specifier) #f) ++ (else (find-bundle (rdc specifier) ++ template-name)))))) ++ (lambda (package-name template-name) ++ (let loop ((specifier (cons package-name ++ (list (current-language) ++ (current-country))))) ++ (and (not (null? specifier)) ++ (let ((bundle (find-bundle specifier template-name))) ++ (and bundle ++ (cond ((assq template-name bundle) => cdr) ++ ((null? (cdr specifier)) #f) ++ (else (loop (rdc specifier))))))))))) ++ ++;;An SRFI-28 and SRFI-29 compliant version of format. It requires ++;;SRFI-23 for error reporting. ++(define format ++ (lambda (format-string . objects) ++ (let ((buffer (open-output-string))) ++ (let loop ((format-list (string->list format-string)) ++ (objects objects) ++ (object-override #f)) ++ (cond ((null? format-list) (get-output-string buffer)) ++ ((char=? (car format-list) #~) ++ (cond ((null? (cdr format-list)) ++ (error 'format "Incomplete escape sequence")) ++ ((char-numeric? (cadr format-list)) ++ (let posloop ((fl (cddr format-list)) ++ (pos (string->number ++ (string (cadr format-list))))) ++ (cond ((null? fl) ++ (error 'format "Incomplete escape sequence")) ++ ((and (eq? (car fl) '#@) ++ (null? (cdr fl))) ++ (error 'format "Incomplete escape sequence")) ++ ((and (eq? (car fl) '#@) ++ (eq? (cadr fl) '#*)) ++ (loop (cddr fl) objects (list-ref objects pos))) ++ (else ++ (posloop (cdr fl) ++ (+ (* 10 pos) ++ (string->number ++ (string (car fl))))))))) ++ (else ++ (case (cadr format-list) ++ ((#\a) ++ (cond (object-override ++ (begin ++ (display object-override buffer) ++ (loop (cddr format-list) objects #f))) ++ ((null? objects) ++ (error 'format "No value for escape sequence")) ++ (else ++ (begin ++ (display (car objects) buffer) ++ (loop (cddr format-list) ++ (cdr objects) #f))))) ++ ((#\s) ++ (cond (object-override ++ (begin ++ (display object-override buffer) ++ (loop (cddr format-list) objects #f))) ++ ((null? objects) ++ (error 'format "No value for escape sequence")) ++ (else ++ (begin ++ (write (car objects) buffer) ++ (loop (cddr format-list) ++ (cdr objects) #f))))) ++ ((#%) ++ (if object-override ++ (error 'format "Escape sequence following positional override does not require a value")) ++ (display #\newline buffer) ++ (loop (cddr format-list) objects #f)) ++ ((#~) ++ (if object-override ++ (error 'format "Escape sequence following positional override does not require a value")) ++ (display #~ buffer) ++ (loop (cddr format-list) objects #f)) ++ (else ++ (error 'format "Unrecognized escape sequence")))))) ++ (else (display (car format-list) buffer) ++ (loop (cdr format-list) objects #f))))))) ++ ++</pre> ++ ++ <H1>Copyright</H1> ++ ++ Copyright (C) Scott G. Miller (2002). All Rights Reserved. ++ ++ <p>This document and translations of it may be copied and ++ furnished to others, and derivative works that comment on or ++ otherwise explain it or assist in its implementation may be ++ prepared, copied, published and distributed, in whole or in ++ part, without restriction of any kind, provided that the above ++ copyright notice and this paragraph are included on all such ++ copies and derivative works. However, this document itself may ++ not be modified in any way, such as by removing the copyright ++ notice or references to the Scheme Request For Implementation ++ process or editors, except as needed for the purpose of ++ developing SRFIs in which case the procedures for copyrights ++ defined in the SRFI process must be followed, or as required to ++ translate it into languages other than English.</p> ++ ++ <p>The limited permissions granted above are perpetual and will ++ not be revoked by the authors or their successors or ++ assigns.</p> ++ ++ <p>This document and the information contained herein is ++ provided on an "AS IS" basis and THE AUTHOR AND THE SRFI ++ EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING ++ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION ++ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES ++ OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.</p> ++ <hr> ++ ++ <address> ++ Editor: <a href="mailto:srfi-editors@srfi.schemers.org">David ++ Rush</a> ++ </address> ++ ++ <address> ++ Author: <a href="mailto:scgmille@freenetproject.org">Scott G. ++ Miller</a> ++ </address> ++ <!-- Created: Tue Sep 29 19:20:08 EDT 1998 --> ++ <!-- hhmts start -->Last modified: Mon Jun 17 12:00:08 Pacific ++ Daylight Time 2002 <!-- hhmts end --> <br> ++ </body> ++</html> ++ +diff -urN racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html +--- racket-6.12-orig/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-doc-nonfree/srfi/scribblings/srfi-std/srfi-5.html 2018-01-31 12:22:58.144502000 -0500 +@@ -0,0 +1,345 @@ ++<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN"> ++<html> ++<head> ++ <title>SRFI 5: A compatible let form with signatures and rest arguments</title> ++</head> ++<body> ++ ++<H1>Title</H1> ++ ++SRFI-5: A compatible <code>let</code> form with signatures and rest arguments ++ ++<H1>Author</H1> ++ ++Andy Gaynor ++ ++<H1>Status</H1> ++ ++This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>. ++You can access the discussion on this SRFI via <A HREF="http://srfi.schemers.org/srfi-5/mail-archive/maillist.html">the archive of the mailing list</A>. ++<P><UL> ++<LI>Received: 1999/2/2 ++<LI>Draft: 1999/2/10-1999/04/12 ++<LI>Final: 1999/4/26 ++<LI>Revised reference implementation: 2003/01/27 ++</UL> ++ ++<H1>Abstract</H1> ++ ++The <i>named-let</i> incarnation of the <code>let</code> form has two slight ++inconsistencies with the <code>define</code> form. As defined, the <code>let</code> ++form makes no accommodation for rest arguments, an issue of functionality ++and consistency. As defined, the <code>let</code> form does not accommodate ++signature-style syntax, an issue of aesthetics and consistency. Both ++issues are addressed here in a manner which is compatible with the traditional ++<code>let</code> form but for minor extensions. ++ ++<H1>Rationale</H1> ++ ++<H2>Signature-style Syntax</H2> ++ ++Consider the following two equivalent definitions: ++ ++<p><pre> ++(define fibonacci ++ (lambda (n i f0 f1) ++ (if (= i n) ++ f0 ++ (fibonacci n (+ i 1) f1 (+ f0 f1))))) ++ ++(define (fibonacci n i f0 f1) ++ (if (= i n) ++ f0 ++ (fibonacci n (+ i 1) f1 (+ f0 f1)))) ++</pre> ++ ++Although there is a named-let analog for the former form, there is none ++for the latter. To wit, suppose one wished to compute the 10th element ++of the Fibonacci sequence using a named let: ++ ++<p> ++<pre> ++(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) ++ (if (= i n) ++ f0 ++ (fibonacci n (+ i 1) f1 (+ f0 f1)))) ++Values: 55 ++</pre> ++ ++As it stands, one cannot equivalently write ++ ++<p> ++<pre> ++(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) ++ (if (= i n) ++ f0 ++ (fibonacci n (+ i 1) f1 (+ f0 f1)))) ++</pre> ++ ++which is consistent with <code>define</code>'s signature-style form. ++<p>Those that favor the signature style may prefer this extension. ++In any case, it may be more appropriate to include all bound names within ++the binding section. As presented, this straightforward extension ++introduces no ambiguity or incompatibility with the existing definition ++of let. ++ ++<H2>Rest Arguments</H2> ++ ++As it stands, one cannot write a named let with rest arguments, as in ++ ++<p> ++<pre> ++(let (blast (port (current-output-port)) . (x (+ 1 2) 4 5)) ++ (if (null? x) ++ 'just-a-silly-contrived-example ++ (begin ++ (write (car x) port) ++ (apply blast port (cdr x))))) ++</pre> ++ ++otherwise equivalent to ++ ++<p> ++<pre> ++(letrec ((blast (lambda (port . x) ++ (if (null? x) ++ 'just-a-silly-contrived-example ++ (begin ++ (write (car x) port) ++ (apply blast port (cdr x))))))) ++ (blast (current-output-port) (+ 1 2) 4 5)) ++</pre> ++ ++While this example is rather contrived, the functionality is not. ++There are several times when the author has used this construct in practice. ++Regardless, there is little reason to deny the <code>let</code> form access to ++all the features of lambda functionality. ++ ++<H2>Symbols in Binding Sections</H2> ++ ++Both the features above rely upon the placement of symbols in <code>let</code> ++binding lists (this statement is intentially simplistic). The only ++other apparent use of such symbol placement is to tersely bind variables ++to unspecified values. For example, one might desire to use ++<code>(let (foo bar baz) ...)</code> ++to bind <code>foo</code>, <code>bar</code>, and <code>baz</code> to ++unspecified values. ++ ++<p>This usage is considered less important in light of the rationales ++presented above, and an alternate syntax is immediately apparent, as ++in <code>(let ((foo) (bar) (baz)) ...)</code> This may even ++be preferable, consistently parenthesizing normal binding clauses. ++ ++<H1>Specification</H1> ++ ++<H2>Syntax</H2> ++ ++<p> ++A formal specification of the syntax follows. Below, body, expression, ++and identifier are free. Each instantiation of binding-name must be ++unique. ++</p> ++ ++<p> ++<pre> ++ let = "(" "let" let-bindings body ")" ++ expressions = nothing | expression expressions ++ let-bindings = let-name bindings ++ |"(" let-name "." bindings ")" ++ let-name = identifier ++ bindings = "(" ")" ++ | rest-binding ++ | "(" normal-bindings ["." rest-binding] ")" ++normal-bindings = nothing ++ | normal-binding normal-bindings ++normal-binding = "(" binding-name expression ")" ++ binding-name = identifier ++ rest-binding = "(" binding-name expressions ")" ++</pre> ++ ++<p> ++For clarity and convenience, an informal specification follows. ++</p> ++ ++<ol> ++<li><a name="unnamed">Unnamed</a> ++ ++<p><pre> ++(let ((<parameter> <argument>)...) ++ <body>...) ++</pre> ++</li> ++ ++<li><a name="named-non-sig"> ++Named, non-signature-style, no rest argument</a> ++ ++<p><pre> ++(let <name> ((<parameter> <argument>)...) ++ <body>...) ++</pre> ++</li> ++ ++<li><a name="named-sig">Named, signature-style, no rest argument</a> ++ ++<p><pre> ++(let (<name> (<parameter> <argument>)...) ++ <body>...) ++</pre> ++</li> ++ ++<li><a name="named-non-sig-rest">Named, non-signature-style, rest argument</a> ++ ++<p><pre> ++(let <name> ((<parameter> <argument>)... ++ ++. (<rest-parameter> <rest-argument>...)) ++ <body>...) ++</pre> ++ ++<li><a name="named-sig-rest">Named, signature-style, rest argument</a> ++ ++<p><pre> ++(let (<name> (<parameter> <argument>)... ++ ++. (<rest-parameter> <rest-argument>...)) ++ <body>...) ++</pre> ++</li> ++</ol> ++ ++<H2>Semantics</H2> ++ ++Let <code>$lambda</code> and <code>$letrec</code> be hygienic bindings for the <code>lambda</code> ++and <code>letrec</code> forms, respectively. ++ ++<ul> ++<li>For informal syntax 1: ++ ++<p><pre> ++(($lambda (<parameter>...) <body>...) <argument>...) ++</pre> ++</li> ++ ++<li>For informal syntaxes 2 and 3: ++ ++<p> ++<pre> ++($letrec ((<name> ($lambda (<parameter>...) <body>...))) ++ (<name> <argument>...)) ++</pre> ++</li> ++ ++<li>For informal syntaxes 4 and 5: ++ ++<p> ++<pre> ++($letrec ((<name> ($lambda (<parameter>... ++ ++. <rest-parameter>) <body>...))) ++ (<name> <argument>... <rest-argument>...)) ++</pre> ++</li> ++</ul> ++ ++<H1>Implementation</H1> ++ ++Here is an implementation using <code>SYNTAX-RULES</code>. ++ ++<p> ++<pre> ++;; Use your own standard let. ++;; Or call a lambda. ++;; (define-syntax standard-let ++;; ++;; (syntax-rules () ++;; ++;; ((let ((var val) ...) body ...) ++;; ((lambda (var ...) body ...) val ...)))) ++ ++(define-syntax let ++ ++ (syntax-rules () ++ ++ ;; No bindings: use standard-let. ++ ((let () body ...) ++ (standard-let () body ...)) ++ ;; Or call a lambda. ++ ;; ((lambda () body ...)) ++ ++ ;; All standard bindings: use standard-let. ++ ((let ((var val) ...) body ...) ++ (standard-let ((var val) ...) body ...)) ++ ;; Or call a lambda. ++ ;; ((lambda (var ...) body ...) val ...) ++ ++ ;; One standard binding: loop. ++ ;; The all-standard-bindings clause didn't match, ++ ;; so there must be a rest binding. ++ ((let ((var val) . bindings) body ...) ++ (let-loop #f bindings (var) (val) (body ...))) ++ ++ ;; Signature-style name: loop. ++ ((let (name binding ...) body ...) ++ (let-loop name (binding ...) () () (body ...))) ++ ++ ;; defun-style name: loop. ++ ((let name bindings body ...) ++ (let-loop name bindings () () (body ...))))) ++ ++(define-syntax let-loop ++ ++ (syntax-rules () ++ ++ ;; Standard binding: destructure and loop. ++ ((let-loop name ((var0 val0) binding ...) (var ... ) (val ... ) body) ++ (let-loop name ( binding ...) (var ... var0) (val ... val0) body)) ++ ++ ;; Rest binding, no name: use standard-let, listing the rest values. ++ ;; Because of let's first clause, there is no "no bindings, no name" clause. ++ ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) ++ (standard-let ((var val) ... (rest-var (list rest-val ...))) . body)) ++ ;; Or call a lambda with a rest parameter on all values. ++ ;; ((lambda (var ... . rest-var) . body) val ... rest-val ...)) ++ ;; Or use one of several other reasonable alternatives. ++ ++ ;; No bindings, name: call a letrec'ed lambda. ++ ((let-loop name () (var ...) (val ...) body) ++ ((letrec ((name (lambda (var ...) . body))) ++ name) ++ val ...)) ++ ++ ;; Rest binding, name: call a letrec'ed lambda. ++ ((let-loop name (rest-var rest-val ...) (var ...) (val ...) body) ++ ((letrec ((name (lambda (var ... . rest-var) . body))) ++ name) ++ val ... rest-val ...)))) ++</pre> ++ ++ ++<H1>Copyright</H1> ++ ++Copyright (C) Andy Gaynor (1999). All Rights Reserved. ++<p>This document and translations of it may be copied and furnished to ++others, and derivative works that comment on or otherwise explain it or ++assist in its implementation may be prepared, copied, published and distributed, ++in whole or in part, without restriction of any kind, provided that the ++above copyright notice and this paragraph are included on all such copies ++and derivative works. However, this document itself may not be modified ++in any way, such as by removing the copyright notice or references to the ++Scheme Request For Implementation process or editors, except as needed ++for the purpose of developing SRFIs in which case the procedures for copyrights ++defined in the SRFI process must be followed, or as required to translate ++it into languages other than English. ++<p>The limited permissions granted above are perpetual and will not be ++revoked by the authors or their successors or assigns. ++<p>This document and the information contained herein is provided on an ++"AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, ++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE ++USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED ++WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ++ ++ <hr> ++ <address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address> ++ ++</body> ++</html> +diff -urN racket-6.12-orig/share/pkgs/srfi-lib/info.rkt racket-6.12/share/pkgs/srfi-lib/info.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib/info.rkt 2018-01-26 16:10:02.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib/info.rkt 2018-01-31 12:22:58.144502000 -0500 +@@ -1 +1,15 @@ +-(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define deps (quote ("scheme-lib" "base" "srfi-lite-lib" "r6rs-lib" "compatibility-lib"))) (define implies (quote ("srfi-lite-lib"))) (define pkg-desc "implementation (no documentation) part of "srfi"") (define pkg-authors (quote (mflatt noel chongkai jay))))) ++#lang info ++ ++(define collection 'multi) ++ ++(define deps '("scheme-lib" ++ "base" ++ "srfi-lite-lib" ++ "r6rs-lib" ++ "compatibility-lib")) ++ ++(define implies '("srfi-lite-lib")) ++ ++(define pkg-desc "implementation (no documentation) part of "srfi"") ++ ++(define pkg-authors '(mflatt noel chongkai jay)) +diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/sort.txt racket-6.12/share/pkgs/srfi-lib/srfi/32/sort.txt +--- racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/sort.txt 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib/srfi/32/sort.txt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,1069 +0,0 @@ +-The SRFI-32 sort libraries -*- outline -*- +-Olin Shivers +-First draft: 1998/10/19 +-Last update: 2002/7/21 +- +-[Todo: del-list-neighbor-dups! +- vector-copy -> subvector +- use srfi-23 for reporting errors +- use srfi-16 for n-aries? +- +-Emacs should display this document in outline mode. Say c-h m for +-instructions on how to move through it by sections (e.g., c-c c-n, c-c c-p). +- +-* Table of contents +-------------------- +-Abstract +-Procedure index +-Introduction +-What's wrong with the current state of affairs? +-Design rules +- What vs. how +- Consistency across function signatures +- Data parameter first, less-than parameter after +- Ordering, comparison functions & stability +- All vector operations accept optional subrange parameters +- Required vs. allowed side-effects +-Procedure specification +- Procedure naming and functionality +- Types of parameters and return values +- sort-lib - general sorting package +- Algorithm-specific sorting packages +-Algorithmic properties +-Topics to be resolved during discussion phase +-Porting and optimisation +-References & Links +-Acknowledgements +-Copyright +- +- +-* Abstract +----------- +-Current Scheme sorting packages are, every one of them, surprisingly bad. I've +-designed the API for a full-featured sort toolkit, which I propose as a SRFI. +- +-The spec comes with 1200 lines of high-quality reference code: tightly +-written, highly commented, portable code, available for free. Implementors +-want this code. It's better than what you have. +- +-------------------------------------------------------------------------------- +-* Procedure index +------------------ +-list-sorted? vector-sorted? +- +-list-merge vector-merge +-list-sort vector-sort +-list-stable-sort vector-stable-sort +-list-delete-neighbor-dups vector-delete-neighbor-dups +- +-list-merge! vector-merge! +-list-sort! vector-sort! +-list-stable-sort! vector-stable-sort! +-list-delete-neighbor-dups! vector-delete-neighbor-dups! +- +-quick-sort heap-sort insert-sort list-merge-sort vector-merge-sort +-quick-sort! heap-sort! insert-sort! list-merge-sort! vector-merge-sort! +-quick-sort3! +- +-vector-binary-search +-vector-binary-search3 +- +-------------------------------------------------------------------------------- +-* Introduction +--------------- +-As I'll detail below, I wasn't very happy with the state of the Scheme +-world for sorting and merging lists and vectors. So I have designed and +-written a fairly comprehensive sorting & merging toolkit. It is +- +- - very portable, +- +- - much better code than what is currently in Elk, Gambit, Bigloo, +- Scheme->C, MzScheme, RScheme, Scheme48, MIT Scheme, or slib, and +- +- - priced to move: free code. +- +-The package includes +- - Vector insert sort (stable) +- - Vector heap sort +- - Vector quick sort (with median-of-3 pivot picking) +- - Vector merge sort (stable) +- - Pure and destructive list merge sort (stable) +- - Stable vector and list merge +- - Miscellaneous sort-related procedures: Vector and list merging, +- sorted? predicates, vector binary search, vector and list +- delete-equal-neighbor procedures. +- - A general, non-algorithmic set of procedure names for general sorting +- and merging. +- +-Scheme programmers may want to adopt this package. I'd like Scheme +-implementors to adopt this code and its API -- in fact, the code is a bribe to +-make it easy for implementors to converge on the suggested API. I mean, you'd +-really have to be a boor to take this free code I wrote and mutate its +-interface over to your incompatible, unportable API, wouldn't you? But you +-could, of course -- it's freely available. More in the spirit of the offering, +-you could make this API available, and then also write a little module +-providing your old interface that is defined in terms of this API. "Scheme +-implementors," in this context, includes slib, which is not a standalone +-implementation of Scheme, but rather an influential collection of API's and +-code. +- +-The code is tightly bummed. It is clearly written, and commented in my usual +-voluminous style. This includes notes on porting and implementation-specific +-optimisations. +- +- +-------------------------------------------------------------------------------- +-* What's wrong with the current state of affairs? +-------------------------------------------------- +- +-It's just amazing to me that in 2002, sorting and merging hasn't been +-completely put to bed. These are well-understood algorithms, each of them well +-under a page of code. The straightforward algorithms are basic, core stuff -- +-sophomore-level. But if you tour the major Scheme implementations out there on +-the Net, you find badly written code that provides extremely spotty coverage +-of the algorithm space. One implementation even has a buggy implementation +-that has been in use for about 20 years. Another has an O(n^2) algorithm... +-implemented in C for speed. +- +-Open source-code is a wonderful thing. In a couple of hours, I was able to +-download and check the sources of 9 Scheme systems. Here are my notes from the +-systems I checked. You can skip to the next section if you aren't morbidly +-curious. +- +-slib +- sorted? vector-or-list < +- merge list1 list2 < +- merge! list1 list2 < +- sort vector-or-list < +- sort! vector-or-list < +- +- Richard O'Keefe's stable list merge sort is right idea, but implemented +- using gratuitous variable side effects. It also does redundant SET-CDR!s. +- The vector sort converts to list, merge sorts, then reconverts +- to vector. This is a bad idea -- non-local pointer chasing bad; vector +- shuffling good. If you must allocate temp storage, might as well allocate +- a temp vector and use vector merge sort. +- +-MIT Scheme +- sort! vector < +- merge-sort! vector < +- quick-sort! vector < +- +- sort vector-or-list < +- merge-sort vector-or-list < +- quick-sort vector-or-list < +- +- Naive vector quicksort: loser, for worst-case performance reasons. +- List sort by "list->vector; quicksort; vector->list," hence also loser. +- A clever stable vector merge sort, albeit not very bummed. +- +-Scheme 48 & T +- sort-list list < +- sort-list! list < +- list-merge! list1 list2 < +- +- Bob Nix's implementation of online merge-sort, written in the early 80's. +- Conses unnecessary bookkeeping structure, which isn't necessary with a +- proper recursive formulation. Also, does redundant SET-CDR!s. No vector +- sort. Also, has a bug -- is claimed to be a stable sort, but isn't! To see +- this, get the S48 code, and try +- (define (my< x y) (< (abs x) (abs y))) +- (list-merge! (list 0 2) (list -2) my<) ; -> (0 2 -2) +- (list-merge! (list 2) (list 0 -2) my<) ; -> (0 -2 2) +- This could be fixed very easily, but it isn't worth it given the +- other problems with the algorithm. +- +-RScheme +- vector-sort! vector < +- sort collection < +- +- Good basic implementation of vector heapsort, which has O(n lg n) +- worst-case time. Code ugly, needs tuning. List sort by "list->vector; +- sort; vector->list." Nothing for stable sorting. +- +-MzScheme +- quicksort lis < +- mergesort alox < +- +- Sorts lists with (list->vector; quicksort; vector->list) -- but the core +- quicksort is not available for vector sorting. Nothing for stable sorting. +- Quicksort picks pivot naively, inducing O(n^2) worse-case behaviour on a +- fairly common case: an already-sorted list. +- +-Bigloo, STK +- sort vector-or-list < +- Uses an O(n^2) algorithm... implemented in C for speed. Hmm. +- (See runtime/Ieee/vector.scm and runtime/Clib/cvector.c) +- +-Gambit +- sort-list list < +- Nothing for vectors. Simple, slow, unstable merge sort for lists. +- +-Elk +- Another naive quicksort. Lists handled by converting to vector. +- sort vector-or-list < +- sort! vector-or-list < +- +-Chez Scheme +- merge < list1 list2 +- merge! < list1 list2 +- sort < list +- sort! < list +- +- These are stable. I have not seen the source code. +- +-Common Lisp +- sort sequence < [key] +- stable-sort sequence < [key] +- merge result-type sequence1 sequence2 < [key] +- +- The sort procedures are allowed, but not required, to be destructive. +- +-SML/NJ +- sort: ('a*'a -> bool) -> 'a list -> 'a list +- "Smooth applicative merge sort," which is stable. +- There is also a highly bummed quicksort for vectors. +- +-The right solution: Implement a full toolbox of carefully written standard sort +-routines. +- +-Having the source of all these above-cited Schemes available for study made +-life a lot easier writing this code. I appreciate the authors making their +-source available under such open terms. +- +- +-------------------------------------------------------------------------------- +-* Design rules +--------------- +- +-** What vs. how +-=============== +-There are two different interfaces: "what" (simple) & "how" (detailed). +- +- - Simple: you specify semantics: datatype (list or vector), +- mutability, and stability. +- +- - Detailed: you specify the actual algorithm (quick, heap, +- insert, merge). Different algorithms have different properties, +- both semantic & pragmatic, so these exports are necessary. +- +- It is necessarily the case that the specifications of these procedures +- make statements about execution "pragmatics." For example, the sole +- distinction between heap sort and quick sort -- both of which are +- provided by this library -- is one of execution time, which is not a +- "semantic" distinction. Similar resource-use statements are made about +- "iterative" procedures, meaning that they can execute on input of +- arbitrary size in a constant number of stack frames. +- +-** Consistency across function signatures +-========================================= +-The two interfaces share common function signatures wherever +-possible, to facilitate switching a given call from one procedure +-to another. +- +-** Less-than parameter first, data parameter after +-================================================== +-These procedures uniformly observe the following parameter order: +-the data to be sorted comes after the comparison function. +-That is, we write +- (sort < lis) +-not +- (sort lis <). +- +-With the sole exception of Chez Scheme, this is the exact opposite of +-every sort function out there in current use in the Scheme world. (See +-the summary of related APIs above.) However, it is consistent with common +-practice across Scheme libraries in general to put the ordering function +-first -- the "operation currying" convention. (E.g., consider FOR-EACH or +-MAP or FIND.) +- +-The original draft of this SRFI used the data-first/comparison-last convention +-for backwards compatibility -- a decision I made with internal misgivings. +-Happily, however, the overwhelming response from the discussion phase +-supported "cleaning up" this issue and re-converging the parameter order with +-the general Scheme "op currying" convention. So the original decision was +-inverted in favor of the comparison-first/data-last convention. +- +-** Ordering, comparison functions & stability +-============================================= +-These routines take a < comparison function, not a <= comparison +-function, and they sort into increasing order. The difference between +-a < spec and a <= spec comes up in three places: +- - the definition of an ordered or sorted data set, +- - the definition of a stable sorting algorithm, and +- - correctness of quicksort. +- +-+ We say that a data set (a list or vector) is *sorted* or *ordered* +- if it contains no adjacent pair of values ... X Y ... such that Y < X. +- +- In other words, scanning across the data never takes a "downwards" step. +- +- If you use a <= procedure where these algorithms expect a < +- procedure, you may not get the answers you expect. For example, +- the LIST-SORTED? function will return false if you pass it a <= comparison +- function and an ordered list containing adjacent equal elements. +- +-+ A "stable" sort is one that preserves the pre-existing order of equal +- elements. Suppose, for example, that we sort a list of numbers by +- comparing their absolute values, i.e., using comparison function +- (lambda (x y) (< (abs x) (abs y))) +- If we sort a list that contains both 3 and -3: +- ... 3 ... -3 ... +- then a stable sort is an algorithm that will not swap the order +- of these two elements, that is, the answer is guaranteed to to look like +- ... 3 -3 ... +- not +- ... -3 3 ... +- +- Choosing < for the comparison function instead of <= affects how stability +- is coded. Given an adjacent pair X Y, (< y x) means "Y should be moved in +- front of X" -- otherwise, leave things as they are. So using a <= function +- where a < function is expected will *invert* stability. +- +- This is due to the definition of equality, given a < comparator: +- (and (not (< x y)) +- (not (< y x))) +- The definition is rather different, given a <= comparator: +- (and (<= x y) +- (<= y x)) +- +-+ A "stable" merge is one that reliably favors one of its data sets +- when equal items appear in both data sets. *All merge operations in +- this library are stable*, breaking ties between data sets in favor +- of the first data set -- elements of the first list come before equal +- elements in the second list. +- +- So, if we are merging two lists of numbers ordered by absolute value, +- the stable merge operation LIST-MERGE +- (list-merge (lambda (x y) (< (abs x) (abs y))) +- '(0 -2 4 8 -10) '(-1 3 -4 7)) +- reliably places the 4 of the first list before the equal-comparing -4 +- of the second list: +- (0 -1 -2 4 -4 7 8 -10) +- +-+ Some sort algorithms will *not work correctly* if given a <= when they +- expect a < comparison (or vice-versa). For example, violating quicksort's +- spec may cause it to produce wrong answers, diverge, raise an error, or do +- some fourth thing. To see why, consider the left-scan part of the standard +- quicksort partition step: +- (let ((i (let scan ((i i)) (if (elt< (vector-ref v i) pivot) +- (scan (+ i 1)) +- i)))) +- ...) +- Consider applying this loop to a vector of all zeroes (hence, PIVOT, as +- well, is zero), but erroneously using <= for the ELT< function. The loop +- will scan right off the end of the vector, producing a vector-index error. +- The guarantee that the scan loop will terminate before running off the end +- of the vector depends critically upon ELT< performing as a true, irreflexive +- < relation. Running off the end of the vector is only one of a variety of +- possibly ways to lose -- other, variant implementations of quicksort can, +- instead, loop forever on some data sets if ELT< is a <= predicate. +- +-In short, if your comparison function F answers true to (F x x), then +- - using a stable sorting or merging algorithm will not give you a +- stable sort or merge, +- - LIST-SORTED? may surprise you, and +- - quicksort may fail in a variety of possible ways. +-Note that you can synthesize a < function from a <= function with +- (lambda (x y) (not (<= y x))) +-if need be. +- +-Precise definitions give sharp edges to tools, but require care in use. +-"Measure twice, cut once." +- +-I have adopted the choice of < from Common Lisp. One would assume the definers +-of Common Lisp had a good reason for adopting < instead of <=, but canvassing +-several of the principal actors in the definition process has turned up no +-better reason than "an arbitrary but consistent choice." At minimum, then, +-this SRFI extends the coverage of that consistent choice. +- +-** All vector operations accept optional subrange parameters +-============================================================ +-The vector operations specified below all take optional START/END arguments +-indicating a selected subrange of a vector's elements. If a START parameter or +-START/END parameter pair is given to such a procedure, they must be exact, +-non-negative integers, such that +- 0 <= START <= END <= (VECTOR-LENGTH V) +-where V is the related vector parameter. If not specified, they default to 0 +-and the length of the vector, respectively. They are interpreted to select the +-range [START,END), that is, all elements from index START (inclusive) up to, +-but not including, index END. +- +-** Required vs. allowed side-effects +-==================================== +-LIST-SORT! and LIST-STABLE-SORT! are allowed, but not required, +-to alter their arguments' cons cells to construct the result list. This is +-consistent with the what-not-how character of the group of procedures +-to which they belong (the "sort-lib" package). +- +-The LIST-DELETE-NEIGHBOR-DUPS!, LIST-MERGE! and LIST-MERGE-SORT! procedures, +-on the other hand, provide specific algorithms, and, as such, explicitly +-commit to the use of side-effects on their input lists in order to guarantee +-their key algorithmic properties (e.g., linear-time operation, constant-space +-stack use). +- +-------------------------------------------------------------------------------- +-* Procedure specification +-------------------------- +-The procedures are split into several packages. In a Scheme system that has a +-module or package system, these procedures should be contained in modules +-named as follows: +- Package name Functionality +- ------------ ------------- +- sort-lib General sorting for lists & vectors +- sorted?-lib Sorted predicates for lists & vectors +- list-merge-sort-lib List merge sort +- vector-merge-sort-lib Vector merge sort +- vector-heap-sort-lib Vector heap sort +- vector-quick-sort-lib Vector quick sort +- vector-insert-sort-lib Vector insertion sort +- delndup-lib List and vector delete neighbor duplicates +- binsearch-lib Vector binary search +- +-A Scheme system without a module system should provide all of the bindings +-defined in all of these modules as components of the "SRFI-32" package. +- +-Note that there is no "list insert sort" package, as you might as well always +-use list merge sort. The reference implementation's destructive list merge +-sort will do fewer SET-CDR!s than a destructive insert sort. +- +-** Procedure naming and functionality +-===================================== +-Almost all of the procedures described below are variants of two basic +-operations: sorting and merging. These procedures are consistently named +-by composing a set of basic lexemes to indicate what they do. +- +-Lexeme Meaning +------- ------- +-"sort" The procedure sorts its input data set by some < comparison function. +- +-"merge" The procedure merges two ordered data sets into a single ordered +- result. +- +-"stable" This lexeme indicates that the sort is a stable one. +- +-"vector" The procedure operates upon vectors. +- +-"list" The procedure operates upon lists. +- +-"!" Procedures that end in "!" are allowed, and sometimes required, +- to reuse their input storage to construct their answer. +- +-** Types of parameters and return values +-======================================== +-In the procedures specified below, +- - A LIS parameter is a list; +- +- - A V parameter is a vector; +- +- - A < or = parameter is a procedure accepting two arguments taken from the +- specified procedure's data set(s), and returning a boolean; +- +- - START and END parameters are exact, non-negative integers that +- serve as vector indices selecting a subrange of some associated vector. +- When specified, they must satisfy the relation +- 0 <= start <= end <= (vector-length v) +- where V is the associated vector. +- +-Passing values to procedures with these parameters that do not satisfy these +-types is an error. +- +-If a procedure is said to return "unspecified," this means that nothing at all +-is said about what the procedure returns, not even the number of return +-values. Such a procedure is not even required to be consistent from call to +-call in the nature or number of its return values. It is simply required to +-return a value (or values) that may be passed to a command continuation, e.g. +-as the value of an expression appearing as a non-terminal subform of a BEGIN +-expression. Note that in R5RS, this restricts such a procedure to returning a +-single value; non-R5RS systems may not even provide this restriction. +- +-** sort-lib - general sorting package +-===================================== +-This library provides basic sorting and merging functionality suitable for +-general programming. The procedures are named by their semantic properties, +-i.e., what they do to the data (sort, stable sort, merge, and so forth). +- +- Procedure Suggested algorithm +- ------------------------------------------------------------------------- +- list-sorted? < lis -> boolean +- list-merge < lis1 lis2 -> list +- list-merge! < lis1 lis2 -> list +- list-sort < lis -> list (vector heap or quick) +- list-sort! < lis -> list (list merge sort) +- list-stable-sort < lis -> list (vector merge sort) +- list-stable-sort! < lis -> list (list merge sort) +- list-delete-neighbor-dups = lis -> list +- list-delete-neighbor-dups! = lis -> list +- +- vector-sorted? < v [start end] -> boolean +- vector-merge < v1 v2 [start1 end1 start2 end2] -> vector +- vector-merge! < v v1 v2 [start start1 end1 start2 end2] -> unspecified +- vector-sort < v [start end] -> vector (heap or quick sort) +- vector-sort! < v [start end] -> unspecified (heap or quick sort) +- vector-stable-sort < v [start end] -> vector (vector merge sort) +- vector-stable-sort! < v [start end] -> unspecified (vector merge sort) +- vector-delete-neighbor-dups = v [start end] -> vector +- vector-delete-neighbor-dups! = target source [t-start s-start s-end] -> t-end +- +- LIST-SORTED? and VECTOR-SORTED? return true if their input list or vector +- is in sorted order, as determined by their < comparison parameter. +- +- All four merge operations are stable: an element of the initial list LIS1 +- or vector V1 will come before an equal-comparing element in the second +- list LIS2 or vector V2 in the result. +- +- The procedures +- LIST-MERGE +- LIST-SORT +- LIST-STABLE-SORT +- LIST-DELETE-NEIGHBOR-DUPS +- do not alter their inputs and are allowed to return a value that shares +- a common tail with a list argument. +- +- The procedures +- LIST-SORT! +- LIST-STABLE-SORT! +- are "linear update" operators -- they are allowed, but not required, to +- alter the cons cells of their arguments to produce their results. +- +- On the other hand, the procedures +- LIST-DELETE-NEIGHBOR-DUPS! +- LIST-MERGE! +- make only a single, iterative, linear-time pass over their argument lists, +- using SET-CDR!s to rearrange the cells of the lists into the final result +- -- they work "in place." Hence, any cons cell appearing in the result must +- have originally appeared in an input. The intent of this +- iterative-algorithm commitment is to allow the programmer to be sure that +- if, for example, LIST-MERGE! is asked to merge two ten-million-element +- lists, the operation will complete without performing some extremely +- (possibly twenty-million) deep recursion. +- +- The vector procedures +- VECTOR-SORT +- VECTOR-STABLE-SORT +- VECTOR-DELETE-NEIGHBOR-DUPS +- do not alter their inputs, but allocate a fresh vector for their result, +- of length END - START. +- +- The vector procedures +- VECTOR-SORT! +- VECTOR-STABLE-SORT! +- sort their data in-place. (But note that VECTOR-STABLE-SORT! may +- allocate temporary storage proportional to the size of the input -- +- I am not aware of O(n lg n) stable vector-sorting algorithms that +- run in constant space.) +- +- VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). +- +- VECTOR-MERGE! writes its result into vector V, beginning at index START, +- for indices less than END = START + (END1-START1) + (END2-START2). The +- target subvector +- V[start,end) +- may not overlap either source subvector +- V1[start1,end1) +- V2[start2,end2). +- +- The ...-DELETE-NEIGHBOR-DUPS-... procedures: +- These procedures delete adjacent duplicate elements from a list or a +- vector, using a given element-equality procedure. The first/leftmost +- element of a run of equal elements is the one that survives. The list or +- vector is not otherwise disordered. +- +- These procedures are linear time -- much faster than the O(n^2) general +- duplicate-element deletors that do not assume any "bunching" of elements +- (such as the ones provided by SRFI-1). If you want to delete duplicate +- elements from a large list or vector, you can sort the elements to bring +- equal items together, then use one of these procedures, for a total time +- of O(n lg n). +- +- The comparison function = passed to these procedures is always applied +- (= x y) +- where X comes before Y in the containing list or vector. +- +- - LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer +- may share storage with the input list. +- +- - VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but +- rather allocates a fresh vector to hold the result. +- +- - LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to +- mutate its input list in order to construct its answer. +- +- - VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the +- answer, packing its answer into the index range [start,end'), where +- END' is the non-negative exact integer returned as its value. It +- returns END' as its result. The vector is not altered outside the range +- [start,end'). +- +- - VECTOR-DELETE-NEIGHBOR-DUPS! scans vector SOURCE in range +- [S-START,S-END), writing its result to vector TARGET beginning at index +- T-START. It returns exact, non-negative integer T-END, which indicates +- that the results of the operation are found in index range +- [T-START,T-END) of TARGET; elements of TARGET outside this range +- are unaltered. +- +- It is an error for memory cell TARGET[T-START] to be a memory cell in +- the region SOURCE[1 + S-START, S-END). In a Scheme implementation +- that does not allow distinct vectors to share storage, this means +- that one of the following must be true: +- 1. (not (eq? source target)) +- 2. t-start not-in [s-start + 1, s-end) +- +- - Examples: +- (list-delete-neighbor-dups = '(1 1 2 7 7 7 0 -2 -2)) +- => (1 2 7 0 -2) +- +- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2)) +- => #(1 2 7 0 -2) +- +- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2) 3 7) +- => #(7 0 -2) +- +- ;; Result left in v[3,9): +- (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) +- (cons (vector-delete-neighbor-dups! = v 3) +- v)) +- => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) +- +- +-** Algorithm-specific sorting packages +-====================================== +-These packages provide more specific sorting functionality, that is, +-specific commitment to particular algorithms that have particular +-pragmatic consequences (such as memory locality, asymptotic running time) +-beyond their semantic behaviour (sorting, stable sorting, merging, etc.). +-Programmers that need a particular algorithm can use one of these packages. +- +-sorted?-lib - sorted predicates +- list-sorted? < lis -> boolean +- vector-sorted? < v [start end] -> boolean +- +- Return #f iff there is an adjacent pair ... X Y ... in the input +- list or vector such that Y < X. The optional START/END range +- arguments restrict VECTOR-SORTED? to the indicated subvector. +- +-list-merge-sort-lib - list merge sort +- list-merge-sort < lis -> list +- list-merge-sort! < lis -> list +- list-merge lis1 < lis2 -> list +- list-merge! lis1 < lis2 -> list +- +- The sort procedures sort their data using a list merge sort, which is +- stable. (The reference implementation is, additionally, a "natural" sort. +- See below for the properties of this algorithm.) +- +- The ! procedures are destructive -- they use SET-CDR!s to rearrange the +- cells of the lists into the proper order. As such, they do not allocate +- any extra cons cells -- they are "in place" sorts. Additionally, +- LIST-MERGE! is iterative -- it can operate on arguments of arbitrary size +- with a constant number of stack frames. +- +- The merge operations are stable: an element of LIS1 will come before an +- equal-comparing element in LIS2 in the result list. +- +-vector-merge-sort-lib - vector merge sort +- vector-merge-sort < v [start end temp] -> vector +- vector-merge-sort! < v [start end temp] -> unspecified +- vector-merge < v1 v2 [start1 end1 start2 end2] -> vector +- vector-merge! < v v1 v2 [start start1 end1 start2 end2] -> unspecified +- +- The sort procedures sort their data using vector merge sort, which is +- stable. (The reference implementation is, additionally, a "natural" sort. +- See below for the properties of this algorithm.) +- +- The optional START/END arguments provide for sorting of subranges, and +- default to 0 and the length of the corresponding vector. +- +- Merge-sorting a vector requires the allocation of a temporary "scratch" +- work vector for the duration of the sort. This scratch vector can be +- passed in by the client as the optional TEMP argument; if so, the supplied +- vector must be of size >= END, and will not be altered outside the range +- [start,end). If not supplied, the sort routines allocate one themselves. +- +- The merge operations are stable: an element of V1 will come before an +- equal-comparing element in V2 in the result vector. +- +- VECTOR-MERGE-SORT! leaves its result in V[start,end). +- +- VECTOR-MERGE-SORT returns a vector of length END-START. +- +- VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). +- +- VECTOR-MERGE! writes its result into vector V, beginning at index START, +- for indices less than END = START + (END1-START1) + (END2-START2). The +- target subvector +- V[start,end) +- may not overlap either source subvector +- V1[start1,end1) +- V2[start2,end2). +- +-vector-heap-sort-lib - vector heap sort +- heap-sort < v [start end] -> vector +- heap-sort! < v [start end] -> unspecified +- +- These procedures sort their data using heap sort, +- which is not a stable sorting algorithm. +- +- HEAP-SORT returns a vector of length END-START. +- HEAP-SORT! is in-place, leaving its result in V[start,end). +- +-vector-quick-sort-lib - vector quick sort +- quick-sort < v [start end] -> vector +- quick-sort! < v [start end] -> unspecified +- quick-sort3! c v [start end] -> unspecified +- +- These procedures sort their data using quick sort, +- which is not a stable sorting algorithm. +- +- QUICK-SORT returns a vector of length END-START. +- QUICK-SORT! is in-place, leaving its result in V[start,end). +- +- QUICK-SORT3! is a variant of quick-sort that takes a three-way +- comparison function C. C compares a pair of elements and returns +- an exact integer whose sign indicates their relationship: +- (c x y) < 0 => x<y +- (c x y) = 0 => x=y +- (c x y) > 0 => x>y +- To help remember the relationship between the sign of the result and +- the relation, use the function - as the model for C: (- x y) < 0 +- means that x < y; (- x y) > 0 means that x > y. +- +- The extra discrimination provided by the three-way comparison can +- provide significant speedups when sorting data sets with many duplicates, +- especially when the comparison function is relatively expensive (e.g., +- comparing long strings). +- +- WARNING: Some sort algorithms, such as insertion sort or heap sort, +- can tolerate being passed a <= comparison function when they expect a < +- function -- insertion and merge sort may simply invert stability; and +- heap sort will run a bit slower, but otherwise produce a correct answer. +- +- Quicksort, however, is much more critically sensitive to the distinction +- between a < and a <= comparison. If QUICK-SORT or QUICK-SORT! expect a < +- comparison function, and are erroneously given a <= function, they may, +- depending on implementation, produce an unsorted result, go into an +- infinite loop, cause a run-time error, occasionally produce a correct +- result, or do some fifth thing. +- +- Implementors may wish to write QUICKSORT3! so that it (a) tests the +- comparison function (by checking that (c v[start] v[start]) produces +- false), or (b) is tolerant of an erroneous <= function, or (c) both. +- Clients of this function, however, should not count on this. +- +-vector-insert-sort-lib - vector insertion sort +- insert-sort < v [start end] -> vector +- insert-sort! < v [start end] -> unspecified +- +- These procedures stably sort their data using insertion sort. +- +- INSERT-SORT returns a vector of length END-START. +- INSERT-SORT! is in-place, leaving its result in V[start,end). +- +-delndup-lib - list and vector delete neighbor duplicates +- list-delete-neighbor-dups = lis -> list +- list-delete-neighbor-dups! = lis -> list +- +- vector-delete-neighbor-dups = v [start end] -> vector +- vector-delete-neighbor-dups! = v [start end] -> end' +- +- These procedures delete adjacent duplicate elements from a list or +- a vector, using a given element-equality procedure =. The first/leftmost +- element of a run of equal elements is the one that survives. The list +- or vector is not otherwise disordered. +- +- These procedures are linear time -- much faster than the O(n^2) general +- duplicate-element deletors that do not assume any "bunching" of elements +- (such as the ones provided by SRFI-1). If you want to delete duplicate +- elements from a large list or vector, you can sort the elements to bring +- equal items together, then use one of these procedures, for a total time +- of O(n lg n). +- +- The comparison function = passed to these procedures is always applied +- (= x y) +- where X comes before Y in the containing list or vector. +- +- LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer +- may share storage with the input list. +- +- VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but +- rather allocates a fresh vector to hold the result. +- +- LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to +- mutate its input list in order to construct its answer. +- +- VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the +- answer, packing its answer into the index range [start,end'), where +- END' is the non-negative exact integer returned as its value. It +- returns END' as its result. The vector is not altered outside the range +- [start,end'). +- +- Examples: +- (list-delete-neighbor-dups = '(1 1 2 7 7 7 0 -2 -2)) +- => (1 2 7 0 -2) +- +- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2)) +- => #(1 2 7 0 -2) +- +- (vector-delete-neighbor-dups = '#(1 1 2 7 7 7 0 -2 -2) 3 7) +- => #(7 0 -2) +- +- ;; Result left in v[3,9): +- (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) +- (cons (vector-delete-neighbor-dups! = v 3) +- v)) +- => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) +- +-binsearch-lib - vector binary search lib +- vector-binary-search elt< elt->key key v [start end] -> integer-or-false +- vector-binary-search3 c v [start end] -> integer-or-false +- +- VECTOR-BINARY-SEARCH searches vector V in range [START,END) (which +- default to 0 and the length of V, respectively) for an element whose +- associated key is equal to KEY. The procedure ELT->KEY is used to map +- an element to its associated key. The elements of the vector are assumed +- to be ordered by the ELT< relation on these keys. That is, +- (vector-sorted? (lambda (x y) (elt< (elt->key x) (elt->key y))) +- v start end) => true +- An element E of V is a match for KEY if it's neither less nor greater +- than the key: +- (and (not (elt< (elt->key e) key)) +- (not (elt< key (elt->key e)))) +- If there is such an element, the procedure returns its index in the +- vector as an exact integer. If there is no such element in the searched +- range, the procedure returns false. +- +- (vector-binary-search < car 4 '#((1 . one) (3 . three) +- (4 . four) (25 . twenty-five))) +- => 2 +- +- (vector-binary-search < car 7 '#((1 . one) (3 . three) +- (4 . four) (25 . twenty-five))) +- => #f +- +- VECTOR-BINARY-SEARCH3 is a variant that uses a three-way comparison +- function C. C compares its parameter to the search key, and returns an +- exact integer whose sign indicates its relationship to the search key. +- (c x) < 0 => x < search-key +- (c x) = 0 => x = search-key +- (c x) > 0 => x > search-key +- +- (vector-binary-search3 (lambda (elt) (- (car elt) 4)) +- '#((1 . one) (3 . three) +- (4 . four) (25 . twenty-five))) +- => 2 +- +- Rationale: +- - Why isn't VECTOR-BINARY-SEARCH's ELT->KEY computation simply absorbed +- into the < function? It is separated out because the < function is +- applied twice inside the binary-search inner loop, once with the search +- key for the first argument and the element key for the second argument, +- and once, with the reverse argument order. This is not necessary for +- VECTOR-BINARY-SEARCH3. +- +- - When a comparison operation is able to produce a three-way +- discrimination, the inner loop of the binary search can trim the number +- of per-iteration comparisons from an average of 1.5 to a guaranteed +- single comparison per iteration. This can be a significant savings when +- searching with an expensive comparison operation (e.g., one that +- uses string compare, sends email, references a database, or queries +- a network service such as a web server). +- +- - Failure is signaled by false (rather than, say, -1) so that searches +- can be used in conditional forms such as +- (or (vector-binary-search ...) ...) +- or +- (cond ((vector-binary-search ...) => index-consumer) +- ...) +- +-------------------------------------------------------------------------------- +-* Algorithmic properties +------------------------- +-Different sort and merge algorithms have different properties. +-Choose the algorithm that matches your needs: +- +-Vector insert sort +- Stable, but only suitable for small vectors -- O(n^2). +- +-Vector quick sort +- Not stable. Is fast on average -- O(n lg n) -- but has bad worst-case +- behaviour. Has good memory locality for big vectors (unlike heap sort). +- A clever pivot-picking trick (median of three samples) helps avoid +- worst-case behaviour, but pathological cases can still blow up. +- +-Vector heap sort +- Not stable. Guaranteed fast -- O(n lg n) *worst* case. Poor locality +- on large vectors. A very reliable workhorse. +- +-Vector merge sort +- Stable. Not in-place -- requires a temporary buffer of equal size. +- Fast -- O(n lg n) -- and has good memory locality for large vectors. +- +- The implementation of vector merge sort provided by this SRFI's reference +- implementation is, additionally, a "natural" sort, meaning that it +- exploits existing order in the input data, providing O(n) best case. +- +-Destructive list merge sort +- Stable, fast and in-place (i.e., allocates no new cons cells). "Fast" +- means O(n lg n) worse-case, and substantially better if the data +- is already mostly ordered, all the way down to linear time for +- a completely-ordered input list (i.e., it is a "natural" sort). +- +- Note that sorting lists involves chasing pointers through memory, which +- can be a loser on modern machine architectures because of poor cache & +- page locality. Pointer *writing*, which is what the SET-CDR!s of a +- destructive list-sort algorithm do, is even worse, especially if your +- Scheme has a generational GC -- the writes will thrash the write-barrier. +- Sorting vectors has inherently better locality. +- +- This SRFI's destructive list merge and merge sort implementations are +- opportunistic -- they avoid redundant SET-CDR!s, and try to take long +- already-ordered runs of list structure as-is when doing the merges. +- +-Pure list merge sort +- Stable and fast -- O(n lg n) worst-case, and possibly O(n), depending +- upon the input list (see discussion above). +- +- +-Algorithm Stable? Worst case Average case In-place +------------------------------------------------------- +-Vector insert Yes O(n^2) O(n^2) Yes +-Vector quick No O(n^2) O(n lg n) Yes +-Vector heap No O(n lg n) O(n lg n) Yes +-Vector merge Yes O(n lg n) O(n lg n) No +-List merge Yes O(n lg n) O(n lg n) Either +- +- +-------------------------------------------------------------------------------- +-* Porting and optimisation +--------------------------- +-This package should be trivial to port. There are only four non-R4RS bits +-in the code: +-- Use of multiple-value return, with the R5RS VALUES procedure, and the +- simple (RECEIVE (var ...) mv-exp body ...) multiple-value binding macro +- of SRFI-8. +- +-- A VECTOR-COPY procedure. This is a tiny little procedure: +- (vector-copy v [start end]) +- +-- Use of the LET-OPTIONALS macro from scsh to parse and default optional +- arguments to three routines. Again, easy to port the macro or rewrite +- the code to parse, default, and error check the args by hand. +- +-- Calls to an ERROR function for complaining about bad arguments. +- +-This code is tightly bummed, as far as I can go in portable Scheme. +- +-You could speed up the vector code a lot by error-checking the procedure +-parameters and then shifting over to fixnum-specific arithmetic and dangerous +-vector-indexing and vector-setting primitives. The comments in the code +-indicate where the initial error checks would have to be added. There are +-several (QUOTIENT N 2)'s that could be changed to a fixnum right-shift, as +-well, in both the list and vector code (SRFI 33 provides such an operator). +-The code is designed to enable this -- each file usually exports one or two +-"safe" procedures that end up calling an internal "dangerous" primitive. The +-little exported cover procedures are where you move the error checks. +- +-This should provide *big* speedups. In fact, all the code bumming I've done +-pretty much disappears in the noise unless you have a good compiler and also +-can dump the vector-index checks and generic arithmetic -- so I've really just +-set things up for you to exploit. +- +-The optional-arg parsing, defaulting, and error checking is done with a +-portable R4RS macro. But if your Scheme has a faster mechanism (e.g., Chez), +-you should definitely port over to it. Note that argument defaulting and +-error-checking are interleaved -- you don't have to error-check defaulted +-START/END args to see if they are fixnums that are legal vector indices for +-the corresponding vector, etc. +- +- +-------------------------------------------------------------------------------- +-* References & Links +--------------------- +- +-This document, in HTML: +- http://srfi.schemers.org/srfi-32/srfi-32.html +- [This link may not be valid while the SRFI is in draft form.] +- +-This document, in simple text format: +- http://srfi.schemers.org/srfi-32/srfi-32.txt +- +-Archive of SRFI-32 discussion-list email: +- http://srfi.schemers.org/srfi-32/mail-archive/maillist.html +- +-SRFI web site: +- http://srfi.schemers.org/ +- +-[CommonLisp] +- Common Lisp: the Language +- Guy L. Steele Jr. (editor). +- Digital Press, Maynard, Mass., second edition 1990. +- Available at http://www.elwood.com/alu/table/references.htm#cltl2 +- +- The Common Lisp "HyperSpec," produced by Kent Pitman, is essentially +- the ANSI spec for Common Lisp: +- http://www.xanalys.com/software_tools/reference/HyperSpec/ +- +-[R5RS] +- Revised^5 Report on the Algorithmic Language Scheme, +- R. Kelsey, W. Clinger, J. Rees (editors). +- Higher-Order and Symbolic Computation, Vol. 11, No. 1, September, 1998. +- and ACM SIGPLAN Notices, Vol. 33, No. 9, October, 1998. +- +- Available at http://www.schemers.org/Documents/Standards/ +- +- +-------------------------------------------------------------------------------- +-* Acknowledgements +------------------- +- +-I thank the authors of the open source I consulted when designing this +-library, particularly Richard O'Keefe, Donovan Kolby and the MIT Scheme Team. +- +- +-------------------------------------------------------------------------------- +-* Copyright +------------ +- +-** SRFI text +-============ +-This document is copyright (C) Olin Shivers (1998, 1999). +-All Rights Reserved. +- +-This document and translations of it may be copied and furnished to others, +-and derivative works that comment on or otherwise explain it or assist in its +-implementation may be prepared, copied, published and distributed, in whole or +-in part, without restriction of any kind, provided that the above copyright +-notice and this paragraph are included on all such copies and derivative +-works. However, this document itself may not be modified in any way, such as +-by removing the copyright notice or references to the Scheme Request For +-Implementation process or editors, except as needed for the purpose of +-developing SRFIs in which case the procedures for copyrights defined in the +-SRFI process must be followed, or as required to translate it into languages +-other than English. +- +-The limited permissions granted above are perpetual and will not be revoked by +-the authors or their successors or assigns. +- +-This document and the information contained herein is provided on an "AS IS" +-basis and THE AUTHORS AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR +-IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE +-INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF +-MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +- +-** Reference implementation +-=========================== +-Short summary: no restrictions. +- +-While I wrote all of this code myself, I read a lot of code before I began +-writing. However, all such code is, itself, either open source or public +-domain, rendering irrelevant any issue of "copyright taint." +- +-The natural merge sorts (pure list, destructive list, and vector) are not only +-my own code, but are implementations of an algorithm of my own devising. They +-run in O(n lg n) worst case, O(n) best case, and require only a logarithmic +-number of stack frames. And they are stable. And the destructive-list variant +-allocates zero cons cells; it simply rearranges the cells of the input list. +- +-Hence the reference implementation is +- Copyright (c) 1998 by Olin Shivers. +-and made available under the same copyright as the SRFI text (see above). +diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/srfi-32.txt racket-6.12/share/pkgs/srfi-lib/srfi/32/srfi-32.txt +--- racket-6.12-orig/share/pkgs/srfi-lib/srfi/32/srfi-32.txt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib/srfi/32/srfi-32.txt 2018-01-31 12:22:58.152501970 -0500 +@@ -0,0 +1,938 @@ ++The SRFI-32 sort libraries -*- outline -*- ++Olin Shivers ++First draft: 1998/10/19 ++Last update: 2002/7/21 ++ ++Emacs should display this document in outline mode. Say c-h m for ++instructions on how to move through it by sections (e.g., c-c c-n, c-c c-p). ++ ++* Table of contents ++------------------- ++Abstract ++Procedure index ++Introduction ++What's wrong with the current state of affairs? ++Design rules ++ What vs. how ++ Consistency across function signatures ++ Data parameter first, less-than parameter after ++ Ordering, comparison functions & stability ++ All vector operations accept optional subrange parameters ++ Required vs. allowed side-effects ++Procedure specification ++ Procedure naming and functionality ++ Types of parameters and return values ++ sort-lib - general sorting package ++ Algorithm-specific sorting packages ++Algorithmic properties ++Topics to be resolved during discussion phase ++Porting and optimisation ++References & Links ++Acknowledgements ++Copyright ++ ++ ++* Abstract ++---------- ++Current Scheme sorting packages are, every one of them, surprisingly bad. I've ++designed the API for a full-featured sort toolkit, which I propose as an SRFI. ++The spec comes with 1200 lines of high-quality reference code: tightly ++written, highly commented, portable code, available for free. Implementors ++want this code. It's better than what you have. ++ ++------------------------------------------------------------------------------- ++* Procedure index ++----------------- ++list-sorted? vector-sorted? ++ ++list-merge vector-merge ++list-sort vector-sort ++list-stable-sort vector-stable-sort ++list-delete-neighbor-dups vector-delete-neighbor-dups ++ ++list-merge! vector-merge! ++list-sort! vector-sort! ++list-stable-sort! vector-stable-sort! ++list-delete-neighbor-dups! vector-delete-neighbor-dups! ++ ++heap-sort quick-sort insert-sort list-merge-sort vector-merge-sort ++heap-sort! quick-sort! insert-sort! list-merge-sort! vector-merge-sort! ++ ++------------------------------------------------------------------------------- ++* Introduction ++-------------- ++As I'll detail bewlow, I wasn't very happy with the state of the Scheme ++world for sorting and merging lists and vectors. So I have designed and ++written a fairly comprehensive sorting & merging toolkit. It is ++ ++ - very portable, ++ ++ - much better code than what is currently in Elk, Gambit, Bigloo, ++ Scheme->C, MzScheme, RScheme, Scheme48, MIT Scheme, or slib, and ++ ++ - priced to move: free code. ++ ++The package includes ++ - Vector insert sort (stable) ++ - Vector heap sort ++ - Vector quick sort (with median-of-3 pivot picking) ++ - Vector merge sort (stable) ++ - Pure and destructive list merge sort (stable) ++ - Stable vector and list merge ++ - Miscellaneous sort-related procedures: Vector and list merging, ++ sorted? predicates, vector binary search, vector and list ++ delete-equal-neighbor procedures. ++ - A general, non-algorithmic set of procedure names for general sorting ++ and merging. ++ ++Scheme programmers may want to adopt this package. I'd like Scheme ++implementors to adopt this code and its API -- in fact, the code is a bribe to ++make it easy for implementors to converge on the suggested API. I mean, you'd ++really have to be a boor to take this free code I wrote and mutate its ++interface over to your incompatible, unportable API, wouldn't you? But you ++could, of course -- it's freely available. More in the spirit of the offering, ++you could make this API available, and then also write a little module ++providing your old interface that is defined in terms of this API. "Scheme ++implementors," in this context, includes slib, which isn't really a standalone ++implementation of Scheme, but is an influential collection of API's and code. ++ ++The code is tightly bummed. It is clearly written, and commented in my usual ++voluminous style. This includes notes on porting and implementation-specific ++optimisations. ++ ++ ++------------------------------------------------------------------------------- ++* What's wrong with the current state of affairs? ++------------------------------------------------- ++ ++It's just amazing to me that in 2002, sorting and merging hasn't been ++completely put to bed. These are well-understood algorithms, each of them well ++under a page of code. The straightforward algorithms are basic, core stuff -- ++sophomore-level. But if you tour the major Scheme implementations out there on ++the Net, you find badly written code that provides extremely spotty coverage ++of the algorithm space. One implementation even has a buggy implementation ++that has been in use for about 20 years! ++ ++Open source-code is a wonderful thing. In a couple of hours, I was able to ++download and check the sources of 9 Scheme systems. Here are my notes from the ++systems I checked. You can skip to the next section if you aren't morbidly ++curious. ++ ++slib ++ sorted? vector-or-list < ++ merge list1 list2 < ++ merge! list1 list2 < ++ sort vector-or-list < ++ sort! vector-or-list < ++ ++ Richard O'Keefe's stable list merge sort is right idea, but implemented ++ using gratuitous variable side effects. It also does redundant SET-CDR!s. ++ The vector sort converts to list, merge sorts, then reconverts ++ to vector. This is a bad idea -- non-local pointer chasing bad; vector ++ shuffling good. ++ ++MIT Scheme ++ sort! vector < ++ merge-sort! vector < ++ quick-sort! vector < ++ ++ sort vector-or-list < ++ merge-sort vector-or-list < ++ quick-sort vector-or-list < ++ ++ Naive vector quicksort: loser, for worst-case performance reasons. ++ List sort by "list->vector; quicksort; vector->list," hence also loser. ++ A clever stable vector merge sort, albeit not very bummed. ++ ++Scheme 48 & T ++ sort-list list < ++ sort-list! list < ++ list-merge! list1 list2 < ++ ++ Bob Nix's implementation of online merge-sort, written in the early 80's. ++ Conses unnecessary bookkeeping structure, which isn't necessary with a ++ proper recursive formulation. Also, does redundant SET-CDR!s. No vector ++ sort. Also, has a bug -- is claimed to be a stable sort, but isn't! To see ++ this, get the S48 code, and try ++ (define (my< x y) (< (quotient x 2) (quotient y 2))) ++ (list-merge! (list 0 2) (list 3) my<) ; -> (0 2 3) ++ (list-merge! (list 2) (list 0 3) my<) ; -> (0 3 2) ++ This could be fixed very easily, but it isn't worth it given the ++ other problems with the algorithm. ++ ++RScheme ++ vector-sort! vector < ++ sort collection < ++ ++ Good basic implementation of vector heapsort, which has O(n lg n) ++ worst-case time. Code ugly, needs tuning. List sort by "list->vector; ++ sort; vector->list", which allocates unneeded temp storage. Nothing ++ for stable sorting. ++ ++MzScheme ++ Naive quicksort -- but not available for vector sorting, even ++ though it internally uses a vector. Nothing for stable sorting, ++ and naive quicksort has bad worst-case behaviour. ++ ++Bigloo, Scheme->C ++ Couldn't find anything -- but maybe I didn't search for the right ++ thing, since the Bigloo names are French. (I invite correction from ++ the Bigloo implementors.) ++ ++Gambit ++ sort-list list < ++ Nothing for vectors. Simple, slow, unstable merge sort for lists. ++ ++Elk ++ Another naive quicksort. Lists handled by converting to vector. ++ sort vector-or-list < ++ sort! vector-or-list < ++ ++Chez Scheme ++ merge < list1 list2 ++ merge! < list1 list2 ++ sort < list ++ sort! < list ++ ++ These are stable. I have not seen the source code. ++ ++Common Lisp ++ sort sequence < [key] ++ stable-sort sequence < [key] ++ merge result-type sequence1 sequence2 < [key] ++ ++ The sort procedures are allowed, but not required, to be destructive. ++ ++SML/NJ ++ sort: ('a*'a -> bool) -> 'a list -> 'a list ++ "Smooth applicative merge sort," which is stable. ++ There is also a highly bummed quicksort for vectors. ++ ++The right solution: Implement a full toolbox of carefully written standard sort ++routines. ++ ++Having the source available for all of these above-cited Schemes made ++life a lot easier writing this code. I appreciate the authors making their ++source available under such open terms. ++ ++ ++------------------------------------------------------------------------------- ++* Design rules ++-------------- ++ ++** What vs. how ++=============== ++There are two different interfaces: "what" (simple) & "how" (detailed). ++ ++ - Simple: you specify semantics: datatype (list or vector), ++ mutability, and stability. ++ ++ - Detailed: you specify the actual algorithm (quick, heap, ++ insert, merge). Different algorithms have different properties, ++ both semantic & pragmatic, so these exports are necessary. ++ ++ It is necessarily the case that the specifications of these procedures ++ make statements about execution "pragmatics." For example, the sole ++ distinction between heap sort and quick sort -- both of which are ++ provided by this library -- is one of execution time, which is not a ++ "semantic" distinction. Similar resource-use statements are made about ++ "iterative" procedures, meaning that they can execute on input of ++ arbitrary size without needing to allocate an unbounded number of stack ++ frames. ++ ++** Consistency across function signatures ++========================================= ++The two interfaces share common function signatures wherever ++possible, to facilitate switching a given call from one procedure ++to another. ++ ++** Data parameter first, less-than parameter after ++================================================== ++These procedures uniformly observe the following parameter order: ++the data to be sorted come before the the comparison function. ++That is, we write ++ (sort lis <) ++not ++ (sort < lis). ++This is consistent with every single implementation out there, with ++the sole exception of Chez Scheme. ++ ++In my opinion, it would be more consistent with other Scheme libraries ++to put the ordering function first -- the "operation currying" convention. ++(E.g., consider FOR-EACH or MAP or FIND.) I decided to leave things as they ++are in favor of near-total backwards compatibility with existing practice. ++ ++[Perhaps this should be discussed.] ++ ++** Ordering, comparison functions & stability ++============================================= ++These routines take a < comparison function, not a <= comparison ++function, and they sort into increasing order. The difference between ++a < spec and a <= spec comes up in two places: ++ - the definition of an ordered or sorted data set, and ++ - the definition of a stable sorting algorithm. ++ +++ We say that a data set (a list or vector) is *sorted* or *ordered* ++ if it contains no adjacent pair of values ... X Y ... such that Y < X. ++ ++ In other words, scanning across the data never takes a "downwards" step. ++ ++ If you use a <= procedure where these algorithms expect a < ++ procedure, you may not get the answers you expect. For example, ++ the LIST-SORTED? function will return false if you pass it a <= comparison ++ function and an ordered list containing adjacent equal elements. ++ +++ A "stable" sort is one that preserves the pre-existing order of equal ++ elements. Suppose, for example, that we sort a list of numbers by ++ comparing their absolute values, i.e., using comparison function ++ (lambda (x y) (< (abs x) (abs y))) ++ If we sort a list that contains both 3 and -3: ++ ... 3 ... -3 ... ++ then a stable sort is an algorithm that will not swap the order ++ of these two elements, that is, the answer will look like ++ ... 3 -3 ... ++ not ++ ... -3 3 ... ++ ++ Choosing < for the comparison function instead of <= affects how stability ++ is coded. Given an adjacent pair X Y, (< y x) means "Y should be moved in ++ front of X" -- otherwise, leave things as they are. So using a <= function ++ where a < function is expected will *invert* stability. ++ ++ This is due to the definition of equality, given a < comparator: ++ (and (not (< x y)) ++ (not (< y x))) ++ The definition is rather different, given a <= comparator: ++ (and (<= x y) ++ (<= x y)) ++ +++ A "stable" merge is one that reliably favors one of its data sets ++ when equal items appear in both data sets. *All merge operations in ++ this library are stable*, breaking ties between data sets in favor ++ of the first data set -- elements of the first list come before equal ++ elements in the second list. ++ ++ So, if we are merging two lists of numbers ordered by absolute value ++ using the stable merge operation LIST-MERGE ++ (list-merge '(0 -2 4 8 -10) '(-1 3 -4 7) ++ (lambda (x y) (< (abs x) (abs y)))) ++ reliably places the 4 of the first list before the equal-comparing -4 ++ of the second list: ++ (0 -1 -2 4 -4 7 8 -10) ++ ++In short, if your comparison function F answers true to (F x x), then ++using a stable sorting or merging algorithm will not give you a stable sort ++or merge, and LIST-SORTED? may surprise you. Note that you can synthesize a < ++function from a <= function with ++ (lambda (x y) (not (<= y x))) ++if need be. ++ ++Precise definitions give sharp edges to tools, but require care ++in use. "Measure twice, cut once." ++ ++I have adopted the choice of < from Common Lisp. I assume they ++had a good reason for adopting < instead of <=. I'd love to know ++what this reason is; send me email if you can explain it, please. ++ ++** All vector operations accept optional subrange parameters ++============================================================ ++The vector operations specified below all take optional START/END arguments ++indicating a selected subrange of a vector's elements. If a START parameter or ++START/END parameter pair is given to such a procedure, they must be exact, ++non-negative integers, such that ++ 0 <= START <= END <= (VECTOR-LENGTH V) ++where V is the related vector parameter. If not specified, they default to 0 ++and the length of the vector, respectively. They are interpreted to select the ++range [START,END), that is, all elements from index START (inclusive) up to, ++but not including, index END. ++ ++** Required vs. allowed side-effects ++==================================== ++LIST-SORT! and LIST-STABLE-SORT! are allowed, but not required, ++to alter their arguments' cons cells to construct the result list. This is ++consistent with the what-not-how character of the group of procedures ++to which they belong (the "sort-lib" package). ++ ++The LIST-DELETE-NEIGHBOR-DUPS!, LIST-MERGE! and LIST-MERGE-SORT! procedures, ++on the other hand, provide specific algorithms, and, as such, explicitly ++commit to the use of side-effects on their input lists in order to guarantee ++their key algorithmic properties (e.g., linear-time operation, constant-space ++stack use). ++ ++------------------------------------------------------------------------------- ++* Procedure specification ++------------------------- ++The procedures are split into several packages. In a Scheme system that has a ++module or package system, these procedures should be contained in modules ++named as follows: ++ Package name Functionality ++ ------------ ------------- ++ sort-lib General sorting for lists & vectors ++ sorted?-lib Sorted predicates for lists & vectors ++ list-merge-sort-lib List merge sort ++ vector-merge-sort-lib Vector merge sort ++ vector-heap-sort-lib Vector heap sort ++ vector-quick-sort-lib Vector quick sort ++ vector-insert-sort-lib Vector insertion sort ++ delndup-lib List and vector delete neighbor duplicates ++ ++A Scheme system without a module system should provide all of the bindings ++defined in all of these modules as components of the "SRFI-32" package. ++ ++Note that there is no list insert sort package, as you might as well always ++use list merge sort. The reference implementation's destructive list merge ++sort will do fewer SET-CDR!s than a destructive insert sort. ++ ++** Procedure naming and functionality ++===================================== ++Almost all of the procedures described below are variants of two basic ++operations: sorting and merging. These procedures are consistently named ++by composing a set of basic lexemes to indicate what they do. ++ ++Lexeme Meaning ++------ ------- ++"sort" The procedure sorts its input data set by some < comparison function. ++ ++"merge" The procedure merges two ordered data sets into a single ordered ++ result. ++ ++"stable" This lexeme indicates that the sort is a stable one. ++ ++"vector" The procedure operates upon vectors. ++ ++"list" The procedure operates upon lists. ++ ++"!" Procedures that end in "!" are allowed, and sometimes required, ++ to reuse their input storage to construct their answer. ++ ++** Types of parameters and return values ++======================================== ++In the procedures specified below, ++ - A LIS parameter is a list; ++ ++ - A V parameter is a vector; ++ ++ - A < or = parameter is a procedure accepting two arguments taken from the ++ specified procedure's data set(s), and returning a boolean; ++ ++ - START and END parameters are exact, non-negative integers that ++ serve as vector indices selecting a subrange of some associated vector. ++ When specified, they must satisfy the relation ++ 0 <= start <= end <= (vector-length v) ++ where V is the associated vector. ++ ++Passing values to procedures with these parameters that do not satisfy these ++types is an error. ++ ++If a procedure is said to return "unspecified," this means that nothing at all ++is said about what the procedure returns, not even the number of return ++values. Such a procedure is not even required to be consistent from call to ++call in the nature or number of its return values. It is simply required to ++return a value (or values) that may be passed to a command continuation, e.g. ++as the value of an expression appearing as a non-terminal subform of a BEGIN ++expression. Note that in R5RS, this restricts such a procedure to returning a ++single value; non-R5RS systems may not even provide this restriction. ++ ++** sort-lib - general sorting package ++===================================== ++This library provides basic sorting and merging functionality suitable for ++general programming. The procedures are named by their semantic properties, ++i.e., what they do to the data (sort, stable sort, merge, and so forth). ++ ++ Procedure Suggested algorithm ++ ------------------------------------------------------------------------- ++ list-sorted? lis < -> boolean ++ list-merge lis1 lis2 < -> list ++ list-merge! lis1 lis2 < -> list ++ list-sort lis < -> list (vector heap or quick) ++ list-sort! lis < -> list (list merge sort) ++ list-stable-sort lis < -> list (vector merge sort) ++ list-stable-sort! lis < -> list (list merge sort) ++ list-delete-neighbor-dups lis = -> list ++ list-delete-neighbor-dups! lis = -> list ++ ++ vector-sorted? v < [start end] -> boolean ++ vector-merge v1 v2 < [start1 end1 start2 end2] -> vector ++ vector-merge! v v1 v2 < [start start1 end1 start2 end2] -> unspecific ++ vector-sort v < [start end] -> vector (heap or quick sort) ++ vector-sort! v < [start end] -> unspecific (heap or quick sort) ++ vector-stable-sort v < [start end] -> vector (vector merge sort) ++ vector-stable-sort! v < [start end] -> unspecific (vector merge sort) ++ vector-delete-neighbor-dups v = [start end] -> vector ++ vector-delete-neighbor-dups! v = [start end] -> end' ++ ++ LIST-SORTED? and VECTOR-SORTED? return true if their input list or vector ++ is in sorted order, as determined by their < comparison parameter. ++ ++ All four merge operations are stable: an element of the initial list LIS1 ++ or vector V1 will come before an equal-comparing element in the second ++ list LIS2 or vector V2 in the result. ++ ++ The procedures ++ LIST-MERGE ++ LIST-SORT ++ LIST-STABLE-SORT ++ LIST-DELETE-NEIGHBOR-DUPS ++ do not alter their inputs and are allowed to return a value that shares ++ a common tail with a list argument. ++ ++ The procedures ++ LIST-SORT! ++ LIST-STABLE-SORT! ++ are "linear update" operators -- they are allowed, but not required, to ++ alter the cons cells of their arguments to produce their results. ++ ++ On the other hand, the procedures ++ LIST-DELETE-NEIGHBOR-DUPS! ++ LIST-MERGE! ++ make only a single, iterative, linear-time pass over their argument lists, ++ using SET-CDR!s to rearrange the cells of the lists into the final result ++ -- they work "in place." Hence, any cons cell appearing in the result must ++ have originally appeared in an input. The intent of this ++ iterative-algorithm commitment is to allow the programmer to be sure that ++ if, for example, LIST-MERGE! is asked to merge two ten-million-element ++ lists, the operation will complete without performing some extremely ++ (possibly twenty-million) deep recursion. ++ ++ The vector procedures ++ VECTOR-SORT ++ VECTOR-STABLE-SORT ++ VECTOR-DELETE-NEIGHBOR-DUPS ++ do not alter their inputs, but allocate a fresh vector for their result, ++ of length END-START. ++ ++ The vector procedures ++ VECTOR-SORT! ++ VECTOR-STABLE-SORT! ++ sort their data in-place. (But note that VECTOR-STABLE-SORT! may ++ allocate temporary storage proportional to the size of the input -- ++ I am not aware of O(n lg n) stable vector sorting algorithms that ++ run in constant space.) ++ ++ VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). ++ ++ VECTOR-MERGE! writes its result into vector V, beginning at index START0, ++ for indices less than END0 = START0 + (END1-START1) + (END2-START2). The ++ target subvector ++ V[start0,end0) ++ may not overlap either source subvector ++ V1[start1,end1) ++ V2[start2,end2). ++ ++ The DELETE-NEIGHBOR-DUP-... procedures: ++ These procedures delete adjacent duplicate elements from a list or a ++ vector, using a given element-equality procedure. The first/leftmost ++ element of a run of equal elements is the one that survives. The list or ++ vector is not otherwise disordered. ++ ++ These procedures are linear time -- much faster than the O(n^2) general ++ duplicate-element deletors that do not assume any "bunching" of elements ++ (such as the ones provided by SRFI-1). If you want to delete duplicate ++ elements from a large list or vector, sort the elements to bring equal ++ items together, then use one of these procedures, for a total time of ++ O(n lg n). ++ ++ The comparison function = passed to these procedures is always applied ++ (= x y) ++ where X comes before Y in the containing list or vector. ++ ++ - LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer ++ may share storage with the input list. ++ ++ - VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but ++ rather allocates a fresh vector to hold the result. ++ ++ - LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to ++ mutate its input list in order to construct its answer. ++ ++ - VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the ++ answer, packing its answer into the index range [start,end'), where ++ END' is the non-negative exact integer returned as its value. It ++ returns END' as its result. The vector is not altered outside the range ++ [start,end'). ++ ++ [Maybe this procedure should take a "target" vector to write?] ++ ++ - Examples: ++ (list-delete-neighbor-dups '(1 1 2 7 7 7 0 -2 -2) =) ++ => (1 2 7 0 -2) ++ ++ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) =) ++ => #(1 2 7 0 -2) ++ ++ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) = 3 7) ++ => #(7 0 -2) ++ ++ ;; Result left in v[3,9): ++ (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) ++ (cons (vector-delete-neighbor-dups! v = 3) ++ v)) ++ => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) ++ ++ ++** Algorithm-specific sorting packages ++====================================== ++These packages provide more specific sorting functionality, that is, ++specific committment to particular algorithms that have particular ++pragmatic consequences (such as memory locality, asymptotic running time) ++beyond their semantic behaviour (sorting, stable sorting, merging, etc.). ++Programmers that need a particular algorithm can use one of these packages. ++ ++sorted?-lib - sorted predicates ++ list-sorted? lis < -> boolean ++ vector-sorted? v < [start end] -> boolean ++ ++ Return #f iff there is an adjacent pair ... X Y ... in the input ++ list or vector such that Y < X. The optional START/END range ++ arguments restrict VECTOR-SORTED? to the indicated subvector. ++ ++list-merge-sort-lib - list merge sort ++ list-merge-sort lis < -> list ++ list-merge-sort! lis < -> list ++ list-merge lis1 lis2 < -> list ++ list-merge! lis1 lis2 < -> list ++ ++ The sort procedures sort their data using a list merge sort, which is ++ stable. (The reference implementation is, additionally, a "natural" sort. ++ See below for the properties of this algorithm.) ++ ++ The ! procedures are destructive -- they use SET-CDR!s to rearrange the ++ cells of the lists into the proper order. As such, they do not allocate ++ any extra cons cells -- they are "in place" sorts. Additionally, ++ LIST-MERGE! is iterative, not recursive -- it can operate on arguments of ++ arbitrary size without requiring an unbounded amount of stack space. ++ ++ The merge operations are stable: an element of LIS1 will come before an ++ equal-comparing element in LIS2 in the result list. ++ ++vector-merge-sort-lib - vector merge sort ++ vector-merge-sort v < [start end temp] -> vector ++ vector-merge-sort! v < [start end temp] -> unspecific ++ vector-merge v1 v2 < [start1 end1 start2 end2] -> vector ++ vector-merge! v v1 v2 < [start0 start1 end1 start2 end2] -> unspecific ++ ++ The sort procedures sort their data using vector merge sort, which is ++ stable. (The reference implementation is, additionally, a "natural" sort. ++ See below for the properties of this algorithm.) ++ ++ The optional START/END arguments provide for sorting of subranges, and ++ default to 0 and the length of the corresponding vector. ++ ++ Merge-sorting a vector requires the allocation of a temporary "scratch" ++ work vector for the duration of the sort. This scratch vector can be ++ passed in by the client as the optional TEMP argument; if so, the supplied ++ vector must be of size >= END, and will not be altered outside the range ++ [start,end). If not supplied, the sort routines allocate one themselves. ++ ++ The merge operations are stable: an element of V1 will come before an ++ equal-comparing element in V2 in the result vector. ++ ++ VECTOR-MERGE-SORT! leaves its result in V[start,end). ++ ++ VECTOR-MERGE-SORT returns a vector of length END-START. ++ ++ VECTOR-MERGE returns a vector of length (END1-START1)+(END2-START2). ++ ++ VECTOR-MERGE! writes its result into vector V, beginning at index START0, ++ for indices less than END0 = START0 + (END1-START1) + (END2-START2). The ++ target subvector ++ V[start0,end0) ++ may not overlap either source subvector ++ V1[start1,end1) ++ V2[start2,end2). ++ ++vector-heap-sort-lib - vector heap sort ++ heap-sort v < [start end] -> vector ++ heap-sort! v < [start end] -> unspecific ++ ++ These procedures sort their data using heap sort, ++ which is not a stable sorting algorithm. ++ ++ HEAP-SORT returns a vector of length END-START. ++ HEAP-SORT! is in-place, leaving its result in V[start,end). ++ ++vector-quick-sort-lib - vector quick sort ++ quick-sort v < [start end] -> vector ++ quick-sort! v < [start end] -> unspecific ++ ++ These procedures sort their data using quick sort, ++ which is not a stable sorting algorithm. ++ ++ QUICK-SORT returns a vector of length END-START. ++ QUICK-SORT! is in-place, leaving its result in V[start,end). ++ ++vector-insert-sort-lib - vector insertion sort ++ insert-sort v < [start end] -> vector ++ insert-sort! v < [start end] -> unspecific ++ ++ These procedures stably sort their data using insertion sort. ++ ++ INSERT-SORT returns a vector of length END-START. ++ INSERT-SORT! is in-place, leaving its result in V[start,end). ++ ++delndup-lib - list and vector delete neighbor duplicates ++ list-delete-neighbor-dups lis = -> list ++ list-delete-neighbor-dups! lis = -> list ++ ++ vector-delete-neighbor-dups v = [start end] -> vector ++ vector-delete-neighbor-dups! v = [start end] -> end' ++ ++ These procedures delete adjacent duplicate elements from a list or ++ a vector, using a given element-equality procedure =. The first/leftmost ++ element of a run of equal elements is the one that survives. The list ++ or vector is not otherwise disordered. ++ ++ These procedures are linear time -- much faster than the O(n^2) general ++ duplicate-element deletors that do not assume any "bunching" of elements ++ (such as the ones provided by SRFI-1). If you want to delete duplicate ++ elements from a large list or vector, sort the elements to bring equal ++ items together, then use one of these procedures, for a total time of ++ O(n lg n). ++ ++ The comparison function = passed to these procedures is always applied ++ (= x y) ++ where X comes before Y in the containing list or vector. ++ ++ LIST-DELETE-NEIGHBOR-DUPS does not alter its input list; its answer ++ may share storage with the input list. ++ ++ VECTOR-DELETE-NEIGHBOR-DUPS does not alter its input vector, but ++ rather allocates a fresh vector to hold the result. ++ ++ LIST-DELETE-NEIGHBOR-DUPS! is permitted, but not required, to ++ mutate its input list in order to construct its answer. ++ ++ VECTOR-DELETE-NEIGHBOR-DUPS! reuses its input vector to hold the ++ answer, packing its answer into the index range [start,end'), where ++ END' is the non-negative exact integer returned as its value. It ++ returns END' as its result. The vector is not altered outside the range ++ [start,end'). ++ ++ Examples: ++ (list-delete-neighbor-dups '(1 1 2 7 7 7 0 -2 -2) =) ++ => (1 2 7 0 -2) ++ ++ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) =) ++ => #(1 2 7 0 -2) ++ ++ (vector-delete-neighbor-dups '#(1 1 2 7 7 7 0 -2 -2) = 3 7) ++ => #(7 0 -2) ++ ++ ;; Result left in v[3,9): ++ (let ((v (vector 0 0 0 1 1 2 2 3 3 4 4 5 5 6 6))) ++ (cons (vector-delete-neighbor-dups! v = 3) ++ v)) ++ => (9 . #(0 0 0 1 2 3 4 5 6 4 4 5 5 6 6)) ++ ++ ++------------------------------------------------------------------------------- ++* Algorithmic properties ++------------------------ ++Different sort and merge algorithms have different properties. ++Choose the algorithm that matches your needs: ++ ++Vector insert sort ++ Stable, but only suitable for small vectors -- O(n^2). ++ ++Vector quick sort ++ Not stable. Is fast on average -- O(n lg n) -- but has bad worst-case ++ behaviour. Has good memory locality for big vectors (unlike heap sort). ++ A clever pivot-picking trick (median of three samples) helps avoid ++ worst-case behaviour, but pathological cases can still blow up. ++ ++Vector heap sort ++ Not stable. Guaranteed fast -- O(n lg n) *worst* case. Poor locality ++ on large vectors. A very reliable workhorse. ++ ++Vector merge sort ++ Stable. Not in-place -- requires a temporary buffer of equal size. ++ Fast -- O(n lg n) -- and has good memory locality for large vectors. ++ ++ The implementation of vector merge sort provided by this SRFI's reference ++ implementation is, additionally, a "natural" sort, meaning that it ++ exploits existing order in the input data, providing O(n) best case. ++ ++Destructive list merge sort ++ Stable, fast and in-place (i.e., allocates no new cons cells). "Fast" ++ means O(n lg n) worse-case, and substantially better if the data ++ is already mostly ordered, all the way down to linear time for ++ a completely-ordered input list (i.e., it is a "natural" sort). ++ ++ Note that sorting lists involves chasing pointers through memory, which ++ can be a loser on modern machine architectures because of poor cache & ++ page locality. Pointer *writing*, which is what the SET-CDR!s of a ++ destructive list-sort algorithm do, is even worse, especially if your ++ Scheme has a generational GC -- the writes will thrash the write-barrier. ++ Sorting vectors has inherently better locality. ++ ++ This SRFIs destructive list merge and merge sort implementations are ++ opportunistic -- they avoid redundant SET-CDR!s, and try to take long ++ already-ordered runs of list structure as-is when doing the merges. ++ ++Pure list merge sort ++ Stable and fast -- O(n lg n) worst-case, and possibly better, depending ++ upon the input list (see above). ++ ++ ++Algorithm Stable? Worst case Average case In-place ++------------------------------------------------------ ++V insert Yes O(n^2) O(n^2) Yes ++V quick No O(n^2) O(n lg n) Yes ++V heap No O(n lg n) O(n lg n) Yes ++V merge Yes O(n lg n) O(n lg n) No ++L merge Yes O(n lg n) O(n lg n) Either ++ ++ ++------------------------------------------------------------------------------- ++* Topics to be resolved during discussion phase ++----------------------------------------------- ++I particularly solicit comments about the following topics. ++ ++- Include VECTOR-BINARY-SEARCH ? ++ Should we include ++ (VECTOR-BINARY-SEARCH v key< elt->key key [start end]) ++ in the SRFI? It sort of goes with sorting; it's exactly ten lines of code. ++ ++- Comparison function before or after the list/vector argument? ++ Should it be ++ (list-sort < lis) ++ or ++ (list-sort lis <) ++ There is overwhelming consistency among the implementations: data first, ++ < after. Only Chez does it differently. ++ ++ I have done it in the backwards-compatible way. But I prefer the < first, ++ data after way. ++ ++ ++------------------------------------------------------------------------------- ++* Porting and optimisation ++-------------------------- ++This package should be trivial to port. There are only four non-R4RS bits ++in the code: ++- Use of multiple-value return, with the R5RS VALUES procedure, and the ++ simple (RECEIVE (var ...) mv-exp body ...) multiple-value binding macro. ++ ++- A VECTOR-COPY procedure. This is a tiny little procedure: ++ (vector-copy v [start end]) ++ ++- Use of the LET-OPTIONALS macro from scsh to parse and default optional ++ arguments to three routines. Again, easy to port the macro or rewrite ++ the code to parse, default, and error check the args by hand. ++ ++- Calls to an ERROR function for complaining about bad arguments. ++ ++This code is tightly bummed, as far as I can go in portable Scheme. ++ ++You could speed up the vector code a lot by error-checking the procedure ++parameters and then shifting over to fixnum-specific arithmetic and ++dangerous vector-indexing and vector-setting primitives. The comments ++in the code indicate where the initial error checks would have to be ++added. There are several (QUOTIENT N 2)'s that could be changed to a ++fixnum right-shift, as well, in both the list and vector code. The code ++is designed to enable this -- each file usually exports one or two "safe" ++procedures that end up calling an internal "dangerous" primitive. The ++little exported cover procedures are where you move the error checks. ++ ++This should provide *big* speedups. In fact, all the code bumming I've done ++pretty much disappears in the noise unless you have a good compiler and also ++can dump the vector-index checks and generic arithmetic -- so I've really just ++set things up for you to exploit. ++ ++The optional-arg parsing, defaulting, and error checking is done with a ++portable R4RS macro. But if your Scheme has a faster mechanism (e.g., Chez), ++you should definitely port over to it. Note that argument defaulting and ++error-checking are interleaved -- you don't have to error-check defaulted ++START/END args to see if they are fixnums that are legal vector indices for ++the corresponding vector, etc. ++ ++ ++------------------------------------------------------------------------------- ++* References & Links ++-------------------- ++ ++This document, in HTML: ++ http://srfi.schemers.org/srfi-32/srfi-32.html ++ [This link may not be valid while the SRFI is in draft form.] ++ ++This document, in simple text format: ++ http://srfi.schemers.org/srfi-32/srfi-32.txt ++ ++Archive of SRFI-32 discussion-list email: ++ http://srfi.schemers.org/srfi-32/mail-archive/maillist.html ++ ++SRFI web site: ++ http://srfi.schemers.org/ ++ ++[CommonLisp] ++ Common Lisp: the Language ++ Guy L. Steele Jr. (editor). ++ Digital Press, Maynard, Mass., second edition 1990. ++ Available at http://www.elwood.com/alu/table/references.htm#cltl2 ++ ++ The Common Lisp "HyperSpec," produced by Kent Pitman, is essentially ++ the ANSI spec for Common Lisp: ++ http://www.xanalys.com/software_tools/reference/HyperSpec/ ++ ++[R5RS] ++ Revised^5 Report on the Algorithmic Language Scheme, ++ R. Kelsey, W. Clinger, J. Rees (editors). ++ Higher-Order and Symbolic Computation, Vol. 11, No. 1, September, 1998. ++ and ACM SIGPLAN Notices, Vol. 33, No. 9, October, 1998. ++ ++ Available at http://www.schemers.org/Documents/Standards/ ++ ++ ++------------------------------------------------------------------------------- ++* Acknowledgements ++------------------ ++ ++I thank the authors of the open source I consulted when designing this ++library, particularly Richard O'Keefe, Donovan Kolby and the MIT Scheme Team. ++ ++ ++------------------------------------------------------------------------------- ++* Copyright ++----------- ++ ++** SRFI text ++============ ++This document is copyright (C) Olin Shivers (1998, 1999). ++All Rights Reserved. ++ ++Permission is hereby granted, free of charge, to any person obtaining ++a copy of this software and associated documentation files (the ++"Software"), to deal in the Software without restriction, including ++without limitation the rights to use, copy, modify, merge, publish, ++distribute, sublicense, and/or sell copies of the Software, and to ++permit persons to whom the Software is furnished to do so, subject to ++the following conditions: ++ ++The above copyright notice and this permission notice shall be ++included in all copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ++LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ++OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ++WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ ++** Reference implementation ++=========================== ++Short summary: no restrictions. ++ ++While I wrote all of this code myself, I read a lot of code before I began ++writing. However, all such code is, itself, either open source or public ++domain, rendering irrelevant any issue of "copyright taint." ++ ++The natural merge sorts (pure list, destructive list, and vector) are not only ++my own code, but are implementations of an algorithm of my own devising. They ++run in O(n lg n) worst case, O(n) best case, and require only a logarithmic ++number of stack frames. And they are stable. And the destructive-list variant ++allocates zero cons cells; it simply rearranges the cells of the input list. ++ ++Hence the reference implementation is ++ Copyright (c) 1998 by Olin Shivers. ++and made available under the same copyright as the SRFI text (see above). +diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5/let.rkt racket-6.12/share/pkgs/srfi-lib/srfi/%3a5/let.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5/let.rkt 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib/srfi/%3a5/let.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1 +0,0 @@ +-#lang s-exp srfi/provider srfi/%3a5 +diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5.rkt racket-6.12/share/pkgs/srfi-lib/srfi/%3a5.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib/srfi/%3a5.rkt 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib/srfi/%3a5.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,3 +0,0 @@ +-#lang s-exp srfi/provider srfi/5 +- +-;; FIXME: "rest arguments" need to generate mutable lists +diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/5/let.rkt racket-6.12/share/pkgs/srfi-lib/srfi/5/let.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib/srfi/5/let.rkt 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib/srfi/5/let.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,86 +0,0 @@ +-;;; +-;;; <let.rkt> ---- SRFI 5 A compatible let form with signatures and rest arguments +-;;; Time-stamp: <03/04/08 09:56:06 solsona> +-;;; +-;;; Usually, I would add a copyright notice, and the announce that +-;;; this code is under the LGPL licence. Nevertheless, I only did the +-;;; port to PLT Scheme v200, and here is the copyright notice, +-;;; comments, and licence from the original source: +-;;; +-;;; Copyright (C) Andy Gaynor (1999-2003) +-;;; +-;;; The version of my-let here was cleaned up by: Paul Schlie schlie@attbi.com. +-;;; Renamed to s:let by Eli Barzilay +- +-#lang scheme/base +-(provide s:let) +- +-(define-syntax s:let +- (syntax-rules () +- ;; standard +- ((s:let () body ...) +- (let () body ...)) +- ((s:let ((var val) ...) body ...) +- (let ((var val) ...) body ...)) +- +- ;; rest style +- ((s:let ((var val) . bindings) body ...) +- (let-loop #f bindings (var) (val) (body ...))) +- +- ;; signature style +- ((s:let (name bindings ...) body ...) +- (let-loop name (bindings ...) () () (body ...))) +- +- ;; standard named style +- ((s:let name (bindings ...) body ...) +- (let-loop name (bindings ...) () () (body ...))) +- +- )) +- +-;; A loop to walk down the list of bindings. +- +-(define-syntax let-loop +- (syntax-rules () +- +- ;; No more bindings - make a LETREC. +- ((let-loop name () (vars ...) (vals ...) body) +- ((letrec ((name (lambda (vars ...) . body))) +- name) +- vals ...)) +- +- ;; Rest binding, no name +- ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) +- (let ((var val) ... (rest-var (list rest-val ...))) . body)) +- +- ;; Process a (var val) pair. +- ((let-loop name ((var val) more ...) (vars ...) (vals ...) body) +- (let-loop name (more ...) (vars ... var) (vals ... val) body)) +- +- ;; End with a rest variable - make a LETREC. +- ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body) +- ((letrec ((name (lambda (vars ... . rest-var) . body))) +- name) +- vals ... rest-vals ...)))) +- +-;; Four loops - normal and `signature-style', each with and without a rest +-;; binding. +-;; +-;;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) +-;; (if (= i n) +-;; f0 +-;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-;; +-;;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) +-;; (if (= i n) +-;; f0 +-;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) +-;; +-;;(let fibonacci ((n 10) (i 0) . (f 0 1)) +-;; (if (= i n) +-;; (car f) +-;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) +-;; +-;;(let (fibonacci (n 10) (i 0) . (f 0 1)) +-;; (if (= i n) +-;; (car f) +-;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) +diff -urN racket-6.12-orig/share/pkgs/srfi-lib/srfi/5.rkt racket-6.12/share/pkgs/srfi-lib/srfi/5.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib/srfi/5.rkt 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib/srfi/5.rkt 1969-12-31 19:00:00.000000000 -0500 +@@ -1,2 +0,0 @@ +-;; module loader for SRFI-5 +-#lang s-exp srfi/provider srfi/5/let #:unprefix s: +diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/info.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/info.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/info.rkt 2018-01-31 12:22:58.159501944 -0500 +@@ -0,0 +1,14 @@ ++#lang info ++ ++(define collection 'multi) ++ ++(define deps '("scheme-lib" ++ "base" ++ "r6rs-lib" ++ "srfi-lib" ++ "compatibility-lib")) ++ ++ ++(define pkg-desc "implementation (no documentation) part of "srfi nonfree"") ++ ++(define pkg-authors '(mflatt noel chongkai jay)) +diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5/let.rkt 2018-01-31 12:22:58.159501944 -0500 +@@ -0,0 +1 @@ ++#lang s-exp srfi/provider srfi/%3a5 +diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/%3a5.rkt 2018-01-31 12:22:58.159501944 -0500 +@@ -0,0 +1,3 @@ ++#lang s-exp srfi/provider srfi/5 ++ ++;; FIXME: "rest arguments" need to generate mutable lists +diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5/let.rkt 2018-01-31 12:22:58.159501944 -0500 +@@ -0,0 +1,86 @@ ++;;; ++;;; <let.rkt> ---- SRFI 5 A compatible let form with signatures and rest arguments ++;;; Time-stamp: <03/04/08 09:56:06 solsona> ++;;; ++;;; Usually, I would add a copyright notice, and the announce that ++;;; this code is under the LGPL licence. Nevertheless, I only did the ++;;; port to PLT Scheme v200, and here is the copyright notice, ++;;; comments, and licence from the original source: ++;;; ++;;; Copyright (C) Andy Gaynor (1999-2003) ++;;; ++;;; The version of my-let here was cleaned up by: Paul Schlie schlie@attbi.com. ++;;; Renamed to s:let by Eli Barzilay ++ ++#lang scheme/base ++(provide s:let) ++ ++(define-syntax s:let ++ (syntax-rules () ++ ;; standard ++ ((s:let () body ...) ++ (let () body ...)) ++ ((s:let ((var val) ...) body ...) ++ (let ((var val) ...) body ...)) ++ ++ ;; rest style ++ ((s:let ((var val) . bindings) body ...) ++ (let-loop #f bindings (var) (val) (body ...))) ++ ++ ;; signature style ++ ((s:let (name bindings ...) body ...) ++ (let-loop name (bindings ...) () () (body ...))) ++ ++ ;; standard named style ++ ((s:let name (bindings ...) body ...) ++ (let-loop name (bindings ...) () () (body ...))) ++ ++ )) ++ ++;; A loop to walk down the list of bindings. ++ ++(define-syntax let-loop ++ (syntax-rules () ++ ++ ;; No more bindings - make a LETREC. ++ ((let-loop name () (vars ...) (vals ...) body) ++ ((letrec ((name (lambda (vars ...) . body))) ++ name) ++ vals ...)) ++ ++ ;; Rest binding, no name ++ ((let-loop #f (rest-var rest-val ...) (var ...) (val ...) body) ++ (let ((var val) ... (rest-var (list rest-val ...))) . body)) ++ ++ ;; Process a (var val) pair. ++ ((let-loop name ((var val) more ...) (vars ...) (vals ...) body) ++ (let-loop name (more ...) (vars ... var) (vals ... val) body)) ++ ++ ;; End with a rest variable - make a LETREC. ++ ((let-loop name (rest-var rest-vals ...) (vars ...) (vals ...) body) ++ ((letrec ((name (lambda (vars ... . rest-var) . body))) ++ name) ++ vals ... rest-vals ...)))) ++ ++;; Four loops - normal and `signature-style', each with and without a rest ++;; binding. ++;; ++;;(let fibonacci ((n 10) (i 0) (f0 0) (f1 1)) ++;; (if (= i n) ++;; f0 ++;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) ++;; ++;;(let (fibonacci (n 10) (i 0) (f0 0) (f1 1)) ++;; (if (= i n) ++;; f0 ++;; (fibonacci n (+ i 1) f1 (+ f0 f1)))) ++;; ++;;(let fibonacci ((n 10) (i 0) . (f 0 1)) ++;; (if (= i n) ++;; (car f) ++;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) ++;; ++;;(let (fibonacci (n 10) (i 0) . (f 0 1)) ++;; (if (= i n) ++;; (car f) ++;; (fibonacci n (+ i 1) (cadr f) (+ (car f) (cadr f))))) +diff -urN racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5.rkt racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt +--- racket-6.12-orig/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 1969-12-31 19:00:00.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lib-nonfree/srfi/5.rkt 2018-01-31 12:22:58.159501944 -0500 +@@ -0,0 +1,2 @@ ++;; module loader for SRFI-5 ++#lang s-exp srfi/provider srfi/5/let #:unprefix s: +diff -urN racket-6.12-orig/share/pkgs/srfi-lite-lib/info.rkt racket-6.12/share/pkgs/srfi-lite-lib/info.rkt +--- racket-6.12-orig/share/pkgs/srfi-lite-lib/info.rkt 2018-01-26 16:10:04.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lite-lib/info.rkt 2018-01-31 12:22:58.160501940 -0500 +@@ -1 +1,9 @@ +-(module info setup/infotab (#%module-begin (define package-content-state (quote (built "6.12"))) (define collection (quote multi)) (define deps (quote ("base"))) (define pkg-desc "implementation of the most widely used "srfi" libraries") (define pkg-authors (quote (mflatt))))) ++#lang info ++ ++(define collection 'multi) ++ ++(define deps '("base")) ++ ++(define pkg-desc "implementation of the most widely used "srfi" libraries") ++ ++(define pkg-authors '(mflatt)) +Binary files racket-6.12-orig/share/pkgs/srfi-lite-lib/.info.rkt.swp and racket-6.12/share/pkgs/srfi-lite-lib/.info.rkt.swp differ +diff -urN racket-6.12-orig/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt racket-6.12/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt +--- racket-6.12-orig/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt 2018-01-26 15:34:52.000000000 -0500 ++++ racket-6.12/share/pkgs/srfi-lite-lib/srfi/29/localization.rkt 2018-01-31 12:22:58.162501933 -0500 +@@ -2,6 +2,7 @@ + + (require racket/contract/base + racket/file ++ racket/list + (only-in racket/runtime-path define-runtime-path) + racket/string racket/format + syntax/modread +@@ -113,10 +114,6 @@ + (lambda () + (with-input-from-file path read)))) + #t)))) +- (define (rdc ls) +- (if (null? (cdr ls)) +- '() +- (cons (car ls) (rdc (cdr ls))))) + + ;;Retrieve a localized template given its package name and a template name + (define (localized-template package-name template-name) +@@ -127,5 +124,5 @@ + (let ((bundle (hash-ref *localization-bundles* specifier #f))) + (cond ((and bundle (assq template-name bundle)) => cdr) + ((null? (cdr specifier)) #f) +- (else (loop (rdc specifier)))))))) ++ (else (loop (drop-right specifier 1)))))))) + ) diff --git a/racket.spec b/racket.spec new file mode 100644 index 0000000..d3dc907 --- /dev/null +++ b/racket.spec @@ -0,0 +1,369 @@ +Name: racket +Version: 6.12 +Release: 8%{?dist} +Summary: General purpose programming language + +License: GPLv3 and LGPLv3 and MIT +URL: https://racket-lang.org +Source0: https://mirror.racket-lang.org/installers/%%7Bversion%7D/%%7Bname%7D-%%7Bver... + +# Update SRFI libraries to include upstream PR 5. +# See: https://github.com/racket/srfi/pull/5 (merged) +Patch0: racket-6.12-update-srfi.patch + +# Remove SRFI library and docs with restrictive licensing. +# See: https://github.com/racket/srfi/issues/4 (open) +# Note: Upstream maintainers have confirmed this +# is safe, since the removed components are +# extra elements which nothing else in the +# package depends on. +Patch1: racket-6.12-remove-nonfree.patch + +# Backport upstream fix of rpaths in racket/racket +# which break check-buildroot +# https://github.com/racket/racket/pull/1947 (merged) +Patch2: racket-6.12-fix-rpaths.patch + +# Backport upstream fix of rpaths in racket/web-server +# which break check-buildroot +# https://github.com/racket/web-server/issues/36 (closed) +Patch3: racket-6.12-fix-webserver-rpaths.patch + +# Update racket-doc/search to use https://docs.racket-lang.org +# when no docs exist locally +# https://github.com/racket/scribble/pull/164 (open) +Patch4: racket-6.12-fix-doc-open-url.patch + +# Issue Building for s390x and armv7hl in koji +ExcludeArch: s390x armv7hl + +# To compile the program +BuildRequires: gcc + +# To fix rpath issue with executables. +BuildRequires: chrpath + +# Racket heavily utilizes the system ffi library. +BuildRequires: libffi-devel + +# For the racket/gui library (via libffi) +# https://github.com/racket/gui/blob/master/gui-lib/mred/private/wx/gtk/gtk3.r... +BuildRequires: gtk3 + +# For the racket/draw library (via libffi) +# https://github.com/racket/draw/blob/master/draw-lib/racket/draw/unsafe/cairo... +BuildRequires: cairo +# https://github.com/racket/draw/blob/master/draw-lib/racket/draw/unsafe/pango... +BuildRequires: pango +# https://github.com/racket/draw/blob/master/draw-lib/racket/draw/unsafe/png.r... +BuildRequires: libpng +# https://github.com/racket/draw/blob/master/draw-lib/racket/draw/unsafe/jpeg.... +BuildRequires: libjpeg-turbo +# https://github.com/racket/draw/blob/master/draw-lib/racket/draw/unsafe/glib.... +BuildRequires: glib2 + +# To validate desktop file +BuildRequires: desktop-file-utils + +BuildRequires: git + +# Require the subpackages +Requires: racket-minimal%{?_isa} = %{version}-%{release} +Requires: racket-pkgs = %{version}-%{release} + +%description +Racket is a general-purpose programming language as well as +the world's first ecosystem for developing and deploying new +languages. Make your dream language, or use one of the dozens +already available. + +%prep +%autosetup -v -p1 +# Remove bundled libffi +rm -r src/foreign/libffi + +%build +cd src +%configure \ + --enable-pthread \ + --enable-shared \ + --enable-libffi \ + --disable-strip +%make_build + +%install +cd src +%make_install + +# Delete mred binaries and replace them with links. +rm -vf ${RPM_BUILD_ROOT}%{_bindir}/mred +rm -vf ${RPM_BUILD_ROOT}%{_bindir}/mred-text +ln -vs %{_bindir}/gracket ${RPM_BUILD_ROOT}%{_bindir}/mred +ln -vs %{_bindir}/gracket-text ${RPM_BUILD_ROOT}%{_bindir}/mred-text + +# Delete static library. Apperently --disable-libs does not stop it. +rm -vf ${RPM_BUILD_ROOT}%{_libdir}/libracket3m.a + +# Delete duplicate license files +rm -rf %{buildroot}%{_datadir}/racket/COPYING*txt + +# Fix the rpath error. +chrpath --delete ${RPM_BUILD_ROOT}%{_bindir}/racket +chrpath --delete ${RPM_BUILD_ROOT}%{_libdir}/racket/gracket + +# Remove the libtool files. +rm -f ${RPM_BUILD_ROOT}%{_libdir}/*.la + +# Fix paths in the desktop files. +sed -i "s#${RPM_BUILD_ROOT}##g" \ + ${RPM_BUILD_ROOT}/%{_datadir}/applications/*.desktop + +# Validate desktop files +desktop-file-validate %{buildroot}/%{_datadir}/applications/*.desktop + +# Fix paths in html docs +DOCS_TO_FIX=" +syntax/module-helpers.html +rackunit/api.html +reference/collects.html" +for i in $DOCS_TO_FIX; do + sed -i "s#${RPM_BUILD_ROOT}##g" \ + ${RPM_BUILD_ROOT}/%{_datadir}/doc/racket/$i +done + +chmod -x ${RPM_BUILD_ROOT}%{_libdir}/racket/starter-sh + +%ldconfig_scriptlets + +# Equivalent to upstream's minimal-racket release +%package minimal +Summary: A minimal Racket installation +Requires: racket-collects = %{version}-%{release} +%description minimal +Racket's core runtime + +%package collects +Summary: Racket's core collections libraries +BuildArch: noarch +%description collects +Libraries providing Racket's core functionality + +# Arch independent source and bytecode files +%package pkgs +Summary: Racket package collections +# See BuildRequires section for details on dependencies +Requires: gtk3 +Requires: cairo +Requires: pango +Requires: libpng +Requires: glib2 +Requires: libjpeg-turbo +Requires: racket-minimal = %{version}-%{release} +BuildArch: noarch +%description pkgs +Additional packages and libraries for Racket + +# Development headers and links +%package devel +Summary: Development files for Racket +Requires: racket-minimal%{?_isa} = %{version}-%{release} +%description devel +Files needed to link against Racket. + +# HTML documentation +%package doc +Summary: Documentation files for Racket +BuildArch: noarch +%description doc +A local installation of the Racket documentation system. + +%files +%license src/COPYING.txt src/COPYING_LESSER.txt src/COPYING-libscheme.txt +%{_bindir}/drracket +%{_bindir}/gracket +%{_bindir}/gracket-text +%{_bindir}/mred-text +%{_bindir}/mred +%{_bindir}/mzc +%{_bindir}/mzpp +%{_bindir}/mzscheme +%{_bindir}/mztext +%{_bindir}/pdf-slatex +%{_bindir}/plt-games +%{_bindir}/plt-help +%{_bindir}/plt-r5rs +%{_bindir}/plt-r6rs +%{_bindir}/plt-web-server +%{_bindir}/scribble +%{_bindir}/setup-plt +%{_bindir}/slatex +%{_bindir}/slideshow +%{_bindir}/swindle +%{_datadir}/applications/ + +%files collects +%license src/COPYING.txt src/COPYING_LESSER.txt src/COPYING-libscheme.txt +%{_datadir}/racket/collects + +%files minimal +%license src/COPYING.txt src/COPYING_LESSER.txt src/COPYING-libscheme.txt +%{_bindir}/racket +%{_bindir}/raco +%{_libdir}/racket +%{_libdir}/libracket3m-%{version}.so +%{_datadir}/racket/links.rktd +%{_datadir}/racket/pkgs/racket-lib +%{_datadir}/man/man1/racket* +%{_datadir}/man/man1/raco* +%dir %{_datadir}/racket +%dir %{_sysconfdir}/racket/ +%config %{_sysconfdir}/racket/config.rktd +%exclude %{_libdir}/libracket3m.so + +%files pkgs +%license src/COPYING.txt src/COPYING_LESSER.txt src/COPYING-libscheme.txt +%{_datadir}/racket +%{_datadir}/man/man1/drracket* +%{_datadir}/man/man1/gracket* +%{_datadir}/man/man1/mred* +%{_datadir}/man/man1/mzc* +%{_datadir}/man/man1/mzscheme* +%{_datadir}/man/man1/plt-help* +%{_datadir}/man/man1/setup-plt* +%exclude %{_datadir}/racket/links.rktd +%exclude %dir %{_datadir}/racket/pkgs/racket-lib +%exclude %dir %{_datadir}/racket/collects + +%files devel +%license src/COPYING.txt src/COPYING_LESSER.txt src/COPYING-libscheme.txt +%{_includedir}/racket +%{_libdir}/libracket3m.so + +%files doc +%license src/COPYING.txt src/COPYING_LESSER.txt src/COPYING-libscheme.txt +%{_datadir}/doc/racket + +%changelog +* Mon Jul 30 2018 David Benoit dbenoit@redhat.com 6.12-8 +- Annotate dependencies with links to source code +- Move dependencies to racket-pkgs, since they are only used + by that subpackage +- Update mred symbolic links +- Fix ownership of directories +- Remove executable bit from starter-sh + +* Thu Jul 12 2018 David Benoit dbenoit@redhat.com 6.12-7 +- Remove hardened build since it is enabled by default +- Add gcc to BuildRequires +- Remove wildcards from directory listings in files section + +* Fri Apr 13 2018 David Benoit dbenoit@redhat.com 6.12-6 +- Remove license wildcard and add license field to each subpackage + +* Fri Apr 6 2018 David Benoit dbenoit@redhat.com 6.12-5 +- remove update-database post scripts +- move libracket3m.so link into -devel +- add ldconfig_scriptlets after install +- remove disable debug_package and configure + with --disable-strip instead +- add license to files section and update + license header field +- validate desktop files +- change ownership of /etc/racket +- update changelog with release info +- use specific man directory man/man1/* +- refactor racket into subpackages + racket-minimal, racket-collects, and racket-pkgs + +* Wed Apr 4 2018 David Benoit dbenoit@redhat.com 6.12-4 +- noarch -docs subpackage + +* Tue Mar 20 2018 David Benoit dbenoit@redhat.com 6.12-3 +- fix text encoding issue in description section +- remove doc-open-url scriptlets +- add scriptlet to fix paths in html docs +- add patch2 to backport rpaths fix in compiled .zo files +- add patch3 to backport rpaths fix in web-server-lib +- add patch4 to configure doc open url dynamically at runtime +- remove override of __arch_install_post to allow full + checking of buildroot. + +* Thu Feb 1 2018 David Benoit dbenoit@redhat.com - 6.12-2 +- Fix duplication of object files +- Add version to racket-devel requirements +- Remove base package as a dependency of racket-doc +- Remove Groups tag + +* Wed Jan 31 2018 David Benoit dbenoit@redhat.com - 6.12-1 +- Update to current stable version +- Add patch0 to update SRFIs to latest upstream +- Add patch1 to remove nonfree SRFI components + +* Thu Oct 26 2017 David Benoit dbenoit@redhat.com - 6.10-1 +- Update to current stable version +- Remove libedit readline patch (fixed upstream) +- Break docs into separate package +- Add scriptlets to set doc-open-url based on + whether docs are installed +- Exclude armv7hl and s390x as target arches +- Update description to match website +- Change URLs to use https instead of http + + +* Thu Jul 6 2017 David Benoit dbenoit@redhat.com - 6.9-1 +- Update to current stable version +- Patch libedit readline error +- Remove ExclusiveArch to test all builds in koji + +* Fri Jan 22 2016 Brandon Thomas bthomaszx@gmail.com - 6.3-1 +- Update to current stable version. +- Updated description to match website. +- Removed build requirement "racket-packaging". +- Updated to gtk+3. +- Let Autoprovides determine provides. +- Debuginfo package is empty and preventing the package from building. +- Removed uneeded file copies. +- Remove possible extra static library. + +* Sun Dec 14 2014 Jan Dvorak mordae@anilinux.org - 6.1.1.6-1 +- Update to current snapshot to fix match hash-table expander. + +* Mon Dec 01 2014 Jan Dvorak mordae@anilinux.org - 6.1.1-1 +- Update to current stable version. + +* Fri Sep 05 2014 Jan Dvorak mordae@anilinux.org - 6.1.0.5-4 +- Use racket-packaging to capture module dependencies. + +* Tue Aug 19 2014 Jan Dvorak mordae@anilinux.org - 6.1.0.5-1 +- Updated to 6.1.0.5 +- Merged the -doc package back in. + +* Fri Aug 08 2014 Jan Dvorak mordae@anilinux.org - 6.1.0.4-2 +- Do not alter .zo files, prevent check-buildroot from being run instead. + +* Thu Aug 07 2014 Jan Dvorak mordae@anilinux.org - 6.1.0.4-1 +- Updated to 6.1.0.4 +- Split-off -doc package. + +* Fri Jul 25 2014 Jan Dvorak mordae@anilinux.org - 6.1.0.3-4 +- Updated to 6.1.0.3 +- Dropped the unnecessary static library. +- Dropped mred programs to enable debug package. + +* Sat Jun 22 2013 Daniel E. Wilson danw@bureau-13.org - 5.3.5-1 +- Changed to use 5.3.5 version of Racket. +- Created static package for developers who may need static libraries. +- Added RPM optimization options to CFLAGS for build. +- Added macro to use SMP build options in make. + +* Thu May 16 2013 Daniel E. Wilson danw@bureau-13.org - 5.3.4-1 +- Changed to use 5.3.4 version of Racket. + +* Tue May 14 2013 Daniel E. Wilson danw@bureau-13.org - 5.3.3-3 +- Moved documentation to /usr/doc directory. + +* Mon May 13 2013 Daniel E. Wilson danw@bureau-13.org - 5.3.3-2 +- Remove bundled libffi from racket before building program. + +* Thu May 9 2013 Daniel E. Wilson danw@bureau-13.org - 5.3.3-1 +- Initial Revision.
arch-excludes@lists.fedoraproject.org