The old implementation turns a single optional argument into two
arguments: the optional value and a boolean to indicate whether the
optional value is supplied.
The new expansion uses `unsafe-undefined` in place of not-supplied
arguments, in the general case. If the default-value expression is
simple enough, however, it is copied to call sites that would
otherwise supply `unsafe-undefined`. In the common case where the
default value is `#f`, for example, no run-time test is needed in the
core implementation function to check whether the default is supplied,
because a `#f` will be filled in for callers.
The performance improvement is tiny to non-existent for realistic
programs, but the simpler and reduced generated code may help in the
long run.
This commit adds a section to the reference to document how the expander
tracks information about local bindings, and it extends some
syntax-local functions to allow them to accept multiple definition
contexts instead of just one. In addition, it improves the documentation
on how first-class definition contexts interact with local-expand,
syntax-local-value, and syntax-local-bind-syntaxes, and it also
clarifies what it means to create a child definition context.
The expander as a linklet will be instantiated once, so there's no
need to capture references in closures among functions within the
expander. Add a "static" linklet compilation mode to inline the
variable addresses that would otherwise be referenced via a closure.
Although the change is intended to speed up the expander by avoiding
some indrections, it also reduces the bytecode size of the expander.
Bitmaps that track which linklet variables are used in closures turn
out to have been about 25% of the expander's bytecode size, since the
linklet has so many definitions.
Some parts of the optimizer were inconsistent in whether a tracked
structure type needed to have a constructor that always succeeds
(i.e., no associated guard). Increase precision to track both kinds of
structure types, and avoid some unnecessary space-safety clearing in
the vicinity of nonfailing constructors.
Make `s-exp->fasl` generate an encoding that can be parsed by any
future version of `fasl->s-exp`. The new format does not rely on the
runtime system's bytecode writer and reader.
This commit merges changes that were developed in the "racket7" repo.
See that repo (which is no longer modified) for a more fine-grained
change history.
The commit includes experimental support for running Racket on Chez
Scheme, but that "CS" variant is not built by default.
Add a `_bytes` variant type that will work more consistently with
Racket-on-Chez, where the representation of a byte string does not
include an implicit nul terminator.
Provide unsafe functions for working with file descriptors and
sockets. Although more functions are potentially useful, these
reflect the one scurrently exported by the C API.
And unquoted-printing string contains a string to `display` in all
print modes. Although it could be implemented with a structure type
that has a printing function, `raise-arguments-error` further treats
unquoted-printing strings specially by not using the error value
conversion handler, so it reliably produces literal text in the error
message; that way, `raise-arguments-error` can be used to construct
more error messages.
Accessing unsafe functionality through the FFI seemed like a good way
to avoid writing C code, but it made things more complicated instead
of easier, and it interacts badly with a more agressive shift away
from C (such as porting to Chez Scheme). So, add functions to the
primitive `#%unsafe` module, instead.
An authentic structure type is one whose instances cannot be
impersonated or chaperoned. The intended use of `prop:authentic` is to
annotate a library-private data structure where impersonators are
never needed internally for the data structure, and the declaration
lets the compiler produce less code and fewer branches by omitting
impersonator support.
Support an external implementation of `read-syntax` by exposing
functionality that is currently internal to `read-syntax`: a srcloc
argument to a "special"-producing port function and wrapping special
results to reliably distinguish them from characters.
Adjust list and stream handling as sequences so that during the body
(for ([i (in-list l)])
....)
then `i` and its cons cell in `l` are not implicitly retained while
the body is evaluated. A `for .... in-stream` similarly avoids
retaining the stream whose head is being used in the loop body.
The `map`, `for-each`, `andmap`, and `ormap` functions are similarly
updated.
The `make-do-sequence` protocol allows an optional extra result so
that new sequence types could have the same properties. It's not clear
that using `make-do-sequence` is any more useful than creating the new
sequence as a stream, but it was easier to expose the new
functionality than to hide it.
Making this work required a repair to the optimizer, which would
incorrectly move an `if` expression in a way that could affect
space complexity, as well as a few repairs to the run-time system
(especially in the vicinity of the built-in `map`, which we should
just get rid of eventually, anyway).
Also, add a new primitive interned-char? that is hidden, but it's
useful to track in the optimizer the the chars? with a value < 256
that are interned because they are treated specially, and if they
are equal? then they are eq?.
Previously the relevant predicates where disjoint, and until this commit
the only predicate that recognizes #f was `not`. So it's necessary to fix
two reductions to allow other predicates that recognize #f, like `boolean?`.
Add a hidden `true-object?` primitive that recognizes only #t, that is also
useful to calculate unions and complements with `boolean?` and `not`.
Also, extend a special case for expressions like
(or (symbol? x) (something))
where the optimizer is confused by the temporal variable that saves the
result of `(symbol? x)`, and the final expression is equivalent to
(let ([temp (symbol? x)])
(if temp #t (something)))
This extension detects that the temporal variable is a `boolean?` and
reduces the expression to
(if (symbol? x) #t (something))
lookup-errno now returns #f when given an unknown symbol instead
of raising a contract error. It should not return #f for any
symbol that it previously accepted.
Along with the `PLT_COMPILED_FILE_CHECK` environment variable, allows
the timestamp check to be disabled when deciding whether to use a
compiled bytecode file.
In accomodating this change, `raco make` and `raco setup` in all modes
check whether the SHA1 hash of a module source matches the one
recorded in its ".dep" file, even if the timestamp on the bytecode
file is newer. (If the compile-file check mode is 'exists, the
timestamp is completely ignored.)
This function exposes the fast subset operation that is built in for
immutable hash tables (and used by the set-of-scopes implementation).
Also, make the space optimization implicit for `eq?`-based hash tables
that contain only #t values (instead of explicit and only available
internally). It turns out to be easy and efficient to make the
representation automatic, because the HAMT implementation can support
a mixture of nodes with some containing explicit values and some
containing implicit #t values.