The rktio conversion lost the deregistration of file descriptors in an
internal fd-to-semaphore table building on kqueue/epoll, causing the
wrong semaphore to be checked for a later recycling of the file
descriptor. This bug mainly affects Linux and ports created by
`subprocess`, since kqueue is not used for pipes on Mac OS and BSD
variants. The bug does not affect network sockets (which are the
primary intended clients of epoll/kqueue support), since the relevant
semaphore is deregistered when a socket is closed.
Thanks to James Bornholt for discovering the problem and providing the
repair.
Closes#1769
Fix a problem with compile-time bindings added to a
namespace created by `module->namespace` for a module
that does not have a source file.
Possibly, there's a different fault that should be fixed that caused a
binding to use the module's instantiation-time module path index
instead of its compile-time module path index (which is what happens
when a file is involved). This repair fixes the problem in a general
way, though, and leaves further improvement to the reimplementation of
the expander in Racket (which already does not suffer from the bug).
Thanks to Alexis for providing the example.
In a non-tail position, a JIT-generated application of `apply`
retained the argument list until the called function returned.
Fix it to drop the reference to the list before the function
is called.
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.
As discussed on the racket users list (subj: ~literal vs ~datum) at https://groups.google.com/d/msg/racket-users/KWANfGc7qcI/G_MClWJpBAAJ
New example based on code from Jens Axel Soegaard.
Caveat: I've run this in DrRacket with (require (for-syntax syntax/parse)) to verify the three distinct outputs, but am submitting this PR in-browser, so I haven't run the doc build on it myself.
Before this line, it says the function flows from providing module to requiring module.
After this line, it says the argument travels back from requiring moduleo to providing module.
I believe that argument supplying and function invoking should happen at requiring module, rather than providing module.
For the French counting, "une" is not quite correct. It is the female form for "one" as an article. It is much more common to count "un", "deux", "troix", "quatre", "cinq", ....
The hack to implement `_union` without help from libffi failed when
the total size of the variants is too large. Try a different approach,
which involves a bet that the total size plus whether the content is
all floating-point numbers will be enough information for most cases.
Relevant to #1351
The simpler example uses `dynamic-require`, which will hopefully set
readers on a better path if they don't need a REPL and the associated
complexities of `load` and `eval`.
Make `raco setup` propagate the original value of
`use-compiled-file-paths` in case it's reset to avoid loading bytecode
files. Then, `--clean` mode can remove bytecode relevant to that
setting, instead of always clearing "compiled" subdirectories.
There's no external way to initialize `use-compiled-file-paths` right
now, other than forcing it to `null` with the `-c` flag at the
`racket` level, but the current "racket7" implementation uses
different `use-compiled-file-paths` settings for different build
modes, and it seems to make sense in general.
Also, make `--clean` sensitive to `-D` and `-d`, so that it's easy to
clean just bytecode.
Add guard, if first argument to `find-relative-path` is not a path,
then don't call `path-convention-type` on it.
Thanks to Jack Firth for reporting:
https://github.com/racket/rackunit/pull/46
Avoid printing `(unquote @d)` or `(unsyntax @d)` as `,@d` or `#,@d`,
which would mean `(unquote-splicing @d)` or `(unsyntax-splicing @d)`
to the reader, by adding an extra space before the `@`.
Additionally this adds macros that distinguish between the chaperone redirects of prop-only vector
chaperones, function chaperones, and structure chaperones since each of these may store a vector
in the redirects field.
Auto fields were incorrectly recorded as immutable in a structure type
that is first generated from the prefab struct key instead of
`make-struct-type`.
Thanks to Deren Dohoda for the report.
When `--update-deps` (which is implied by `--all`) was used on
user-scope packages that depend on installation-scope packages, the
installation-scope dependencies were treated as missing, which forced
an update of the user-scope packages. Check both scopes for
dependencies.
Closes#1730
In the process of extracting minimal Windows path encoding for rktio,
I noticed a decoding issue with a path that ends with an unpaired
high-surrogate value. Add a suitable tests and fix the old decoder
(although it will probably go away).
Closes#1721, which points out that the `for/list` expansion
introduced in commit 5e94a906cd interacts badly with a body
that captures a continuation plus Racket's current implemenation
of continuations.
When Racket one day gets a better implementation of continuations,
this change could be considered again, but the general question is
whether programs can detect or be affected by the size of the
continuation (when the programs don't directly control the
continuation creation --- otherwise continuation marks obviously
expose the size).
For a term
(lambda (arg-id ...) (define def-id _rhs) ... (arg-id def-id) ...)
the expander could take quadratic time in the number of `def-id`s
due to walking an environment to remove use-site scopes. (The
variant of the expander rewritten in Racket didn't have this
problem.)
This make-c-id allows an author to specify a convention for how
to connect and identifier defined with define-ffi-definer and
the actual symbol in the file.
* Adds docs.
* Adds tests.
* Adds history.
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.
* Fixed typo in the docs for serialization (serializable-struct/version → serializable-struct/versions)
* Fixed typo in scribble documentation (head pattern → a-pattern)
* Made the order of the argument descriptions match the order of the arguments in the documentation for import and export
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.
The blame object passed to a late-neg-proj function will be missing
one party. The missing party is sometimes the negative party and
sometimes the positive party.
In non-cross mode, `-C` needs to go after `-G` and `-X` when setting
up a "bundle" directory to turn into an installer, because that mode
needs to use foreign libraries (such as SQLite) at build time, and it
can use the instances that are being set up for the installer.
Meanwhile, improve the advice for setting `PLAIN_RACKET` to use `-C`
for a cross-platform build mode, even though things tend to work
anyway without it.
When comparing a part of a hamt that is a collision node versus a
subtree node, a "hash code" was extracted from the collision node ---
but that's really a code for an integer key is that used for the
collision element. The comparison should instead use a code extracted
from the reference to the collision node (which is the code that is
common to all colliding keys).
Detangle the target and host DLL and library directories by
making `get-lib-search-dirs` and `get-dll-dir` report the
host system's directories, and add `get-cross-lib-search-dirs`
and `get-cross-dll-dir`.
A new `-C`/`--cross` flag causes `racket` to save a host config and
collection directory and make them available via `(find-system-path
'host-{config,collects}-dir)`, while plus `(system-type 'cross)`
reports whether `-C` mode is in effect. Besides making the host paths
available, this change allows a same-platform build to run in
corss-platform mode.
The immediate problem to solve was the creation of Windows installers
on Windows, where recent changes to support 'gui-bin-dir configuration
need a clear distinction between the host Racket and the target Racket
being built, even if they're the same platform. (The "GRacket.exe"
executable didn't work, for example.)
The changes in this commit are more than needed for the immediate
problem, but they naturally build on the necessary `-C` flag, and they
support cross-platform package setup where native libraries are needed
during setup.
Avoid the well-known possibility of quadratic handling of ephemeron
chains, where all ephemerons are immediately known, no keys are
immediately known, and each link in the chain has a value that refers
to the next link's key.
To aviod quadratic behior, attach a list of ephemerons to each page of
allocated objecst, where marking any object on the page triggers a
rescan of the ephemerons without waiting to rescan all ephemerons.
The test cases relied on arity and changing log to have an arity
of both 1 and 2 activated new (incorrect) tests. I fixed the
incorrect tests as they applied to the log function.
Make `log` in `racket/base` optionally accept a second argument.
The second argument is the log `base`. The docs also recommend
`fllogb` when precision is important.
* Error message when base is 1
* Added docs.
* Add tests.
Remove the history annotation on `build-flat-contract` property
about removing the `#:exercise` keyword.
Because the keyword wasn't actually removed from the function,
only from the (incorrect) documentation. So there aren't any
legal programs that depend on the removed keyword argument.
Optimization to convert `(hash-ref <ht> <key> (lambda () <constant>))`
to `(hash-ref <ht> <key> <constant>)` didn't check that the `lambda`
for had zero argument.
Closes#1648
* generics: optional scope arg for private macros
To make them more friendly to macros that expand to generics
* add tests for generic-method-table macro
The process of creating an installer involves building "racket-index"
in user scope, but the license and acks files are normally only in
installation scope. An explicit targeting of the installation-scope
output needs to be disabled when the documentats are rendered to
user scope.
Closes#1635
and/c, and between/c (which implies <=/c and >=/c) so that they turn
themselves into integer-in when appropriate
for example, (contract-stronger? (integer-in 0 4) (and/c natural? (<=/c 4)))
returns #t
Fix problem with once-use tracking and delayed variable-use marking
that is performed for local function bodies. A delayed variable-use
registration might happen after a once-used variable is replaced by
its use.
This scenario is difficult to provoke, because the optimizer has to
first decide not to move a once-use function, and in a latter pass
decide to move it after all. There's not enough information to
retract the tentative use plus its transitive implications.
The solution is to avoid the generic once-use layer for `lambda` forms
whose uses are delayed (and that likely has a good effect on inlining
anyway). The other half of the solution is to avoid transitive use
marking on a once-used variable whose expression has been moved (and
there are no transitive things to skip, because that expression isn't
a `lambda` form).
The previous for/fold/derived examples in the docs
incorrectly expanded, placing the entire body of the
user defined for loop into a let expression inside of
for/fold/derived. This meant that break clauses (i.e. #:break
or #:final) that appeared in the body of the user-defined
for loop were not visible to the underlying for/fold/derived
macro after expansion and therefore usages of #:break or #:final
incorrectly resulted in syntax errors (since with the incorrect
expansion, they were seemingly misplaced keywords inside of a let).
With this PR the for/fold/derived examples in the docs now
expand correctly into a form that mirrors the actual
expected syntax of for loops:
(user-defined-for (for-clause ...) body-or-break ... body)
==(now expands more or less into)==>
(for/fold/derived (for-clause ...) body-or-break ... body)
Or in other words, the body of the user defined for loop now correctly
expands directly into the body of for/fold/derived.
When the second argument to `bytes-set!` is a reference to a
module-level variable that is definitely defined but not a known
constant, then an incorrect reordering was used that would cause
the third argument value to get overwritten before the call.
Closes#1601
The primitive `read` uses a shortcut --- a private "ungetc"
implementation --- that did not count position correctly for
non-ASCII characters.
Closes#1599
The documentation says that it should work on any output port,
although there's special treatment of ports that originate
from `pretty-print` itself.
Closes#1579.
Allow the directory for GUI executables to be specified as different
from console executables. The defaults for those two are different
on Mac OS, and configuring them differently might be useful to
address #1575.
Although there is probably no demand on Windows or Unix for splitting
the console and GUI bin directories, this patch tries to make things
work sensible there. On Windows, there's a corner case where a
launcher that starts GRacket (especially with `-z`) is intended to be
a console executable. The launcher creator can be told that via a
`subsystem` option, but a new `#:console?` argument was needed for
`make-gracket-launcher-path` lets the path selector know.
After some reductions, the new rator advance less the effect
clocks than the original rator. For example in
(equal? x 7) ==> (eq? x 7)
(my-struct? x) ==> #t or #f
The lambdas can be marked as single valued and/or mark preserving.
With this information is possible to remove unnecessary wrapping
like the `values` in
(let ([f (lambda () '(1))])
(display f f)
(values (f)))
or in reductions like
(car (list (f))) ==> (values (f)) ==> (f)
Moreover, this is useful to test that the optimizer has marked
correctly the function f as single valued and mark preserving.
If a module has any sort of complex bindings, such as a definition of
a macor-introduced identifiers, then `module->namespace` and variants
(like `variable-reference->namespace`) need to recreate suitable
bindings. Make sure that the module-path index for recreated bindings
is the run-time one, not the compile-time one.
Closes#1584
To avoid moving expressions that may have a side effect, the optimizer must
recognize that in this position this will cause an error and advance
the virtual clock.
Currently the only primitive that is flagged as SCHEME_PRIM_IS_OMITABLE and
may have multiple return values is `values`.
Thanks to Robby for finding the original version of the test.
we don't want an actual dependency from at-exp-lib to those libraries,
so when they aren't present, don't just crash, but instead fall back
to the defaults passed to the get-info procs
When a hash table or other special value appears immediately on the
right-hand side of `define-values`, it needs to be protected by an
explicit quote when writing to bytecode.
Closes#1580
* byte-regexp? values should not be considered 3D syntax.
* hash? values are now allowed in serialized syntax properties with (template … #:properties (…))
* marshalling properties which were prefab structs called map on the result of struct->vector, changed it to struct->list as the struct "name" is always serializable.
Continuing the saga that includes 8190a7730d and d1ba9fbb6e, it turns
out that a 0-binding clause as the last one isn't so special after
all. A little later in the optimizer, now that we're sometimes moving
an error to the body, we can't assume that the body can be discard
if an error was detected.
Set up bindings and shift phases as needed to make
`variable-reference->namespace` work in a run-time position when the
enclosing module is instantiated at a phase other than 0.
Thanks to Rohin Shah for the bug report.
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.
I originally picked "under" as the preposition to go before
a platform name, but obviously you should build "on" a
platform, and "under" suddenly annoys me. The choice of "on"
is now codified in the documentation style guide. Meanwhile,
"Unix" insted of "X" seems more clear and consistent in the
`racket/gui' docs.
More usefully, this patch also fixes a few out-of-date
platform-specific claims.
original commit: f34a31cac9
When multiple-binding `let-values` form is split into a single-binding
form on the grounds that the right-hand side will definitely error,
the optimizer's effect clocks were advance incorrectly.
Closes#1552
Specifically, when it sees these contracts:
(and/c real? negative?)
(and/c real? positive?)
(and/c real? (not/c positive?))
(and/c real? (not/c negative?))
it generates the corresponding use of >=/c, <=/c, </c, or >/c, but
those contracts have also been adjusted to report their names as
(and/c real? ...).
This mostly is an improvement for contract-stronger, but also make it
so that (between/c -inf.0 +inf.0) just uses the real? predicate
directly, instead of a more complex function
Although "macOS" is the correct name for Apple's current desktop OS,
we've decided to go with "Mac OS" to cover all of Apple's Unix-like
desktop OS versions. The label "Mac OS" is more readable, clear in
context (i.e., unlikely to be confused with the Mac OSes that
proceeded Mac OS X), and as likely to match Apple's future OS names
as anything.
For example, an `unsafe-unbox` call should not be moved past the
call to an unknown function that might change a box's content.
Thanks to Sergey Pinaev for the report.
The objective of lookup_constant_proc and the first part of
optimize_for_inline was to find out if the value of an expression was a
procedure and get it to analyze its properties or try to inline it. Both
were called together in a few places, because each one had some special
cases that were missing in the other.
So, move the lookup and special cases from optimize_for_inline to
lookup_constant_proc, and keep only the code relevant to inlinig in
optimize_for_inline.
If an OS-level thread other than a Racket thread logs a message, then
the message needs to be queued instead of handled immediately.
If multiple places are running, then the right handler thread is not
clear, so just queue to the main place's thread.
Closesracket/gui#66Closesracket/drracket#77
Implement POSIX.1-2001/pax and GNU extensions for long paths and links
in `untar` and `tar`. Add a `#:format` argument to `tar` to select
among POSIX.1-2001/pax, GNU, or error encoding for long paths.
it doesn't apply it the second time (since we know that the
only difference for indy blame is in the negative position
and we know that flat contracts never assign negative blame)
This commit combined with the two previous (2b9d855 and 003e8c7) do
not seem to have a significant effect on the performance of ->i
contract checking. In particular, I see a 50% slowdown between the
version before and the version after these commits on the third `time`
expression below, but no significant difference on the first two.
(without the improvement to flat-contract?, these commits are
a significant slowdown to `g`)
#lang racket
(require profile)
(define f
(contract (->i ([y () integer?]
[x (y) integer?])
(values [a () integer?]
[b (a) integer?]))
values
'pos 'neg))
(define g
(contract (->i ([y () (<=/c 10)]
[x (y) (>=/c y)])
(values [a () (<=/c 10)]
[b (a) (>=/c a)]))
values
'pos 'neg))
(define (slow-predicate n)
(cond
[(zero? n) #t]
[else (slow-predicate (- n 1))]))
(define h
(contract (->i ([y () slow-predicate]
[x (y) slow-predicate])
(values [a () slow-predicate]
[b (a) slow-predicate]))
values
'pos 'neg))
(time
(for ([x (in-range 100000)])
(f 1 2) (f 1 2) (f 1 2)
(f 1 2) (f 1 2) (f 1 2)
(f 1 2) (f 1 2) (f 1 2)))
(time
(for ([x (in-range 100000)])
(g 1 2) (g 1 2) (g 1 2)
(g 1 2) (g 1 2) (g 1 2)
(g 1 2) (g 1 2) (g 1 2)))
(time
(for ([x (in-range 10000)])
(h 50000 50000)))
Both function have a similar purpose and implementation, so merge them to consider
all the special cases for both uses.
In particular, detect that:
(if x (error 'e) (void)) is single-valued
(with-continuation-mark <chaperone-key> <val> <omittable>) is not tail sensitive.
Also, as ensure_single_value was checking also that the expression was has not a
continuation mark in tail position, it added in some cases an unnecessary
wrapper. Now ensure_single_value checks only that the expression produces
a single vale and a new function ensure_single_value_noncm checks both
properties like the old function.
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).
Compile a `for[*]/list` form to behave more like `map` by `cons`ing
onto a recursive call, instead of accumulating a list to reverse.
This style of compilation requires a different strategy than before.
A form like
(for*/fold ([v 0]) ([i (in-range M)]
[j (in-range N)])
j)
compiles as nested loops, like
(let i-loop ([v 0] [i 0])
(if (unsafe-fx< i M)
(i-loop (let j-loop ([v v] [j 0])
(if (unsafe-fx< j N)
(j-loop (SEL v j) (unsafe-fx+ j 1))
v))
(unsafe-fx+ i 1))
v))
instead of mutually recursive loops, like
(let i-loop ([v 0] [i 0])
(if (unsafe-fx< i M)
(let j-loop ([v v] [j 0])
(if (unsafe-fx< j N)
(j-loop (SEL v j) (unsafe-fx+ j 1))
(i-loop v (unsafe-fx+ i 1))))
v))
The former runs slightly faster. It's difficult to say why, for
certain, but the reason may be that the JIT can generate more direct
jumps for self-recursion than mutual recursion. (In the case of mutual
recursion, the JIT has to generate one function or the other to get a
known address to jump to.)
Nested loops con't work for `for/list`, though, since each `cons`
needs to be wrapped around the whole continuation of the computation.
So, the `for` compiler adapts, depending on the initial form. (With a
base, CPS-like approach to support `for/list`, it's easy to use the
nested mode when it works by just not fully CPSing.)
Forms that use `#:break` or `#:final` use the mutual-recursion
approach, because `#:break` and #:final` are easier and faster that
way. Internallt, that simplies the imoplementation. Externally, a
`for` loop with `#:break` or `#:final` can be slightly faster than
before.
Quote marks (at a minimum) should be triggered by any of the
characters in `atom-specials` from the IMAP RFC. The previous trigger
would not have worked for a password that includes parentheses, curly
braces, or an open quare bracket, for example.
The optimizer can detect that some expressions will escape through
an error, and it can discard surrounding code in that case. It should
not change the tailness of a `with-continuation-mark` form by
liftng it out of a nested position, however. Doing so can eliminate
stack frames that should be visible via errotrace, for example.
This change fixes the optimizer to wrap an extra `(begin ... (void))`
around an expression if it's lifted out of a nested context and
might have a `with-continuation-mark` form in tail position.
In
(with-syntax ([x ....])
#'(x y))
and property on the source syntax object `(x y)` was lost in
constructing a new syntax object to substitute for `x`, while
properties on preserved literal syntax objects, such as `y`
were intact. Change `syntax` to preserve properties for
reconstructed parts of the template.
This change exposes a problem with 'transparent taint modes,
where the internal "is original?" property was preserved while
losing scopes that wuld cancel originalness. So, that's fixed
here, too.
The continuation of a future being evaluated concurrently was not
correctly attributed to the future's custodian (as inherited from
from the creating thread).
extend optimize_ignore to go inside expressions with
begin, begin0 and let.
Also, try to reuse begin's in the first argument of
make_discarding_sequence.
If a mutable hash table changes while it's being printed,
various parts of the printing function could see a mismatch
between the current size and an old array size. To avoid this
problem, extract the size whenever extracting the array.
This adds #:eager as an option for controlling this behavior.
Using `#:eager 10` is a 2x improvement in performance for configuration 010001
of the suffixtree benchmark from Takikawa et al, POPL 2016.
The default behavior is unchanged. This is configurable because some
programs are much faster when eager checking is performed. For example:
(require racket/contract)
(collect-garbage)
(time (for/sum ([_ 100000])
(vector-ref (contract (vectorof integer? #:eager #t) #(1) 'pos 'neg)
0)))
(collect-garbage)
(time (for/sum ([_ 100000])
(vector-ref (contract (vectorof integer? #:eager #f) #(1) 'pos 'neg)
0)))
The second loop is 3-4 times slower than the first. However, making
the vector much larger will make the difference go the other way.
An identifier that gets a module context via `module->namespace` plus
`namespace-syntax-introduce` should not count as having the module as
its source as reported by `syntax-source-module`.
The correct behavior happened for the wrong reason prior to commit
cb6af9664c.
Closes#1515
For a template expression that involevs ellipses, a wrapper is added
to catch failures an report as an "incompatible ellipsis match count"
error. The wrapper was only added when there are multiple pattern
variables with ellipses, but it turns out that it's possible to fail
with incompatible counts using a single pattern variable.
Besides handlign that case, the revised check avoids an unnecessary
wrapper in cases where multiple pattern variables have ellipses but
they are used independently in a template.
Closes#1511
Without this repair,
#lang racket/base
(require 2htdp/abstraction)
(for/list ((dropping-which-one (in-naturals)))
1)
fails to compile with a "optimizer clock tracking has gone wrong"
error. A variant of this test (that doesn't depend on `2htdp`)
is now in the "optimize.rktl"; a simpler and more direct test
should be possible, but I wasn't able to construct one.
When a thread that is blocked on a set of semaphores and channels
is suspended and resumed after one of the events becomes ready,
and if the event has a wrapper function, then the wrapper was
not applied and the event selection was not reported correctly.
Thanks to Philip McGrath for reporting the problem.
Remove “ancient browsers” netscape and mosaic.
Remove non-browsers (xdg-open, gnome-open), because we really want a
browser, and they don’t understand file URLs with queries.
Add chromium-browser.
Add default browser finders x-www-browser and sensible-browser (Debian &
derivatives).
This kind of reductions were applied only when x or y was a constant.
Classify the relevant predicates in 4 categories. In particular,
if <expr> satisfy pred? we can use this classification to apply
the correct reduction:
(equal? <expr> y) ==> [no reduction, unless y has a different type]
(equal? <expr> y) ==> (eqv? <expr> y)
(equal? <expr> y) ==> (eq? <expr> y)
(equal? <expr> y) ==> (begin <expr> (pred? y))
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?.
... + prefix-in + relative-path module. All of those ingredients
(or some similar alternatives) are necessary to trigger a slow
way of saving module context for interaction evaluation where
a module-path index shift was getting lost.
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))
* Wrong contract for syntax-local-value in the documentation.
* Clarified signature in documentation for expand-import, expand-export and pre-expand-export
* Corrected typo in documentation for "for".
* Fixed error message for function which seems to have been renamed in the docs
* Fixed typo in a comment in the tests
* Fixed a typo in the documentation for set-subtract.
* Use double ellipses for the free-id-table-set*, free-id-table-set*!, bound-id-table-set* and bound-id-table-set*! operations
The optimizer assumed a fixnum result if either argument to
`bitwise-and` implies a fixnum result. That's not correct if the
fixnum agument is negative.
Thanks to Peter Samarin for a bug report.
Merge to v6.7