diff --git a/docs/api/cyclone/test.md b/docs/api/cyclone/test.md index e29ad8c2..94a63f32 100644 --- a/docs/api/cyclone/test.md +++ b/docs/api/cyclone/test.md @@ -7,82 +7,149 @@ title: API The `(cyclone test)` library contains a testing framework ported from `(chibi test)` which in turn was ported from CHICKEN. -- [`warning`](#warning) -- [`test-group-inc!`](#test-group-inc) -- [`print-exception`](#print-exception) +## Testing - [`test`](#test) - [`test-equal`](#test-equal) - [`test-error`](#test-error) - [`test-assert`](#test-assert) - [`test-not`](#test-not) - [`test-values`](#test-values) +- [`test-propagate-info`](#test-propagate-info) +- [`test-run`](#test-run) + +## Test Groups - [`test-group`](#test-group) -- [`current-test-group`](#current-test-group) - [`test-begin`](#test-begin) - [`test-end`](#test-end) -- [`test-syntax-error`](#test-syntax-error) -- [`test-propagate-info`](#test-propagate-info) -- [`test-vars`](#test-vars) -- [`test-run`](#test-run) - [`test-exit`](#test-exit) + +## Parameters +- [`current-test-group`](#current-test-group) - [`current-test-verbosity`](#current-test-verbosity) - [`current-test-applier`](#current-test-applier) -- [`current-test-handler`](#current-test-handler) - [`current-test-skipper`](#current-test-skipper) - [`current-test-group-reporter`](#current-test-group-reporter) -- [`test-failure-count`](#test-failure-count) - [`current-test-epsilon`](#current-test-epsilon) - [`current-test-comparator`](#current-test-comparator) - -# warning - -# test-group-inc! - -# print-exception +- [`test-failure-count`](#test-failure-count) # test +*Syntax* + + (test [name] expect expr) + +Evaluate `expr` and check that it is `equal?` to `expect`. + +`name` is used in reporting, and defaults to a printed summary of `expr`. + # test-equal +*Syntax* + + (test-equal equal [name] expect expr) + +Equivalent to test, using `equal` for comparison instead of `equal?`. + # test-error +*Syntax* + + (test-error [name] expr) + +Like `test` but evaluates `expr` and checks that it raises an error. + # test-assert +*Syntax* + + (test-assert [name] expr) + +Like `test` but evaluates `expr` and checks that it's true. + # test-not +*Syntax* + + (test-not [name] expr) + +Like `test` but evaluates `expr` and checks that it's false. + # test-values -# test-group +*Syntax* -# current-test-group + (test-values [name] expect expr) + +Like `test` but `expect` and `expr` can both return multiple values. # test-begin + (test-begin) + (test-begin name) + +Begin testing a new group until the closing `(test-end)`. + # test-end -# test-syntax-error + (test-end) + (test-end name) + +Ends testing group introduced with `(test-begin)`, and summarizes the results. # test-propagate-info -# test-vars + (test-propagate-info name expect expr info) + +Low-level macro to pass alist info to the underlying `test-run`. # test-run + (test-run expect expr info) + +The procedural interface to testing. `expect` and `expr` should be thunks, and `info` is an alist of properties used in test reporting. + # test-exit + (test-exit) + +Exits with a failure status if any tests have failed, and a successful status otherwise. + +# test-group + + (test-group body ...) + +Wraps `body` as a single test group, which can be filtered and summarized separately. + +# current-test-group + +The current test group as started by `test-group` or `test-begin`. + # current-test-verbosity +If true, show more verbose output per test. Inferred from the environment variable `TEST_VERBOSE`. + # current-test-applier -# current-test-handler +The test applier - what we do with non-skipped tests. Takes the same signature as `test-run`, should be responsible for evaluating the thunks, determining the status of the test, and passing this information to `current-test-reporter`. # current-test-skipper +The test skipper - what we do with non-skipped tests. This should not evaluate the thunks and simply pass off to `current-test-reporter`. + # current-test-group-reporter +Takes one argument, a test group, and prints a summary of the test results for that group. + # test-failure-count +A running count of all test failures and errors across all groups (and threads). Used by `test-exit`. + # current-test-epsilon +The epsilon used for floating point comparisons. + # current-test-comparator +The underlying comparator used in testing, defaults to `test-equal?`. + diff --git a/docs/api/scheme/cyclone/ast.md b/docs/api/scheme/cyclone/ast.md index 1b0dfde9..7a96d0c1 100644 --- a/docs/api/scheme/cyclone/ast.md +++ b/docs/api/scheme/cyclone/ast.md @@ -7,8 +7,9 @@ title: API The `(scheme cyclone ast)` library defines abstract syntax tree types used during compilation. +*This library is used internally by the compiler and its API may change at any time.* + - [`ast:make-lambda`](#astmake-lambda) -- [`ast:%make-lambda`](#astmake-lambda-1) - [`ast:lambda?`](#astlambda) - [`ast:lambda-id`](#astlambda-id) - [`ast:lambda-args`](#astlambda-args) @@ -21,42 +22,72 @@ The `(scheme cyclone ast)` library defines abstract syntax tree types used durin # ast:make-lambda (ast:make-lambda args body) + (ast:make-lambda args body cont) -# ast:%make-lambda - (ast:%make-lambda lambda-id args body) +Create an instance of the `ast-lambda` record type. + +This data type is at the center of this module and consists of the following data: + +* `id` - Unique numeric ID assigned to each lambda +* `args` - Arguments to the lambda. This may be one of: + * symbol indicating a function takes any number of arguments + * list of symbols corresponding to each of a fixed number of arguments to the function + * improper list indicating a function taking a fixed number of required arguments as well as an arbitrary number of optional arguments +* `body` - Expression in the function body of the lambda +* `cont` - Boolean indicating whether the lambda has a continuation + +`ast:make-lambda` automatically assigns the `id` field to a unique value. # ast:lambda? (ast:lambda? obj) +Predicate indicating whether `obj` is an `ast-lambda` object. + # ast:lambda-id (ast:lambda-id lambda-obj) +Return the `id` field of the given `ast-lambda` object. + # ast:lambda-args (ast:lambda-args lambda-obj) +Return the `args` field of the given `ast-lambda` object. + # ast:set-lambda-args! (ast:set-lambda-args! lambda-obj args) +Change the `args` field of the given `ast-lambda` object. + # ast:lambda-body (ast:lambda-body lambda-obj) +Return the `body` field of the given `ast-lambda` object. + # ast:set-lambda-body! (ast:set-lambda-body! lambda-obj body) +Change the `body` field of the given `ast-lambda` object. + # ast:ast->sexp (ast:ast->sexp exp) +Convert an abstract syntax tree `exp` back into an equivalent expression consisting of standard Scheme S-expressions. IE: `lambda` forms instead of `ast-lambda` objects. + # ast:sexp->ast (ast:sexp->ast exp) +Convert a standard Scheme S-expression tree containing `lambda` forms into an equivalent abstract syntax tree consisting of equivalent `ast-lambda` objects. + # ast:ast->pp-sexp (ast:ast->pp-sexp exp) +Transform an abstract syntax tree into one that prints more cleanly. + diff --git a/docs/api/scheme/cyclone/cgen.md b/docs/api/scheme/cyclone/cgen.md index f942761a..ac78b3cc 100644 --- a/docs/api/scheme/cyclone/cgen.md +++ b/docs/api/scheme/cyclone/cgen.md @@ -7,6 +7,8 @@ title: API The `(scheme cyclone cgen)` library compiles scheme code to a Cheney-on-the-MTA C runtime. +*This library is used internally by the compiler and its API may change at any time.* + - [`mta:code-gen`](#mtacode-gen) - [`emit`](#emit) - [`emit*`](#emit-1) @@ -50,4 +52,3 @@ Call `emits` for each of the given strings. `display` a newline to the current output port. - diff --git a/docs/api/scheme/cyclone/common.md b/docs/api/scheme/cyclone/common.md index dff68998..7df0f659 100644 --- a/docs/api/scheme/cyclone/common.md +++ b/docs/api/scheme/cyclone/common.md @@ -7,6 +7,8 @@ title: API The `(scheme cyclone common)` library contains definitions used by the compiler and interpreter. +*This library is used internally by the compiler and its API may change at any time.* + - [`*Cyc-version-banner*`](#cyc-version-banner) - [`*version*`](#version) - [`*version-number*`](#version-number) diff --git a/docs/api/scheme/cyclone/cps-optimizations.md b/docs/api/scheme/cyclone/cps-optimizations.md index 6cc858fc..cf9a356e 100644 --- a/docs/api/scheme/cyclone/cps-optimizations.md +++ b/docs/api/scheme/cyclone/cps-optimizations.md @@ -7,6 +7,8 @@ title: API The `(scheme cyclone optimizations)` library performs CPS analysis and optimizations. +*This library is used internally by the compiler and its API may change at any time.* + - [`optimize-cps`](#optimize-cps) - [`analyze-cps`](#analyze-cps) - [`opt:contract`](#optcontract) diff --git a/docs/api/scheme/cyclone/libraries.md b/docs/api/scheme/cyclone/libraries.md index 8c459e3d..744e006d 100644 --- a/docs/api/scheme/cyclone/libraries.md +++ b/docs/api/scheme/cyclone/libraries.md @@ -7,6 +7,8 @@ title: API The `(scheme cyclone libraries)` library implements r7rs libraries. +*This library is used internally by the compiler and its API may change at any time.* + - [`library?`](#library) - [`lib:list->import-set`](#liblist-import-set) - [`lib:name`](#libname) diff --git a/docs/api/scheme/cyclone/macros.md b/docs/api/scheme/cyclone/macros.md index 33cc6d1d..0c9751c1 100644 --- a/docs/api/scheme/cyclone/macros.md +++ b/docs/api/scheme/cyclone/macros.md @@ -3,6 +3,11 @@ layout: main title: API --- +--- +layout: main +title: API +--- + # Macro Library The `(scheme cyclone macro)` library contains code to deal with macros. diff --git a/docs/api/scheme/cyclone/match.md b/docs/api/scheme/cyclone/match.md index 785e1568..0b857204 100644 --- a/docs/api/scheme/cyclone/match.md +++ b/docs/api/scheme/cyclone/match.md @@ -23,6 +23,11 @@ layout: main title: API --- +--- +layout: main +title: API +--- + # Match Library The `(scheme cyclone match)` library provides a hygienic pattern matcher, based on Alex Shinn's portable `match.scm`. diff --git a/docs/api/scheme/cyclone/primitives.md b/docs/api/scheme/cyclone/primitives.md index 5f22b3e5..972e4aaa 100644 --- a/docs/api/scheme/cyclone/primitives.md +++ b/docs/api/scheme/cyclone/primitives.md @@ -7,9 +7,9 @@ title: API The `(scheme cyclone primitives)` library contains information about Cyclone's scheme primitives. +*This library is used internally by the compiler and its API may change at any time.* + - [`prim?`](#prim) -- [`*primitives*`](#primitives) -- [`*primitives-num-args*`](#primitives-num-args) - [`prim-call?`](#prim-call) - [`prim->c-func`](#prim-c-func) - [`prim/data-arg?`](#prata-arg) @@ -24,29 +24,75 @@ The `(scheme cyclone primitives)` library contains information about Cyclone's s # prim? -# \*primitives\* + (prim? obj) -# \*primitives-num-args\* +Determine if the given object is a symbol referring to a primitive. # prim-call? + (prim-call? exp) + +Determine if the given expression `exp` is a call to a primitive. + # prim->c-func + (prim->c-func sym use-alloca? emit-unsafe) + +Returns text containing the C function that is used to implement primitive `sym`. + +If `emit-unsafe` is true then an unsafe version of the primtive, if available, will be returned. + # prim/data-arg? + (prim/data-arg? sym) + +Primitive indicating if the primitive requires passing thread data as its first argument. + # prim/c-var-assign + (prim/c-var-assign sym) + +Return the C data type of variable used to assign the result of primitive `sym`, if applicable. `#f` is returned otherwise. + # prim/cvar? + (prim/cvar? sym) + +Determine if primitive `sym` creates a C variable. + # prim:check-arg-count + (prim:check-arg-count sym num-args expected) + +Return `#f` the primitive `sym` cannot accept the given number of arguments `num-args` given the expected number of arguments `expected`, and `#t` otherwise. + # prim:mutates? + (prim:mutates? sym) + +Does primitive `sym` mutate any of its arguments? + # prim:cont? + (prim:cont? sym) + +Should the compiler pass a continuation as the function's first parameter? + # prim:cont/no-args? + (prim:cont/no-args? sym) + +Is `sym` a primitive function that passes a continuation or thread data but has no other arguments? + # prim:arg-count? + (prim:arg-count? sym) + +Should the compiler pass an integer arg count as the function's first parameter? + # prim:allocates-object?) + (prim:allocates-object? sym use-alloca?) + +Does primitive `sym` allocate an object? + diff --git a/docs/api/scheme/cyclone/test.md b/docs/api/scheme/cyclone/test.md index 4540fa9b..aede14ed 100644 --- a/docs/api/scheme/cyclone/test.md +++ b/docs/api/scheme/cyclone/test.md @@ -23,6 +23,11 @@ layout: main title: API --- +--- +layout: main +title: API +--- + # Test Library The `(scheme cyclone test)` library contains a testing framework ported from `(chibi test)` which in turn was ported from CHICKEN. diff --git a/docs/api/scheme/cyclone/transforms.md b/docs/api/scheme/cyclone/transforms.md index 031152c8..a5a32607 100644 --- a/docs/api/scheme/cyclone/transforms.md +++ b/docs/api/scheme/cyclone/transforms.md @@ -7,6 +7,8 @@ title: API The `(scheme cyclone transforms)` library performs Scheme-to-Scheme transformations, and also contains various utility functions used by the compiler. +*This library is used internally by the compiler and its API may change at any time.* + - [`*defined-macros* `](#*defined-macros) - [`*do-code-gen* `](#*do-code-gen) - [`*primitives* `](#*primitives) diff --git a/docs/api/scheme/cyclone/util.md b/docs/api/scheme/cyclone/util.md index d4d31922..e396bc0c 100644 --- a/docs/api/scheme/cyclone/util.md +++ b/docs/api/scheme/cyclone/util.md @@ -7,6 +7,8 @@ title: API The `(scheme cyclone util`) library contains various utility functions used internally the compiler. +*This library is used internally by the compiler and its API may change at any time.* + - [`Cyc-er-compare? `](#cyc-er-compare) - [`Cyc-er-rename `](#cyc-er-rename) - [`app? `](#app) diff --git a/docs/api/srfi/106.md b/docs/api/srfi/106.md index 46423217..c92f6717 100644 --- a/docs/api/srfi/106.md +++ b/docs/api/srfi/106.md @@ -61,77 +61,348 @@ See the [SRFI document](http://srfi.schemers.org/srfi-106/srfi-106.html) for mor # make-client-socket + (make-client-socket node service [ai-family [ai-socktype [ai-flags [ai-protocol]]]]) -> socket + +Returns a client socket connected to an Internet address. +The Internet address is identified by node and service. node and service must be string. +Example value of node: `"localhost" "127.0.0.1"` +Example value of service: `"http" "80"` +The optional parameter may specify the created socket's behaviour. +If the optional argument(s) is omitted, then following flags should be used as default: + + ai-family + *af-inet* + ai-socktype + *sock-stream* + ai-flags + (socket-merge-flags *ai-v4mapped* *ai-addrconfig*) + ai-protocol + *ipproto-ip* + +The created socket may not be closed automatically so it is users' responsibility to close it explicitly. + # make-server-socket + (make-server-socket service [ai-family [ai-socktype [ai-protocol]]]) -> socket + +Returns a server socket waiting for connection. +The description of node argument is the same as make-client-socket. +The optional parameter may specify the created socket's behaviour. + +If the optional argument(s) is omitted, then following flags should be used as default. + + ai-family + *af-inet* + ai-socktype + *sock-stream* + ai-protocol + *ipproto-ip* + +The created socket may not be closed automatically so it is users' responsibility to close it explicitly. + # socket? + (socket? object) -> boolean + +Returns `#t` if given `object` is socket object. Otherwise `#f`. + # socket-accept + (socket-accept socket) -> socket + +Wait for an incoming connection request, and returns a fresh connected client socket. + # socket-send + (socket-send socket bv [flags]) -> size + +Sends a binary data block to a socket and returns the sent data size. +`flags` may specify the procedure's behaviour. + +If the `flags` is omitted, the default value must be the result of following form: + + (message-type none) + # socket-recv + (socket-recv socket size [flags]) -> bv + +Receives a binary data block from a socket. If zero length bytevector is returned, it means the peer connection is closed. +`flags` may specify the procedure's behaviour. + +If the `flags` is omitted, the default value must be the result of following form: + + (message-type none) + # socket-shutdown + (socket-shutdown socket how) -> (unspecified) + +Shutdowns a socket. +`how` must be one of the following constants: + + *shut-rd* + *shut-wr* + *shut-rdwr* + # socket-close + (socket-close socket) -> (unspecified) + +Closes a socket. +The procedure does not shutdown the given socket. To shutdown a socket, socket-shutdown should be called explicitly. + # socket-input-port + (socket-input-port socket) -> binary-input-port + +Returns a fresh binary input port associated with a socket, respectively. +The port should not close underlying socket when it's closing. + # socket-output-port + (socket-output-port socket) -> binary-output-port + +Returns a fresh binary output port associated with a socket, respectively. +The port should not close underlying socket when it's closing. + # call-with-socket + (call-with-socket socket proc) -> object + +Calls a given procedure with a given socket as an argument. + +If given `proc` returns then it returns the result of `proc` and socket will be automatically closed. If `proc` doesn't return then given socket won't be closed automatically. It's analogy of `call-with-port`. + # address-family +*Syntax* + + (address-family name) -> address-family + +Returns proper address family from given name. + + inet + +Returns `*af-inet*` + + inet6 + +Returns `*af-inet6*` + + unspec + +Returns `*af-unspec*` + # address-info +*Syntax* + + (address-info names ...) -> address-info + +Returns merged address info flags from given names. + + canoname + +Returns `*ai-canonname*` + + numerichost + +Returns `*ai-numerichost*` + + v4mapped + +Returns `*ai-v4mapped*` + + all + +Returns `*ai-all*` + + addrconfig + +Returns `*ai-addrconfig*` + # socket-domain +*Syntax* + + (socket-domain name) -> socket-domain + +Returns socket domain flags from given name. + + stream + +Returns `*sock-stream*` + + datagram + +Returns `*sock-dgram*` + # ip-protocol +*Syntax* + + (ip-protocol name) -> ip-protocol + +Returns ip-protocol flag from given name. + + ip + +Returns `*ipproto-ip*` + + tcp + +Returns `*ipproto-tcp*` + + udp + +Returns `*ipproto-udp*` + # message-type +*Syntax* + + (message-type names ...) -> message-type + +Returns message type flag from given name. + +The flag can be used both socket-recv and socket-send. + + none + +Returns no flag. + + peek + +Returns `*msg-peek*` + + oob + +Returns `*msg-oob*` + + wait-all + +Returns `*msg-waitall*` + # shutdown-method +*Syntax* + + (shutdown-method names ...) -> shutdown-method + +Returns shutdown method flags from given names. + + read + +Returns `*shut-rd*` + + write + +Returns `*shut-wr*` + +If shutdown-method is given both read and write, then it must return `*shut-rdwr*` + # socket-merge-flags + (socket-merge-flags flags ...) -> new-flags + +Merges given `flags` and returns a new flag. + # socket-purge-flags + (socket-purge-flags base-flag flags ...) -> new-flags + +Removes `flags` from `base-flag` if exists and returns a new flag. + # \*af-unspec\* +This must behave the same as POSIX's `AF_UNSPEC`. + # \*af-inet\* +Internet domain sockets for use with IPv4 addresses. +This must behave the same as POSIX's `AF_INET`. + # \*af-inet6\* +Internet domain sockets for use with IPv6 addresses. +This must behave the same as POSIX's `AF_INET6`. + # \*sock-stream\* +Byte-stream socket. +This must behave the same as POSIX's `SOCK_STREAM`. + # \*sock-dgram\* +Datagram socket. +This must behave the same as POSIX's `SOCK_DGRAM`. + # \*ai-canonname\* +This must behave the same as POSIX's `AI_CANONNAME`. + # \*ai-numerichost\* +This must behave the same as POSIX's `AI_NUMERICHOST`. + # \*ai-v4mapped\* +This must behave the same as POSIX's `AI_V4MAPPED`. + # \*ai-all\* +This must behave the same as POSIX's `AI_ALL`. + # \*ai-addrconfig\* +This must behave the same as POSIX's `AI_ADDRCONFIG`. + # \*ipproto-ip\* +Internet protocol. +This must behave the same as POSIX's `IPPROTO_IP`. + # \*ipproto-tcp\* +Transmission control protocol. +This must behave the same as POSIX's `IPPROTO_TCP`. + # \*ipproto-udp\* +User datagram protocol. +This must behave the same as POSIX's `IPPROTO_UDP`. + # \*msg-peek\* +For socket-recv. +Peeks at an incoming message. The data is treated as unread and the next socket-recv shall still return this data. +This must behave the same as `POSIX's MSG_PEEK`. + # \*msg-oob\* +For both `socket-recv` and `socket-send`. +Requests/sends out-of-band data. +This must behave the same as POSIX's `MSG_OOB`. + # \*msg-waitall\* +For socket-recv. +On sockets created with `*sock-stream*` flag, this requests the procedure block until the full amount of data ban be returned. +This must behave the same as POSIX's `MSG_WAITALL`. + # \*shut-rd\* +Disables further receive operation. +This must behave the same as POSIX's `SHUT_RD`. + # \*shut-wr\* +Disables further send operations. +This must behave the same as POSIX's `SHUT_WR`. + # \*shut-rdwr\* +Disables further send and receive operations. +This must behave the same as POSIX's `SHUT_RDWR`. + diff --git a/docs/api/srfi/117.md b/docs/api/srfi/117.md index ebd4a783..c59c5acd 100644 --- a/docs/api/srfi/117.md +++ b/docs/api/srfi/117.md @@ -36,9 +36,6 @@ See the [SRFI document](http://srfi.schemers.org/srfi-117/srfi-117.html) for mor [`list-queue-append`](#list-queue-append) [`list-queue-append!`](#list-queue-append-1) [`list-queue-concatenate`](#list-queue-concatenate) -[`list-queue-append`](#list-queue-append) -[`list-queue-append!`](#list-queue-append-1) -[`list-queue-concatenate`](#list-queue-concatenate) ## Mapping [`list-queue-map`](#list-queue-map) @@ -47,53 +44,153 @@ See the [SRFI document](http://srfi.schemers.org/srfi-117/srfi-117.html) for mor # make-list-queue + (make-list-queue list [ last ]) + +Returns a newly allocated list queue containing the elements of `list` in order. The result shares storage with `list`. If the last argument is not provided, this operation is `O(n)` where n is the length of `list`. + +However, if last is provided, `make-list-queue` returns a newly allocated list queue containing the elements of the list whose first pair is `first` and whose last pair is `last`. It is an error if the pairs do not belong to the same list. Alternatively, both `first` and `last` can be the empty list. In either case, the operation is `O(1)`. + +Note: To apply a non-destructive list procedure to a list queue and return a new list queue, use `(make-list-queue (proc (list-queue-list list-queue)))`. + # list-queue + (list-queue element ...) + +Returns a newly allocated list queue containing the elements. This operation is `O(n)` where `n` is the number of elements. + # list-queue-copy + (list-queue-copy list-queue) + +Returns a newly allocated list queue containing the elements of list-queue. This operation is `O(n)` where `n` is the length of list-queue. + # list-queue-unfold + (list-queue-unfold stop? mapper successor seed [ queue ]) + +Performs the following algorithm: + +If the result of applying the predicate `stop?` to seed is true, return `queue`. Otherwise, apply the procedure `mapper` to `seed`, returning a value which is added to the front of `queue`. Then get a new seed by applying the procedure `successor` to `seed`, and repeat this algorithm. + +If `queue` is omitted, a newly allocated list queue is used. + # list-queue-unfold-right + (list-queue-unfold-right stop? mapper successor seed [ queue ]) + +Performs the following algorithm: + +If the result of applying the predicate `stop?` to `seed` is true, return the list queue. Otherwise, apply the procedure `mapper` to `seed`, returning a value which is added to the back of the list queue. Then get a new seed by applying the procedure successor to `seed`, and repeat this algorithm. + +If queue is omitted, a newly allocated list queue is used. + # list-queue? + (list-queue? obj) + +Returns `#t` if `obj` is a list queue, and `#f` otherwise. This operation is `O(1)`. + # list-queue-empty? + (list-queue-empty? list-queue) + +Returns `#t` if `list-queue` has no elements, and `#f` otherwise. This operation is `O(1)`. + # list-queue-front + (list-queue-front list-queue) + +Returns the first element of `list-queue`. If the list queue is empty, it is an error. This operation is `O(1)`. + # list-queue-back + (list-queue-back list-queue) + +Returns the last element of `list-queue`. If the list queue is empty, it is an error. This operation is `O(1)`. + # list-queue-list + (list-queue-list list-queue) + +Returns the list that contains the members of `list-queue` in order. The result shares storage with `list-queue`. This operation is `O(1)`. + # list-queue-first-last + (list-queue-first-last list-queue) + +Returns two values, the first and last pairs of the list that contains the members of `list-queue` in order. If `list-queue` is empty, returns two empty lists. The results share storage with `list-queue`. This operation is `O(1)`. + # list-queue-add-front! + (list-queue-add-front! list-queue element) + +Adds element to the beginning of `list-queue`. Returns an unspecified value. This operation is `O(1)`. + # list-queue-add-back! + (list-queue-add-back! list-queue element) + +Adds `element` to the end of `list-queue`. Returns an unspecified value. This operation is `O(1)`. + # list-queue-remove-front! + (list-queue-remove-front! list-queue) + +Removes the first element of `list-queue` and returns it. If the list queue is empty, it is an error. This operation is `O(1)`. + # list-queue-remove-back! + (list-queue-remove-back! list-queue) + +Removes the last element of `list-queue` and returns it. If the list queue is empty, it is an error. This operation is `O(n)` where `n` is the length of `list-queue`, because queues do not not have backward links. + # list-queue-remove-all! + (list-queue-remove-all! list-queue) + +Removes all the elements of `list-queue` and returns them in order as a list. This operation is `O(1)`. + # list-queue-set-list! -# list-queue-append + (list-queue-set-list! list-queue list [ last ]) -# list-queue-append! +Replaces the list associated with `list-queue` with `list`, effectively discarding all the elements of `list-queue` in favor of those in `list`. Returns an unspecified value. This operation is `O(n)` where `n` is the length of `list`. If `last` is provided, it is treated in the same way as in `make-list-queue`, and the operation is O(1). -# list-queue-concatenate +Note: To apply a destructive list procedure to a list queue, use `(list-queue-set-list! (proc (list-queue-list list-queue)))`. # list-queue-append + (list-queue-append list-queue ...) + +Returns a list queue which contains all the elements in front-to-back order from all the list-queues in front-to-back order. The result does not share storage with any of the arguments. This operation is `O(n)` in the total number of elements in all queues. + # list-queue-append! + (list-queue-append! list-queue ...) + +Returns a list queue which contains all the elements in front-to-back order from all the list-queues in front-to-back order. It is an error to assume anything about the contents of the list-queues after the procedure returns. This operation is `O(n)` in the total number of queues, not elements. It is not part of the R7RS-small list API, but is included here for efficiency when pure functional append is not required. + # list-queue-concatenate + (list-queue-concatenate list-of-list-queues) + +Returns a list queue which contains all the elements in front-to-back order from all the list queues which are members of list-of-list-queues in front-to-back order. The result does not share storage with any of the arguments. This operation is `O(n)` in the total number of elements in all queues. It is not part of the R7RS-small list API, but is included here to make appending a large number of queues possible in Schemes that limit the number of arguments to apply. + # list-queue-map + (list-queue-map proc list-queue) + +Applies `proc` to each element of `list-queue` in unspecified order and returns a newly allocated list queue containing the results. This operation is `O(n)` where `n` is the length of `list-queue`. + # list-queue-map! + (list-queue-map! proc list-queue) + +Applies proc to each element of `list-queue` in front-to-back order and modifies `list-queue` to contain the results. This operation is `O(n)` in the length of `list-queue`. It is not part of the R7RS-small list API, but is included here to make transformation of a list queue by mutation more efficient. + # list-queue-for-each + (list-queue-for-each proc list-queue) + +Applies `proc` to each element of `list-queue` in front-to-back order, discarding the returned values. Returns an unspecified value. This operation is `O(n)` where `n` is the length of `list-queue`. + diff --git a/docs/api/srfi/128.md b/docs/api/srfi/128.md index 18941362..b1a70c0b 100644 --- a/docs/api/srfi/128.md +++ b/docs/api/srfi/128.md @@ -9,9 +9,16 @@ The `(srfi 128)` provides comparators, which bundle a type test predicate, an eq See the [SRFI document](http://srfi.schemers.org/srfi-128/srfi-128.html) for more information. +## Predicates + - [`comparator? `](#comparator) - [`comparator-ordered? `](#comparator-ordered) - [`comparator-hashable? `](#comparator-hashable) + +## Constructors + +The following comparator constructors all supply appropriate type test predicates, equality predicates, ordering predicates, and hash functions based on the supplied arguments. They are allowed to cache their results: they need not return a newly allocated object, since comparators are pure and functional. In addition, the procedures in a comparator are likewise pure and functional. + - [`make-comparator `](#make-comparator) - [`make-pair-comparator `](#make-pair-comparator) - [`make-list-comparator `](#make-list-comparator) @@ -19,6 +26,11 @@ See the [SRFI document](http://srfi.schemers.org/srfi-128/srfi-128.html) for mor - [`make-eq-comparator `](#make-eq-comparator) - [`make-eqv-comparator `](#make-eqv-comparator) - [`make-equal-comparator `](#make-equal-comparator) + +## Standard Hash Functions + +These are hash functions for some standard Scheme types, suitable for passing to make-comparator. Users may write their own hash functions with the same signature. However, if programmers wish their hash functions to be backward compatible with the reference implementation of SRFI 69, they are advised to write their hash functions to accept a second argument and ignore it. + - [`boolean-hash `](#boolean-hash) - [`char-hash `](#char-hash) - [`char-ci-hash `](#char-ci-hash) @@ -26,9 +38,15 @@ See the [SRFI document](http://srfi.schemers.org/srfi-128/srfi-128.html) for mor - [`string-ci-hash `](#string-ci-hash) - [`symbol-hash `](#symbol-hash) - [`number-hash `](#number-hash) + +## Default Comparators + - [`make-default-comparator `](#make-default-comparator) - [`default-hash `](#default-hash) - [`comparator-register-default! `](#comparator-register-default) + +## Accessors and Invokers + - [`comparator-type-test-predicate`](#comparator-type-test-predicate) - [`comparator-equality-predicate `](#comparator-equality-predicate) - [`comparator-ordering-predicate `](#comparator-ordering-predicate) @@ -36,82 +54,308 @@ See the [SRFI document](http://srfi.schemers.org/srfi-128/srfi-128.html) for mor - [`comparator-test-type `](#comparator-test-type) - [`comparator-check-type `](#comparator-check-type) - [`comparator-hash `](#comparator-hash) + +## Bounds and Salt + +The following macros allow the callers of hash functions to affect their behavior without interfering with the calling signature of a hash function, which accepts a single argument (the object to be hashed) and returns its hash value. They are provided as macros so that they may be implemented in different ways: as a global variable, a SRFI 39 or R7RS parameter, or an ordinary procedure, whatever is most efficient in a particular implementation. + - [`hash-bound `](#hash-bound) - [`hash-salt `](#hash-salt) + +## Comparison Predicates + +These procedures are analogous to the number, character, and string comparison predicates of Scheme. They allow the convenient use of comparators to handle variable data types. + +These procedures apply the equality and ordering predicates of comparator to the objects as follows. If the specified relation returns `#t` for all `objecti` and `objectj` where `n` is the number of objects and `1 <= i < j <= n`, then the procedures return `#t`, but otherwise `#f`. Because the relations are transitive, it suffices to compare each object with its successor. The order in which the values are compared is unspecified. + - [`=? `](#section) - [`? `](#section-2) - [`<=? `](#section-3) - [`>=? `](#section-4) + +## Syntax + - [`comparator-if<=> `](#comparator-if) # comparator? + (comparator? obj) + +Returns `#t` if `obj` is a comparator, and `#f` otherwise. + # comparator-ordered? + (comparator-ordered? comparator) + +Returns `#t` if `comparator` has a supplied ordering predicate, and `#f` otherwise. + # comparator-hashable? + (comparator-hashable? comparator) + +Returns `#t` if `comparator` has a supplied hash function, and `#f` otherwise. + # make-comparator + (make-comparator type-test equality ordering hash) + +Returns a comparator which bundles the `type-test`, `equality`, `ordering`, and `hash` procedures provided. However, if `ordering` or `hash` is `#f`, a procedure is provided that signals an error on application. The predicates `comparator-ordered?` and/or `comparator-hashable?`, respectively, will return `#f` in these cases. + +Here are calls on `make-comparator` that will return useful comparators for standard Scheme types: + +* `(make-comparator boolean? boolean=? (lambda (x y) (and (not x) y)) boolean-hash)` will return a comparator for booleans, expressing the ordering `#f < #t` and the standard hash function for booleans. + +* `(make-comparator real? = < (lambda (x) (exact (abs x))))` will return a comparator expressing the natural ordering of real numbers and a plausible (but not optimal) hash function. + +* `(make-comparator string? string=? stringstring` to the symbols and comparing them using the total order implied by `string,` so are the numbers; otherwise, the numbers are ordered by their imaginary parts. This can still produce somewhat surprising results if one real part is exact and the other is inexact. + +* When comparing real numbers, it must use `=` and `<.` + +* When comparing strings, it must use `string=?` and `string? + (>? comparator object1 object2 object3 ...) + # <=? + (<=? comparator object1 object2 object3 ...) + # >=? + (>=? comparator object1 object2 object3 ...) + # comparator-if<=> +*Syntax* + + (comparator-if<=> [ ] ) + +It is an error unless `` evaluates to a comparator and `` and `` evaluate to objects that the comparator can handle. If the ordering predicate returns true when applied to the values of `` and `` in that order, then `` is evaluated and its value returned. If the equality predicate returns true when applied in the same way, then `` is evaluated and its value returned. If neither returns true, `` is evaluated and its value returned. + +If `` is omitted, a default comparator is used. + diff --git a/docs/api/srfi/132.md b/docs/api/srfi/132.md index d043c52a..9af0360a 100644 --- a/docs/api/srfi/132.md +++ b/docs/api/srfi/132.md @@ -9,58 +9,168 @@ The `(srfi 132)` library implements the the API for a full-featured sort toolkit See the [SRFI document](http://srfi.schemers.org/srfi-132/srfi-132.html) for more information. -- [`list-sorted?`](#list-sorted) -- [`vector-sorted?`](#vector-sorted) -- [`list-merge`](#list-merge) -- [`vector-merge`](#vector-merge) -- [`list-sort`](#list-sort) -- [`vector-sort`](#vector-sort) -- [`list-stable-sort`](#list-stable-sort) -- [`vector-stable-sort`](#vector-stable-sort) -- [`list-merge!`](#list-merge-1) -- [`vector-merge!`](#vector-merge-1) -- [`list-sort!`](#list-sort-1) -- [`vector-sort!`](#vector-sort-1) -- [`list-stable-sort!`](#list-stable-sort) -- [`vector-stable-sort!`](#vector-stable-sort) -- [`list-delete-neighbor-dups`](#list-delete-neighbor-dups) -- [`vector-delete-neighbor-dups`](#vector-delete-neighbor-dups) - [`list-delete-neighbor-dups!`](#list-delete-neighbor-dups-1) +- [`list-delete-neighbor-dups`](#list-delete-neighbor-dups) +- [`list-merge!`](#list-merge-1) +- [`list-merge`](#list-merge) +- [`list-sort!`](#list-sort-1) +- [`list-sort`](#list-sort) +- [`list-sorted?`](#list-sorted) +- [`list-stable-sort!`](#list-stable-sort) +- [`list-stable-sort`](#list-stable-sort) - [`vector-delete-neighbor-dups!`](#vector-delete-neighbor-dups-1) - -# list-sorted? - -# vector-sorted? - -# list-merge - -# vector-merge - -# list-sort - -# vector-sort - -# list-stable-sort - -# vector-stable-sort - -# list-merge! - -# vector-merge! - -# list-sort! - -# vector-sort! - -# list-stable-sort! - -# vector-stable-sort! +- [`vector-delete-neighbor-dups`](#vector-delete-neighbor-dups) +- [`vector-find-median`](#vector-find-median) +- [`vector-find-median!`](#vector-find-median-1) +- [`vector-merge!`](#vector-merge-1) +- [`vector-merge`](#vector-merge) +- [`vector-select!`](#vector-select) +- [`vector-separate!`](#vector-separate) +- [`vector-sort!`](#vector-sort-1) +- [`vector-sort`](#vector-sort) +- [`vector-sorted?`](#vector-sorted) +- [`vector-stable-sort!`](#vector-stable-sort) +- [`vector-stable-sort`](#vector-stable-sort) # list-delete-neighbor-dups -# vector-delete-neighbor-dups + (list-delete-neighbor-dups = lis) + +This procedure does not alter its input list, but its result may share storage with the input list. # list-delete-neighbor-dups! + (list-delete-neighbor-dups! = lis) + +This procedure mutates its input list in order to construct its result. It makes only a single, iterative, linear-time pass over its argument, using set-cdr!s to rearrange the cells of the list into the final result — it works "in place." Hence, any cons cell appearing in the result must have originally appeared in the input. + +# list-merge + + (list-merge < lis1 lis2) + +This procedure does not alter its inputs, and is allowed to return a value that shares a common tail with a list argument. + +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. + +# list-merge! + + (list-merge! < lis1 lis2) + +This procedure makes only a single, iterative, linear-time pass over its argument lists, using `set-cdr!`s to rearrange the cells of the lists into the list that is returned — it works "in place." Hence, any cons cell appearing in the result must have originally appeared in an input. It returns the sorted input. + +Additionally, `list-merge!` is iterative, not recursive — it can operate on arguments of arbitrary size without requiring an unbounded amount of stack space. 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. + +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. + +# list-sort + + (list-sort < lis) + +This procedure provides basic sorting. + +# list-sort! + + (list-sort! < lis) + +This procedure is a linear update operator and is allowed to alter the cons cells of the arguments to produce its results. A sorted list containing the same elements as `lis` is returned. + +# list-sorted? + + (list-sorted? < lis) + +Returns true iff the input list is in sorted order, as determined by `<`. Specifically, return `#f` iff there is an adjacent pair `... X Y ...` in the input list such that `Y < X` in the sense of `<`. + +# list-stable-sort + + (list-stable-sort < lis) + +Provides a stable sort. + +# list-stable-sort! + + (list-stable-sort! < lis) + +This procedure is a linear update operator and is allowed to alter the cons cells of the arguments to produce its results. A sorted list containing the same elements as `lis` is returned. + +# vector-delete-neighbor-dups + + (vector-delete-neighbor-dups = v [ start [ end ] ]) + +This procedure does not alter its input vector, but rather newly allocates and returns a vector to hold the result. + # vector-delete-neighbor-dups! +(vector-delete-neighbor-dups! = v [ start [ end ] ]) + +This procedure reuses its input vector to hold the answer, packing it into the index range [start, newend), where newend is the non-negative exact integer that is returned as its value. The vector is not altered outside the range [start, newend). + +# vector-find-median + + (vector-find-median < v knil [ mean ]) + +This procedure does not alter its input vector, but rather newly allocates a vector to hold the intermediate result. Runs in O(n) time. + +# vector-find-median! + + (vector-find-median! < v knil [ mean ]) + +This procedure reuses its input vector to hold the intermediate result, leaving it sorted, but is otherwise the same as vector-find-median. Runs in O(n ln n) time. + +# vector-merge + + (vector-merge < v1 v2 [ start1 [ end1 [ start2 [ end2 ] ] ] ]) + +This procedure does not alter its inputs, and returns a newly allocated vector of length `(end1 - start1) + (end2 - start2)`. + +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. + +# vector-merge! + + (vector-merge! < to from1 from2 [ start [ start1 [ end1 [ start2 [ end2 ] ] ] ] ]) + +This procedure writes its result into vector `to`, beginning at index `start`, for indices less than `end`, which is defined as `start + (end1 - start1) + (end2 - start2)`. The target subvector `to[start, end)` may not overlap either of the source subvectors `from1[start1, end1]` and `from2[start2, end2]`. It returns an unspecified value. + +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. + +# vector-select! + + (vector-select! < v k [ start [ end ] ] ) + +This procedure returns the `k`th smallest element (in the sense of the `<` argument) of the region of a vector between `start` and `end`. Elements within the range may be reordered, whereas those outside the range are left alone. Runs in `O(n)` time. + +# vector-separate! + + (vector-separate! < v k [ start [ end ] ] ) + +This procedure places the smallest `k` elements (in the sense of the `<` argument) of the region of a vector between `start` and `end` into the first `k` positions of that range, and the remaining elements into the remaining positions. Otherwise, the elements are not in any particular order. Elements outside the range are left alone. Runs in `O(n)` time. Returns an unspecified value. + +# vector-sort + + (vector-sort < v [ start [ end ] ]) + +This procedure does not alter its inputs, but allocates a fresh vector as the result, of length `end - start`. + +# vector-sort! + + (vector-sort! < v [ start [ end ] ]) + +Sort the data in-place and return an unspecified value. + +# vector-sorted? + + (vector-sorted? < v [start [ end ] ]) + +Returns true iff the input vector is in sorted order, as determined by `<`. Specifically, return `#f` iff there is an adjacent pair `... X Y ...` in the input vector such that `Y < X` in the sense of `<`. The optional `start` and `end` range arguments restrict `vector-sorted?` to examining the indicated subvector. + +# vector-stable-sort + + (vector-stable-sort < v [ start [ end ] ]) + +This procedure does not alter its inputs, but allocates a fresh vector as the result, of length `end - start`. + +# vector-stable-sort! + + (vector-stable-sort! < v [ start [ end ] ]) + +Sorts the data in-place. (But note that `vector-stable-sort!` may allocate temporary storage proportional to the size of the input — there are no known `O(n lg n)` stable vector sorting algorithms that run in constant space.) Returns an unspecified value. + diff --git a/docs/api/srfi/133.md b/docs/api/srfi/133.md index 660b5ed6..b6355026 100644 --- a/docs/api/srfi/133.md +++ b/docs/api/srfi/133.md @@ -3,7 +3,7 @@ layout: main title: API --- -# SRFI 133 - Sort Libraries +# SRFI 133 - Vector Library The `(srfi 133)` provides a vector library. @@ -50,55 +50,316 @@ See the [SRFI document](http://srfi.schemers.org/srfi-133/srfi-133.html) for mor # vector-unfold + (vector-unfold f length initial-seed ...) -> vector + +The fundamental vector constructor. Creates a vector whose length is `length` and iterates across each index `k` between `0` and `length`, applying `f` at each iteration to the current index and current seeds, in that order, to receive n + 1 values: first, the element to put in the kth slot of the new vector and n new seeds for the next iteration. It is an error for the number of seeds to vary between iterations. Note that the termination condition is different from the `unfold` procedure of SRFI 1. + +Examples: + + (vector-unfold (λ (i x) (values x (- x 1))) + 10 0) + #(0 -1 -2 -3 -4 -5 -6 -7 -8 -9) + +Construct a vector of the sequence of integers in the range [0,n). + + (vector-unfold values n) + #(0 1 2 ... n-2 n-1) + +Copy vector. + + (vector-unfold (λ (i) (vector-ref vector i)) + (vector-length vector)) + # vector-unfold-right + (vector-unfold-right f length initial-seed ...) -> vector + +Like `vector-unfold`, but it uses `f` to generate elements from right-to-left, rather than left-to-right. The first `index` used is `length - 1`. Note that the termination condition is different from the `unfold-right` procedure of SRFI 1. + +Examples: + +Construct a vector of pairs of non-negative integers whose values sum to 4. + + (vector-unfold-right (λ (i x) (values (cons i x) (+ x 1))) 5 0) + #((0 . 4) (1 . 3) (2 . 2) (3 . 1) (4 . 0)) + +Reverse vector. + + (vector-unfold-right (λ (i x) (values (vector-ref vector x) (+ x 1))) + (vector-length vector) + 0) + + # vector-reverse-copy + (vector-reverse-copy vec [start [end]]) -> vector + +Like `vector-copy`, but it copies the elements in the reverse order from `vec`. + +Example: + + (vector-reverse-copy '#(5 4 3 2 1 0) 1 5) + #(1 2 3 4) + # vector-concatenate + (vector-concatenate list-of-vectors) -> vector + +Appends each vector in `list-of-vectors`. This is equivalent to: + + (apply vector-append list-of-vectors) + +However, it may be implemented better. + +Example: + + (vector-concatenate '(#(a b) #(c d))) + #(a b c d) + # vector-append-subvectors + (vector-append-subvectors [vec start end] ...) -> vector + +Returns a vector that contains every element of each `vec` from `start` to `end` in the specified order. This procedure is a generalization of `vector-append`. + +Example: + + (vector-append-subvectors '#(a b c d e) 0 2 '#(f g h i j) 2 4) + #(a b h i) + # vector-empty? + (vector-empty? vec) -> boolean + +Returns `#t` if `vec` is empty, i.e. its length is `0`, and `#f` if not. + # vector= + (vector= elt=? vec ...) -> boolean + +Vector structure comparator, generalized across user-specified element comparators. Vectors `a` and `b` are considered equal by `vector=` iff their lengths are the same, and for each respective element `Ea` and `Eb`, `(elt=? Ea Eb)` returns a true value. `Elt=?` is always applied to two arguments. + +If there are only zero or one vector arguments, `#t` is automatically returned. The dynamic order in which comparisons of elements and of vectors are performed is left completely unspecified; do not rely on a particular order. + +Examples: + + (vector= eq? '#(a b c d) '#(a b c d)) + #t + + (vector= eq? '#(a b c d) '#(a b d c)) + #f + + (vector= = '#(1 2 3 4 5) '#(1 2 3 4)) + #f + + (vector= = '#(1 2 3 4) '#(1 2 3 4)) + #t + +The two trivial cases. + + (vector= eq?) + #t + + (vector= eq? '#(a)) + #t + +Note the fact that we don't use vector literals in the next two. It is unspecified whether or not literal vectors with the same external representation are `eq?`. + + (vector= eq? (vector (vector 'a)) (vector (vector 'a))) + #f + + (vector= equal? (vector (vector 'a)) (vector (vector 'a))) + #t + # vector-fold + (vector-fold kons knil vec1 vec2 ...) -> value + +The fundamental vector iterator. `Kons` is iterated over each value in all of the vectors, stopping at the end of the shortest; `kons` is applied as `(kons state (vector-ref vec1 i) (vector-ref vec2 i) ...)` where `state` is the current state value. The current state value begins with `knil`, and becomes whatever `kons` returned on the previous iteration, and `i` is the current index. + +The iteration is strictly left-to-right. + +Examples: + +Find the longest string's length in `vector-of-strings`. + + (vector-fold (λ (len str) (max (string-length str) len)) + 0 vector-of-strings) + +Produce a list of the reversed elements of `vec`. + + (vector-fold (λ (tail elt) (cons elt tail)) + '() vec) + +Count the number of even numbers in `vec`. + + (vector-fold (λ (counter n) + (if (even? n) (+ counter 1) counter)) + 0 vec) + # vector-fold-right + (vector-fold-right kons knil vec1 vec2 ...) -> value + +Similar to `vector-fold`, but it iterates right to left instead of left to right. + +Example: + +Convert a vector to a list. + + (vector-fold-right (λ (tail elt) (cons elt tail)) + '() '#(a b c d)) + (a b c d) + # vector-map! + (vector-map! f vec1 vec2 ...) -> unspecified + +Similar to `vector-map`, but rather than mapping the new elements into a new vector, the new mapped elements are destructively inserted into `vec1`. Again, the dynamic order of application of `f` is unspecified, so it is dangerous for `f` to apply either `vector-ref` or `vector-set!` to `vec1` in `f`. + # vector-count + (vector-count pred? vec1 vec2 ...) -> exact nonnegative integer + +Counts the number of parallel elements in the vectors that satisfy `pred?`, which is applied, for each index `i` in the range [0, length) where `length` is the length of the smallest vector argument, to each parallel element in the vectors, in order. + +Examples: + + (vector-count even? '#(3 1 4 1 5 9 2 5 6)) + 3 + + (vector-count < '#(1 3 6 9) '#(2 4 6 8 10 12)) + 2 + # vector-cumulate + (vector-cumulate f knil vec) -> vector + +Returns a newly allocated vector `new` with the same length as `vec`. Each element `i` of `new` is set to the result of invoking `f` on `newi-1` and `veci`, except that for the first call on `f`, the first argument is `knil`. The new vector is returned. + +Example: + + (vector-cumulate + 0 '#(3 1 4 1 5 9 2 5 6)) + #(3 4 8 9 14 23 25 30 36) + # vector-index + (vector-index pred? vec1 vec2 ...) -> exact nonnegative integer or #f + +Finds & returns the index of the first elements in `vec1 vec2 ...` that satisfy `pred?`. If no matching element is found by the end of the shortest vector, `#f` is returned. + +Examples: + + (vector-index even? '#(3 1 4 1 5 9)) + 2 + + (vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2)) + 1 + + (vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2)) + #f + # vector-index-right + (vector-index-right pred? vec1 vec2 ...) -> exact nonnegative integer or #f + +Like `vector-index`, but it searches right-to-left, rather than left-to-right, and all of the vectors must have the same length. + # vector-skip + (vector-skip pred? vec1 vec2 ...) -> exact nonnegative integer or #f + +Finds & returns the index of the first elements in `vec1 vec2 ...` that do not satisfy `pred?`. If all the values in the vectors satisfy `pred?` until the end of the shortest vector, this returns `#f`. This is equivalent to: + + (vector-index (λ (x1 x2 ...) (not (pred? x1 x1 ...))) + vec1 vec2 ...) + +Example: + + (vector-skip number? '#(1 2 a b 3 4 c d)) + 2 + # vector-skip-right + (vector-skip-right pred? vec1 vec2 ...) -> exact nonnegative integer or #f + +Like `vector-skip`, but it searches for a non-matching element right-to-left, rather than left-to-right, and it is an error if all of the vectors do not have the same length. This is equivalent to: + + (vector-index-right (λ (x1 x2 ...) (not (pred? x1 x1 ...))) + vec1 vec2 ...) + # vector-binary-search + (vector-binary-search vec value cmp) -> exact nonnegative integer or #f + +Similar to `vector-index` and `vector-index-right`, but instead of searching left to right or right to left, this performs a binary search. If there is more than one element of `vec` that matches value in the sense of `cmp`, `vector-binary-search` may return the index of any of them. + +`cmp` should be a procedure of two arguments and return a negative integer, which indicates that its first argument is less than its second, zero, which indicates that they are equal, or a positive integer, which indicates that the first argument is greater than the second argument. An example `cmp` might be: + + (lambdaλ (char1 char2) + (cond ((char value or #f + +Finds the first set of elements in parallel from `vec1 vec2 ...` for which `pred?` returns a true value. If such a parallel set of elements exists, `vector-any` returns the value that `pred?` returned for that set of elements. The iteration is strictly left-to-right. + # vector-every + (vector-every pred? vec1 vec2 ...) -> value or #f + +If, for every index `i` between `0` and the length of the shortest vector argument, the set of elements `(vector-ref vec1 i) (vector-ref vec2 i) ...` satisfies `pred?`, `vector-every` returns the value that `pred?` returned for the last set of elements, at the last index of the shortest vector. The iteration is strictly left-to-right. + # vector-partition + (vector-partition pred? vec) -> vector and integer + +A vector the same size as `vec` is newly allocated and filled with all the elements of `vec` that satisfy `pred?` in their original order followed by all the elements that do not satisfy `pred?`, also in their original order. + +Two values are returned, the newly allocated vector and the index of the leftmost element that does not satisfy `pred?`. + # vector-swap! + (vector-swap! vec i j) -> unspecified + +Swaps or exchanges the values of the locations in `vec` at `i` & `j`. + # vector-reverse! + (vector-reverse! vec [start [end]]) -> unspecified + +Destructively reverses the contents of the sequence of locations in `vec` between `start` and `end`. Start defaults to `0` and `end` defaults to the length of `vec`. Note that this does not deeply reverse. + # vector-reverse-copy! + (vector-reverse-copy! to at from [start [end]]) -> unspecified + +Like `vector-copy!`, but the elements appear in to in reverse order. + # vector-unfold! + (vector-unfold! f vec start end initial-seed ...) -> unspecified + +Like `vector-unfold`, but the elements are copied into the vector `vec` starting at element `start` rather than into a newly allocated vector. Terminates when `end-start` elements have been generated. + # vector-unfold-right! + (vector-unfold-right! f vec start end initial-seed ...) -> unspecified + +`Like `vector-unfold!`, but the elements are copied in reverse order into the vector `vec` starting at the index preceding `end`. + # reverse-vector->list + (reverse-vector->list vec [start [end]]) -> proper-list + +Like `vector->list`, but the resulting list contains the elements in reverse of `vec`. + # reverse-list->vector + (reverse-list->vector proper-list) -> vector + +Like `list->vector`, but the resulting vector contains the elements in reverse of `proper-list`. +