Re: [racket-dev] [plt] Push #29677: master branch updated
This change seemed to change the format of .dep files, likely as intended to add the indirect dependencies. Is there any documentation of what the format is supposed to be? Currently I've just been trying to read cm.rkt and understand how it treats them. On Thu, Jan 8, 2015 at 9:31 AM, mfl...@racket-lang.org wrote: mflatt has updated `master' from c56c9250f1 to 95e85ec5bd. http://git.racket-lang.org/plt/c56c9250f1..95e85ec5bd =[ 2 Commits ]== Directory summary: 45.1% pkgs/racket-doc/scribblings/raco/ 4.7% pkgs/racket-doc/scribblings/reference/ 47.5% racket/collects/compiler/ ~~ fe9a04d Matthew Flatt mfl...@racket-lang.org 2015-01-08 09:11 : | doc tweaks for `raco {setup,make}` : M pkgs/racket-doc/scribblings/raco/make.scrbl | 4 ++-- M pkgs/racket-doc/scribblings/raco/setup.scrbl | 22 -- ~~ 95e85ec Matthew Flatt mfl...@racket-lang.org 2015-01-08 09:57 : | add support for indirect CM dependencies; use in `lazy-require` | | If module M in package P imports module N from package Q, | and if N has a `lazy-require` for a module in R that is | triggered during the compilation of M, then P doesn't really | depend on R; P depends on Q, and Q depends on R, and P | shoudn't necessarily know anything about Q. At the same time, | a change to the file in R means that M must be recompiled. | So, continue to track the compilation dependency, but mark | it as indirect so that the package-dependency checker can | ignore the dependency. : M pkgs/racket-doc/scribblings/raco/make.scrbl | 33 - M racket/collects/compiler/cm-accomplice.rkt| 14 +++--- M racket/collects/compiler/cm.rkt | 49 ++-- M racket/collects/racket/lazy-require.rkt | 2 +- M racket/collects/setup/private/pkg-deps.rkt| 1 + M .../racket-doc/scribblings/reference/syntax.scrbl | 8 ++-- =[ Overall Diff ]=== pkgs/racket-doc/scribblings/raco/make.scrbl ~~~ --- OLD/pkgs/racket-doc/scribblings/raco/make.scrbl +++ NEW/pkgs/racket-doc/scribblings/raco/make.scrbl @@ -123,7 +123,7 @@ would create only @filepath{compiled/b_rkt.zo} and @; -- -@section{Dependency Files} +@section[#:tag Dependency Files]{Dependency Files} In addition to a bytecode file, @exec{raco make} creates a file @filepath{compiled/@nonterm{name}_@nonterm{ext}.dep} that records @@ -538,7 +538,7 @@ messages are instances of a @racket[parallel-compile-event] prefab structure: @racketblock[ (struct parallel-compile-event (worker event) #:prefab) -]. +] The worker field is the index of the worker that the created the event. The event field is a @racket[compile-event] as document in @@ -550,25 +550,36 @@ field is a @racket[compile-event] as document in @defmodule[compiler/cm-accomplice] -@defproc[(register-external-file [file (and path? complete-path?)]) void?]{ +@defproc[(register-external-file [file (and path? complete-path?)] + [#:indirect? indirect? any/c #f]) + void?]{ -Logs a message (see @racket[log-message]) at level @racket['info] to -a logger named @racket['cm-accomplice]. The -message data is a @racketidfont{file-dependency} prefab structure type -with two fields; the first field's value is @racket[file] and the second -field's value is @racket[#f] (to indicate a non-module dependency). +Logs a message (see @racket[log-message]) at level @racket['info] to a +logger named @racket['cm-accomplice]. The message data is a +@racketidfont{file-dependency} prefab structure type with two fields; +the first field's value is @racket[file] and the second field's value +is @racket[#f] (to indicate a non-module dependency). If the +@racket[indirect?] argument is true, the data is more specifically an +instance of a @racketidfont{file-dependency/indirect} prefab structure +type that is a subtype of @racketidfont{file-dependency} with no new +fields. A compilation manager implemented by @racketmodname[compiler/cm] looks -for such messages to register an external dependency. The compilation -manager records (in a @filepath{.dep} file) the path as contributing -to the implementation of the module currently being +for such messages to register an external dependency. In response, the +compilation manager records (in a @filepath{.dep} file) the path as +contributing to the implementation of the module currently being compiled. Afterward, if the registered file is modified, the -compilation manager will know to recompile the module. +compilation manager will know to recompile the module. An ``indirect'' +dependency has no effect on recompilation, but it can signal to other +tools, such as a package-dependency
[racket-dev] Understanding the performance of raco make
I'm trying to improve the compilation speed of some modules, and to do that I need to understand how raco make is spending its time. I decided to call parallel-compile-files myself with a handler that gets the time of start and done messages, and then turn those into a timeline plot. I have a attached a screen shot of what that produces. Screen Shot 2014-10-28 at 8.07.42 AM.png https://docs.google.com/file/d/0By8GtCCnLFX9WGgyWTRpbXdMQUU/edit?usp=drive_web The problem I have found is that when one builder is building a module I don't get insight into what it is doing while compiling that modules dependencies that were not prefetched by a different builder. This causes two problems. The first is that compilation time for some modules looks very long, even though most of it is in compiling their dependencies. The second is that I cannot tell what is going on when only the original threads are doing processing, and so it isn't obvious why other threads start up again. Is there a better way to instrument raco make? Hacky code: Instrumented compile: #lang racket/base (require setup/parallel-build racket/match) (define times (make-hash)) (parallel-compile-files (list /Users/endobson/proj/racket/plt/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/core.rkt) #:handler (λ (id type path-string msg out err) (define time (current-inexact-milliseconds)) (define ps (if (path? path-string) (path-string path-string) path-string)) (cond [(equal? type 'start) (hash-set! times (list ps id) time)] [(equal? type 'done) (hash-set! times (list ps id) (list (hash-ref times (list ps id)) time))]))) (for ([(name time) times]) (match-define (list start stop) time) (match-define (list file id) name) (write (list id file start stop)) (newline)) Plotter: #lang racket/base (require plot racket/match racket/list) (plot-new-window? #t) (define work-units (call-with-input-file* data.rktd (lambda (port) (let loop ([items empty]) (define item (read port)) (if (eof-object? item) items (loop (cons item items))) (define converted-work-units (for/list ([work-unit (in-list work-units)]) (match-define (list index file-name start stop) work-unit) (list (rectangles #:alpha 0 (list (list (ivl start stop) (ivl (- index 1/3) (+ index 1/3) #; (point-label (list (/ (+ start stop) 2) index) file-name #:anchor 'center #:point-size 0 (plot #:width 1500 converted-work-units) _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #28930: master branch updated
On Tue, Jun 24, 2014 at 3:17 PM, stch...@racket-lang.org wrote: stchang has updated `master' from 49ff6d3c84 to 500745f41b. http://git.racket-lang.org/plt/49ff6d3c84..500745f41b =[ One Commit ]= Directory summary: 7.5% pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/ 4.6% pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/ 6.6% pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/ 7.6% pkgs/typed-racket-pkgs/typed-racket-more/typed/racket/private/ 7.5% pkgs/typed-racket-pkgs/typed-racket-more/typed/racket/ 5.0% pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/fail/ 60.8% pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/ ~~ 500745f Stephen Chang stch...@racket-lang.org 2014-06-24 18:16 : | add typed/racket/async-channel : A pkgs/typed-racket-pkgs/typed-racket-more/typed/racket/async-channel.rkt A pkgs/typed-racket-pkgs/typed-racket-more/typed/racket/private/async-channel-wrapped.rkt A pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/fail/async-channel-contract.rkt C pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/{events.rkt = events-with-async-channel.rkt} (86%) C pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/{threads-and-channels.rkt = threads-and-async-channels.rkt} (50%) M .../scribblings/reference/libraries.scrbl | 1 + M .../static-contracts/combinators/derived.rkt| 3 ++- M .../typed-racket/base-env/base-types.rkt| 2 ++ M .../typed-racket/infer/infer-unit.rkt | 3 +++ M .../typed-racket-lib/typed-racket/rep/type-rep.rkt | 6 ++ M .../typed-racket-lib/typed-racket/types/abbrev.rkt | 2 ++ M .../typed-racket-lib/typed-racket/types/printer.rkt | 2 ++ M .../typed-racket-lib/typed-racket/types/subtype.rkt | 3 +++ M .../typed-racket/private/type-contract.rkt | 1 + M .../typed-racket/scribblings/reference/types.scrbl | 18 +- M .../typed-racket/succeed/make-top-predicate.rkt | 1 + M .../typed-racket/types/structural.rkt | 2 ++ =[ Overall Diff ]=== pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/libraries.scrbl ~~ --- OLD/pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/libraries.scrbl +++ NEW/pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/libraries.scrbl @@ -71,6 +71,7 @@ The following libraries are included with Typed Racket in the @defmodule/incl[typed/openssl/md5] @defmodule/incl[typed/openssl/sha1] @defmodule/incl[typed/pict] +@defmodule/incl[typed/racket/async-channel] @defmodule/incl[typed/rackunit] @defmodule/incl[typed/srfi/14] @defmodule/incl[typed/syntax/stx] pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/types.scrbl ~~ --- OLD/pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/types.scrbl +++ NEW/pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/types.scrbl @@ -4,7 +4,8 @@ numeric-tower-pict.rkt scribble/eval racket/sandbox) - (require (for-label (only-meta-in 0 [except-in typed/racket for])))] + (require (for-label (only-meta-in 0 [except-in typed/racket for]) + racket/async-channel))] @(define the-eval (make-base-eval)) @(the-eval '(require (except-in typed/racket #%top-interaction #%module-begin))) @@ -412,6 +413,21 @@ corresponding to @racket[trest], where @racket[bound] @ex[(lambda: ([x : Any]) (if (channel? x) x (error not a channel!)))] } +@defform[(Async-Channelof t)]{An @rtech{asynchronous channel} on which only @racket[t]s can be sent. +@ex[ +(require typed/racket/async-channel) +(ann (make-async-channel) (Async-Channelof Symbol)) +] +} + +@defidform[Async-ChannelTop]{is the type of an @rtech{asynchronous channel} with unknown + message type and is the supertype of all asynchronous channel types. This type typically + appears in programs via the combination of occurrence typing and + @racket[async-channel?]. +@ex[(require typed/racket/async-channel) +(lambda: ([x : Any]) (if (async-channel? x) x (error not an async-channel!)))] +} + @defform*[[(Parameterof t) (Parameterof s t)]]{A @rtech{parameter} of @racket[t]. If two type arguments are supplied, the first is the type the parameter accepts, and the second is the type returned.
Re: [racket-dev] Machinery for eliding contracts
On Tue, Jun 10, 2014 at 6:15 AM, Matthias Felleisen matth...@ccs.neu.edu wrote: On Jun 9, 2014, at 6:02 PM, Eric Dobson eric.n.dob...@gmail.com wrote: Eric, are you talking about changing the proxy values that wrap HO/mutable contracted values? Yes. I want the proxy values to include information about who agreed to the contract in addition to the contract agreed to. I actually realize that I might need more than just the contract agreed to because of how TR changes the generated contract to remove checks for what it guarantees, so that info is not in the contract. But I believe that can be added back as a structure property on the contract. Would some form of hash-consing contracts work here? -- Matthias I don't think so. But not sure exactly what you are proposing. The issue is that there are 4 contracts here and 2 of them currently do not exist at runtime. The 4 are TRs checks/promises on an export/import. (Using import for a value flowing into an exported function). The promise contracts do not currently exist as removing them was my previous optimization (They never fail). What I want to do is change the check on import from (array/c symbol?) to (if/c (protected? (array/c symbol?)) any/c (array/c symbol?)). Where (protected? x/c) checks if TR already promised something stronger than x/c. I believe that you are proposing that we can use the identity of the contract returned by value-contract to determine what the promised contract would have been. This does not work as (Array Symbol) and (Array Float) both get translated to (array/c any/c) for export, and we would want to lookup different promised contracts for them. We could use weak hash map as an extra field but that seems like it would be slow. _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Machinery for eliding contracts
One of the slowest parts when using TR is the contract boundary between untyped and typed code. Even with recent changes it still causes a large overhead. Example: #lang racket/load (module lib typed/racket (provide f g) (: f (Symbol - (Boxof Symbol))) (define (f x) (box x)) (: g ((Boxof Symbol) - Symbol)) (define (g x) (unbox x))) (module user-1 racket (provide go1) (require 'lib) (define (go1) (for ((i (in-range 20))) (g (f 'x) (module user-2 typed/racket (provide go2) (require 'lib) (define (go2) (for ((i (in-range 1))) (g (f 'x) (require 'user-1 'user-2) (for ((j 5)) (time (go1)) (time (go2))) It would be nice if the contract on the input to g could be elided. It seems like this could be done by using something like prop:contracted but that allowed accessing the parties that agreed to the contract. I'm imagining something like (lambda (v) (and (has-contract? v) (contracted-value-providing-side=? v 'the-typed-world) (contract-stronger? (value-contract v) new-contract))) One issue I see is that we need an unforgeable property that the value actually came from the typed world so we know that eliding the new contract is safe. Does this seem like a reasonable thing to support/do people see issues with it? Other related ideas I had were: A similar thing could be done if the same contract were being applied multiple times with the same blame parties. In that case the later contracts could be elided because they would error out in exactly the same cases with exactly the same messages. That in addition to not applying the new contract if it is weaker than the old contract, we remove the old contract (and access the unprotected value) if the new contract is stronger. In the case that they were the same contract this would mean that there would be no higher order contract checks while the typed code was executing. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Machinery for eliding contracts
On Mon, Jun 9, 2014 at 2:44 PM, Matthias Felleisen matth...@ccs.neu.edu wrote: On Jun 9, 2014, at 9:38 AM, Sam Tobin-Hochstadt sa...@cs.indiana.edu wrote: On Mon, Jun 9, 2014 at 3:19 AM, Eric Dobson eric.n.dob...@gmail.com wrote: It would be nice if the contract on the input to g could be elided. It seems like this could be done by using something like prop:contracted but that allowed accessing the parties that agreed to the contract. I'm imagining something like (lambda (v) (and (has-contract? v) (contracted-value-providing-side=? v 'the-typed-world) (contract-stronger? (value-contract v) new-contract))) One issue I see is that we need an unforgeable property that the value actually came from the typed world so we know that eliding the new contract is safe. Does this seem like a reasonable thing to support/do people see issues with it? It seems like this could be simplified a little just by allowing contract parties to be compared. IOW, at the point where you're writing that function, we have two contracts, and we need to know if the negative party of one is the positive party of the other. Then you don't need to worry about unforgeability, I think. Well some code could swap identities on such things. Not accidentally. Plus I think this would eliminate the anticipated benefits if there are chains of TR modules involved. I think Eric just needs to know whether something came out of the TR world and flows back w/o being touched. Yes I think this is what I want. TR should consider all typed modules as being the same. ;; --- Eric, are you talking about changing the proxy values that wrap HO/mutable contracted values? Yes. I want the proxy values to include information about who agreed to the contract in addition to the contract agreed to. I actually realize that I might need more than just the contract agreed to because of how TR changes the generated contract to remove checks for what it guarantees, so that info is not in the contract. But I believe that can be added back as a structure property on the contract. -- Matthias _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Slow contracts
Splitting this out because this is actually a different issue. This is about us generating slow contracts. There are two things in play here. One is that TR doesn't use the new lazy parts of struct/dc. This would require changing struct contracts from flat contracts to chaperone-contracts. Given that I think we are going to need to change struct contracts to sometimes be chaperone contracts anyways for soundness that might not be a huge loss. #lang racket (struct my-cons (fst snd)) (define (list-my-list xs) (if (empty? xs) xs (my-cons (first xs) (list-my-list (rest xs) (define (my-first xs) (if (empty? xs) (error 'bad) (my-cons-fst xs))) (define c1 (recursive-contract (struct/dc my-cons [fst () #:flat any/c] [snd () #:flat (or/c null c1)]) #:flat)) (define c2 (recursive-contract (struct/dc my-cons [fst () #:flat any/c] [snd () #:chaperone #:lazy (or/c null c2)]) #:chaperone)) (define/contract (f1 xs) (- c1 any) (my-first xs)) (define/contract (f2 xs) (- c2 any) (my-first xs)) (define lst1 (list-my-list '(1 2))) (for ([_ (in-range 5)]) (time (for ([_ (in-range 1)]) (my-first lst1 (for ([_ (in-range 5)]) (time (for ([_ (in-range 1)]) (f1 lst1 (for ([_ (in-range 5)]) (time (for ([_ (in-range 1)]) (f2 lst1 (define lst2 (list-my-list '(1 2 3 4 5 6 7 8 9))) (for ([_ (in-range 5)]) (time (for ([_ (in-range 1)]) (my-first lst2 (for ([_ (in-range 5)]) (time (for ([_ (in-range 1)]) (f1 lst2 (for ([_ (in-range 5)]) (time (for ([_ (in-range 1)]) (f2 lst2 f2 is constant where f1 grows. And the other is that TR cannot follow the logic that you use to show that just running my-cons? is as strong as checking the entire list. If we could do that reduction we would get a large speedup. On Mon, Jun 9, 2014 at 10:01 AM, Neil Toronto neil.toro...@gmail.com wrote: On 06/09/2014 10:25 AM, Neil Toronto wrote: On 06/09/2014 01:19 AM, Eric Dobson wrote: Does this seem like a reasonable thing to support/do people see issues with it? I can only speak on reasonableness, and my answer is emphatically YES. Typed Racket is a great language in which to define and use data structures: access is very fast, and many properties are checked statically. But accessor performance suffers badly when the data types are used in untyped Racket. If access uses higher-order functions (e.g. math/array), wrapping the functions slows access by a very high constant factor. If the data structures are first-order, every O(1) access becomes O(n). I recently had to work around this in Plot when I needed an untyped module to be able to operate on typed BSP trees. I ended up making a typed weak hash map from BSP tree handles (gensyms) to BSP trees, and writing a new untyped API for operating on trees using handles. It was ugly. If the untyped and typed modules had been too tightly coupled, it would have been impossible. IIUC, your proposal would make untyped use of typed data structures actually feasible for real-world use. So again, YES. Here's a concrete example, using Typed Racket to define a new list type. #lang racket (module typed-defs typed/racket (provide list-my-list my-first) (define-type (My-Listof A) (U Null (my-cons A))) (struct (A) my-cons ([fst : A] [snd : (My-Listof A)]) #:transparent) (: list-my-list (All (A) (- (Listof A) (My-Listof A (define (list-my-list xs) (if (empty? xs) xs (my-cons (first xs) (list-my-list (rest xs) (: my-first (All (A) (- (My-Listof A) A))) (define (my-first xs) (if (empty? xs) (error 'bad) (my-cons-fst xs))) ;; Timing loop speed is very fast and O(1) (define lst (list-my-list '(1))) (for ([_ (in-range 5)]) (time (for ([_ (in-range 100)]) (my-first lst ) (require 'typed-defs) ;; Timing loop speed is very slow and O(n) (define lst (list-my-list '(1))) (for ([_ (in-range 5)]) (time (for ([_ (in-range 100)]) (my-first lst I get 4ms for the timing loop in the typed module, and 620ms for the timing loop in the untyped module, so the constant factor is about 150. When I change the test data from '(1) to '(1 2), the untyped module's timing loop takes about 1010ms. The contract boundary has changed the asymptotic complexity of `my-first' from O(1) to O(n). Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #28817: master branch updated
I think that there was a miscomunication over the word context and other than that we are in agreement. The context in context-free has not the same as the logical context, and the context free rewrite rules you are proposing have the logical context as part of them. My claim was that without the logical context (just over the ast/bytecode) we would be very limited, and that we absolutely need it. On Thu, May 29, 2014 at 7:40 AM, Matthias Felleisen matth...@ccs.neu.edu wrote: Let me spell out my cryptic comment. 1. I said that a bunch of optimizations are simple context-free rewrite rules. 2. I also said that what we really need to keep track of contexts. If you think of Γ ⊢ e ~ e' if Γ ⊨ e ~ e' as the general form of optimizing rewrites, then the key generalization over 2 is the context Γ. 3. Matthew calls this 'type inference' because that's where Γs like the above are most common. But Γ could also contain statements such as 'f = \x.e, f \not∈ AV(P)' which then gives rise to inlining. [Optimizations really are about the logic of the program, if you want sound ones.] 4. In general optimizers gather a lot of knowledge about contexts that they exploit, and front-ends do so mostly for type checking reasons. That's why the two are often conflated. But you really do want more than type info in the context. 5. Our current major problem is that the type checker does not communicate the type checking information from the front end to the optimizer. The general formulation is that #lang-languages have only a few hooks to tell the compiler what they figured out. 6. Now in this context, my Perhaps remark means two distinct things: -- it would be wonderful if we could centralize rewriting rules in one place through one mechanism, and syntax-* looks promising That does not mean that these things are part of the program. I could see using some syntax-* used to generate code for the current optimizer. [I know that this is a stretch.] -- it would be even wonderfuller if (a) this centralized mechanism came with a mechanism for collecting context information and (b) if #lang languages had a mechanism to communicate the contextual information they have gathered to this central rewriter. This would avoid leakage [citation to Julia omitted] Does this make sense? Okay I understand that I am laying out a research agenda to improve our infrastructure. Don't bother to tell me, I know. It's my job. Now I have to look for someone who wishes to write this very real dissertation. -- Matthias On May 28, 2014, at 10:50 PM, Eric Dobson eric.n.dob...@gmail.com wrote: Cases like this make me think that we need something stronger than context free rewrite rules over the ast/bytecode. On May 29, 2014, at 1:19 AM, Matthew Flatt mfl...@cs.utah.edu wrote: Ok, I see. I'll revise my comment to this would be better done with a more general form of type inference, leaving out the claim of where that inference should live. I don't currently know how to do it other than building inference into the complier. Matthias's plug-in rules sounds like a point that we hope to eventually reach through macros as a compiler API. On Sam's general question, I agree that there's no simple answer. Some languages/libraries will provide particular optimizations that are made possible by syntactic constraints. A type system is a particularly fancy syntactic constraint, and it can offer particularly fancy optimizations (such as splitting complex numbers). Syntactic constraints are the reason to have multiple languages and a choice, instead of just one language and compiler. I suppose a single compiler could try several languages and find the one that a program matches syntactically, but often the constraints are complex enough that programs won't fit without careful attention. In that case, a programmer knows (and can declare, and would really prefer to declare and get feedback on) the restricted form that they intend to use for a program. Meanwhile, we have a lot of code in plain Racket. Optimizing by hand is so painful that even writing more C code (for the current optimizer) seems like a better trade-off than hand-optimization. I imagine that the PR was provoked by actual code somewhere. When the compiler is finally itself implemented in Racket, the balance should shift even further toward optimizations for plain Racket, whether or not we find better a macro API for optimizations. At Wed, 28 May 2014 19:50:50 -0700, Eric Dobson wrote: I don't think that TR should provide the majority of the optimizations in its current form because it has to run before inlining, and this limits what it can do. Here is an example program: #lang typed/racket (: my-sequence-map (All (A B) (case- ((A - B) (Vectorof A) - (Vectorof B)) ((A - B) (Listof
Re: [racket-dev] [plt] Push #28817: master branch updated
I don't think that TR should provide the majority of the optimizations in its current form because it has to run before inlining, and this limits what it can do. Here is an example program: #lang typed/racket (: my-sequence-map (All (A B) (case- ((A - B) (Vectorof A) - (Vectorof B)) ((A - B) (Listof A) - (Listof B) (define (my-sequence-map f s) (if (vector? s) (vector-map f s) (map f s))) (my-sequence-map add1 (vector 1 2 3)) (my-sequence-map add1 (list 1 2 3)) I would like this to be optimized to: (vector-map add1 (vector 1 2 3)) (map add1 (list 1 2 3)) I think this case of code will be very common if we move to a world where we work over generic sequences/datastructures, and specializing the call sites will be a big win. TR cannot do this optimization because it requires inlining. And the current version of racket cannot optimize this either because it becomes (let ((s (vector 1 2 3))) (if (vector? s) (vector-map add1 s) (map add1 s))) Which isn't optimized because when we see (vector? s) we don't know that s is a vector as Mathew's change only works if the constructor is inline (i.e. of the form (vector? (vector 1 2 3))). Cases like this make me think that we need something stronger than context free rewrite rules over the ast/bytecode. On Wed, May 28, 2014 at 6:36 PM, Matthias Felleisen matth...@ccs.neu.edu wrote: Perhaps the right answer is to organize the optimizer as a rewriting engine to which other devs can add rules as they discover them (and their absence in the existing rule set). -- Indeed, one could then even have programmers extend the rule set for a specific program (though then we have to worry about soundness). With syntax-* we should have no problem formulating the mostly context-free rules and we could figure out in addition how to keep track of contexts. (This is the other half of what we used to call the 'open compiler' idea at Rice.) -- Matthias On May 28, 2014, at 9:25 PM, Sam Tobin-Hochstadt wrote: On Thu, May 29, 2014 at 4:26 AM, mfl...@racket-lang.org wrote: | optimizer: ad hoc optimization of predicates applied to constructions | | This is probably more of a job for Typed Racket, but maybe it's | useful to detect some obviously unnecessary allocations of lists, etc. I think this is a useful discussion to have. I think there are two questions to answer: 1. Do we want people to need to use a particular language for greater optimization, whether that's Typed Racket or some other optimizer? 2. How should we optimize the code that Typed Racket depends on? Since this is a finite amount, we could manually do this, but we might not want to. Of course, in the absence of other constraints, it would be great to have infinite optimizations at every level. But in our actual setting, I don't know what I think the answer to either of these questions is. Sam _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [DrDr] R28812 (timeout 1) (unclean 6) (stderr 7) (changes 17)
Ok, clarification its not the binding of values. Its the annotation added by the #{ : } form which doesn't work if the unit tests are compiled ahead of time. I'm guessing that is because in that case the syntax obects go through zo-serialization and thus lose the property. On Tue, May 27, 2014 at 9:15 PM, Eric Dobson eric.n.dob...@gmail.com wrote: +dev in case others have likely insights. Recap: TR's with contracts unit test is failing. I have diagonsed the issue to the bindings in the test case are not the same as expected, and syntax parse doesn't match them. I have made a reasonably minimal test case, and figure out that the line that is causing it is (use-compiled-filepaths null). I believe that this shouldn't cause semantic changes, so I'm wondering if any one can give any insight as to why this could cause problems. Reduced test case (Checkout the branch): https://github.com/shekari/racket/tree/namespace-issues Run: racket -l tests/typed-racket/with-tr-contracts Code that is not matching the binding: https://github.com/shekari/racket/blob/namespace-issues/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/tc-app/tc-app-values.rkt#L45 Actual rackunit test case: https://github.com/shekari/racket/blob/namespace-issues/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/unit-tests/typecheck-tests.rkt#L481 On Tue, May 27, 2014 at 8:04 PM, Eric Dobson eric.n.dob...@gmail.com wrote: Confirmed that this is not about contracts, it is about the namespacing that is being done. Some how the `values` that is in the test case doesn't have the right binding when done throught with-tr-contracts. This causes us to use the regular app typechecking instead of the one specialized for values which is why the result changes. I'm actually suprised that no other tests fail. On Tue, May 27, 2014 at 9:10 AM, Eric Dobson eric.n.dob...@gmail.com wrote: I'm not able to replicate this on my local machine, nor does it make sense for one unit test to fail because of a bad value is returned because contracts are turned on. Any insight into what could be causing this? On Tue, May 27, 2014 at 9:07 AM, d...@racket-lang.org wrote: DrDr has finished building push #28812 after 3.40h. http://drdr.racket-lang.org/28812/ A file you are responsible for has a condition that may need inspecting. stderr: http://drdr.racket-lang.org/28812/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/with-tr-contracts.rkt _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #28799: master branch updated
I don't think you would be interested as it is entirely internal to TR. We have a bunch of functions, (infer, subtype, var-promote, var-demote, substitute, etc) that need to traverse the type and do things on it. Currently many of them are hardcoded match loops, and this is work to make them less repetative, and easier to add new cases to all of them. Examples of code that I want to eventually replace: https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/subtype.rkt#L481 On Mon, May 26, 2014 at 4:11 PM, Neil Toronto neil.toro...@gmail.com wrote: On 05/26/2014 09:21 AM, endob...@racket-lang.org wrote: 9efa4af Eric Dobson endob...@racket-lang.org 2014-05-16 08:13 : | Make initial version of structural type recursion, and use it. : A pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/structural.rkt M .../typed-racket/infer/promote-demote.rkt | 66 +++- M .../typed-racket/rep/type-rep.rkt | 8 ++- I'm trying to figure out how excited I should be about this. Can you explain it a little? Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Release Announcement for v6.0.1
6f56948cff75dd4497b742ae01cd5df18c654e6f - The contract boundary between typed/untyped modules is much less expensive. dd8b646b0b3a0fd7905467f275f0f786eac958dd - Occurrence typing now works better with when/unless. Example: (let ((x (read))) (unless (number? x) (error 'bad-input)) (add1 x)) On Thu, May 1, 2014 at 2:16 PM, Neil Toronto neil.toro...@gmail.com wrote: On 05/01/2014 11:49 AM, Ryan Culpepper wrote: The release announcement sketch that I have so far is below. Please mail me new items and/or edits. -- neil: - plot 3D BSP tree (a515e7ce) - PDF/PS scaling changed to 1.0x1.0 (efc46ded) - Plot correctly renders intersecting 3D graphs and non-grid-aligned 3D rectangles. - Elements in plots output in PDF/PS format have the same relative scale as in other formats. In particular, it is not necessary to adjust `plot-font-size` to make PDF plots look the same as PNG. Neil _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #28619: master branch updated
Doesn't this make the dead clauses return void the function instead of void the value? Not that they ever should run. On Fri, Apr 25, 2014 at 10:45 AM, stamo...@racket-lang.org wrote: stamourv has updated `master' from b40619ffd5 to ce3033a0c7. http://git.racket-lang.org/plt/b40619ffd5..ce3033a0c7 =[ One Commit ]= Directory summary: 52.9% pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/ 47.0% pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/ ~~ ce3033a Vincent St-Amour stamo...@racket-lang.org 2014-04-25 13:40 : | Keep dead case-lambda clauses around to avoid changing arity. | | Closes PR14468. : A pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/dead-case-lambda.rkt M .../tests/typed-racket/optimizer/tests/unboxed-for.rkt | 2 +- M .../typed-racket-lib/typed-racket/optimizer/dead-code.rkt | 10 +++--- =[ Overall Diff ]=== pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/dead-code.rkt --- OLD/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/dead-code.rkt +++ NEW/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/optimizer/dead-code.rkt @@ -49,9 +49,13 @@ (begin0 (case-lambda #,@(for/list ((formals (in-syntax #'(formals ...))) - (bodies (in-syntax #'(bodies ...))) - #:unless (dead-lambda-branch? formals)) - (cons formals (stx-map (optimize) bodies + (bodies (in-syntax #'(bodies ... + (if (dead-lambda-branch? formals) + ;; keep the clause (to have a case-lambda with the right arity) + ;; but not the body (to make the function smaller for inlining) + ;; TODO could do better, and keep a single clause per arity + (list formals #'(void)) ; return type doesn't matter, should never run + (cons formals (stx-map (optimize) bodies) ;; We need to keep the syntax objects around in the generated code with the correct bindings ;; so that CheckSyntax displays the arrows correctly #,@(for/list ((formals (in-syntax #'(formals ...))) pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/dead-case-lambda.rkt --- /dev/null +++ NEW/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/dead-case-lambda.rkt @@ -0,0 +1,19 @@ +#;#; +#END +TR opt: dead-case-lambda.rkt 4:10 () -- dead case-lambda branch +TR opt: dead-case-lambda.rkt 6:10 (d . rst) -- dead case-lambda branch +END +#END +(arity-at-least 0) + +END + +#lang typed/racket +#reader tests/typed-racket/optimizer/reset-port + +(procedure-arity + (ann (case-lambda + [() (void)] + [(d) (void)] + [(d . rst) (void)]) + (Any - Any))) pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-for.rkt ~~~ --- OLD/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-for.rkt +++ NEW/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/optimizer/tests/unboxed-for.rkt @@ -2,7 +2,6 @@ #END TR opt: unboxed-for.rkt 2:0 (for/fold: : Float-Complex ((sum : Float-Complex 0.0+0.0i)) ((i : Float-Complex (quote (1.0+2.0i 2.0+4.0i (+ i sum)) -- call to fun with unboxed args TR opt: unboxed-for.rkt 2:0 (for/fold: : Float-Complex ((sum : Float-Complex 0.0+0.0i)) ((i : Float-Complex (quote (1.0+2.0i 2.0+4.0i (+ i sum)) -- fun - unboxed fun -TR opt: unboxed-for.rkt 2:0 (for/fold: : Float-Complex ((sum : Float-Complex 0.0+0.0i)) ((i : Float-Complex (quote (1.0+2.0i 2.0+4.0i (+ i sum)) -- unbox float-complex TR opt: unboxed-for.rkt 2:0 (for/fold: : Float-Complex ((sum : Float-Complex 0.0+0.0i)) ((i : Float-Complex (quote (1.0+2.0i 2.0+4.0i (+ i sum)) -- unboxed call site TR opt: unboxed-for.rkt 2:0 (for/fold: : Float-Complex ((sum : Float-Complex 0.0+0.0i)) ((i : Float-Complex (quote (1.0+2.0i 2.0+4.0i (+ i sum)) -- unboxed call site TR opt: unboxed-for.rkt 2:0 (for/fold: : Float-Complex ((sum : Float-Complex 0.0+0.0i)) ((i : Float-Complex (quote (1.0+2.0i 2.0+4.0i (+ i sum)) -- unboxed let bindings @@ -17,6 +16,7 @@ TR opt: unboxed-for.rkt 2:53 0.0+0.0i -- unboxed literal TR opt: unboxed-for.rkt 3:13 i -- unboxed complex variable TR opt: unboxed-for.rkt 3:13 i -- unboxed complex variable TR opt: unboxed-for.rkt 3:33 (quote
Re: [racket-dev] Regular expression types [was Re: [racket-bug] all/14455: wrong type for hash]
Asumu has a rough draft of a commit that would allow this to work, I don't know the current status though. https://github.com/plt/racket/pull/564 I was thinking about the problem and I think our current union types and recursive types covers a lot of ground. For example as one user wanted to do, exactly one vector and bunch of numbers: (Rec T (U (Cons (Vectorof Real) (Listof Real)) (Cons Real T))). On Sun, Apr 20, 2014 at 11:38 AM, Matthias Felleisen matth...@ccs.neu.edu wrote: This might be one of those areas where we could 'generalize' gradual typing. On Apr 19, 2014, at 7:37 PM, Sam Tobin-Hochstadt wrote: On Sat, Apr 19, 2014 at 7:24 PM, Neil Toronto neil.toro...@gmail.com wrote: Are there type systems that can? It seems like you could specify this type and similar ones using regular expressions. There is lots of work on types for XML specification that can handle this sort of thing, I believe, but not specifically in the context of function arguments. Note that TR can handle alternating types just fine in lists, for example -- it's just that the function argument sequence is different. Sam _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Compile cache being incorrect
Also this is a poor solution for me because `raco make` compiles all the dependencies serially. I have also tried doing 'raco setup -D' for the packages I am dependent on but that has the issue of compiling everything in those packages which is over kill (and thus slower than needed). My end goal is a very fast edit/test loop (~100ms), which may be impossible but I want to be aggressive. On Sat, Apr 5, 2014 at 8:14 AM, Robby Findler ro...@eecs.northwestern.edu wrote: Yes, Sam. I don't think anyone is happy with the status quo. Perhaps the tradeoffs have changed since last time a careful investigation happened. Robby On Saturday, April 5, 2014, Sam Tobin-Hochstadt sa...@cs.indiana.edu wrote: I don't think this is a good answer for Racket. Certainly the docs don't say that you need to always do this if you want your program to work right. If Racket doesn't work right in the presence of stale compiled filed, then it should just error in those cases, rather than doing the wrong thing. Of course it would be better to work correctly in that case, but this is a hard problem, and it's reasonable to not have a solution. But having the system act like it works when it doesn't is worse. Sam On Sat, Apr 5, 2014 at 8:13 AM, Robby Findler ro...@eecs.northwestern.edu wrote: raco make x.rkt racket x.rkt Robby On Fri, Apr 4, 2014 at 11:16 PM, Eric Dobson eric.n.dob...@gmail.com wrote: Great that explains it and with that information I was able to simplify my test case to tmp.rkt #lang racket (require tmp2.rkt) (define-syntax (go stx) (foo)) (go) tmp2.rkt #lang racket (provide (for-syntax foo)) (begin-for-syntax (define (foo) #'3)) So now the question is how do I run my code so as to not be bit by this? I want a command to run my program that is both fast to run and correct with regards to my source. My previous assumption was that the zo file's logic was safe if I wasn't trying to break it but I now know better. Is my only option to either always compile or never compile? On Fri, Apr 4, 2014 at 7:15 AM, Matthew Flatt mfl...@cs.utah.edu wrote: If I understand the question: * With 34c3eed615, pr12644.rkt can compile and run. * With d29df205f7, pr12644.rkt fails to compile. * A bytecode form of pr12644.rkt compiled with 34c3eed615 can still run in d29df205f7, because run-time support for pr12644.rkt didn't change. * When you tell `racket` to run pr12644.rkt, it will use a .zo for each of pr12644.rkt and its dependencies as long each individual .zo file has a newer timestamp than its .rkt file. That is, the only timestamp comparisons are on individual .rkt and .zo pairs. * When you tell `raco make` to build pr12644.rkt, it checks dependencies (via .dep file) and compares a .rkt file's timestamp against the times of all of its dependencies, instead of just checking individual .rkt and .zo pairs. That's why a `raco make` in d29df205f7 tries to recompile pr12644.rkt. At Thu, 3 Apr 2014 09:41:19 -0700, Eric Dobson wrote: I have seen multiple times changes in TR not getting properly propogated to TR programs in my debugging, and I finally have found a repeatable example. I am under the impression that if I compile a file and then change a (transitive) dependency of it, then it should have to be recompiled, but I am not seeing that. Steps to reproduce: git checkout 34c3eed6155765a1e457f69194786575128a13a5 raco setup -D typed-racket typed raco make pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/pr12644.rkt racket -l tests/typed-racket/succeed/pr12644 The test should run successfully and output '(6 7 8 9) Now make the change (rolling forward one commit): git checkout d29df205f7bb8347f60c82206b74e3e167e2de24 racket -l tests/typed-racket/succeed/pr12644 raco make pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/pr12644.rkt The test runs the first time successfully but fails if you try to compile it again. Can someone explain why this is not working like I expect? _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Compile cache being incorrect
Great that explains it and with that information I was able to simplify my test case to tmp.rkt #lang racket (require tmp2.rkt) (define-syntax (go stx) (foo)) (go) tmp2.rkt #lang racket (provide (for-syntax foo)) (begin-for-syntax (define (foo) #'3)) So now the question is how do I run my code so as to not be bit by this? I want a command to run my program that is both fast to run and correct with regards to my source. My previous assumption was that the zo file's logic was safe if I wasn't trying to break it but I now know better. Is my only option to either always compile or never compile? On Fri, Apr 4, 2014 at 7:15 AM, Matthew Flatt mfl...@cs.utah.edu wrote: If I understand the question: * With 34c3eed615, pr12644.rkt can compile and run. * With d29df205f7, pr12644.rkt fails to compile. * A bytecode form of pr12644.rkt compiled with 34c3eed615 can still run in d29df205f7, because run-time support for pr12644.rkt didn't change. * When you tell `racket` to run pr12644.rkt, it will use a .zo for each of pr12644.rkt and its dependencies as long each individual .zo file has a newer timestamp than its .rkt file. That is, the only timestamp comparisons are on individual .rkt and .zo pairs. * When you tell `raco make` to build pr12644.rkt, it checks dependencies (via .dep file) and compares a .rkt file's timestamp against the times of all of its dependencies, instead of just checking individual .rkt and .zo pairs. That's why a `raco make` in d29df205f7 tries to recompile pr12644.rkt. At Thu, 3 Apr 2014 09:41:19 -0700, Eric Dobson wrote: I have seen multiple times changes in TR not getting properly propogated to TR programs in my debugging, and I finally have found a repeatable example. I am under the impression that if I compile a file and then change a (transitive) dependency of it, then it should have to be recompiled, but I am not seeing that. Steps to reproduce: git checkout 34c3eed6155765a1e457f69194786575128a13a5 raco setup -D typed-racket typed raco make pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/pr12644.rkt racket -l tests/typed-racket/succeed/pr12644 The test should run successfully and output '(6 7 8 9) Now make the change (rolling forward one commit): git checkout d29df205f7bb8347f60c82206b74e3e167e2de24 racket -l tests/typed-racket/succeed/pr12644 raco make pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/pr12644.rkt The test runs the first time successfully but fails if you try to compile it again. Can someone explain why this is not working like I expect? _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Internal crashes
I have seen a crash that looks like this twice recently. Seg fault (internal error during gc) at 0x19fd08000 I reran the same program and would not get the crash again. Is there anything that I can do to turn something like this into an actionable/useful bug report? _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] DrDr hung?
DrDr seems to be behind by about 8 pushes (in terms of what it is showing in the UI) currently and is stuck running on push 28468 for 36 hours. _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Compile cache being incorrect
I have seen multiple times changes in TR not getting properly propogated to TR programs in my debugging, and I finally have found a repeatable example. I am under the impression that if I compile a file and then change a (transitive) dependency of it, then it should have to be recompiled, but I am not seeing that. Steps to reproduce: git checkout 34c3eed6155765a1e457f69194786575128a13a5 raco setup -D typed-racket typed raco make pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/pr12644.rkt racket -l tests/typed-racket/succeed/pr12644 The test should run successfully and output '(6 7 8 9) Now make the change (rolling forward one commit): git checkout d29df205f7bb8347f60c82206b74e3e167e2de24 racket -l tests/typed-racket/succeed/pr12644 raco make pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/succeed/pr12644.rkt The test runs the first time successfully but fails if you try to compile it again. Can someone explain why this is not working like I expect? _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #28453: master branch updated
My understanding is that since it is pushed to master, you don't, as it can mess up other peoples repositories. Given that there are no other commits besides yours on top of it, it may not be impossible, but probably not worth the effort. Some one may correct me though. On Tue, Apr 1, 2014 at 9:30 AM, Neil Toronto neil.toro...@gmail.com wrote: On 04/01/2014 02:08 AM, ntoro...@racket-lang.org wrote: ntoronto has updated `master' from 8a93eeb52b to a515e7cee1. http://git.racket-lang.org/plt/8a93eeb52b..a515e7cee1 =[ 2 Commits ]== Directory summary: 90.9% pkgs/plot-pkgs/plot-lib/plot/private/plot3d/ 5.1% pkgs/plot-pkgs/plot-test/plot/tests/ 3.8% pkgs/plot-pkgs/ ~~ 97d20c9 Neil Toronto neil.toro...@gmail.com 2014-03-27 09:16 : | Checkpoint : M .../plot-lib/plot/private/plot3d/plot-area.rkt| 119 ++- Whoops, forgot to rewrite history. How do I fix this? Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #28450: master branch updated
Do we have a performance test case which shows improvment with this change? On Mon, Mar 31, 2014 at 3:21 PM, as...@racket-lang.org wrote: asumu has updated `master' from 6722b7a71e to 92b0e86ed1. http://git.racket-lang.org/plt/6722b7a71e..92b0e86ed1 =[ One Commit ]= Directory summary: 100.0% pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/base-env/ ~~ 92b0e86 Asumu Takikawa as...@racket-lang.org 2014-03-31 17:46 : | Refactor TR `define` to avoid a performance bug | | After commit 3d177e454ea3634060a4b9b0814f588bc7c74e49 | running the main `math.scrbl` file would show peak memory | usage of around 600-700MB when before it was around 400MB. | | The proximal cause appears to be the expansion of TR | definitions, which added an extra `begin` in some cases, | combined with redefinitions at the top-level. I don't | know the core cause yet. | | Thanks to Matthew for pointing out the issue and to | Vincent for helping with debugging. : M .../typed-racket-lib/typed-racket/base-env/prims.rkt | 15 +-- =[ Overall Diff ]=== pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/base-env/prims.rkt ~~~ --- OLD/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/base-env/prims.rkt +++ NEW/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/base-env/prims.rkt @@ -1218,15 +1218,18 @@ This file defines two sorts of primitives. All of them are provided into any mod (define-syntax (-define stx) (syntax-parse stx #:literals (:) -;; the first two cases are actually subsumed by the last, +;; the first three cases are actually subsumed by the last, ;; but manually expanding to using the : annotation form ;; produces better error messages on duplicate annotations +;; +;; note, these first two cases can be collapsed into one +;; but we keep them separate because in some cases it ruins +;; typechecking performance to merge them. +[(-define nm:id body) + (syntax/loc stx (define nm body))] [(-define nm:id return:return-ann body) - (define/with-syntax maybe-ann - (if (attribute return.type) - #'(: nm return.type) - #'(void))) - (syntax/loc stx (begin maybe-ann (define nm body)))] + (quasisyntax/loc stx + (begin (: nm #,(attribute return.type)) (define nm body)))] [(-define vars:lambda-type-vars nm:id : ty body) (define/with-syntax type (syntax/loc #'ty (All vars.type-vars ty))) _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [DrDr] R28413 (timeout 4) (unclean 16) (stderr 35) (changes 22)
Looks like what is actually happening is that redex is actually generating reals for this program now. #lang racket (require redex/reduction-semantics) (define-language tr-arith [n real]) (redex-check tr-arith n #t #:prepare (lambda (x) (displayln x) x)) Before we were only getting small integers. On Wed, Mar 26, 2014 at 9:46 AM, Eric Dobson eric.n.dob...@gmail.com wrote: This push has started breaking the random TR tests. I think the issue is that TR assumed that redex wouldn't generate so large numbers that it exceeded the flonum range. Could that have changed in this commit? Or changed so that were generated earlier in random testing? If so the issue is definitely on the TR side, but just want to confirm that the theory is likely. On Wed, Mar 26, 2014 at 4:58 AM, d...@racket-lang.org wrote: DrDr has finished building push #28413 after 1.20h. http://drdr.racket-lang.org/28413/ A file you are responsible for has a condition that may need inspecting. stderr: http://drdr.racket-lang.org/28413/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/tr-random-testing.rkt unclean: http://drdr.racket-lang.org/28413/pkgs/typed-racket-pkgs/typed-racket-test/tests/typed-racket/tr-random-testing.rkt _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Changing the default error display handler to use
Yes the default error display handler. Ok, I'll put this on my list of things to do, and hopefully have a version for review at some point. On Thu, Mar 13, 2014 at 7:22 PM, Robby Findler ro...@racket-lang.org wrote: You'll want to check DrRacket in both Debugging and No Debugging and Profiling mode to see if you're happy with the results (and I can help change them if you're not happy with them). Robby On Thu, Mar 13, 2014 at 8:34 PM, Matthew Flatt mfl...@cs.utah.edu wrote: At Wed, 12 Mar 2014 18:05:03 -0700, Eric Dobson wrote: A common issue I have is that the default error handler does not display error message's exn:srcloc if it has it [...] Is this reasonable to add to the default error handler, and if so do people have suggestions on the format? You mean the default error display handler, right? I think this change may be worth a try, but there are many exception-generating, exception-handling, and exception-printing parameters to worry about, both in their interactions and how they're currently used. For example, does DrRacket use the default error display handler? If so, it will start printing source locations that it's already showing a different way, and I think that's not what you intend. Or some other program harness might be worse off if the default display error handler starts showing source locations. Then again, the whole point is that you want to change the display of errors. Trying to change some things and not changes others --- and having enough extension points to accommodate certain combinations of changes and non-changes --- is why the existing set of parameters and handlers is complex. I will not be surprised if we end up with yet another parameter here. If the change makes sense, probably the handler should not print the first returned source location for `exn:fail:read`, `exn:fail:syntax`, and `exn:fail:contract:variable` exceptions --- because that location is supposed to be built into the error-message text, unless the `error-print-source-location` parameter has a false value. Awkward, I know; see the previous paragraph. The right format is likely to print an extra field: detail, similar to the way that the default error display handler prints context lines (if the `error-context-display-depth` parameter is not 0). I imagine that the source-location lines should precede the context lines, but follow the exception's error message. _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Changing the default error display handler to use exn:srclocs
A common issue I have is that the default error handler does not display error message's exn:srcloc if it has it racket -e (require racket/match) -e (match 2) = match: no matching clause for 2 context...: /Users/endobson/proj/rnacket/plt/racket/collects/racket/match/runtime.rkt:21:0: match:error But no information about what match raised the issue. The handler in DrRacket uses this info nicely in the buttons that it provides and the highlighting. Is this reasonable to add to the default error handler, and if so do people have suggestions on the format? My current .racketrc has (let ((old-error-display-handler (error-display-handler))) (error-display-handler (λ (str exn) (when (exn:srclocs? exn) (for ((srcloc ((exn:srclocs-accessor exn) exn))) (displayln (source-location-string srcloc (old-error-display-handler str exn) Which is a hack but works for my interactive use. It doesn't work for when I run a program on its own, and I don't see a way to configure anything to do that. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #27909: master branch updated
The changes to TR contract generation are now in at HEAD. If you can find any cases where contracts are still slowing programs down by a lot I'd like to take a look at them. (Excepting the case of structs where I know it is still an issue). On Thu, Dec 12, 2013 at 10:52 AM, Robby Findler ro...@eecs.northwestern.edu wrote: Re-reading your message I see that you're not actually asserting something different from what I said, but just for some precision here I wish to point out that I wasn't basing my opinion on intuition from the code, but on some microbenchmark timings. (There was a much more substantial difference yesterday because the loop inside any-wrap/c wasn't as cheap as it could have been.) I'd be interested to see if your improvements to type-contract improve the situation any! I expect they will make things better again for the Number case, but at the moment, there isn't a big difference. Program 1: #lang racket/base (module m typed/racket/base (: f (Any - Any)) (define (f x) 1) (provide f)) (require 'm) (time (for ([x (in-range 2)]) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7))) Timings: cpu time: 142 real time: 142 gc time: 8 cpu time: 144 real time: 144 gc time: 7 cpu time: 144 real time: 143 gc time: 6 cpu time: 142 real time: 142 gc time: 6 cpu time: 142 real time: 142 gc time: 7 cpu time: 146 real time: 146 gc time: 6 Program 2: #lang racket/base (module m typed/racket/base (: f (Any - Integer)) (define (f x) 1) (provide f)) (require 'm) (time (for ([x (in-range 2)]) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7))) Timings: cpu time: 139 real time: 138 gc time: 7 cpu time: 145 real time: 144 gc time: 7 cpu time: 140 real time: 140 gc time: 6 cpu time: 151 real time: 150 gc time: 6 cpu time: 139 real time: 138 gc time: 6 cpu time: 139 real time: 139 gc time: 8 On Thu, Dec 12, 2013 at 12:33 PM, Eric Dobson eric.n.dob...@gmail.com wrote: any-wrap/c still requires the check for one value, while any (which is from Number not Any) does not. So I would still guess at Number being faster, but Robby's changes may make it so that inlining and dead code elimination can see through everything and turn it into the same code. On Thu, Dec 12, 2013 at 10:27 AM, Robby Findler ro...@eecs.northwestern.edu wrote: FWIW, my push speeds up the any-wrap/c implementation a bunch. Those two should have similar speeds after you get that, I guess. Robby On Thu, Dec 12, 2013 at 11:03 AM, Neil Toronto neil.toro...@gmail.com wrote: I tried your branch that implements it and saw about 3.5x speedup for the `magnitude*' test. This is of course without Robby's recent first-order contract changes. (I think it's about 3.5x: I tried with magnitude* : Number - Any first and got 2400ms on the easy tests. I changed it to magnitude* : Number - Number and got 690ms. Apparently, for an `Any' return type, an `any-wrap/c' contract is generated instead of nothing. If that's much faster to check than `number?', though, the speedup is even better.) I'd love to see this with Robby's recent changes. Hint? Nudge? Please? I didn't see very much speedup with arrays (about 1.2x). Speed tests on the math library's distribution objects were very interesting, though, and indicate why the arrays might not be much faster. Here's my test program: #lang racket (require math/distributions) (define d (normal-dist 0 1)) (printf pdf d 0~n) (for ([_ (in-range 5)]) (time (for ([_ (in-range 10)]) (pdf d 0 (newline) (define p (distribution-pdf d)) (printf p 0~n) (for ([_ (in-range 5)]) (time (for ([_ (in-range 10)]) (p 0 (newline) The two tests are equivalent, as `pdf' just pulls the pdf function out of the distribution struct and applies it. In TR, the tests are exactly the same speed (extremely fast). In untyped Racket, on the main branch, the second test is 16x faster, and on your branch, it's 44x faster. (It's still 10x slower than TR on your branch, so again... I'd love to see your changes and Robby's together. :D) Neil ⊥ On 12/12/2013 12:40 AM, Eric Dobson
Re: [racket-dev] [plt] Push #27909: master branch updated
Here is an example program. You need the step from 0 to 2 because TR is smart enough to turn (case- (- R) (A - R) (A B - R)) into -*. #lang racket/load (module m typed/racket (provide foo) (: foo (case- (- Symbol) (Symbol Symbol - Symbol))) (define (foo [x 'x] [y 'y]) x)) (require 'm) (require (for-syntax syntax/parse)) (require racket/contract/private/provide) (define-syntax (contract-on stx) (syntax-parse stx [(_ id) (provide/contract-info-contract-id (syntax-local-value #'id))])) (displayln (contract-on foo)) On Tue, Jan 14, 2014 at 9:33 AM, Robby Findler ro...@eecs.northwestern.edu wrote: Great, thanks! It occurred to me this morning that there is probably a significant slowdown for types that turn into case- instead of just - (due to the contract system). I would like to test this hypothesis, but I'm not sure how to. Do you mind posting a little program, like the ones below that generates a case- so we can play around with it to see? Robby On Tue, Jan 14, 2014 at 11:27 AM, Eric Dobson eric.n.dob...@gmail.com wrote: The changes to TR contract generation are now in at HEAD. If you can find any cases where contracts are still slowing programs down by a lot I'd like to take a look at them. (Excepting the case of structs where I know it is still an issue). On Thu, Dec 12, 2013 at 10:52 AM, Robby Findler ro...@eecs.northwestern.edu wrote: Re-reading your message I see that you're not actually asserting something different from what I said, but just for some precision here I wish to point out that I wasn't basing my opinion on intuition from the code, but on some microbenchmark timings. (There was a much more substantial difference yesterday because the loop inside any-wrap/c wasn't as cheap as it could have been.) I'd be interested to see if your improvements to type-contract improve the situation any! I expect they will make things better again for the Number case, but at the moment, there isn't a big difference. Program 1: #lang racket/base (module m typed/racket/base (: f (Any - Any)) (define (f x) 1) (provide f)) (require 'm) (time (for ([x (in-range 2)]) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7))) Timings: cpu time: 142 real time: 142 gc time: 8 cpu time: 144 real time: 144 gc time: 7 cpu time: 144 real time: 143 gc time: 6 cpu time: 142 real time: 142 gc time: 6 cpu time: 142 real time: 142 gc time: 7 cpu time: 146 real time: 146 gc time: 6 Program 2: #lang racket/base (module m typed/racket/base (: f (Any - Integer)) (define (f x) 1) (provide f)) (require 'm) (time (for ([x (in-range 2)]) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7) (f 0) (f 1) (f 2) (f 3) (f 4) (f 5) (f 6) (f 7))) Timings: cpu time: 139 real time: 138 gc time: 7 cpu time: 145 real time: 144 gc time: 7 cpu time: 140 real time: 140 gc time: 6 cpu time: 151 real time: 150 gc time: 6 cpu time: 139 real time: 138 gc time: 6 cpu time: 139 real time: 139 gc time: 8 On Thu, Dec 12, 2013 at 12:33 PM, Eric Dobson eric.n.dob...@gmail.com wrote: any-wrap/c still requires the check for one value, while any (which is from Number not Any) does not. So I would still guess at Number being faster, but Robby's changes may make it so that inlining and dead code elimination can see through everything and turn it into the same code. On Thu, Dec 12, 2013 at 10:27 AM, Robby Findler ro...@eecs.northwestern.edu wrote: FWIW, my push speeds up the any-wrap/c implementation a bunch. Those two should have similar speeds after you get that, I guess. Robby On Thu, Dec 12, 2013 at 11:03 AM, Neil Toronto neil.toro...@gmail.com wrote: I tried your branch that implements it and saw about 3.5x speedup for the `magnitude*' test. This is of course without Robby's recent first-order contract changes. (I think it's about 3.5x: I tried with magnitude* : Number - Any first and got 2400ms on the easy tests. I changed it to magnitude* : Number - Number and got 690ms. Apparently, for an `Any' return type, an `any-wrap/c' contract is generated instead
Re: [racket-dev] [plt] Push #27909: master branch updated
Any will always be slow to check for values leaving TR. This is because we don't statically know how we should protect the value and have to do expensive runtime checks. Using return types like Number will definitely see better performance. The changes shouldn't see too much improvement on structs since struct contracts are still expensive and I don't think it is possible to elide them safely with rackets introspection features (but I may be wrong about that, but it requires heavy thinking). On Thu, Dec 12, 2013 at 9:03 AM, Neil Toronto neil.toro...@gmail.com wrote: I tried your branch that implements it and saw about 3.5x speedup for the `magnitude*' test. This is of course without Robby's recent first-order contract changes. (I think it's about 3.5x: I tried with magnitude* : Number - Any first and got 2400ms on the easy tests. I changed it to magnitude* : Number - Number and got 690ms. Apparently, for an `Any' return type, an `any-wrap/c' contract is generated instead of nothing. If that's much faster to check than `number?', though, the speedup is even better.) I'd love to see this with Robby's recent changes. Hint? Nudge? Please? I didn't see very much speedup with arrays (about 1.2x). Speed tests on the math library's distribution objects were very interesting, though, and indicate why the arrays might not be much faster. Here's my test program: #lang racket (require math/distributions) (define d (normal-dist 0 1)) (printf pdf d 0~n) (for ([_ (in-range 5)]) (time (for ([_ (in-range 10)]) (pdf d 0 (newline) (define p (distribution-pdf d)) (printf p 0~n) (for ([_ (in-range 5)]) (time (for ([_ (in-range 10)]) (p 0 (newline) The two tests are equivalent, as `pdf' just pulls the pdf function out of the distribution struct and applies it. In TR, the tests are exactly the same speed (extremely fast). In untyped Racket, on the main branch, the second test is 16x faster, and on your branch, it's 44x faster. (It's still 10x slower than TR on your branch, so again... I'd love to see your changes and Robby's together. :D) Neil ⊥ On 12/12/2013 12:40 AM, Eric Dobson wrote: Removing the return value checking is in the works. It actually is removing all of the checks that would blame typed code, so higher order functions/datastructure get improvements too. It is actually functional the last time I checked, but lacking documentation which is what is holding up merging with mainline. https://github.com/plt/racket/pull/453 On Wed, Dec 11, 2013 at 7:57 PM, Robby Findler ro...@eecs.northwestern.edu wrote: I see that TR's type-contract returns (- (flat-named-contract (quote Float) flonum?) (flat-named-contract (quote Float) flonum?)) for the type (Float - Float), but it could return (- (flat-named-contract (quote Float) flonum?) any) which wouldn't do any result value checking (this being different from any/c as the range of the arrow contract). Robby On Wed, Dec 11, 2013 at 6:18 PM, Neil Toronto neil.toro...@gmail.com wrote: On 12/11/2013 02:49 PM, Neil Toronto wrote: On 12/11/2013 01:55 PM, Stephen Bloch wrote: On Dec 11, 2013, at 2:36 PM, Neil Toronto wrote: numeric primitives implemented in Typed Racket are faster than the same primitives implemented in C. Whoa! How did that happen? Whoa! That's not what I meant! O_o I said we might be getting close to that. I haven't tried porting a numeric C primitive to TR yet, but I have a hunch that it'll still be slower. I'll try one now and report what I find. Neil ⊥ I can't figure out why `flsinh' is faster to call from untyped Racket than `sinh'. All my tests with a Typed Racket `magnitude' show calls from untyped code are significantly slower, except in the one case that it computes Euclidean distance. That case is only twice as slow. I've attached the benchmark program. The `magnitude*' function is more or less a direct translation of `magnitude' from number.c into Typed Racket. Here's a summary of the results I get on my computer, in milliseconds, for 5 million calls from untyped Racket, by data type. Function Flonum Rational Fixnum Integer Float-Complex --- magnitude* 385 419 378 414 686 magnitude 59 44 40 40 390 The only one that's close in relative terms is Float-Complex. The others just call `abs'. The decompiled code doesn't show any inlining of `magnitude', so this comparison should be good. I'll bet checking the return value contract (which is unnecessary) is the main slowdown. It has to check for number of values. For comparison, here are the timings for running the benchmarks in TR with #:no-optimize: Function Flonum Rational Fixnum Integer Float-Complex
Re: [racket-dev] [plt] Push #27909: master branch updated
any-wrap/c still requires the check for one value, while any (which is from Number not Any) does not. So I would still guess at Number being faster, but Robby's changes may make it so that inlining and dead code elimination can see through everything and turn it into the same code. On Thu, Dec 12, 2013 at 10:27 AM, Robby Findler ro...@eecs.northwestern.edu wrote: FWIW, my push speeds up the any-wrap/c implementation a bunch. Those two should have similar speeds after you get that, I guess. Robby On Thu, Dec 12, 2013 at 11:03 AM, Neil Toronto neil.toro...@gmail.com wrote: I tried your branch that implements it and saw about 3.5x speedup for the `magnitude*' test. This is of course without Robby's recent first-order contract changes. (I think it's about 3.5x: I tried with magnitude* : Number - Any first and got 2400ms on the easy tests. I changed it to magnitude* : Number - Number and got 690ms. Apparently, for an `Any' return type, an `any-wrap/c' contract is generated instead of nothing. If that's much faster to check than `number?', though, the speedup is even better.) I'd love to see this with Robby's recent changes. Hint? Nudge? Please? I didn't see very much speedup with arrays (about 1.2x). Speed tests on the math library's distribution objects were very interesting, though, and indicate why the arrays might not be much faster. Here's my test program: #lang racket (require math/distributions) (define d (normal-dist 0 1)) (printf pdf d 0~n) (for ([_ (in-range 5)]) (time (for ([_ (in-range 10)]) (pdf d 0 (newline) (define p (distribution-pdf d)) (printf p 0~n) (for ([_ (in-range 5)]) (time (for ([_ (in-range 10)]) (p 0 (newline) The two tests are equivalent, as `pdf' just pulls the pdf function out of the distribution struct and applies it. In TR, the tests are exactly the same speed (extremely fast). In untyped Racket, on the main branch, the second test is 16x faster, and on your branch, it's 44x faster. (It's still 10x slower than TR on your branch, so again... I'd love to see your changes and Robby's together. :D) Neil ⊥ On 12/12/2013 12:40 AM, Eric Dobson wrote: Removing the return value checking is in the works. It actually is removing all of the checks that would blame typed code, so higher order functions/datastructure get improvements too. It is actually functional the last time I checked, but lacking documentation which is what is holding up merging with mainline. https://github.com/plt/racket/pull/453 On Wed, Dec 11, 2013 at 7:57 PM, Robby Findler ro...@eecs.northwestern.edu wrote: I see that TR's type-contract returns (- (flat-named-contract (quote Float) flonum?) (flat-named-contract (quote Float) flonum?)) for the type (Float - Float), but it could return (- (flat-named-contract (quote Float) flonum?) any) which wouldn't do any result value checking (this being different from any/c as the range of the arrow contract). Robby On Wed, Dec 11, 2013 at 6:18 PM, Neil Toronto neil.toro...@gmail.com wrote: On 12/11/2013 02:49 PM, Neil Toronto wrote: On 12/11/2013 01:55 PM, Stephen Bloch wrote: On Dec 11, 2013, at 2:36 PM, Neil Toronto wrote: numeric primitives implemented in Typed Racket are faster than the same primitives implemented in C. Whoa! How did that happen? Whoa! That's not what I meant! O_o I said we might be getting close to that. I haven't tried porting a numeric C primitive to TR yet, but I have a hunch that it'll still be slower. I'll try one now and report what I find. Neil ⊥ I can't figure out why `flsinh' is faster to call from untyped Racket than `sinh'. All my tests with a Typed Racket `magnitude' show calls from untyped code are significantly slower, except in the one case that it computes Euclidean distance. That case is only twice as slow. I've attached the benchmark program. The `magnitude*' function is more or less a direct translation of `magnitude' from number.c into Typed Racket. Here's a summary of the results I get on my computer, in milliseconds, for 5 million calls from untyped Racket, by data type. Function Flonum Rational Fixnum Integer Float-Complex --- magnitude* 385 419 378 414 686 magnitude 59 44 40 40 390 The only one that's close in relative terms is Float-Complex. The others just call `abs'. The decompiled code doesn't show any inlining of `magnitude', so this comparison should be good. I'll bet checking the return value contract (which is unnecessary) is the main slowdown. It has to check for number of values. For comparison, here are the timings for running the benchmarks in TR with #:no-optimize: Function Flonum Rational Fixnum Integer Float-Complex
Re: [racket-dev] [plt] Push #27909: master branch updated
Removing the return value checking is in the works. It actually is removing all of the checks that would blame typed code, so higher order functions/datastructure get improvements too. It is actually functional the last time I checked, but lacking documentation which is what is holding up merging with mainline. https://github.com/plt/racket/pull/453 On Wed, Dec 11, 2013 at 7:57 PM, Robby Findler ro...@eecs.northwestern.edu wrote: I see that TR's type-contract returns (- (flat-named-contract (quote Float) flonum?) (flat-named-contract (quote Float) flonum?)) for the type (Float - Float), but it could return (- (flat-named-contract (quote Float) flonum?) any) which wouldn't do any result value checking (this being different from any/c as the range of the arrow contract). Robby On Wed, Dec 11, 2013 at 6:18 PM, Neil Toronto neil.toro...@gmail.com wrote: On 12/11/2013 02:49 PM, Neil Toronto wrote: On 12/11/2013 01:55 PM, Stephen Bloch wrote: On Dec 11, 2013, at 2:36 PM, Neil Toronto wrote: numeric primitives implemented in Typed Racket are faster than the same primitives implemented in C. Whoa! How did that happen? Whoa! That's not what I meant! O_o I said we might be getting close to that. I haven't tried porting a numeric C primitive to TR yet, but I have a hunch that it'll still be slower. I'll try one now and report what I find. Neil ⊥ I can't figure out why `flsinh' is faster to call from untyped Racket than `sinh'. All my tests with a Typed Racket `magnitude' show calls from untyped code are significantly slower, except in the one case that it computes Euclidean distance. That case is only twice as slow. I've attached the benchmark program. The `magnitude*' function is more or less a direct translation of `magnitude' from number.c into Typed Racket. Here's a summary of the results I get on my computer, in milliseconds, for 5 million calls from untyped Racket, by data type. Function Flonum Rational Fixnum Integer Float-Complex --- magnitude* 385 419 378 414 686 magnitude 59 44 40 40 390 The only one that's close in relative terms is Float-Complex. The others just call `abs'. The decompiled code doesn't show any inlining of `magnitude', so this comparison should be good. I'll bet checking the return value contract (which is unnecessary) is the main slowdown. It has to check for number of values. For comparison, here are the timings for running the benchmarks in TR with #:no-optimize: Function Flonum Rational Fixnum Integer Float-Complex --- magnitude* 45 70* 37 102* 318 magnitude 61 45 39 91* 394 * = unexpectedly high Here's what I understand from comparing the numbers: * Except for non-fixnum integers, calling `magnitude' in TR is just as fast as in untyped Racket. I have no idea why it would be slower on big integers. That's just weird. * Calling `abs' in Racket is faster than calling `scheme_abs' in C, except on rationals and big integers. * Operating on flonums in Typed Racket, using generic numeric functions, is faster than doing the same in C. Overall, it looks like the TR code is within the same order of magnitude (pun not intended) as the C code. I would love to try this benchmark with either 1) a `magnitude*' with an `AnyValues' return type; or 2) a contract boundary that doesn't check TR's return types for first-order functions. (I managed to make a `magnitude*' with type Number - AnyValues, but TR couldn't make a contract for it.) Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Is there a way to print out all inferred types for a typed racket program?
No it is not easy. It should all be there in the expanded output. TR stores the type of an expression in a hashtable on the side, see https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/type-table.rkt#L34. So if you did #lang racket (require racket/pretty syntax/kerncase typed-racket/types/type-table) (define prog #'(module tr typed/racket #:no-optimize foo)) (define expanded-prog (expand prog)) (pretty-print (syntax-datum expanded-prog)) (kernel-syntax-case expanded-prog #f ((module _ _ (#%module-begin (module . _) (begin-for-syntax (module* . _)) (begin-for-syntax . _) (#%plain-app _ (_ () body) _) . _)) (type-of #'body))) You should get the value, except that between the time that TR expands the output and typechecks it and the time that it comes back from expansion it has gotten changed so that the hash lookup will not work. You can probably hack the internals of TR to export the original syntax object out a side channel and do the same thing at it should work. You want the fully-expanded-syntax value here: https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/tc-setup.rkt#L64 On Thu, Sep 19, 2013 at 9:00 AM, John Smith johnsm...@thurn.ca wrote: I'm essentially looking for a dump of the typed AST of a given typed racket program for use in an undergraduate research project. Is there an easy way to get this information? _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #27446: master branch updated
I have ideas to remove about the contracts from TR code, but currently that is only prototyped. Example: #lang typed/racket (provide f) (: f (Number - Number)) (define (f x) x) Currently f is exported with the contract (number? . - . number?), but this can be safely reduced to (number . - . any). This is because the return value contract is checking things we have already ensured statically. IIRC checking return values of functions is much more expensive than just arguments, so this should reduce the cost of TR boundary cost, but I don't have any numbers. On Mon, Sep 9, 2013 at 10:57 AM, Sam Tobin-Hochstadt sa...@cs.indiana.edu wrote: On Mon, Sep 9, 2013 at 11:35 AM, Neil Toronto neil.toro...@gmail.com wrote: Nice, and thanks for the explanation. Just to make sure I get it: does this mean fully expanded TR modules are smaller? Yes. Does it reduce the number of generated contracts? No. On 09/08/2013 12:24 PM, Sam Tobin-Hochstadt wrote: Typed Racket has to expand into code that registers the type of each module-top-level identifier in the global environment so that other modules can find the types to typecheck with. For example, this program: #lang typed/racket (provide x) (define: x : Integer 1) expands into (greatly simplified): #lang ... (#%provide x) (begin-for-syntax (declare #'x Integer-rep)) (define-values (x) 1) but what is `Integer-rep`? It needs to be an expression that _constructs_ the internal Typed Racket representation of the `Integer` type. Previously, that looked something like this: (make-Union (sort (list Negative-Fixnum-rep Positive-Fixnum-rep ...))) and so on and so forth for the components, all the way down to base types. You can imagine how this gets quite large, especially for large types. However, this is wasteful, because every Typed Racket program, at type checking time, defines a constant that's the representation of the `Integer` type, right here [1]. So instead of serializing an expression that constructs the same thing as `-Int`, we can just *reference* `-Int` in the expanded code. To make that possible, Typed Racket now builds a hash table [2] mapping types (really, their representations) to identifiers that denote those types. Then the serializer just consults this table [3]. It turns out that base types (but no others) already used basically this mechanism, by storing the identifier *in* the type representation. But that's now obsolete, and thus was removed in my subsequent commit. As a result, the type serialization is much smaller. [1] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/numeric-tower.rkt#L107 [2] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/base-abbrev.rkt#L23 [3] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/env/init-envs.rkt#L51 On Sat, Sep 7, 2013 at 3:20 PM, Neil Toronto neil.toro...@gmail.com wrote: On 09/06/2013 04:14 PM, sa...@racket-lang.org wrote: 56b372c Sam Tobin-Hochstadt sa...@racket-lang.org 2013-09-06 14:22 : | Remember types that are defined, and use them in serialization. | | This extends a facility already available for base types, | making that facility no longer strictly needed. | | Shrinks the zo size for the `math` package by almost 1MB. : M .../typed-racket/env/init-envs.rkt| 1 + M .../typed-racket/typecheck/def-export.rkt | 7 +- M .../typed-racket/typecheck/tc-toplevel.rkt| 31 +++--- M .../typed-racket/types/abbrev.rkt | 36 +++ M .../typed-racket/types/base-abbrev.rkt| 12 ++- M .../typed-racket/types/numeric-tower.rkt | 108 +-- Would you mind explaining this a little more? It sounds interesting, and the commit almost has my name in it. :) Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #27446: master branch updated
When did you add this? Last time I checked (June-ish) this was not added. Can you point to the code that does it? On Mon, Sep 9, 2013 at 5:55 PM, Sam Tobin-Hochstadt sa...@cs.indiana.edu wrote: Not only did our own Sam write about this, but he thought that he changed Typed Racket to do this. Am I missing something here, or are you describing more optimization than we do already or ...? Sam On Sep 9, 2013 8:33 PM, Robby Findler ro...@eecs.northwestern.edu wrote: FWIW, this is something that's been studied in small calculi in the literature. Nothing that will have to get thru all of the little details that you have to get right to make it work in a real language design like TR, but maybe you'll find some useful ways to look at the problem. (Mostly the papers I'm thinking of have Jeremy Siek as a co-author but there are others, including our own Sam.) Robby On Mon, Sep 9, 2013 at 7:14 PM, Eric Dobson eric.n.dob...@gmail.com wrote: I have ideas to remove about the contracts from TR code, but currently that is only prototyped. Example: #lang typed/racket (provide f) (: f (Number - Number)) (define (f x) x) Currently f is exported with the contract (number? . - . number?), but this can be safely reduced to (number . - . any). This is because the return value contract is checking things we have already ensured statically. IIRC checking return values of functions is much more expensive than just arguments, so this should reduce the cost of TR boundary cost, but I don't have any numbers. On Mon, Sep 9, 2013 at 10:57 AM, Sam Tobin-Hochstadt sa...@cs.indiana.edu wrote: On Mon, Sep 9, 2013 at 11:35 AM, Neil Toronto neil.toro...@gmail.com wrote: Nice, and thanks for the explanation. Just to make sure I get it: does this mean fully expanded TR modules are smaller? Yes. Does it reduce the number of generated contracts? No. On 09/08/2013 12:24 PM, Sam Tobin-Hochstadt wrote: Typed Racket has to expand into code that registers the type of each module-top-level identifier in the global environment so that other modules can find the types to typecheck with. For example, this program: #lang typed/racket (provide x) (define: x : Integer 1) expands into (greatly simplified): #lang ... (#%provide x) (begin-for-syntax (declare #'x Integer-rep)) (define-values (x) 1) but what is `Integer-rep`? It needs to be an expression that _constructs_ the internal Typed Racket representation of the `Integer` type. Previously, that looked something like this: (make-Union (sort (list Negative-Fixnum-rep Positive-Fixnum-rep ...))) and so on and so forth for the components, all the way down to base types. You can imagine how this gets quite large, especially for large types. However, this is wasteful, because every Typed Racket program, at type checking time, defines a constant that's the representation of the `Integer` type, right here [1]. So instead of serializing an expression that constructs the same thing as `-Int`, we can just *reference* `-Int` in the expanded code. To make that possible, Typed Racket now builds a hash table [2] mapping types (really, their representations) to identifiers that denote those types. Then the serializer just consults this table [3]. It turns out that base types (but no others) already used basically this mechanism, by storing the identifier *in* the type representation. But that's now obsolete, and thus was removed in my subsequent commit. As a result, the type serialization is much smaller. [1] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/numeric-tower.rkt#L107 [2] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/types/base-abbrev.rkt#L23 [3] https://github.com/plt/racket/blob/master/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/env/init-envs.rkt#L51 On Sat, Sep 7, 2013 at 3:20 PM, Neil Toronto neil.toro...@gmail.com wrote: On 09/06/2013 04:14 PM, sa...@racket-lang.org wrote: 56b372c Sam Tobin-Hochstadt sa...@racket-lang.org 2013-09-06 14:22 : | Remember types that are defined, and use them in serialization. | | This extends a facility already available for base types, | making that facility no longer strictly needed. | | Shrinks the zo size for the `math` package by almost 1MB. : M .../typed-racket/env/init-envs.rkt| 1 + M .../typed-racket/typecheck/def-export.rkt | 7 +- M .../typed-racket/typecheck/tc-toplevel.rkt| 31 +++--- M .../typed-racket/types/abbrev.rkt | 36 +++ M .../typed-racket/types/base-abbrev.rkt| 12 ++- M .../typed-racket/types/numeric-tower.rkt | 108 +-- Would you mind explaining this a little more? It sounds
Re: [racket-dev] [plt] Push #27263: master branch updated
On Thu, Aug 8, 2013 at 9:50 AM, as...@racket-lang.org wrote: asumu has updated `master' from a8405eb77d to 24e55c1faa. http://git.racket-lang.org/plt/a8405eb77d..24e55c1faa =[ 2 Commits ]== Directory summary: 76.4% pkgs/htdp-pkgs/htdp-doc/teachpack/2htdp/scribblings/ 23.5% pkgs/htdp-pkgs/htdp-doc/teachpack/htdp/scribblings/ ~~ 495c70c Asumu Takikawa as...@racket-lang.org 2013-08-07 17:15 : | Doc fixes in 2htdp/image : M .../htdp-doc/teachpack/2htdp/scribblings/image.scrbl | 15 --- ~~ 24e55c1 Asumu Takikawa as...@racket-lang.org 2013-08-07 17:16 : | Doc fixes in htdp/image : M .../htdp-doc/teachpack/htdp/scribblings/image.scrbl | 3 ++- =[ Overall Diff ]=== pkgs/htdp-pkgs/htdp-doc/teachpack/2htdp/scribblings/image.scrbl ~~~ --- OLD/pkgs/htdp-pkgs/htdp-doc/teachpack/2htdp/scribblings/image.scrbl +++ NEW/pkgs/htdp-pkgs/htdp-doc/teachpack/2htdp/scribblings/image.scrbl @@ -1,6 +1,7 @@ #lang scribble/doc -@(require (for-label (only-in racket/contract and/c or/c any/c not/c) +@(require (for-label (only-in racket/contract and/c or/c any/c not/c listof + =/c =/c) 2htdp/image (except-in lang/htdp-beginner posn make-posn posn? posn-x posn-y image?) lang/posn @@ -57,7 +58,7 @@ for a more careful discussion of this issue.})) @defmodule[#:require-form beginner-require 2htdp/image] - +a Was this addition intentional? The image teachpack provides a number of basic image construction functions, along with combinators for building more complex images out of existing images. Basic images include various polygons, ellipses and @@ -504,13 +505,13 @@ They all construct a triangle oriented as follows: } -@defproc*[([(rectangle [width real?] - [height real?] +@defproc*[([(rectangle [width (and/c real? (not/c negative?))] + [height (and/c real? (not/c negative?))] [mode mode?] [color image-color?]) image?] - [(rectangle [width real?] - [height real?] + [(rectangle [width (and/c real? (not/c negative?))] + [height (and/c real? (not/c negative?))] [outline-mode (or/c 'outline outline)] [pen-or-color (or/c pen? image-color?)]) image?])]{ @@ -1110,7 +,7 @@ a black outline. @defproc[(scene+curve [scene image?] [x1 real?] [y1 real?] [angle1 angle?] [pull1 real?] [x2 real?] [y2 real?] [angle2 angle?] [pull2 real?] - [color image-color?]) + [color (or/c pen? image-color?)]) image?]{ Adds a curve to @racket[scene], starting at the point pkgs/htdp-pkgs/htdp-doc/teachpack/htdp/scribblings/image.scrbl ~~ --- OLD/pkgs/htdp-pkgs/htdp-doc/teachpack/htdp/scribblings/image.scrbl +++ NEW/pkgs/htdp-pkgs/htdp-doc/teachpack/htdp/scribblings/image.scrbl @@ -1,6 +1,7 @@ #lang scribble/doc -@(require scribble/manual shared.rkt (for-label racket teachpack/htdp/image)) +@(require scribble/manual shared.rkt + (for-label racket lang/posn teachpack/htdp/image)) @teachpack[image]{Manipulating Images} _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] struct:name exports from 2htdp/image, mrlib/image-core, etc.
I believe that TR will not look for the struct type descriptor if it is not in the static struct-info, so removing that might be another option. Especially since if it isn't provided from the module regularly. On Tue, Aug 6, 2013 at 4:21 PM, Matthias Felleisen matth...@ccs.neu.edu wrote: That might interfere with normal uses of these libraries in *SL. -- Matthias On Aug 6, 2013, at 6:50 PM, Asumu Takikawa as...@ccs.neu.edu wrote: Hi all, A few teaching libraries like `2htdp/image` provide struct constructors and accessors, but don't export the struct type descriptor values. Does anyone mind if I add the exports to libraries like `2htdp/image`, `mrlib/image-core`, etc.? (it's needed for Typed Racket with require/typed) Cheers, Asumu _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] expand, local-expand, and syntax-procedure-converted-arguments-property
I'm not sure about the exact problem. But I have some work for the TR unit tests that make it use a saner way of running the tests, and it allows for the TR syntax properties to be gensyms. It will likely be a week or two until they are in HEAD (tons of commits that need to be cleaned up and reviewed) but I can push to github tonight and let you see if they fix your issue. On Wed, Jul 10, 2013 at 6:04 PM, Asumu Takikawa as...@ccs.neu.edu wrote: Hi all, I'm currently trying to fix the Typed Racket unit tests. I think I've narrowed down the issue to a certain syntax property for keyword functions. The issue is illustrated by the following example: #lang racket (require racket/file (for-syntax racket/file racket/keyword-transform)) ;; the property is #f (begin-for-syntax (displayln (syntax-case (expand-syntax #'(copy-directory/files 1 2)) () [(let-values (((temp1) _) ((temp2) _)) (if _ (#%plain-app1 copy-directory/files15 e1 ...) (#%plain-app2 copy-directory/files17 e2 ...))) (syntax-procedure-converted-arguments-property #'copy-directory/files15)]))) ;; property is syntax (begin-for-syntax (displayln (syntax-case (local-expand #'(copy-directory/files 1 2) 'expression null) () [(let-values (((temp1) _) ((temp2) _)) (if _ (#%plain-app1 copy-directory/files15 e1 ...) (#%plain-app2 copy-directory/files17 e2 ...))) (syntax-procedure-converted-arguments-property #'copy-directory/files15)]))) There are two syntax-time computations here. Both are expanding an application of a keyword function (one with local-expand, one with expand) and looking at the resulting syntax. The key point here is that I want to find the property looked up by `syntax-procedure-converted-arguments-property` on an output identifier because Typed Racket needs it to type-check the expansion. Unfortunately, as the comments indicate, only the second piece of code can find the property. The reason appears to be that the property key is actually a private `gensym`ed symbol and the two pieces of code appear to get separate instantiations of the kw.rkt module (perhaps at different phases). To check that, if I modify kw.rkt to use a plain symbol, both of the snippets above return the same property value. Anyone have any idea how I can keep using `expand` but still be able to look up the property? Cheers, Asumu _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #26939: master branch updated
I don't think this is the right fix to the issue. A core issue (there may be more) is that calls to subtype during the dynamic extent of a call to subtype take the same current-seen list as is the current state of the outer subtype call. This works well when this is supposed to be part of the same type, but doesn't work so well in other cases. For example in a reduced version of the test case: #lang typed/racket ;; Test for PR 13821 ;; ;; Make sure type instantiation with struct names doesn't ;; loop forever (struct: (X) union ([fst : (ISet X)]) #:transparent) (struct: (X) complement ([fst : (ISet X)]) #:transparent) (define-type (ISet X) (U (union X) (complement X) (Setof X))) ;; This involves type instantiation and could loop forever ;; with the bug (: iset-set (All (X) ((ISet X) - (Setof X (define (iset-set A) (union? A) (error 'unimplemented)) ;; A simpler way to reproduce the problem (union? 5) I get the output from my logging: (resolve-once (union Any)) (Un (Setof Any) (union Any) (complement Any)) Union of ((Setof Any) (union Any) (complement Any)) Merging (Setof Any) and () (subtype (Setof Any) (U)) Current seen 27457 1 ((27222 . 27457) (27261 . 27457) (27317 . 27222)) #f (subtype (U) (Setof Any)) Current seen 1 27457 ((27222 . 27457) (27261 . 27457) (27317 . 27222)) #t Merging (complement Any) and ((Setof Any)) (subtype (complement Any) (Setof Any)) Current seen 27261 27457 ((27222 . 27457) (27261 . 27457) (27317 . 27222)) #t Merging (union Any) and ((Setof Any)) (subtype (union Any) (Setof Any)) Current seen 27222 27457 ((27222 . 27457) (27261 . 27457) (27317 . 27222)) #t (Setof Any) #(struct:#syntax:/Users/endobson/proj/racket/plt/collects/tests/typed-racket/succeed/pr13821.rkt:8:13 union ((Setof Any))) Which shows that (union Any) is resolving incorrectly to (struct union ((Setof Any))) instead of (struct union ((U (union Any) (complement Any) (Setof Any. All your change does is prevent one call site of resolve, and thus just covers up the issue instead of solving it. On Fri, Jun 7, 2013 at 12:14 PM, as...@racket-lang.org wrote: asumu has updated `master' from 3d6776680c to 75f0c88feb. http://git.racket-lang.org/plt/3d6776680c..75f0c88feb =[ 3 Commits ]== Directory summary: 8.7% collects/tests/typed-racket/fail/ 25.5% collects/tests/typed-racket/succeed/ 15.3% collects/tests/unstable/ 24.3% collects/typed-racket/types/ 13.9% collects/unstable/scribblings/ 12.0% collects/unstable/ ~~ 12e5bc6 Asumu Takikawa as...@racket-lang.org 2013-06-07 14:31 : | Add match*? to unstable/match : M collects/tests/unstable/match.rkt | 15 ++- M collects/unstable/match.rkt | 10 +- M collects/unstable/scribblings/match.scrbl | 19 +++ ~~ c8e281a Asumu Takikawa as...@racket-lang.org 2013-06-07 14:32 : | Fix union merging | | Trying to merge (and thus resolve) applications of struct | types would cause infinite looping on type instantiation | if the struct type used both a union and recursion. | | Closes PR 13821 : A collects/tests/typed-racket/succeed/pr13821.rkt M collects/typed-racket/types/union.rkt | 14 -- ~~ 75f0c88 Asumu Takikawa as...@racket-lang.org 2013-06-07 15:08 : | Improve TR test case : M collects/tests/typed-racket/fail/pr13209.rkt | 7 ++- =[ Overall Diff ]=== collects/tests/typed-racket/fail/pr13209.rkt --- OLD/collects/tests/typed-racket/fail/pr13209.rkt +++ NEW/collects/tests/typed-racket/fail/pr13209.rkt @@ -1,7 +1,12 @@ #; -(exn-pred exn:fail:syntax?) +(exn-pred #rxarguments for structure type constructor) #lang typed/racket +;; Test for PR 13209 +;; +;; The use of `node` at the end has the wrong number of +;; type arguments. This should not raise an internal error. + (struct: (α) leaf ({value : α})) (struct: (α) node ({left : [Tree α]} {right : [Tree α]})) collects/tests/typed-racket/succeed/pr13821.rkt ~~~ --- /dev/null +++ NEW/collects/tests/typed-racket/succeed/pr13821.rkt @@ -0,0 +1,22 @@ +#lang typed/racket + +;; Test for PR 13821 +;; +;; Make sure type instantiation with struct names doesn't +;; loop forever + +(struct: (X) union ([fst : (ISet X)] [snd : (ISet X)]) #:transparent) +(struct: (X) intersection ([fst : (ISet X)] [snd : (ISet X)]) #:transparent) +(struct: (X) complement ([fst : (ISet X)] [snd : (ISet X)]) #:transparent) +(define-type (ISet X) (U (union X) (intersection X) (complement X) (Setof X))) + +;; This involves type instantiation and could loop forever +;; with the bug +(: iset-set (All (X) ((ISet X) - (Setof X +(define (iset-set A) + (union? A) + (error 'unimplemented)) + +;;
Re: [racket-dev] Unique identifiers
What does unique mean in this context? Does probabilistically unique work? If so could you form an identifier with the symbolic form unique-id-+UUID? On Fri, May 31, 2013 at 8:20 AM, Carl Eastlund c...@ccs.neu.edu wrote: I'm having trouble creating identifiers that are unique with respect to free-identifier=? and that survive marshaling to compiled code. The normal source of fresh identifiers, generate-temporaries, only guarantees they are unique with respect to bound-identifier=?. The obvious alternative, gensym, does not properly survive marshaling -- copies saved in different .zo files load as distinct identifiers. I've tried a few alternative methods, none more successful than either of these. Below, there are a few short files that show the difficulties and can be used to test other methods. The first, fresh.rkt, contains the procedure used to create fresh identifiers. The file original.rkt creates a fresh identifier at compile time. The file identical.rkt copies the identifier from original.rkt using quote-syntax. The file different.rkt creates another fresh identifier at compile time. The file check.rkt checks that the identifiers from original.rkt and identical.rkt are free-identifier=? to each other, and that the identifiers from original.rkt and different.rkt are not free-identifier=? to each other. To run a test, first update fresh.rkt to use the appropriate method for creating identifiers, then run raco make check.rkt. Some of the methods work when simply running racket check.rkt, but raco make marshals the identifiers to .zo files and exposes more problems. Can anyone suggest an implementation that would work here? ; fresh.rkt #lang racket (begin-for-syntax (require racket/syntax) (define (fresh) ;; does not guarantee free-identifier=? #;(generate-temporary) ;; does not survive marshaling #;(gensym) ;; also does not survive marshaling (begin (define id0 (datum-syntax #false 'fresh)) (define ctx (syntax-local-make-definition-context)) (syntax-local-bind-syntaxes (list id0) #false ctx) (internal-definition-context-seal ctx) (internal-definition-context-apply ctx id0))) (provide fresh)) ; original.rkt #lang racket (require fresh.rkt) (define-syntax (macro stx) (with-syntax {[name (fresh)]} #'(begin-for-syntax (define original (quote-syntax name)) (provide original (macro) ; identical.rkt #lang racket (require original.rkt) (define-syntax (macro stx) (with-syntax {[orig original]} #'(begin-for-syntax (define identical (quote-syntax orig)) (provide identical (macro) ; different.rkt #lang racket (require fresh.rkt) (define-syntax (macro stx) (with-syntax {[name (fresh)]} #'(begin-for-syntax (define different (quote-syntax name)) (provide different (macro) ; check.rkt #lang racket (require fresh.rkt original.rkt identical.rkt different.rkt) (begin-for-syntax (unless (free-identifier=? original identical) (error 'fresh ~v != ~v\n original identical)) (when (free-identifier=? original different) (error 'fresh ~v == ~v\n original different))) -- Carl Eastlund _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Unique identifiers
If you replace all of your internal definition manipulation with (syntax-local-lift-expression #'#f), it passes your check.rkt. You don't have control over the names, but I'm guessing you could look into the implementation and see what it is doing to generate such names. On Fri, May 31, 2013 at 8:32 AM, Carl Eastlund c...@ccs.neu.edu wrote: I want a non-probabilistic guarantee of uniqueness, partly because I'd rather not rely on something nondeterministic, and partly because in an ideal solution, I'd like to have control over the printed names of these identifiers. Carl Eastlund On Fri, May 31, 2013 at 9:27 AM, Eric Dobson eric.n.dob...@gmail.com wrote: What does unique mean in this context? Does probabilistically unique work? If so could you form an identifier with the symbolic form unique-id-+UUID? On Fri, May 31, 2013 at 8:20 AM, Carl Eastlund c...@ccs.neu.edu wrote: I'm having trouble creating identifiers that are unique with respect to free-identifier=? and that survive marshaling to compiled code. The normal source of fresh identifiers, generate-temporaries, only guarantees they are unique with respect to bound-identifier=?. The obvious alternative, gensym, does not properly survive marshaling -- copies saved in different .zo files load as distinct identifiers. I've tried a few alternative methods, none more successful than either of these. Below, there are a few short files that show the difficulties and can be used to test other methods. The first, fresh.rkt, contains the procedure used to create fresh identifiers. The file original.rkt creates a fresh identifier at compile time. The file identical.rkt copies the identifier from original.rkt using quote-syntax. The file different.rkt creates another fresh identifier at compile time. The file check.rkt checks that the identifiers from original.rkt and identical.rkt are free-identifier=? to each other, and that the identifiers from original.rkt and different.rkt are not free-identifier=? to each other. To run a test, first update fresh.rkt to use the appropriate method for creating identifiers, then run raco make check.rkt. Some of the methods work when simply running racket check.rkt, but raco make marshals the identifiers to .zo files and exposes more problems. Can anyone suggest an implementation that would work here? ; fresh.rkt #lang racket (begin-for-syntax (require racket/syntax) (define (fresh) ;; does not guarantee free-identifier=? #;(generate-temporary) ;; does not survive marshaling #;(gensym) ;; also does not survive marshaling (begin (define id0 (datum-syntax #false 'fresh)) (define ctx (syntax-local-make-definition-context)) (syntax-local-bind-syntaxes (list id0) #false ctx) (internal-definition-context-seal ctx) (internal-definition-context-apply ctx id0))) (provide fresh)) ; original.rkt #lang racket (require fresh.rkt) (define-syntax (macro stx) (with-syntax {[name (fresh)]} #'(begin-for-syntax (define original (quote-syntax name)) (provide original (macro) ; identical.rkt #lang racket (require original.rkt) (define-syntax (macro stx) (with-syntax {[orig original]} #'(begin-for-syntax (define identical (quote-syntax orig)) (provide identical (macro) ; different.rkt #lang racket (require fresh.rkt) (define-syntax (macro stx) (with-syntax {[name (fresh)]} #'(begin-for-syntax (define different (quote-syntax name)) (provide different (macro) ; check.rkt #lang racket (require fresh.rkt original.rkt identical.rkt different.rkt) (begin-for-syntax (unless (free-identifier=? original identical) (error 'fresh ~v != ~v\n original identical)) (when (free-identifier=? original different) (error 'fresh ~v == ~v\n original different))) -- Carl Eastlund _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Constructing an identifier to an unexported binding
Isn't that exactly what free-indentifier=? is checking for on identfiers with a module level binding? Or is there something else it does? On Thu, May 23, 2013 at 3:13 PM, Carl Eastlund c...@ccs.neu.edu wrote: On Thu, May 23, 2013 at 4:13 PM, Ryan Culpepper ry...@ccs.neu.edu wrote: On 05/23/2013 01:57 AM, Eric Dobson wrote: Some modules have macros which expand into identifiers that are not exported, as they want to protect those bindings. TR currently has the following code which allows it to generate an identifier which is free-identifier=? to what would appear in the output of the macros. define (make-template-identifier what where) (let ([name (module-path-index-resolve (module-path-index-join where #f))]) (parameterize ([current-namespace (make-empty-namespace)]) (namespace-attach-module (current-namespace) ''#%kernel) (parameterize ([current-module-declare-name name]) (eval `(,#'module any '#%kernel (#%provide ,what) (define-values (,what) #f (namespace-require `(for-template ,name)) (namespace-syntax-introduce (datum-syntax #f what) This turns out to be a slightly slow part of the initialization of TR. Does anyone know another way to get such an identifier? There's another way around this issue, which is to avoid creating these identifiers at all. In other words, change the representation of the type environment to something that supports symbol+module pairs as keys in addition to identifiers. The easiest way to do that is to add in a hash table behind the current free-id-table, since the two tables would handle disjoint sets of identifiers. Ryan I would not have thought that'd work, but apparently identifier-binding will give one that information. Nice going, Ryan! --Carl _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Constructing an identifier to an unexported binding
Right, but why cannot we forge an identifier easily? I'm happy getting an armed identifier. What are the reasons for preventing such a construction? On Thu, May 23, 2013 at 6:04 PM, Carl Eastlund c...@ccs.neu.edu wrote: Essentially yes. It doesn't do anything else, but it needs an identifier to do it. Currently, TR starts with a module and a symbol, goes through an expensive process to forge an identifier from them, just to call free-identifier=? to compare based on the module and the symbol after all. Doing the comparison directly, without ever forging the identifier, would be quicker. On Thu, May 23, 2013 at 8:43 PM, Eric Dobson eric.n.dob...@gmail.com wrote: Isn't that exactly what free-indentifier=? is checking for on identfiers with a module level binding? Or is there something else it does? On Thu, May 23, 2013 at 3:13 PM, Carl Eastlund c...@ccs.neu.edu wrote: On Thu, May 23, 2013 at 4:13 PM, Ryan Culpepper ry...@ccs.neu.edu wrote: On 05/23/2013 01:57 AM, Eric Dobson wrote: Some modules have macros which expand into identifiers that are not exported, as they want to protect those bindings. TR currently has the following code which allows it to generate an identifier which is free-identifier=? to what would appear in the output of the macros. define (make-template-identifier what where) (let ([name (module-path-index-resolve (module-path-index-join where #f))]) (parameterize ([current-namespace (make-empty-namespace)]) (namespace-attach-module (current-namespace) ''#%kernel) (parameterize ([current-module-declare-name name]) (eval `(,#'module any '#%kernel (#%provide ,what) (define-values (,what) #f (namespace-require `(for-template ,name)) (namespace-syntax-introduce (datum-syntax #f what) This turns out to be a slightly slow part of the initialization of TR. Does anyone know another way to get such an identifier? There's another way around this issue, which is to avoid creating these identifiers at all. In other words, change the representation of the type environment to something that supports symbol+module pairs as keys in addition to identifiers. The easiest way to do that is to add in a hash table behind the current free-id-table, since the two tables would handle disjoint sets of identifiers. Ryan I would not have thought that'd work, but apparently identifier-binding will give one that information. Nice going, Ryan! --Carl _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] proposal for moving to packages
I agree that 363 to 28 would be a great win. But you seem to be describing the difference between Full Racket and core racket, not the difference between binary and source. For binary vs source, I think you are providing a good argument for the usefulness of a no source distribution. Some people want to use tools written in Racket, and the fact that the tools are written in Racket is immaterial to them. They should be able to have just the binary versions. On Wed, May 22, 2013 at 12:30 PM, Eli Barzilay e...@barzilay.org wrote: Yesterday, Eric Dobson wrote: On Tue, May 21, 2013 at 4:29 AM, Jay McCarthy jay.mccar...@gmail.com wrote: In my tree, I have 20M of compiled code and 13M of source. I like the idea of a reduction of about 50% in size of downloads. I'm not sure if something on the order of 10M is something to worry about optimizing, that takes like 5-6 seconds to download on a 15Mbit connection. And a minute on a much slower connection. I don't know how Jay got those numbers, but I have a very different picture: 363M Current installed tree 278M No-source tree (with docs) 56M Installed textual tree (has no docs and scrbl files) 42M Same minus sources If a package based installation is roughly like the textual thing, and given that it's easy to extend it to a full installation by adding packages, then we're talking about going from a 363M tree down to a 42M thing. I think that the minimal core racket would be even smaller than the textual thing: once I remove things that look like they shouldn't be there, it goes down to 28M. The impact of having a huge tree currently is pretty big, IMO. One example is that it is impractical to have random linux utilities implemented in Racket if you need to drag in a 363M working environment. It's true that you could in theory use the textual thing, but the monolithic tree makes it hard for linux distro packagers to split things into a small core -- hard enough that nobody did it so far. Another example is the few brave people who tried to make things work on small devices, which usually starts with a huge effort to get rid of unnecessary stuff. Finally -- consider J. Random User -- installing a 360M thing on your computer is something that you'd worry about much more than a 28M thing. The smaller thing is at a point where you won't worry about it beind left somewhere, and at a point where it's fine to installed as a kind of a shared runtime thing for someone who wants to distribute racket-based applications. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Constructing an identifier to an unexported binding
Some modules have macros which expand into identifiers that are not exported, as they want to protect those bindings. TR currently has the following code which allows it to generate an identifier which is free-identifier=? to what would appear in the output of the macros. define (make-template-identifier what where) (let ([name (module-path-index-resolve (module-path-index-join where #f))]) (parameterize ([current-namespace (make-empty-namespace)]) (namespace-attach-module (current-namespace) ''#%kernel) (parameterize ([current-module-declare-name name]) (eval `(,#'module any '#%kernel (#%provide ,what) (define-values (,what) #f (namespace-require `(for-template ,name)) (namespace-syntax-introduce (datum-syntax #f what) This turns out to be a slightly slow part of the initialization of TR. Does anyone know another way to get such an identifier? _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] proposal for moving to packages
On Tue, May 21, 2013 at 4:29 AM, Jay McCarthy jay.mccar...@gmail.com wrote: On Mon, May 20, 2013 at 10:05 PM, Eric Dobson eric.n.dob...@gmail.com wrote: I'm not sure I follow on why binary packages make it easier to reduce dependencies between packages, or why binary packages offer faster installs. I'm guessing that binary packages prevent cyclic dependencies between packages, but it seems like there are many other options that still get this side effect. Such as explicit checks when building the package. If you have the source, then you need all the phase = 1 dependencies, but if you just have the binary then you only need the phase = 0 deps. Similarly, for building the documentation. Like Philippe said a viewable source doesn't require this, only source that can be compiled. Whether or not we want to support that I don't know, but it seems like it should be possible. For faster installs, the only benefit I see of binary packages over precompiled source packages is a small savings in size which doesn't seem like it would amount to much of the install time. In my tree, I have 20M of compiled code and 13M of source. I like the idea of a reduction of about 50% in size of downloads. I'm not sure if something on the order of 10M is something to worry about optimizing, that takes like 5-6 seconds to download on a 15Mbit connection. And a minute on a much slower connection. However, the faster install point is really about the fact that users won't need to run raco setup and do the compilation/documentation build once they do the download of the source. Why would you need to run raco setup if the source was already precompiled? Also how well does the source compress compared to compiled code? Jay Can someone explain the claims for binary packages? On Mon, May 20, 2013 at 8:57 PM, Jon Zeppieri zeppi...@gmail.com wrote: On Mon, May 20, 2013 at 10:04 PM, Neil Van Dyke n...@neilvandyke.org wrote: [snip] Example: Imagine I'm in the middle of writing a Racket program and am wondering about characteristics of some kind of I/O port in Racket. With transparent source accessibility, I can just click on an identifier in my program in DrRacket to start browsing the implementation. Maybe I see a possible improvement, or seeing the source pre-empts yet another email list question that otherwise only Matthew could answer, or I feel empowered to go add a new feature. If the source is not as accessible, then I'm more likely to be a mere naive user of the tools, rather than to understand the tools and help improve them. +inf.0 Though the easiest way to make the source available is just to keep it in the distribution. I'll be sad to see it go. -Jon _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev -- Jay McCarthy j...@cs.byu.edu Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay The glory of God is Intelligence - DC 93 _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] proposal for moving to packages
I'm not sure I follow on why binary packages make it easier to reduce dependencies between packages, or why binary packages offer faster installs. I'm guessing that binary packages prevent cyclic dependencies between packages, but it seems like there are many other options that still get this side effect. Such as explicit checks when building the package. For faster installs, the only benefit I see of binary packages over precompiled source packages is a small savings in size which doesn't seem like it would amount to much of the install time. Can someone explain the claims for binary packages? On Mon, May 20, 2013 at 8:57 PM, Jon Zeppieri zeppi...@gmail.com wrote: On Mon, May 20, 2013 at 10:04 PM, Neil Van Dyke n...@neilvandyke.org wrote: [snip] Example: Imagine I'm in the middle of writing a Racket program and am wondering about characteristics of some kind of I/O port in Racket. With transparent source accessibility, I can just click on an identifier in my program in DrRacket to start browsing the implementation. Maybe I see a possible improvement, or seeing the source pre-empts yet another email list question that otherwise only Matthew could answer, or I feel empowered to go add a new feature. If the source is not as accessible, then I'm more likely to be a mere naive user of the tools, rather than to understand the tools and help improve them. +inf.0 Though the easiest way to make the source available is just to keep it in the distribution. I'll be sad to see it go. -Jon _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #26861: master branch updated
This doesn't pass with contract checking enabled. make-StructTop requires a Struct? not any old Type?. Is there a reason that the type is not just bottom? On Sun, May 19, 2013 at 5:33 PM, as...@racket-lang.org wrote: asumu has updated `master' from d9102ac7e7 to 3eb4a75613. http://git.racket-lang.org/plt/d9102ac7e7..3eb4a75613 =[ One Commit ]= Directory summary: 46.8% collects/tests/typed-racket/fail/ 53.1% collects/typed-racket/private/ ~~ 3eb4a75 Asumu Takikawa as...@racket-lang.org 2013-05-19 20:31 : | Fix parsing of (Struct ...) types. | | This was a regression that appeared in 5.3.1 : A collects/tests/typed-racket/fail/bad-struct-top.rkt M collects/typed-racket/private/parse-type.rkt | 4 ++-- =[ Overall Diff ]=== collects/tests/typed-racket/fail/bad-struct-top.rkt ~~~ --- /dev/null +++ NEW/collects/tests/typed-racket/fail/bad-struct-top.rkt @@ -0,0 +1,7 @@ +#; +(exn:pred #rxArgument to Struct must be a structure) +#lang typed/racket + +;; Make sure `Struct` constructor rejects bad arguments +(: x (Struct Integer)) + collects/typed-racket/private/parse-type.rkt --- OLD/collects/typed-racket/private/parse-type.rkt +++ NEW/collects/typed-racket/private/parse-type.rkt @@ -177,9 +177,9 @@ (add-disappeared-use #'kw) (let ([v (parse-type #'t)]) (match (resolve v) - [(and s Struct?) (make-StructTop s)] + [(and s (? Struct?)) (make-StructTop s)] [_ (tc-error/delayed Argument to Struct must be a structure type, got ~a v) - (make-Instance (Un))]))] + (make-StructTop (Un))]))] [((~and kw t:Instance) t) (add-disappeared-use #'kw) (let ([v (parse-type #'t)]) _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #26832: master branch updated
On Mon, May 13, 2013 at 2:14 PM, as...@racket-lang.org wrote: asumu has updated `master' from a857256c77 to f3e6276f9b. http://git.racket-lang.org/plt/a857256c77..f3e6276f9b =[ One Commit ]= Directory summary: 29.0% collects/tests/typed-racket/succeed/ 70.9% collects/typed-racket/typecheck/ ~~ f3e6276 Asumu Takikawa as...@racket-lang.org 2013-05-13 16:47 : | Make `define-type` work at top-level | | Closes PR 12913 : A collects/tests/typed-racket/succeed/pr12913.rkt M collects/typed-racket/typecheck/tc-toplevel.rkt | 14 +++--- =[ Overall Diff ]=== collects/tests/typed-racket/succeed/pr12913.rkt ~~~ --- /dev/null +++ NEW/collects/tests/typed-racket/succeed/pr12913.rkt @@ -0,0 +1,10 @@ +#lang racket + +;; Test that `define-type` works at the top-level + +(define ns (make-base-namespace)) +(eval '(require typed/racket) ns) +(eval '(define-type Foo (U String Symbol)) ns) +(eval '(: x Foo) ns) +(eval '(define x 'x) ns) + Is there a reason to do this this way instead of using racket/load? collects/typed-racket/typecheck/tc-toplevel.rkt ~~~ --- OLD/collects/typed-racket/typecheck/tc-toplevel.rkt +++ NEW/collects/typed-racket/typecheck/tc-toplevel.rkt @@ -417,7 +417,15 @@ ;; used only from #%top-interaction ;; syntax - (values #f (or/c void? tc-results/c)) (define (tc-toplevel-form form) - (tc-toplevel/pass1 form) - (begin0 (values #f (tc-toplevel/pass2 form)) - (report-all-errors))) + (syntax-parse form +[((~literal begin) e ...) + (for-each tc-toplevel-form (syntax-list #'(e ...))) + (begin0 (values #f (tc-toplevel/pass2 form)) + (report-all-errors))] Isn't this going to tc-loplevel/pass2 the interernal forms of the begin multiple times? +[_ + (when ((internal-syntax-pred define-type-alias-internal) form) + ((compose register-type-alias parse-type-alias) form)) + (tc-toplevel/pass1 form) + (begin0 (values #f (tc-toplevel/pass2 form)) + (report-all-errors))])) _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] else clauses: possible change to match?
Keywords are normally right because they are syntactically distinct from expressions --- and so using a keyword avoids various potential ambiguities and sources of confusion. Isn't this only true for default bindings of #%datum? It seems like macros which assume this lose compatibility with #langs that allow keywords as expressions. I'm not sure whether we want to support that or not, but it seems wrong to say that they are syntatically distinct from expressions. On Sun, May 5, 2013 at 9:03 AM, Eli Barzilay e...@barzilay.org wrote: [shuffled] Yesterday, Matthew Flatt wrote: Meanwhile, it might be worth adding support for `#:else' to `cond', `case', and `match'. That would be backward compatible, and we could see whether we like it enough to do things that way in `racket2'. 1. Doesn't that make an argument against using traditional keywords? Perhaps it's a point for having more symbolic comparisons for keywords? (I'm not objecting to keywords -- just trying to figure out the implications of such a move.) IOW, if all such things switched to #:keywords, what would be a good use case for identifiers? 2. Can we also think of a better keyword syntax in racket2 if it's going to be used more? IIRC, the main arguments against `foo:' or `:foo' were existing code, but existing code will need to be modified... 3. And a side-comment: I hope that there will be something better than actual `racket2' used in code... Maybe rename the current one to `racket1' and possibly have code in packages use that unless it's declared new somehow? (The following is all filed under a non-important comment.) Well, Ian provided an example from real code, right? Ian is willing to change his code, but the code sounds real. There's also the use in `unparse-pattern' in Redex. Maybe that's the troublesome one that Robby has in mind changing (or he would be happy to change it, obviously), but it's another real example. IIUC, Ian said that he doesn't actually use that code, and the redex use is exactly what would get unbroken (I think, I didn't look at the code). I'm just saying that there are cases where it's worth breaking strict compatibility if it fixes more code than it breaks -- having (+ 1 2) = 4 is an exaggerated case of this, and relying on `else' being bound seems like it's closer to that end. Especially given that (match x ... [else ... else ...]) would usually be a quick unbound identifier error. (And BTW, I think that `match' is also an exceptional example in how this will go: (let ([else 1]) (match x [else ...])) which is a little more confusing than the same with `cond'.) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] racket2 suggestion: removing (or extending) eqv?
The mutability argument does not hold in Racket. non eq? things can be mutated and affect each other using chaperones and impersonators. On Sat, May 4, 2013 at 5:27 PM, John Gateley rac...@jfoo.org wrote: Personal opinion: performance is a dangerous motivator. Yes, it is a necessity, but it is often abused as a reason to do something. There's a semantic difference between eq? and equal? from the point of view of mutability. Two objects are eq? if modifying one also modifies the other. They are equal? but not eq? if they are the same, but modifying one will not modify the other. I know I'm in a minority here, but I like mutable objects, and this distinction between eq? and equal? is important. For characters, the mutability argument fails: I don't think characters, even multi-byte characters, should be mutable. Thus, they should be eq?. Just my 2 cents, John On 5/4/2013 12:06 PM, Robby Findler wrote: Well, I'm not sure that I buy that motivation, since I think decisions about what should be eq? to what should be driven by performance (and eq? should only be used for performance) but lets put that aside. There are some unused bits in Racket's runtime representation of values, namely when a value's bit representation ends in 10, we know that it isn't a fixnum (since it doesn't end with 1) and that it isn't a pointer (since pointers have end with 00 (at least)), so I think that means that we could have all of the unicode code points represented in a way that requires no allocation (currently, iiuc, the ASCII characters are just pre-allocated at the runtime startup; they require no allocation because you always just get the same pointer). This is a pretty big change, however, so I'm not sure it would be worth it. Robby On Sat, May 4, 2013 at 11:56 AM, Jon Zeppieri zeppi...@gmail.com mailto:zeppi...@gmail.com wrote: Something about my response below has been bothering me, and I think I know what it is: the correspondence between characters and the fixnums that represent their code points seems -- how to put it? -- more complete if it extends to their equality predicates. So, yeah, in addition to performance, there's an aesthetic motivation, too. On May 4, 2013, at 12:03 PM, Jon Zeppieri zeppi...@gmail.com mailto:zeppi...@gmail.com wrote: Just for performance. No other reason. -Jon On Sat, May 4, 2013 at 12:01 PM, Robby Findler ro...@eecs.northwestern.edu mailto:ro...@eecs.northwestern.edu wrote: I'm curious: why do you want all characters to be eq? to each other instead of just equal?? Robby On Sat, May 4, 2013 at 10:57 AM, Jon Zeppieri zeppi...@gmail.com mailto:zeppi...@gmail.com wrote: Since incompatible future changes seem to be coming up a lot, I thought I'd add one more. What do the members of this list think of removing eqv? all of its associated machinery (e.g., memv, hasheqv, etc.)? (Along with this change, it would be nice if characters could all be immediately represented, so that those with equal code points would be eq? RIght now, all unicode code points can be encoded in 22 bits, I think. I'm not so familiar with racket's current representation of characters, but I figure that they could easily be fit into a single machine word on 64-bit builds. I don't know how difficult it would be on 32-bit builds. And, of course, there's no guarantee that the number of code points won't increase significantly.) Alternatively (and following Sam's line of thought from [1]), eqv? could be extended to cover all of racket's immutable data structures. In this case eqv? should also be made generic so that user-defined immutable data structures can use it, as well. [1] http://lists.racket-lang.org/users/archive/2013-April/057510.html _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] seeing compile-time error for Whalesong on HEAD
LGTM, can you submit a testcase or at least a bug so that we can add a test case for this code path? On Mon, Apr 29, 2013 at 4:42 PM, Danny Yoo d...@hashcollision.org wrote: I believe the right fix for this is: https://github.com/dyoo/racket/commit/24d03f2bf308854deb365fe8bcf6599e8d84fab9 but I do not have enough comfort with TR to know if this will break anything. Can someone review this? Thanks! _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] seeing compile-time error for Whalesong on HEAD
I submitted a commit on Thursday which changed the contract generation code, to introduce the buggy behavior. So thats why there wasn't an error until now. It should be during module compilation where the error is raised, so that should narrow it down. I'll try to take a look tonight if you cannot get a small testcase. On Mon, Apr 29, 2013 at 5:16 PM, Danny Yoo d...@hashcollision.org wrote: Yeah, I want to reduce this to a test case, but I haven't been able to figure out yet what part of Whalesong is tickling this one. I'm also a bit confused, as this part of the code hasn't been touched in months, and so I would have expected the error to show up much sooner. Unfortunately, I don't have time today to git bisect to find out at what point this got exposed. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] how to define a custom null in typed racket
You shouldn't be able to send the TR into an inifinite loop. Typechecking is supposed to terminate. Please try to reduce it to the minimum testcase and file a bug. On Thu, Apr 11, 2013 at 3:32 PM, Danny Yoo d...@hashcollision.org wrote: Perhaps something like this? ; #lang typed/racket/base (provide mynull mycar mycdr) (struct: MyNull ()) (define mynull (MyNull)) (define-type MyListof (All (A) (Rec X (U MyNull (Pair A X) (: mycar : (All (A) ((MyListof A) - A))) (define (mycar lst) (if (MyNull? lst) (error 'mycar given list is empty) (car lst))) (: mycdr : (All (A) ((MyListof A) - (MyListof A (define (mycdr lst) (if (MyNull? lst) (error 'mycdr given list is empty) (cdr lst))) ; where mynull is the singleton instance of the opaque structure type MyNull. _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] typed racket errors in current build?
I'm having trouble finding any file with that name in the repo, do you know the full path? On Sat, Apr 6, 2013 at 2:07 PM, Robby Findler ro...@eecs.northwestern.edu wrote: I'm getting this error when I rebuild (sometimes). It doesn't seem to happen in drdr and so maybe it happens only when some files are re-compiled but others aren't? Robby skal_flymake.rkt:119:17: Type Checker: Polymorphic function make-Node could not be applied to arguments: Argument 1: Expected: A Given:A35636 Argument 2: Expected: (U (Leaf A) (Node A)) Given:(U (Node A35648) (Leaf A35648)) Argument 3: Expected: (U (Leaf A) (Node A)) Given:(U (Node A35648) (Leaf A35648)) Result type: (Node A) Expected result: (U (Node A35648) (Leaf A35648)) in: (Node (update first) left right) context...: /Users/robby/git/plt/collects/typed-racket/utils/tc-utils.rkt:95:12: for-loop f16 /Users/robby/git/plt/collects/typed-racket/typecheck/tc-toplevel.rkt:295:0: type-check success /Users/robby/git/plt/collects/typed-racket/typed-racket.rkt:61:4 /Users/robby/git/plt/collects/compiler/cm.rkt:360:0: compile-zo* /Users/robby/git/plt/collects/compiler/cm.rkt:567:26 /Users/robby/git/plt/collects/compiler/cm.rkt:560:42 /Users/robby/git/plt/collects/compiler/cm.rkt:525:0: maybe-compile-zo /Users/robby/git/plt/collects/compiler/cm.rkt:638:2: do-check /Users/robby/git/plt/collects/compiler/cm.rkt:719:4 /Users/robby/git/plt/collects/setup/parallel-do.rkt:420:20: loop _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #26558: master branch updated
Can we make it so that IP addresses are immutable? This would require changing make-ip-address to have a call to make-immutable-bytes in each case. On Thu, Apr 4, 2013 at 10:07 AM, as...@racket-lang.org wrote: asumu has updated `master' from 8246d073c0 to 92102a2f07. http://git.racket-lang.org/plt/8246d073c0..92102a2f07 =[ 2 Commits ]== Directory summary: 55.6% collects/net/private/ 44.3% collects/net/ ~~ 4e76ae8 Asumu Takikawa as...@racket-lang.org 2013-04-03 15:05 : | Add an IP address library | | The library currently lives in a private subfolder so | that the interface can still be changed. The idea is to | eventually make it a top-level `net` library once it is | more mature. : A collects/net/private/ip.rkt ~~ 92102a2 Asumu Takikawa as...@racket-lang.org 2013-04-04 11:53 : | Use net/private/ip in net/dns | | This simplifies the code by outsourcing IP | address functionality to net/private/ip. : M collects/net/dns.rkt | 230 +--- =[ Overall Diff ]=== collects/net/dns.rkt --- OLD/collects/net/dns.rkt +++ NEW/collects/net/dns.rkt @@ -2,7 +2,8 @@ ;; DNS query library for Racket -(require racket/bool +(require private/ip.rkt + racket/bool racket/contract racket/format racket/list @@ -14,13 +15,17 @@ (provide (contract-out [dns-get-address - (-* (ip-address-string? string?) + (-* ((or/c ip-address? ip-address-string?) string?) (#:ipv6? any/c) ip-address-string?)] [dns-get-name - (- ip-address-string? ip-address-string? string?)] + (- (or/c ip-address? ip-address-string?) + (or/c ip-address? ip-address-string?) + string?)] [dns-get-mail-exchanger - (- ip-address-string? string? (or/c bytes? string?))] + (- (or/c ip-address? ip-address-string?) + string? + (or/c bytes? string?))] [dns-find-nameserver (- (or/c ip-address-string? #f))])) @@ -29,95 +34,8 @@ ;; UDP retry timeout: (define INIT-TIMEOUT 50) -;; Contract utilities and Data Definitions -;; +;; Data Definitions ;; An LB is a (Listof Bytes) -;; -;; An IPAddressString passes the following predicate -(define (ip-address-string? val) - (and (string? val) - (or (ipv4-string? val) - (ipv6-string? val - -;; String - Boolean -;; Check if the input string represents an IPv4 address -(define (ipv4-string? str) - ;; String - Boolean - ;; check if the given string has leading zeroes - (define (has-leading-zeroes? str) -(and ( (string-length str) 1) - (char=? (string-ref str 0) #\0))) - (define matches -(regexp-match #px^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$ - str)) - (and matches - (= (length matches) 5) - ;; check that each octet field is an octet - (andmap byte? (map string-number (cdr matches))) - ;; leading zeroes lead to query errors - (not (ormap has-leading-zeroes? matches - -;; String - Boolean -;; Check if the input string represents an IPv6 address -;; TODO: support dotted quad notation -(define (ipv6-string? str) - (define re-::/: #px^([0-9a-fA-F]{1,4})(::|:)) - (define re-:: #px^()(::)) - (define re-: #px^([0-9a-fA-F]{1,4})(:)) - (define re-end #px^[0-9a-fA-F]{1,4}$) - (or (regexp-match? #px^::$ str) ; special case - (let loop ([octet-pairs '()] ; keep octet-pairs to count - [::? #f] ; seen a :: in the string yet? - [str str]) -;; match digit groups and a separator -(define matches - (if ::? - (regexp-match re-: str) - (or (regexp-match re-:: str) - (regexp-match re-::/: str -(cond [matches - (match-define (list match digits sep) matches) - (define rest (substring str (string-length match))) - ;; we need to make sure there is only one :: at most - (if (or ::? (string=? sep ::)) - (loop (cons digits octet-pairs) #t rest) - (loop (cons digits octet-pairs) #f rest))] - [else - (and ;; if there isn't a ::, we need 7+1 octet-pairs -(implies (not ::?) (= (length octet-pairs) 7)) -;; this is the +1 octet pair -(regexp-match? re-end str))] - -(module+ test - (check-true (ip-address-string? 8.8.8.8)) - (check-true (ip-address-string? 12.81.255.109)) - (check-true (ip-address-string? 192.168.0.1)) - (check-true (ip-address-string?
Re: [racket-dev] [plt] Push #26558: master branch updated
Sorry make-immutable-bytes should be bytes-immutable-bytes. On Thu, Apr 4, 2013 at 10:29 AM, Eric Dobson eric.n.dob...@gmail.com wrote: Can we make it so that IP addresses are immutable? This would require changing make-ip-address to have a call to make-immutable-bytes in each case. On Thu, Apr 4, 2013 at 10:07 AM, as...@racket-lang.org wrote: asumu has updated `master' from 8246d073c0 to 92102a2f07. http://git.racket-lang.org/plt/8246d073c0..92102a2f07 =[ 2 Commits ]== Directory summary: 55.6% collects/net/private/ 44.3% collects/net/ ~~ 4e76ae8 Asumu Takikawa as...@racket-lang.org 2013-04-03 15:05 : | Add an IP address library | | The library currently lives in a private subfolder so | that the interface can still be changed. The idea is to | eventually make it a top-level `net` library once it is | more mature. : A collects/net/private/ip.rkt ~~ 92102a2 Asumu Takikawa as...@racket-lang.org 2013-04-04 11:53 : | Use net/private/ip in net/dns | | This simplifies the code by outsourcing IP | address functionality to net/private/ip. : M collects/net/dns.rkt | 230 +--- =[ Overall Diff ]=== collects/net/dns.rkt --- OLD/collects/net/dns.rkt +++ NEW/collects/net/dns.rkt @@ -2,7 +2,8 @@ ;; DNS query library for Racket -(require racket/bool +(require private/ip.rkt + racket/bool racket/contract racket/format racket/list @@ -14,13 +15,17 @@ (provide (contract-out [dns-get-address - (-* (ip-address-string? string?) + (-* ((or/c ip-address? ip-address-string?) string?) (#:ipv6? any/c) ip-address-string?)] [dns-get-name - (- ip-address-string? ip-address-string? string?)] + (- (or/c ip-address? ip-address-string?) + (or/c ip-address? ip-address-string?) + string?)] [dns-get-mail-exchanger - (- ip-address-string? string? (or/c bytes? string?))] + (- (or/c ip-address? ip-address-string?) + string? + (or/c bytes? string?))] [dns-find-nameserver (- (or/c ip-address-string? #f))])) @@ -29,95 +34,8 @@ ;; UDP retry timeout: (define INIT-TIMEOUT 50) -;; Contract utilities and Data Definitions -;; +;; Data Definitions ;; An LB is a (Listof Bytes) -;; -;; An IPAddressString passes the following predicate -(define (ip-address-string? val) - (and (string? val) - (or (ipv4-string? val) - (ipv6-string? val - -;; String - Boolean -;; Check if the input string represents an IPv4 address -(define (ipv4-string? str) - ;; String - Boolean - ;; check if the given string has leading zeroes - (define (has-leading-zeroes? str) -(and ( (string-length str) 1) - (char=? (string-ref str 0) #\0))) - (define matches -(regexp-match #px^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$ - str)) - (and matches - (= (length matches) 5) - ;; check that each octet field is an octet - (andmap byte? (map string-number (cdr matches))) - ;; leading zeroes lead to query errors - (not (ormap has-leading-zeroes? matches - -;; String - Boolean -;; Check if the input string represents an IPv6 address -;; TODO: support dotted quad notation -(define (ipv6-string? str) - (define re-::/: #px^([0-9a-fA-F]{1,4})(::|:)) - (define re-:: #px^()(::)) - (define re-: #px^([0-9a-fA-F]{1,4})(:)) - (define re-end #px^[0-9a-fA-F]{1,4}$) - (or (regexp-match? #px^::$ str) ; special case - (let loop ([octet-pairs '()] ; keep octet-pairs to count - [::? #f] ; seen a :: in the string yet? - [str str]) -;; match digit groups and a separator -(define matches - (if ::? - (regexp-match re-: str) - (or (regexp-match re-:: str) - (regexp-match re-::/: str -(cond [matches - (match-define (list match digits sep) matches) - (define rest (substring str (string-length match))) - ;; we need to make sure there is only one :: at most - (if (or ::? (string=? sep ::)) - (loop (cons digits octet-pairs) #t rest) - (loop (cons digits octet-pairs) #f rest))] - [else - (and ;; if there isn't a ::, we need 7+1 octet-pairs -(implies (not ::?) (= (length octet-pairs) 7)) -;; this is the +1 octet pair -(regexp-match? re-end str))] - -(module+ test - (check-true (ip-address-string? 8.8.8.8)) - (check-true (ip-address
[racket-dev] Purpose of typed/racket/no-check
There have been a couple recent bug reports because certain features need a type, such as cast and define-predicate. I was wondering whether TR/no-check should check that the types are well formed, but not check that the expressions are well typed? I'm thinking this would be less surprising to users, but wondering whether users would expect that type definition errors to still work in TR/no-check. _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Expansion of optional arguments in lambda
lambda supports optional arguments, and does this by expanding out into a core form that has flag arguments for if each argument is supplied. This is tricky to type in TR and so I was investigating why it did it this way. I did a micro benchmark on another method of expansion and it was 60% faster. Is there a reason that racket does it the current way that I am missing. #lang racket (define f (case-lambda (() (f 1)) ((a) (f a (+ 3 a))) ((a b) (f a b (* a b))) ((a b c) (f a b c (- a (/ c b ((a b c d) (+ a b c d (define (g (a 1) (b (+ 3 a)) (c (* a b)) (d (- a (/ c b (+ a b c d)) (define N 100) (collect-garbage) (collect-garbage) (time (for ((i (in-range N))) (f i))) (collect-garbage) (collect-garbage) (time (for ((i (in-range N))) (g i))) (collect-garbage) (collect-garbage) (time (for ((i (in-range N))) (f i))) (collect-garbage) (collect-garbage) (time (for ((i (in-range N))) (g i))) _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Expansion of optional arguments in lambda
I think I figured out the actual answer which is semantics. If the arguments are ever set!ed then my implementation will lead to a different value. (define (f a (b (begin (set! a 2) 3))) a) This should return 2 if b is not supplied, but in my expansion it would return what ever was supplied for a. On Sun, Feb 24, 2013 at 11:14 AM, Matthew Flatt mfl...@cs.utah.edu wrote: At Sun, 24 Feb 2013 09:51:12 -0800, Eric Dobson wrote: lambda supports optional arguments, and does this by expanding out into a core form that has flag arguments for if each argument is supplied. This is tricky to type in TR and so I was investigating why it did it this way. I did a micro benchmark on another method of expansion and it was 60% faster. Is there a reason that racket does it the current way that I am missing. #lang racket (define f (case-lambda (() (f 1)) ((a) (f a (+ 3 a))) ((a b) (f a b (* a b))) ((a b c) (f a b c (- a (/ c b ((a b c d) (+ a b c d (define (g (a 1) (b (+ 3 a)) (c (* a b)) (d (- a (/ c b (+ a b c d)) I'll have to investigate more, but I don't think the story is simple. Below are the decompiled forms, and you'll see that they're essentially the same, due to inlining and other compiler optimizations. Part of the answer is probably how the different forms interact with inlining in the timing loops. If I change the code to (define-values (f g) (let () (define f ) (define g ) (values f g))) (set! f f) (set! g g) after the definition of `g', then performance is the same for the `f' and `g' (with a tiny difference that may be due to the order of clauses in `f' and `g'). You may also want to look at performance in the case that the eventual body cannot be inlined (e.g., because it's too large). Then, I think the chain of applications for `f' will probably be significantly worse than the more direct implementation of `g'. (define-values (_f) (case-lambda (() '#(/private/tmp/c.rkt:5:4 #path:/private/tmp/c.rkt 5 4 44 10 #t) '(flags: preserves-marks single-result) '9) ((arg0-12) '#(/private/tmp/c.rkt:6:4 #path:/private/tmp/c.rkt 6 4 59 19 #t) '(flags: preserves-marks single-result) (let ((local13 (+ '3 arg0-12))) (let ((local16 (* arg0-12 local13))) (+ arg0-12 local13 local16 (- arg0-12 (/ local16 local13)) ((arg0-27 arg1-28) '#(/private/tmp/c.rkt:7:4 #path:/private/tmp/c.rkt 7 4 83 23 #t) '(flags: preserves-marks single-result) (let ((local29 (* arg0-27 arg1-28))) (+ arg0-27 arg1-28 local29 (- arg0-27 (/ local29 arg1-28) ((arg0-40 arg1-41 arg2-42) '#(/private/tmp/c.rkt:8:4 #path:/private/tmp/c.rkt 8 4 111 33 #t) '(flags: preserves-marks single-result) (+ arg0-40 arg1-41 arg2-42 (- arg0-40 (/ arg2-42 arg1-41 ((arg0-51 arg1-52 arg2-53 arg3-54) '#(/private/tmp/c.rkt:9:4 #path:/private/tmp/c.rkt 9 4 149 23 #t) '(flags: preserves-marks single-result) (+ arg0-51 arg1-52 arg2-53 arg3-54 (define-values (_g) (case-lambda (() '(flags: preserves-marks single-result) '9) ((arg0-59 arg1-60 arg2-61 arg3-62) '(flags: preserves-marks single-result) (+ arg0-59 arg1-60 arg2-61 arg3-62)) ((arg0-67 arg1-68 arg2-69) '(flags: preserves-marks single-result) (+ arg0-67 arg1-68 arg2-69 (- arg0-67 (/ arg2-69 arg1-68 ((arg0-78 arg1-79) '(flags: preserves-marks single-result) (let ((local80 (* arg0-78 arg1-79))) (+ arg0-78 arg1-79 local80 (- arg0-78 (/ local80 arg1-79) ((arg0-91) '(flags: preserves-marks single-result) (let ((local92 (+ '3 arg0-91))) (let ((local95 (* arg0-91 local92))) (+ arg0-91 local92 local95 (- arg0-91 (/ local95 local92) _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Typed versions of untyped collections
It is getting exactly the same file as R, except there is a special file in the TR code that gives types to some bindings (all of the ones from racket). Your new module's bindings are not in this file. https://github.com/plt/racket/blob/master/collects/typed-racket/base-env/base-env.rkt On Mon, Dec 17, 2012 at 1:16 PM, Robby Findler ro...@eecs.northwestern.eduwrote: I don't understand Matthias's performance comments. If, in TR (require plot) actually gives me a typed version of the library and in R (require plot) gives me the untyped version of the library, then I am avoiding the performance the untyped/typed performance overhead properly. If, on the other hand, if I have to commit that (require plot) gives me either the untyped or the typed version, then I have to suffer the performance overhead when I require it from the wrong context. Neil's original complaint also has validity, I think: if he provides a plot/typed today, and then later ports plot so it is typed, then he has to keep this extra thing around for what appears to not be a very good reason. And while I do understand Sam's reluctance to mess with module resolution, I think that just not solving this problem is worse. And finally (and perhaps this is the root of the problem), I cannot understand what TR actually does by reading its documentation. For example, the docs for 'require' do not explain why I can make a copy of list.rkt (in the racket collection), call the copy listt.rkt and have that copy not work, but the original one does. Clearly TR is not just get[ting] *exactly* the same file as in R, so I think Sam's comments are off base. Robby On Mon, Dec 17, 2012 at 2:51 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Mon, Dec 17, 2012 at 3:27 PM, Robby Findler ro...@eecs.northwestern.edu wrote: I've long thought something along these lines is a good idea, but perhaps what I think is a good idea isn't what Matthias and Sam think is the bad idea. I think that it makes sense for 'require' in typed-racket to look in a different place than 'require' in untyped racket looks so that one can write the same require spec (in both the docs and the code) and have two versions of the same library, one that is typed and one that isn't typed. Then, then library writer, if they choose, can decide who pays what for going (or not) across the boundary between typed and untyped. (Or maybe submodules would be better.) I think this is exactly what Eli was suggesting, and what I think is a bad idea. I think this is already happening in TR anyways, when I write (require racket/list) I don't get the same file being loaded when that is in a TR program as when it is in a R program. You get *exactly* the same file as in R. I think that (a) this is a valuable invariant and (b) the mechanisms for violating this invariant are all very worrying. Sam _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Embedding racket in vim
Yes I was using the official source. Here is the patch of my changes, some of which you may already have. diff -r 52bfa939fc07 src/auto/configure --- a/src/auto/configure Thu Dec 06 21:30:29 2012 +0100 +++ b/src/auto/configure Sun Dec 16 14:37:19 2012 -0800 @@ -4927,7 +4927,8 @@ if test X$vi_cv_path_mzscheme_pfx != X; then if test x$MACOSX = xyes; then - MZSCHEME_LIBS=-framework PLT_MzScheme + MZSCHEME_LIBS=-framework Racket + MZSCHEME_CFLAGS=-DMZ_PRECISE_GC elif test -f ${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a; then MZSCHEME_LIBS=${vi_cv_path_mzscheme_pfx}/lib/libmzscheme3m.a MZSCHEME_CFLAGS=-DMZ_PRECISE_GC @@ -4968,6 +4969,10 @@ else if test -d $vi_cv_path_mzscheme_pfx/share/racket/collects; then SCHEME_COLLECTS=$vi_cv_path_mzscheme_pfx/share/racket/ +else + if test -d $vi_cv_path_mzscheme_pfx/collects; then +SCHEME_COLLECTS=$vi_cv_path_mzscheme_pfx/ + fi fi fi fi diff -r 52bfa939fc07 src/if_mzsch.c --- a/src/if_mzsch.c Thu Dec 06 21:30:29 2012 +0100 +++ b/src/if_mzsch.c Sun Dec 16 14:37:19 2012 -0800 @@ -183,6 +183,8 @@ } static int buffer_fixup_proc(void *obj) { +vim_mz_buffer* buf = (vim_mz_buffer*) obj; +buf-buf-b_mzscheme_ref = GC_fixup_self(obj); return buffer_size_proc(obj); } static int window_size_proc(void *obj UNUSED) @@ -195,6 +197,8 @@ } static int window_fixup_proc(void *obj) { +vim_mz_window* win = (vim_mz_window*) obj; +win-win-w_mzscheme_ref = GC_fixup_self(obj); return window_size_proc(obj); } #endif @@ -861,6 +865,12 @@ scheme_set_stack_base(stack_base, 1); #endif +#ifndef TRAMPOLINED_MZVIM_STARTUP +/* in newer versions of precise GC the initial env has been created */ +environment = scheme_basic_env(); +#endif +MZ_GC_CHECK(); + MZ_REGISTER_STATIC(environment); MZ_REGISTER_STATIC(curout); MZ_REGISTER_STATIC(curerr); @@ -869,10 +879,6 @@ MZ_REGISTER_STATIC(exn_message); MZ_REGISTER_STATIC(vim_exn); -#ifndef TRAMPOLINED_MZVIM_STARTUP -/* in newer versions of precise GC the initial env has been created */ -environment = scheme_basic_env(); -#endif MZ_GC_CHECK(); #ifdef INCLUDE_MZSCHEME_BASE @@ -925,11 +931,7 @@ MZ_GC_CHECK(); coll_path = scheme_char_string_to_path(coll_char_string); MZ_GC_CHECK(); - coll_pair = scheme_make_pair(coll_path, scheme_null); - MZ_GC_CHECK(); - config = scheme_config; - MZ_GC_CHECK(); - scheme_set_param(config, MZCONFIG_COLLECTION_PATHS, coll_pair); +scheme_set_collects_path(coll_path); MZ_GC_CHECK(); MZ_GC_UNREG(); } @@ -1016,10 +1018,10 @@ #ifdef MZ_PRECISE_GC GC_register_traversers(mz_buffer_type, buffer_size_proc, buffer_mark_proc, buffer_fixup_proc, -TRUE, TRUE); +TRUE, FALSE); GC_register_traversers(mz_window_type, window_size_proc, window_mark_proc, window_fixup_proc, -TRUE, TRUE); +TRUE, FALSE); #endif make_modules(); @@ -1652,7 +1654,7 @@ if (win-w_mzscheme_ref != NULL) return win-w_mzscheme_ref; -self = scheme_malloc_fail_ok(scheme_malloc, sizeof(vim_mz_window)); +self = scheme_malloc_fail_ok(scheme_malloc_tagged, sizeof(vim_mz_window)); vim_memset(self, 0, sizeof(vim_mz_window)); scheme_dont_gc_ptr(self); /* because win isn't visible to GC */ MZ_GC_CHECK(); @@ -1977,7 +1979,7 @@ if (buf-b_mzscheme_ref) return buf-b_mzscheme_ref; -self = scheme_malloc_fail_ok(scheme_malloc, sizeof(vim_mz_buffer)); +self = scheme_malloc_fail_ok(scheme_malloc_tagged, sizeof(vim_mz_buffer)); vim_memset(self, 0, sizeof(vim_mz_buffer)); scheme_dont_gc_ptr(self); /* because buf isn't visible to GC */ MZ_GC_CHECK(); @@ -2298,8 +2300,8 @@ MZ_GC_VAR_IN_REG(1, rest); MZ_GC_REG(); -array = (char **)alloc(new_len * sizeof(char *)); -vim_memset(array, 0, new_len * sizeof(char *)); +array = (char **)alloc((new_len + 1) * sizeof(char *)); +vim_memset(array, 0, (new_len + 1) * sizeof(char *)); rest = line_list; for (i = 0; i new_len; ++i) @@ -2481,8 +2483,8 @@ MZ_GC_VAR_IN_REG(1, rest); MZ_GC_REG(); - array = (char **)alloc(size * sizeof(char *)); - vim_memset(array, 0, size * sizeof(char *)); + array = (char **)alloc((size + 1) * sizeof(char *)); + vim_memset(array, 0, (size + 1) * sizeof(char *)); rest = list; for (i = 0; i size; ++i) On Fri, Dec 14, 2012 at 9:05 AM, Sergey Khorev sergey.kho...@gmail.comwrote: On Fri, Dec 14, 2012 at 9:20 AM, Eric Dobson eric.n.dob...@gmail.comwrote: I figured this out. It was that vim was not being compiled with the precise garbage collection when racket was, and a couple of bugs on the vim allocation of racket objects. I'll hopefully have a patch soon. Are you talking about official Vim source? For http://code.google.com/r/sergeykhorev-vim-mzscheme/source I reworked some memory allocation stuff so something must have changed in this regard
Re: [racket-dev] Embedded racket is much slower in thread 'heavy' programs
That fixed it. It is still a bit slower but it is now much closer and good enough for me. (0.945068359375 1.10400390625 0.961181640625) On Fri, Dec 14, 2012 at 5:28 AM, Matthew Flatt mfl...@cs.utah.edu wrote: At Thu, 13 Dec 2012 22:57:54 -0800, Eric Dobson wrote: I have a program which is thread 'heavy' and runs much slower in embedded racket (vim) than it does in pure racket. [...] If I don't do in in a separate thread, then vim is comparable because it is using the racket scheduler, and not calling scheme_check_threads. Vim calls scheme_check_threads every bit (I think 10 times a second), but it looks like not much progress is made on each of these steps. I can understand if it was slightly slower, but a factor of over 50k is a bit too much. Is it possible for scheme_check_threads to do more work on each invocation in a scenario like this? Yes, I think it would make sense for scheme_check_threads() to loop with its current body until either one thread quantum (10ms) has passed or check_sleep() returns 1 to indicate that no threads are ready to run. Does the variant below help? void scheme_check_threads(void) { double start, now; start = scheme_get_inexact_milliseconds(); while (1) { scheme_current_thread-suspend_break++; scheme_thread_block((float)0); --scheme_current_thread-suspend_break; if (check_sleep(have_activity, 0)) break; now = scheme_get_inexact_milliseconds(); if (((now - start) * 1000) MZ_THREAD_QUANTUM_USEC) break; } } _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Embedding racket in vim
I figured this out. It was that vim was not being compiled with the precise garbage collection when racket was, and a couple of bugs on the vim allocation of racket objects. I'll hopefully have a patch soon. On Mon, Dec 10, 2012 at 10:32 PM, Eric Dobson eric.n.dob...@gmail.comwrote: +correct vim group. On Mon, Dec 10, 2012 at 10:25 PM, Eric Dobson eric.n.dob...@gmail.comwrote: I have recently installed a version of vim with the mzscheme option enabled. And it sortof works except that some times it segfaults or has other memory corruption issues. So I enabled MZ_GC_CHECK when compiling vim, and now I get the corruption every single time on startup. Here is the output from gdb when running it: GNU gdb 6.3.50-20050815 (Apple version gdb-1820) (Sat Jun 16 02:40:11 UTC 2012) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type show copying to see the conditions. There is absolutely no warranty for GDB. Type show warranty for details. This GDB was configured as x86_64-apple-darwin... warning: Unable to read symbols for Racket.framework/Versions/5.3.1.9_3m/Racket (file not found). warning: Unable to read symbols from Racket (not yet mapped into memory). Reading symbols for shared libraries .. done (gdb) run Starting program: /Users/endobson/proj/vim/install/bin/vim Reading symbols for shared libraries .+... done Reading symbols for shared libraries . done ?: bad module path in: #bad-value context...: standard-module-name-resolver Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x00a0 0x000100328d99 in scheme_top_level_do_worker (dyn_state=0x0, k=0x7fff5fbfdd10, eb=1000, new_thread=1606409488) at fun.c:1227 1227scheme_longjmp(*save, 1); (gdb) bt #0 0x000100328d99 in scheme_top_level_do_worker (dyn_state=0x0, k=0x7fff5fbfdd10, eb=1000, new_thread=1606409488) at fun.c:1227 #1 0x0001003ff41e in _module_resolve (modidx=0x103004150, stx=0x103004068, env=0x0, load_it=1) at module.c:3860 #2 0x00010041162a in parse_requires () at schthread.h:376 #3 0x0001004122e4 in do_namespace_require () at module.c:7685 #4 0x0001004123ce in scheme_namespace_require (r=0x103ec8008) at module.c:1316 #5 0x0001001574dd in _mh_execute_header () #6 0x0001001585d8 in _mh_execute_header () #7 0x00010005bc43 in _mh_execute_header () #8 0x00010004ca4a in _mh_execute_header () #9 0x00010015f608 in _mh_execute_header () #10 0x0001002a6093 in call_with_basic (data=0x103ec8008) at schthread.h:376 #11 0x0001002a64a8 in scheme_main_setup (no_auto_statics=1606414024, _main=0x7fff5fbfe268, argc=6433496, argv=0x7fff5fbfe240) at salloc.c:194 #12 0x000100161fff in _mh_execute_header () #13 0x7fff939eb7e1 in start () (gdb) I can include more information if you can tell me what is useful. _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Embedded racket is much slower in thread 'heavy' programs
I have a program which is thread 'heavy' and runs much slower in embedded racket (vim) than it does in pure racket. The program: (note no #lang, as I'm doing this in the repl) (require racket/async-channel) (define (make-passer in) (define chan (make-async-channel)) (thread (lambda () (async-channel-put chan (sync in chan) (define (run-passers num) (define input (make-async-channel)) (define output (for/fold ((chan input)) ((i num)) (make-passer chan))) (define start-time (current-inexact-milliseconds)) (async-channel-put input #f) (sync output) (define end-time (current-inexact-milliseconds)) (- end-time start-time)) (define times '()) (thread (lambda () (collect-garbage) (set! times (cons (run-passers 3) times)) (collect-garbage) (set! times (cons (run-passers 3) times)) (collect-garbage) (set! times (cons (run-passers 3) times If you examine the times variable after sufficient time you get the following: In racket: (0.14501953125 0.134765625 0.619873046875) In vim: (10706.1171875 10999.6611328125 9998.8330078125) If I don't do in in a separate thread, then vim is comparable because it is using the racket scheduler, and not calling scheme_check_threads. Vim calls scheme_check_threads every bit (I think 10 times a second), but it looks like not much progress is made on each of these steps. I can understand if it was slightly slower, but a factor of over 50k is a bit too much. Is it possible for scheme_check_threads to do more work on each invocation in a scenario like this? _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Embedding racket in vim
I have recently installed a version of vim with the mzscheme option enabled. And it sortof works except that some times it segfaults or has other memory corruption issues. So I enabled MZ_GC_CHECK when compiling vim, and now I get the corruption every single time on startup. Here is the output from gdb when running it: GNU gdb 6.3.50-20050815 (Apple version gdb-1820) (Sat Jun 16 02:40:11 UTC 2012) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type show copying to see the conditions. There is absolutely no warranty for GDB. Type show warranty for details. This GDB was configured as x86_64-apple-darwin... warning: Unable to read symbols for Racket.framework/Versions/5.3.1.9_3m/Racket (file not found). warning: Unable to read symbols from Racket (not yet mapped into memory). Reading symbols for shared libraries .. done (gdb) run Starting program: /Users/endobson/proj/vim/install/bin/vim Reading symbols for shared libraries .+... done Reading symbols for shared libraries . done ?: bad module path in: #bad-value context...: standard-module-name-resolver Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x00a0 0x000100328d99 in scheme_top_level_do_worker (dyn_state=0x0, k=0x7fff5fbfdd10, eb=1000, new_thread=1606409488) at fun.c:1227 1227scheme_longjmp(*save, 1); (gdb) bt #0 0x000100328d99 in scheme_top_level_do_worker (dyn_state=0x0, k=0x7fff5fbfdd10, eb=1000, new_thread=1606409488) at fun.c:1227 #1 0x0001003ff41e in _module_resolve (modidx=0x103004150, stx=0x103004068, env=0x0, load_it=1) at module.c:3860 #2 0x00010041162a in parse_requires () at schthread.h:376 #3 0x0001004122e4 in do_namespace_require () at module.c:7685 #4 0x0001004123ce in scheme_namespace_require (r=0x103ec8008) at module.c:1316 #5 0x0001001574dd in _mh_execute_header () #6 0x0001001585d8 in _mh_execute_header () #7 0x00010005bc43 in _mh_execute_header () #8 0x00010004ca4a in _mh_execute_header () #9 0x00010015f608 in _mh_execute_header () #10 0x0001002a6093 in call_with_basic (data=0x103ec8008) at schthread.h:376 #11 0x0001002a64a8 in scheme_main_setup (no_auto_statics=1606414024, _main=0x7fff5fbfe268, argc=6433496, argv=0x7fff5fbfe240) at salloc.c:194 #12 0x000100161fff in _mh_execute_header () #13 0x7fff939eb7e1 in start () (gdb) I can include more information if you can tell me what is useful. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Embedding racket in vim
+correct vim group. On Mon, Dec 10, 2012 at 10:25 PM, Eric Dobson eric.n.dob...@gmail.comwrote: I have recently installed a version of vim with the mzscheme option enabled. And it sortof works except that some times it segfaults or has other memory corruption issues. So I enabled MZ_GC_CHECK when compiling vim, and now I get the corruption every single time on startup. Here is the output from gdb when running it: GNU gdb 6.3.50-20050815 (Apple version gdb-1820) (Sat Jun 16 02:40:11 UTC 2012) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type show copying to see the conditions. There is absolutely no warranty for GDB. Type show warranty for details. This GDB was configured as x86_64-apple-darwin... warning: Unable to read symbols for Racket.framework/Versions/5.3.1.9_3m/Racket (file not found). warning: Unable to read symbols from Racket (not yet mapped into memory). Reading symbols for shared libraries .. done (gdb) run Starting program: /Users/endobson/proj/vim/install/bin/vim Reading symbols for shared libraries .+... done Reading symbols for shared libraries . done ?: bad module path in: #bad-value context...: standard-module-name-resolver Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x00a0 0x000100328d99 in scheme_top_level_do_worker (dyn_state=0x0, k=0x7fff5fbfdd10, eb=1000, new_thread=1606409488) at fun.c:1227 1227scheme_longjmp(*save, 1); (gdb) bt #0 0x000100328d99 in scheme_top_level_do_worker (dyn_state=0x0, k=0x7fff5fbfdd10, eb=1000, new_thread=1606409488) at fun.c:1227 #1 0x0001003ff41e in _module_resolve (modidx=0x103004150, stx=0x103004068, env=0x0, load_it=1) at module.c:3860 #2 0x00010041162a in parse_requires () at schthread.h:376 #3 0x0001004122e4 in do_namespace_require () at module.c:7685 #4 0x0001004123ce in scheme_namespace_require (r=0x103ec8008) at module.c:1316 #5 0x0001001574dd in _mh_execute_header () #6 0x0001001585d8 in _mh_execute_header () #7 0x00010005bc43 in _mh_execute_header () #8 0x00010004ca4a in _mh_execute_header () #9 0x00010015f608 in _mh_execute_header () #10 0x0001002a6093 in call_with_basic (data=0x103ec8008) at schthread.h:376 #11 0x0001002a64a8 in scheme_main_setup (no_auto_statics=1606414024, _main=0x7fff5fbfe268, argc=6433496, argv=0x7fff5fbfe240) at salloc.c:194 #12 0x000100161fff in _mh_execute_header () #13 0x7fff939eb7e1 in start () (gdb) I can include more information if you can tell me what is useful. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Changing call/cc
The issue as I see it is that call/cc can replace all the code above a prompt with a continuation captured from above a different prompt. This can break the invariants that TR wants to enforce. I proposed to Asumu on IRC the follow adjustment which I think gets all the behavior that is wanted. call-with-continuation-prompt adds the equivalent of a dynamic-wind-frame after installing the prompt but before invoking the thunk. This dynamic wind frame has no-op pre and post thunks. Invoking a continuation captured by call/cc has the behavior that it has now if there is shared dynamic-wind-frame between the current continuation and the one being invoked. If there isn't then the whole continuation up to the prompt is removed and the abort handler is called with the appropriate composable continuation, such that if the abort handler is the default then the behavior is the same as the old call/cc. This gets us the following behaviors: Code that uses call/cc but doesn't install any prompts works just as before. The abort handler is called exactly whenever a continuation application would replace the current continuation up to the prompt with one that was captured from a different prompt. This gets around the counter example that Asumu mentioned earlier, because when k1 is invoked it put the original prompts dynamic-wind frame in the continuation, so that when k2 is invoked they share the same base and the effectful dynamic wind is not executed. On Wed, Sep 5, 2012 at 4:27 PM, Matthew Flatt mfl...@cs.utah.edu wrote: At Tue, 4 Sep 2012 06:51:49 -0600, Matthew Flatt wrote: Yes, that's true. I don't think there will be a difference for typical uses of `call/cc' and typical abort handlers, though. And as I understand it, we're not at this point trying to make `call/cc' work seamlessly, but instead support it reasonably well for backward compatibility. It turns out that non-default abort handlers are more common than I thought: every module-level form is wrapped with a prompt whose handler re-aborts to an enclosing prompt. So, relying on default-like behavior of a prompt handler doesn't work in that case, and it seems like a prominent case. (The `module' form was misdocumented on this point. I've fixed the documentation. Not realted to that change, but related to the rest of this thread: I changed the initial prompt for each thread to use the default handler, instead of ignore all abort arguments.) I think it would make sense to add a new argument to `call-with-continuation-prompt' that handles continuation applications. That addition would allow a use of `call-with-continuation-prompt' to enforce invariants on its result --- although it seems awkward to add support for a feature that we'd prefer to get rid of. _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] A more useful struct type predicate for structs with contravariant blah-de-blah?
That should be safe. The issue is that TR cannot do it currently, because it doesn't understand that (foo A) and (exists B. (bar B)) = (bar A). It instead reduces this to (exists B. (bar B)) and then to (bar Nothing). I'm working on some stuff that might make that easier to teach it the correct thing but I am not sure if it will work. On Fri, Aug 24, 2012 at 4:29 PM, Neil Toronto neil.toro...@gmail.com wrote: A while ago, on PR 12903 (I don't know why it's not closed yet, FWIW, because I think it's fixed), we had this discussion: Me: I think this should work. #lang typed/racket (struct: (A) bar ([proc : (A - Any)])) (define-predicate -bar? (bar Any)) Sam: That's evil; here's why. Suppose `bar` had a predicate with type (Any - Boolean : (bar Any)). You could do this: (define: v : Any (bar (lambda: ([x : Integer]) (add1 x (when (my-bar? v) ;; check that `v` is a `(bar Any)` (define: f : (Any - Any) (bar-proc v)) ;; type-correct: A = Any (f not an integer)) Me: Got it. [Consults this answer every time it comes up, because he forgets why a useful `bar?' predicate is bad.] So here's my latest question. Say we have these definitions: #lang typed/racket (struct: (A) foo ()) (struct: (A) bar foo ([proc : (A - Any)])) Could `bar?' have the type (All (A) ((foo A) - Boolean : (bar A)))? Then (I think), something like this should type: (: maybe-foo-proc (All (A) ((foo A) - (U #f (A - Any) (define (maybe-foo-proc v) (if (bar? v) (bar-proc v) #f)) (Well, it wouldn't currently; the error is Expected (bar A); given #(struct:#syntax:4:13 bar ((Nothing - Any))).) Is that also evil? I hope not, because the useless type of `bar?' is precluding a possibly important performance enhancement. Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Is it possible to write `flatten' in TR?
No it is not possible to type flatten. Consider having flatten with this type: (define-type (Listof* A) (Rec T (U A (Listof T (: flatten (All (A) ((Listof* A) - (Listof A And then applying it as such: ((inst flatten (Listof Number)) (list (list 1 2 3))) This would typecheck and return the value (list 1 2 3) with the type (Listof (Listof Number)). This is bad and breaks soundness. On Tue, Aug 7, 2012 at 9:57 AM, Neil Toronto neil.toro...@gmail.com wrote: Short version: Creating arrays from nested lists (and vectors) would be a lot easier if I could write a `flatten' function in TR, but I haven't been able to. Is it possible? Long version: Given this type: (define-type (Listof* A) (Rec T (U A (Listof T I'd like this function: (: flatten (All (A) ((Listof* A) - (Listof A When I use `require/typed' to get it, it won't work: (flatten 0) - : (Listof Zero) '(0) (flatten '(0 1)) flatten: contract violation two of the clauses in the or/c might both match: ... The problem is that an `A' might be a (Listof B), so the generated contract is ambiguous. The ambiguity also shows up in TR, though it's harder to understand from the error message: (: flatten (All (A) ((Listof* A) - (Listof A (define (flatten lst) (cond [(list? lst) (append* ((inst map (Listof A) (Listof* A)) flatten lst))] [else (list lst)])) Expected (Listof (Rec T (U A (Listof T but got (U (Listof (Rec T (U A (Listof T (Pairof Any (Listof Any))) I think this error message is saying that if `lst' is a list, it really could be any kind of list. I can't argue with that. Is there a way around this particular error message? More generally, is it possible to write `flatten' at all? Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Should I expect this program to typecheck?
#lang typed/racket (: vector-first (All (A B) ((U (Vectorof A) (Vectorof B)) - (U A B (define (vector-first vs) (vector-ref vs 0)) I doubt this will typecheck without more work in the typechecker. The issue is that it should work for a union type of as many vectors as you want. If there was a readable-vector type it would be trivial as subtyping would do all of the real work. As (U (ReadVector A) (ReadVector B)) : (ReadVector (U A B)). But that cannot be done with real vectors, as they are invariant. On Mon, Aug 6, 2012 at 5:15 PM, Ray Racine ray.rac...@gmail.com wrote: This type checks. Not sure if it is the same thing as the original however. (: check-array-indexes (Symbol (Vectorof Index) (U (Vectorof Index) (Vectorof Integer)) - (Vectorof Index))) (define (check-array-indexes name ds js) (define (raise-index-error) (error name expected indexes for shape ~e; given ~e ds js)) (: dims Integer) (define dims (vector-length ds)) (unless (= dims (vector-length js)) (raise-index-error)) (: new-js (Vectorof Index)) (define new-js (make-vector dims 0)) (let: loop : (Vectorof Index) ([i : Integer 0]) (if ( i dims) (let: ((di : Index (vector-ref ds i)) (ji : Integer (assert (vector-ref js i) exact-integer?))) (if (and (= 0 ji) ( ji di)) (begin (vector-set! new-js i (assert ji index?)) (loop (add1 i))) (raise-index-error))) new-js))) On Mon, Aug 6, 2012 at 5:47 PM, J. Ian Johnson i...@ccs.neu.edu wrote: I don't get the type Any, rather it doesn't know how to go from the union of vectors to a (vector a) for some a. Vector ref expects a vector, not a union of vectors, and because vectors are invariant, it cannot simplify this to (vector Integer). -Ian - Original Message - From: Neil Toronto neil.toro...@gmail.com To: J. Ian Johnson i...@ccs.neu.edu Cc: dev dev@racket-lang.org Sent: Monday, August 6, 2012 5:07:38 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket-dev] Should I expect this program to typecheck? I can't distinguish the elements' types in the simplified example I gave. The code I'm actually working on is this: (: check-array-indexes (Symbol (Vectorof Index) (U (Vectorof Index) (Vectorof Integer)) - (Vectorof Index))) (define (check-array-indexes name ds js) (define (raise-index-error) (error name expected indexes for shape ~e; given ~e ds js)) (define dims (vector-length ds)) (unless (= dims (vector-length js)) (raise-index-error)) (define: new-js : (Vectorof Index) (make-vector dims 0)) (let loop ([#{i : Nonnegative-Fixnum} 0]) (cond [(i . . dims) (define di (vector-ref ds i)) (define ji (vector-ref js i)) (cond [(and (0 . = . ji) (ji . . di)) (vector-set! new-js i ji) (loop (+ i 1))] [else (raise-index-error)])] [else new-js]))) I get type errors on every expression involving `ji', because TR has determined that it has type `Any'. I would use a `case-' type, but I have an array transformation function that receives an argument with type ((Vectorof Index) - (U (Vectorof Integer) (Vectorof Index))) whose output has to be bounds-checked by `check-array-indexes', and I can't apply a function with a case type to an argument with a union type. The question will of course be moot when TR has something like a `Const' type constructor. I'm anticipating that, and changing the user-facing array API to receive (U (Vectorof Integer) (Vectorof Index)) for array indexes instead of (Listof Integer). (It should eventually be (Const (Vectorof Integer)) or similar, which should be covariant.) So are the type errors an error in TR, or a known limitation? Neil ⊥ On 08/06/2012 02:25 PM, J. Ian Johnson wrote: How do you determine the difference between the two vector types is the question... -Ian - Original Message - From: Neil Toronto neil.toro...@gmail.com To: dev@racket-lang.org dev@racket-lang.org Sent: Monday, August 6, 2012 4:12:53 PM GMT -05:00 US/Canada Eastern Subject: [racket-dev] Should I expect this program to typecheck? #lang typed/racket (: vector-first (All (A B) ((U (Vectorof A) (Vectorof B)) - (U A B (define (vector-first vs) (vector-ref vs 0)) I can't think of a reason this shouldn't work, but I may not be taxing my imagination enough to come up with one. Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list:
[racket-dev] Iteration and Mutation on dictionaries
Dictionaries provide an iteration interface with the primitive operations: dict-iterate-first: Dict - (U #f Iterator) dict-iterate-next: Dict Iterator - (U #f Iterator) dict-iterate-key: Dict Iterator - Key dict-iterate-value: Dict Iterator - Value This interface matches the hash interface and allows a user to iterate over all entries and view them. It does not provide support for mutation. Both the hash and dict have the same disclaimer about mutation during iteration: hash-iterate-first: For a mutable hash, this index is guaranteed to refer to the first item only as long as no items are added to or removed from hash. hash-iterate-next: For a mutable hash, the result index is guaranteed to refer to its item only as long as no items are added to or removed from hash. Note that there are no disclaimers about what happens if you mutate the value associated with a key already in a hash, and thus I assume it is ok to do this. Hashes support this but not all dictionaries do. This is because the only way to mutate a key is to use dict-set! which makes it hard to keep the index valid. ; EXAMPLE ;Broken program using free identifier tables #lang racket (require syntax/id-table) (define a #'a) (define tbl (make-free-id-table)) (free-id-table-set! tbl a 2) (define index (free-id-table-iterate-first tbl)) (free-id-table-set! tbl (free-id-table-iterate-key tbl index) 3) (free-id-table-iterate-next tbl index) The documentation needs to be clarified to whether this kind of mutation is required to be supported or not. I can see it going either way. One problem with forcing it to be required is that the only way to mutate a dictionary is through the dict-set! function, which is not related to the current iteration. A dict-iterate-set! function would alleviate this and allow any necessary updating of the index, but it has the issue that any idiom that hides away the iterator object could not use it, i.e. for loops, dict-for-each. dict-iterate-set!: Dict Iterator Value - Void What should the requirement be? _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] When are values chaperones of another?
The docs on when a value is a chaperone of another are confusing and don't seem to match the implementation. They seem to say that (and (not (chaperone? a)) (not (chaperone? b)) (equal? a b)) implies (chaperone-of? a b) but this does not seem to hold. They also change behavior if I switch from a transparent structure to a structure where I explicitly implement equality. #lang racket (struct foo (v) #:property prop:equal+hash (list (lambda (l r equal?) (equal? l r)) (lambda (v hash) (hash v)) (lambda (v hash) (hash v #; (struct foo (v) #:transparent) (define foo1 (foo (box 0))) (define foo2 (foo (box 0))) (define foo3 (foo (foo-v foo1))) 1 2 (equal? foo1 foo2) (chaperone-of? foo1 foo2) (chaperone-of? foo2 foo1) 1 3 (equal? foo1 foo3) (chaperone-of? foo1 foo3) (chaperone-of? foo3 foo1) ;;--- 1 2 #t #f #f 1 3 #t #f #f I expect these to all return true but only the equals do. If I switch to transparent equality then 1 and 3 are equal. The goal in this is to have my own struct type (free identifier tables) be able to support chaperone-of? like immutable hashes do: (chaperone-of? (hash 'a 'b) (hash 'a 'b)) ;; = #t These are different hashes but are chaperones of each other. The importance of this is chaperone contracts on free identifier tables need to make a copy like hash/c does on immutable hashes. _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Writing tests for contracts outside of racket/contract
I am adding the contract combinators free-id-table/c and bound-id-table/c, and working on the tests for them. It would make sense to put them in tests/racket/id-table-tests.rkt, but tests/racket/contract-test.rkt has many testing combinators for contracts that would be useful. Is it reasonable to extract these out to a module so that other tests can use them as well? If so does it belong in tests/racket because it is only for tests or is tests/racket limited to the actual testing files. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Oversight in type for path-string?
Actually I don't think this is an over sight. The null string is a String. And Path-String is Path U String, but (path-string? (string #\null)) = #f. Sent from a mobile device. On Mar 21, 2012 5:14 PM, John Clements cleme...@brinckerhoff.org wrote: On Mar 21, 2012, at 3:20 PM, Sam Tobin-Hochstadt wrote: On Wed, Mar 21, 2012 at 5:36 PM, John Clements cleme...@brinckerhoff.org wrote: It looks like 'path-string?' is not labeled as a discriminator type. path-string? - : (Any - Boolean) #procedure:path-string? Is this just an oversight? Yes, that's just an oversight, although it's slightly more complicated than you'd think (because `(path-string? (string #\null))' is #f). Well, I just made do with (define-predicate ps? Path-String?), so this certainly isn't a major problem. John _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Windowing API
Thanks that worked. -Eric On Oct 15, 2011, at 7:07 AM, Matthew Flatt wrote: I think you'll have to handle `on-size' at the `racket/gui' level: (define panel (new (class panel% (define/override (on-size w h) (tellv web-view setFrame: #:type _NSRect (make-NSRect (make-NSPoint 0 0) (make-NSSize w h (super-new)) [parent frame])) ;; instead of `frame-view': (define panel-view (send panel get-client-handle)) (tellv panel-view addSubview: web-view) At Fri, 14 Oct 2011 23:19:32 -0700, Eric Dobson wrote: I am trying to implement a WebKit panel in Racket, and am running in to some trouble with the windowing API. I cannot get resizing to work. In OS X it looks like it is supposed to be enabled by default so I assume racket is changing it so that it can do its layout algorithm. The problem is that If I want to hook into this It looks like I need to get access to the platform specific racket windowing API. Currently I can get access to the Objective C layer, but not to the hidden racket layer. Maybe this is not the way I should approach this but I'm hoping someone can help. #lang racket (require racket/gui/base ffi/unsafe/objc ffi/unsafe) (require mred/private/wx/cocoa/types (prefix-in c: mred/private/wx/cocoa/window)) (define webkit-lib (ffi-lib (format /System/Library/Frameworks/WebKit.framework/WebKit))) (import-class WebView) (import-class NSURLRequest) (import-class NSURL) (define web-view (tell (tell WebView alloc) initWithFrame: #:type _NSRect (make-NSRect (make-NSPoint 0 0) (make-NSSize 300 300)) frameName: #f groupName: #f)) (define frame (new frame% (label test-frame) (width 300) (height 300))) ;(define racket-web-view (new c:window% (parent frame) (cocoa web-view) (no-show? #f))) ;This problem is here the parent argument needs to be the platform specific window and not the generic one (define frame-view (send frame get-client-handle)) (tellv frame-view addSubview: web-view) (define request (tell NSURLRequest requestWithURL: (tell NSURL URLWithString: #:type _NSString http://www.google.com;))) (tellv (tell web-view mainFrame) loadRequest: request) (send frame show #t) _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
[racket-dev] Errors with Racket on OS X 10.7 64bit
I regularly build racket from HEAD on OS X with no problems, but tonight I decided to try the 64 bit version and couldn't get it to compile. The error I got was: Undefined symbols for architecture x86_64: _iconv_close, referenced from: _close_converter in libracket.a(string.o) _scheme_close_converter in libracket.a(string.o) _do_convert in libracket.a(string.o) _byte_string_close_converter in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _iconv_open, referenced from: _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _scheme_open_converter in libracket.a(string.o) _iconv, referenced from: _do_convert in libracket.a(string.o) ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status make[4]: *** [Racket.framework/Versions/5.1.3.6/Racket] Error 1 The command I ran to install it was mkdir build cd build ../configure --disable-docs --enable-mac64 make -j2 make install -j2 Is there something I am missing, or is it just broken currently? -Eric Full output is attached: dev-out Description: Binary data _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] drRacket Close/Close tab
As a sample of OS X (10.7) applications I looked at Chrome, Safari, Terminal and Adium. In all of them Command-W did 'close tab' and Shift-Command-W did 'close window'. In the first three they are actually called that, Adium uses 'close chat' and 'close'. Given that Safari and Terminal are Apple products, I think that Command-W as close tab instead of window is fairly standard now. -Eric _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
[racket-dev] Typed Racket support for Ephemerons
I have added support for ephemerons to Typed Racket, and submitted a pull request on Github (https://github.com/plt/racket/pull/5). This patch is supposed to fix PR 11633. Is there anything else I should do to get this patch integrated? -Eric _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] Typed Racket support for Ephemerons
The tests all pass (for me). -Eric On Tue, Apr 26, 2011 at 2:54 PM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Tue, Apr 26, 2011 at 2:19 PM, Eric Dobson eric.n.dob...@gmail.com wrote: I have added support for ephemerons to Typed Racket, and submitted a pull request on Github (https://github.com/plt/racket/pull/5). This patch is supposed to fix PR 11633. All of this looks good, except that `EphemeronTop' is unnecessary. Since ephemerons are covariant, (Ephemeronof Any) is a supertype of (Ephemeronof T) for any type T. Vincent says that he'll change that and push the result. Thanks! -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
[racket-dev] Build failure on OS X
I tried to build the git HEAD today and ran into problems. During the make process, it fails to create the framework with the following error message: gcc -o Racket.framework/Versions/5.1.1.3/Racket -m32 -pthread -framework CoreFoundation -dynamiclib -all_load libracket.a libmzgc.a -ldl -lm -liconv -L/opt/local/lib -lffi Undefined symbols: _iconv_close, referenced from: _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _close_converter in libracket.a(string.o) _iconv_open, referenced from: _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _scheme_open_converter in libracket.a(string.o) _iconv, referenced from: _do_convert in libracket.a(string.o) ld: symbol(s) not found collect2: ld returned 1 exit status Does anyone know what might cause this? Thanks, Eric _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] Build failure on OS X
I don't have any *FLAGS variables set in my environment when I run configure or make. But I do have libiconv installed through macports. It was out of date, and I upgraded it, but now I am getting a different message: gcc -o Racket.framework/Versions/5.1.1.3/Racket -m32 -pthread -framework CoreFoundation -dynamiclib -all_load libracket.a libmzgc.a -ldl -lm -liconv -L/opt/local/lib -lffi ld: warning: in /opt/local/lib/libiconv.dylib, file was built for unsupported file format which is not the architecture being linked (i386) Undefined symbols: _iconv_close, referenced from: _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _close_converter in libracket.a(string.o) _iconv_open, referenced from: _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _scheme_open_converter in libracket.a(string.o) _iconv, referenced from: _do_convert in libracket.a(string.o) ld: symbol(s) not found collect2: ld returned 1 exit status (Note the warning about a different architecture.) I assume that If I tell it to use the system version of iconv, things will work out. But how do I tell it to ignore the bad version? -Eric On Apr 21, 2011, at 9:48 PM, Matthew Flatt wrote: It looke like you have `-L/opt/local/lib' in your LDFLAGS configuration. Do you also have `-I/opt/local/include' in CPPFLAGS? You machine is probably like mine, where you have two installations of libiconv, and this error happens when the C headers of one installation get mixed with the lib of the other. At Thu, 21 Apr 2011 21:42:54 -0400, Eric Dobson wrote: I tried to build the git HEAD today and ran into problems. During the make process, it fails to create the framework with the following error message: gcc -o Racket.framework/Versions/5.1.1.3/Racket -m32 -pthread -framework CoreFoundation -dynamiclib -all_load libracket.a libmzgc.a -ldl -lm -liconv -L/opt/local/lib -lffi Undefined symbols: _iconv_close, referenced from: _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _close_converter in libracket.a(string.o) _iconv_open, referenced from: _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _scheme_open_converter in libracket.a(string.o) _iconv, referenced from: _do_convert in libracket.a(string.o) ld: symbol(s) not found collect2: ld returned 1 exit status Does anyone know what might cause this? Thanks, Eric _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] Build failure on OS X
It looks like it was a problem with libffi, which was also out of date in my macports. I upgraded it before your email, and the build got past that point where it was failing. Hopefully it won't have any more problems. Thanks for the help. -Eric On Apr 21, 2011, at 10:17 PM, Matthew Flatt wrote: The recent change to `configure' makes it use `pkg-config' to add -L and -I flags for libffi. But those should flags be added consistently; that is, you should end up with a build that uses `libiconv' from macports. Did you run `configure' in a fresh build directory? If not, maybe you have files leftover from a previous build that had different flags from `configure'? If not, can you show the compile line for string.c? At Thu, 21 Apr 2011 22:01:31 -0400, Eric Dobson wrote: I don't have any *FLAGS variables set in my environment when I run configure or make. But I do have libiconv installed through macports. It was out of date, and I upgraded it, but now I am getting a different message: gcc -o Racket.framework/Versions/5.1.1.3/Racket -m32 -pthread -framework CoreFoundation -dynamiclib -all_load libracket.a libmzgc.a -ldl -lm -liconv -L/opt/local/lib -lffi ld: warning: in /opt/local/lib/libiconv.dylib, file was built for unsupported file format which is not the architecture being linked (i386) Undefined symbols: _iconv_close, referenced from: _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _close_converter in libracket.a(string.o) _iconv_open, referenced from: _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _scheme_open_converter in libracket.a(string.o) _iconv, referenced from: _do_convert in libracket.a(string.o) ld: symbol(s) not found collect2: ld returned 1 exit status (Note the warning about a different architecture.) I assume that If I tell it to use the system version of iconv, things will work out. But how do I tell it to ignore the bad version? -Eric On Apr 21, 2011, at 9:48 PM, Matthew Flatt wrote: It looke like you have `-L/opt/local/lib' in your LDFLAGS configuration. Do you also have `-I/opt/local/include' in CPPFLAGS? You machine is probably like mine, where you have two installations of libiconv, and this error happens when the C headers of one installation get mixed with the lib of the other. At Thu, 21 Apr 2011 21:42:54 -0400, Eric Dobson wrote: I tried to build the git HEAD today and ran into problems. During the make process, it fails to create the framework with the following error message: gcc -o Racket.framework/Versions/5.1.1.3/Racket -m32 -pthread -framework CoreFoundation -dynamiclib -all_load libracket.a libmzgc.a -ldl -lm -liconv -L/opt/local/lib -lffi Undefined symbols: _iconv_close, referenced from: _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _close_converter in libracket.a(string.o) _iconv_open, referenced from: _do_convert in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _string_to_from_locale in libracket.a(string.o) _scheme_open_converter in libracket.a(string.o) _iconv, referenced from: _do_convert in libracket.a(string.o) ld: symbol(s) not found collect2: ld returned 1 exit status Does anyone know what might cause this? Thanks, Eric _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev