Matthias Felleisen | 20 Apr 20:39 2014

Re: Implementation question


Here is a more Racket-y version of this: 

#lang racket

(define (ping hostname port-no personalip)
  (define c (make-custodian))
  (define t
    (parameterize ((current-custodian c))
      (thread
       (lambda ()
         (with-handlers ((exn:fail:network? 
                          (lambda (x)
                            (printf "~a:~a ~a\n" hostname port-no " NO"))))
           (define-values (in out) (tcp-connect hostname port-no))
           (write "'ping" out)
           (write personalip out)
           (flush-output out)
           (printf "~a:~a ~a\n" hostname port-no (read in)))))))
  (sync/timeout 0.01 t)
  (custodian-shutdown-all c))




On Apr 20, 2014, at 10:41 AM, nicolas carraggi wrote:

Hey guys,

Thanks a lot for your quick answers!

My ping method now:

(define (ping hostname port-no personalip)
  (define t (thread
             (lambda ()
               (with-handlers ((exn:fail:network? (lambda (x) (begin (displayln (string-append hostname ":" (number->string port-no) " NOOOOOOOOOO")) #f))));(displayln (exn-message x)))))
                 (define-values (in out) (tcp-connect hostname port-no))
                 (write "'ping" out)
                 (write personalip out)
                 (flush-output out)
                 (display (string-append hostname ":" (number->string port-no) " "))
                 (displayln (read in))
                 (close-input-port in)
                 (close-output-port out)
                 #t))))
  (sync/timeout 0.01 t)
  (kill-thread t))

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

This is the result when I do a multicast from 192.168.1.0 to 192.168.1.200. ( a lot of these don't exist and that's why tcp-connect was taking ages to throw an error.) Those returning a NOOOOO are existing network nodes where no server is running. Pong is the answer from the server running on my laptop.

> (multicast-ping "192.168.1.100" 8080 0 200)
192.168.1.0:8080 NOOOOOOOOOO
192.168.1.105:8080 NOOOOOOOOOO
192.168.1.108:8080 pong
-------------------
Multicast finished!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


It's still test-code but it's working fine now, maybe the timout time is too small but now it works well!

Greetings,
Nicolas

Subject: Re: [racket-dev] Implementation question
From: matthias-1vnkWVZi4QaVc3sceRu5cw@public.gmane.org
Date: Sat, 19 Apr 2014 09:25:27 -0400
CC: nicocarraggi-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org; dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org
To: laurent.orseau-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org


Let me recommend events instead: 

#lang racket

;; Nat -> Void 
;; wait for t seconds before connecting to google.com, then stop
(define (do-work t)
  (thread
   (lambda ()
     (with-handlers ((exn:fail:network? (lambda (x) (displayln (exn-message x)))))
       (sleep t)
       (define-values (in out) (tcp-connect "google.com" 80)) 
       'done))))

;; returns #f if 3 seconds pass w/o the thread shutting down 
(sync/timeout 3 (do-work (random 6)))



On Apr 19, 2014, at 8:34 AM, Laurent wrote:

One simpler possibility is to use `tcp-connect/enable-break` and run a timer in parallel to break it after a shorter delay.
For example:

(define-values (in out) (values #f #f))

(define connect-thread
  (thread
   (λ()(set!-values (in out) 
                    (tcp-connect "www.google.com" 80)))))

(sleep 3)
(unless in
  (displayln "Connection not established. Breaking thread.")
  (break-thread connect-thread))

The timer can also be place into its own thread if you need to set up several connections in parallel.

Hope this helps,
Laurent


On Thu, Apr 17, 2014 at 6:48 PM, nicolas carraggi <nicocarraggi-PkbjNfxxIARBDgjK7y7TUQ@public.gmane.org> wrote:
Hello,

I am actually using "Racket/tcp" for a project in Racket.
I'm creating a peer-to-peer network but now I encountered a small problem.
For a multicast I want to connect with each server on the same network. 
For this I use "tcp-connect", but when i try to connect to an ip address which is not hosting a server, throwing the error only happens after more than 1 minute. So I would like to use a modified "tcp-connect" with a smaller time-out.

Where can I find the implementation of "tcp-connect"?

I already found "tcp.rkt" but there it gets the "tcp-connect" method from "'#%network" but I can't find this one...

Greetings!
Nicolas

_________________________
  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
Neil Toronto | 20 Apr 01:24 2014
Picon

Regular expression types [was Re: [racket-bug] all/14455: wrong type for hash]

Are there type systems that can? It seems like you could specify this 
type and similar ones using regular expressions.

In my research, I'll probably use regular expressions to represent sets 
of strings. I've been curious about how well regular-expression-like 
things generalize to cartesian products with repeating structure.

Neil ⊥

On 04/19/2014 03:44 PM, Eric Dobson wrote:
> The type for hash is conservative. TR currently cannot express the
> alternating requirement that hash requires.
>
> On Sat, Apr 19, 2014 at 2:40 PM,  <alexander <at> knauth.org> wrote:
>> A new problem report is waiting at
>>    http://bugs.racket-lang.org/query/?cmd=view&pr=14455
>>
>> Reported by Alex Knauth for release: 6.0
>>
>> *** Description:
>> the type for hash appears to be (All (a b) (-> (HashTable a b))), so it's not letting me supply it with
arguments, saying that it expects 0 arguments
>>
>> *** How to repeat:
>> #lang typed/racket
>> (hash 0 0)
>>

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Vincent St-Amour | 19 Apr 23:36 2014

Re: [plt] Push #28576: master branch updated

At Sat, 19 Apr 2014 13:19:25 -0400,
mflatt@... wrote:
> a01b12e Matthew Flatt <mflatt@...> 2014-04-19 10:11
> :
> | optimizer: don't move expressions into a `with-continuation-mark`
> |
> | ... unless the optimizer can prove that the expression doesn't
> | inspect continuation marks.
> :
>   M pkgs/racket-pkgs/racket-test/tests/racket/optimize.rktl | 12 +++++++++++-
>   M racket/src/racket/src/optimize.c                        |  5 +++++

This optimization can be observed from another thread, like a profiler's
sampling thread, even if the relevant code doesn't observe continuation
marks itself.

Vincent
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

nicolas carraggi | 17 Apr 18:48 2014
Picon

Implementation question

Hello,

I am actually using "Racket/tcp" for a project in Racket.
I'm creating a peer-to-peer network but now I encountered a small problem.
For a multicast I want to connect with each server on the same network. 
For this I use "tcp-connect", but when i try to connect to an ip address which is not hosting a server, throwing the error only happens after more than 1 minute. So I would like to use a modified "tcp-connect" with a smaller time-out.

Where can I find the implementation of "tcp-connect"?

I already found "tcp.rkt" but there it gets the "tcp-connect" method from "'#%network" but I can't find this one...

Greetings!
Nicolas
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Neil Toronto | 18 Apr 00:48 2014
Picon

Adding flvector to match

It would be really handy for me right now to be able to match on 
flvectors, and I think it's useful enough for minimal Racket. I've 
already tried this option:

  1. Export flvector as a match expander from racket/flonum

but racket/match depends on racket/flonum somehow. So I looked through 
the match code and determined that this one would be pretty easy:

  2. Change racket/match to recognize patterns with 'flvector head

(The code is very clean; kudos to whoever last rewrote it. :D)

I think #2 would at worst hijack someone's custom flvector match 
expander, but probably do the same thing or better (e.g. also handle 
ellipses). But in case it's worse than I think, I can always go with this:

  3. Export flvector as a match expander from math/flonum

Question for the match and syntax gurus: would doing #2 be safe enough, 
or should I do #3? Or have I got it backwards; i.e. is #2 actually safer 
than #3?

Neil ⊥
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Ryan Culpepper | 18 Apr 00:44 2014

Pre-Release Checklist for v6.0.1

Checklist items for the v6.0.1 release
   (using the v6.0.0.900 release candidate build)

Search for your name to find relevant items, reply when you finish an
item (please indicate which item/s is/are done).  Also, if you have any
commits that should have been picked, make sure that the changes are in.

Important: new builds are created without announcement, usually whenever
I pick a few commits.  If you need to commit changes, please make sure
you tell me to pick it into the release branch.

--> Release candidates are at
-->   http://pre-release.racket-lang.org/

Please use these installers (or source bundles) -- don't test from
your own git clone (don't test the `master' branch by mistake!).  To
get the tests, you can do this:

   cd ...racket-root...
   ./bin/raco pkg install -i main-distribution-test

----------------------------------------------------------------------

* Matthew Flatt <mflatt@...>
   - Racket Tests
   - Languages Tests
   - GRacket Tests (Also check that `gracket -z' and `gracket-text' still
     works in Windows and Mac OS X)
   - mzc --exe tests
   - .plt-packing Tests
   - Games Tests
   - Unit Tests
   - Syntax Color Tests
   - R6RS Tests
   - JPR's test suite
   - Create an executable from a BSL program
   - Run COM tests
   - Try compiling with -funsigned-char
   - Try compiling with TEST_ALTERNATE_TARGET_REGISTER
   Updates:
   - Racket Updates: update HISTORY
   (updates should show v6.0.1 as the most current version)
   - Update man pages in racket/man/man1: racket.1, gracket.1, raco.1
   Email me to pick the changes when they're done, or tell me if there
   are no such changes.

* Robby Findler <robby@...>
   - DrRacket Tests
   - Framework Tests
   - Contracts Tests
   - Games Tests
   - Teachpacks Tests: image tests
   - PLaneT Tests
   - Redex Tests
   Updates:
   - DrRacket Updates: update HISTORY
   - Redex Updates: update HISTORY
   (updates should show v6.0.1 as the most current version)
   - Ensure that previous version of DrRacket's preference files still
     starts up with new DrRacket
   - Update man pages in racket/man/man1: drracket.1
   Email me to pick the changes when they're done, or tell me if there
   are no such changes.

* John Clements <clements@...>
   - Stepper Tests
   Updates:
   - Stepper Updates: update HISTORY
   (updates should show v6.0.1 as the most current version; email me
   to pick the changes when they're done, or tell me if there are no such
   changes.)

* Sam Tobin-Hochstadt <samth@...>,
    Vincent St-Amour <stamourv@...>
   - Match Tests
   - Typed Racket Tests
   - Typed Racket Updates: update HISTORY
   (updates should show v6.0.1 as the most current version; email me
   to pick the changes when they're done, or tell me if there are no such
   changes.)

* Matthias Felleisen <matthias@...>
   - Teachpacks Tests: check that new teachpacks are addable
   - Teachpack Docs: check teachpack docs in the bundles
   Updates:
   - Teachpack Updates: update HISTORY
   (updates should show v6.0.1 as the most current version; email me
   to pick the changes when they're done, or tell me if there are no such
   changes.)

* Ryan Culpepper <ryan@...>
   - Macro Debugger Tests
   - Syntax Classifier Tests
   - RackUnit GUI Tests
   - Data Tests
   - DB Tests

* Jay McCarthy <jay.mccarthy@...>
   - Web Server Tests
   - XML Tests
   - HTML Tests
   - PLAI Tests
   - Racklog tests
   - Datalog tests

* Kathy Gray <kathryn.gray@...>
   - Test Engine Tests

* Noel Welsh <noelwelsh@...>
   - Rackunit Tests
   - SRFI Tests
   - Ensure that all claimed srfi's are in the installer and they all
     load into racket or drracket (as appropriate)

* Stevie Strickland <sstrickl@...>
   - Unit Contract Tests
   - Contract Region Tests
   - Class Contract Tests

* Stephen Chang <stchang@...>
   - Lazy Racket Tests
   - Lazy stepper tests

* Eli Barzilay <eli@...>
   - Swindle Tests
   - XREPL Tests
   - Verify PL language
   - Racket Tree: compare new distribution tree to previous one
   - Run the unix installer tests
   - Run zsh completions tests
     (". .../racket-completion.zsh; _racket --self-test")
   Version Updates: if a major change has happened, update the version
   number in:
   - racket/collects/mzscheme/info.rkt
   - racket/collects/mred/info.rkt

* Stephen Bloch <sbloch@...>
   - Picturing Programs Tests

* Greg Cooper <greg@...>
   - FrTime Tests

* Carl Eastlund <cce@...>
   - Dracula Tests (confirm that Dracula runs from PLaneT)

* Jon Rafkind <rafkind@...>
   Release tests for (one of the) linux releases:
   - Test that the `racket' and `racket-textual' source releases
     compile fine (note that they're still called `plt' and `mz' at
     this stage).
   - Test that the binary installers for both work, try each one in
     both normal and unix-style installation modes. (just ubuntu)
   [Note: get the release candidates from the URL in this email. Use
    the 'static table' link to see a list of all tar files available]

* Mike Sperber <sperber@...>
   - DMdA Tests
   - Stepper Tests
   - Signature Tests

* David Van Horn <dvanhorn@...>
   - EoPL Tests

* Neil Toronto <neil.toronto@...>
   - Plot Tests
   - Images Tests
   - Inspect icons
   - Math tests

* Doug Williams <m.douglas.williams@...>
   - Additional Plot Tests

* Shriram Krishnamurthi <sk@...>
   Tour: check the tour and generate a new one if needed.
   [Note: Since this is a v6.0.0.900 build, you will need to edit your
     .../collects/framework/private/version.rkt
   file and change `(version)' to `"6.0.1"'.]
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

dfeltey | 17 Apr 20:49 2014

class implementation and make-primitive-class

For a course project I've been working on adding generators to contracts for use with
contract-random-generate, and I've been trying to construct classes and objects from simple object/c
contracts. When trying to find a way to functionally create a class at runtime, I came across the
`make-primitive-class` function in class-internal.rkt. 

This function is exported, and available at a plain racket repl, but has no documentation that I have been
able to find and the comments about it in class-internal.rkt seem to be incorrect. 

Trying to call it from the repl has problems also, for example (ignoring for a moment that the arguments
aren't of the expected types)

-> (make-primitive-class #f #f 'foo object% null #f null null null null)
; compose-class: arity mismatch;
;  the expected number of arguments does not match the given number
;   expected: 28
;   given: 27

The definition is in terms of compose-class and is just missing a `null` argument for the abstract-names,
but even after fixing that in my local branch there is a discrepancy with the comments regarding it's first
argument `make-struct:prim`. 

; The `make-struct:prim' function takes prop:object, a class,
  ;  a preparer, a dispatcher function, an unwrap property,
  ;  an unwrapper, and a property assoc list, and produces:
  ;    * a struct constructor (must have prop:object)
  ;    * a struct predicate
  ;    * a struct type for derived classes (mustn't have prop:object)
  ;
  ; The supplied preparer takes a symbol and returns a num.
  ; 
  ; The supplied dispatcher takes an object and a num and returns a method.
  ;
  ; The supplied unwrap property is used for adding the unwrapper
  ;  as a property value on new objects.
  ;
  ; The supplied unwrapper takes an object and returns the unwrapped
  ;  version (or the original object).
  ;
  ; When a primitive class has a superclass, the struct:prim maker
  ;  is responsible for ensuring that the returned struct items match
  ;  the supertype predicate.

This suggests that make-struct:prim should take 7 arguments, but passing a function of 7 arguments to it
from the repl produces:

-> (make-primitive-class (lambda (a b c d e f g) (values #f #f #f)) #f 'foo object% null #f null null null null)
; #<procedure>: arity mismatch;
;  the expected number of arguments does not match the given number
;   expected: 7
;   given: 5

Also as far as I can tell `make-primitive-class` is never used in the code base, it is defined in
class-internal.rkt, but can be commented out without seeming to break anything else. Does anyone know if
there is a purpose for this function, or if there is documentation somewhere on the functions I need to pass
it in order to construct a class. I think I'm starting to get a better idea of how it might work from reading
more of class-internal.rkt and how the class* macro expands, but any guidance would be appreciated.

Thanks
Dan

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

Matthias Felleisen | 17 Apr 00:07 2014

Re: [plt] Push #28550: master branch updated


Can we make sure that some warning appears on the entire page so that nobody loses track of this? A linked
margin note every 10 lines would be fine. 

On Apr 16, 2014, at 2:59 PM, asumu@... wrote:

> asumu has updated `master' from d212fc7eba to d6a3d27e54.
>  http://git.racket-lang.org/plt/d212fc7eba..d6a3d27e54
> 
> =====[ One Commit ]=====================================================
> Directory summary:
> 100.0% pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/
> 
> ~~~~~~~~~~
> 
> d6a3d27 Asumu Takikawa <asumu@...> 2014-04-15 18:09
> :
> | Mark class support as experimental in the TR docs
> |
> | Please merge to v6.0.1
> :
>  M .../typed-racket/scribblings/reference/typed-classes.scrbl   | 5 +++++
> 
> =====[ Overall Diff ]===================================================
> 
> pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/typed-classes.scrbl
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/typed-classes.scrbl
> +++ NEW/pkgs/typed-racket-pkgs/typed-racket-doc/typed-racket/scribblings/reference/typed-classes.scrbl
>  <at>  <at>  -13,6 +13,11  <at>  <at> 
> 
>  <at> title{Typed Classes}
> 
> + <at> bold{Warning}: the features described in this section are experimental
> +and may not work correctly. Some of the features will change by
> +the next release. In particular, typed-untyped interaction for classes
> +will not be backwards compatible so do not rely on the current semantics.
> +
> Typed Racket provides support for object-oriented programming with
> the classes and objects provided by the  <at> racketmodname[racket/class]
> library.

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

John Clements | 16 Apr 18:51 2014

updating public key on git.racket-lang.org

I hope this isn’t a self-service question too…

Who manages the public keys accepted by git.racket-lang.org, now that it’s not Eli’s job? I’m
attaching my new public key.

Ooh, I guess I should also ask; has that machine been patched? Looks like it has, but I just used some random
online tool.

John

Attachment (id_rsa-git.pub): application/octet-stream, 462 bytes
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Matthias Felleisen | 16 Apr 13:39 2014

Re: [plt] Push #28542: master branch updated


Yuck. 

On Apr 15, 2014, at 9:20 PM, asumu@... wrote:

> asumu has updated `master' from aa43797b63 to 9aaaf98b32.
>  http://git.racket-lang.org/plt/aa43797b63..9aaaf98b32
> 
> =====[ One Commit ]=====================================================
> Directory summary:
>  97.6% pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/
> 
> ~~~~~~~~~~
> 
> 9aaaf98 Asumu Takikawa <asumu@...> 2014-04-15 21:15
> :
> | Fix TR class support for new class expansion
> |
> | Also add a type for `check-not-unsafe-undefined` which shows
> | up in the expanded code now.
> :
>  M .../typed-racket/base-env/base-env.rkt            |   4 +
>  M .../typed-racket/typecheck/check-class-unit.rkt   | 100 ++++++++++++-------
> 
> =====[ Overall Diff ]===================================================
> 
> pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/base-env/base-env.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/base-env/base-env.rkt
> +++ NEW/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/base-env/base-env.rkt
>  <at>  <at>  -6,6 +6,7  <at>  <at> 
>  (for-template
>   (except-in racket -> ->* one-of/c class)
>   racket/unsafe/ops
> +  racket/unsafe/undefined
>   ;(only-in rnrs/lists-6 fold-left)
>   '#%paramz
>   "extra-procs.rkt"
>  <at>  <at>  -2716,6 +2717,9  <at>  <at> 
> [unsafe-struct-set! top-func]
> [unsafe-struct*-set! top-func]
> 
> +;; Section 17.4 (Unsafe Undefined)
> +[check-not-unsafe-undefined (-poly (a) (-> a -Symbol a))]
> +
> ;; Section 18.2 (Libraries and Collections)
> [find-library-collection-paths (->opt [(-lst -Pathlike) (-lst -Pathlike)] (-lst -Path))]
> [collection-file-path (->* (list -Pathlike) -Pathlike -Path)]
> 
> pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/check-class-unit.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/check-class-unit.rkt
> +++ NEW/pkgs/typed-racket-pkgs/typed-racket-lib/typed-racket/typecheck/check-class-unit.rkt
>  <at>  <at>  -151,7 +151,7  <at>  <at> 
>               :make-methods-body))))
> 
> (define-syntax-class class-expansion
> -  #:literals (let-values letrec-syntaxes+values #%plain-app)
> +  #:literals (let-values letrec-syntaxes+values #%plain-app quote)
>   #:attributes (superclass-expr
>                 type-parameters
>                 all-init-internals
>  <at>  <at>  -176,13 +176,15  <at>  <at> 
>               ()
>               ((() ;; residual class: data
>                    :internal-class-data))
> -              (let-values (((superclass:id) superclass-expr)
> -                           ((interfaces:id) interface-expr))
> -                (#%plain-app
> -                 compose-class:id
> -                 internal:expr ...
> -                 (~and make-methods :make-methods-class)
> -                 (quote #f)))))))
> +              (#%plain-app
> +               compose-class:id
> +               name:expr
> +               superclass-expr:expr
> +               interface-expr:expr
> +               internal:expr ...
> +               (~and make-methods :make-methods-class)
> +               (quote :boolean)
> +               (quote #f))))))
> 
> ;; This is similar to `type-declaration` from "internal-forms.rkt", but
> ;; the expansion is slightly different in a class so we use this instead.
>  <at>  <at>  -517,15 +519,20  <at>  <at> 
>         #:literals (:-augment)
>         ;; FIXME: this case seems too loose, many things can match this syntax
>         ;;        we likely need to set a property or match against another name
> -        [(let-values ([(obj:id) self])
> -           (let-values ([(field:id) initial-value])
> -             (#%plain-app setter:id _ _)))
> +        [(begin
> +           (quote ((~datum declare-field-assignment) _))
> +           (let-values ([(obj:id) self])
> +            (let-values ([(field:id) initial-value])
> +              (#%plain-app setter:id _ _))))
>          ;; only record the first one, which is the one that initializes
>          ;; the field or private field
>          (unless (dict-has-key? initializers #'setter)
>            (free-id-table-set! initializers #'setter #'initial-value))
>          other-exprs]
> -        [:tr:class:super-new^
> +        ;; The second part of this pattern ensures that we find the actual
> +        ;; initialization call, rather than the '(declare-super-new) in
> +        ;; the expansion.
> +        [(~and :tr:class:super-new^ (#%plain-app . rst))
>          (when super-new
>            (tc-error/delayed "typed classes must only call super-new a single time"))
>          (set! super-new (find-provided-inits expr))
>  <at>  <at>  -830,8 +837,6  <at>  <at> 
>                             super-call-types
>                             pubment-types augment-types inner-types))
>   (values all-names all-types
> -          ;; FIXME: consider removing method names and types
> -          ;;        from top-level environment to avoid <undefined>
>           (append all-names
>                   localized-init-names
>                   localized-init-rest-name
>  <at>  <at>  -909,7 +914,6  <at>  <at> 
>     (syntax-parse form
>       #:literals (let-values #%plain-app quote)
>       ;; init with default
> -      ;; FIXME: undefined can appear here
>       [(set! internal-init:id
>              (#%plain-app extract-arg:id
>                           _
>  <at>  <at>  -939,14 +943,16  <at>  <at> 
>               (tc-error/delayed "Init argument ~a has no type annotation"
>                                 init-name)])]
>       ;; init-field with default
> -      [(let-values (((obj1:id) self:id))
> -         (let-values (((x:id)
> -                       (#%plain-app extract-arg:id
> -                                    _
> -                                    (quote name:id)
> -                                    init-args:id
> -                                    init-val:expr)))
> -           (#%plain-app local-setter:id obj2:id y:id)))
> +      [(begin
> +         (quote ((~datum declare-field-assignment) _))
> +         (let-values (((obj1:id) self:id))
> +           (let-values (((x:id)
> +                         (#%plain-app extract-arg:id
> +                                      _
> +                                      (quote name:id)
> +                                      init-args:id
> +                                      init-val:expr)))
> +             (#%plain-app local-setter:id obj2:id y:id))))
>        #:when (free-identifier=? #'x #'y)
>        #:when (free-identifier=? #'obj1 #'obj2)
>        (define init-name (syntax-e #'name))
>  <at>  <at>  -965,9 +971,11  <at>  <at> 
>       ;; any field or init-field without default
>       ;; FIXME: could use the local table to make sure the
>       ;;        setter is known as a sanity check
> -      [(let-values (((obj1:id) self:id))
> -         (let-values (((x:id) init-val:expr))
> -           (#%plain-app local-setter:id obj2:id y:id)))
> +      [(begin
> +         (quote ((~datum declare-field-assignment) _))
> +         (let-values (((obj1:id) self:id))
> +           (let-values (((x:id) init-val:expr))
> +             (#%plain-app local-setter:id obj2:id y:id))))
>        #:when (free-identifier=? #'x #'y)
>        #:when (free-identifier=? #'obj1 #'obj2)
>        (tc-expr form)]
>  <at>  <at>  -994,7 +1002,8  <at>  <at> 
> ;; generated inside the untyped class macro.
> (define (construct-local-mapping-tables stx)
>   (syntax-parse stx
> -    #:literals (let-values if quote #%plain-app #%plain-lambda values)
> +    #:literal-sets (kernel-literals)
> +    #:literals (values)
>     ;; See base-env/class-prims.rkt to see how this in-syntax
>     ;; table is constructed at the surface syntax
>     ;;
>  <at>  <at>  -1003,60 +1012,83  <at>  <at> 
>                    (#%plain-app
>                     values
>                     (#%plain-lambda ()
> +                      (quote ((~datum declare-this-escapes)))
>                       (#%plain-app (#%plain-app local-method:id _) _))
>                     ...)]
>                   [(private:id ...)
>                    (#%plain-app
>                     values
> -                    (#%plain-lambda () (#%plain-app local-private:id _))
> +                    (#%plain-lambda ()
> +                      (quote ((~datum declare-this-escapes)))
> +                      (#%plain-app local-private:id _))
>                     ...)]
>                   [(field:id ...)
>                    (#%plain-app
>                     values
>                     (#%plain-lambda ()
> +                      (quote ((~datum declare-field-use) _))
>                       (let-values (((_) _)) (#%plain-app local-field-get:id _))
> -                      (let-values (((_) _))
> -                        (let-values (((_) _)) (#%plain-app local-field-set:id _ _))))
> +                      (begin
> +                        (quote ((~datum declare-field-assignment) _))
> +                        (let-values (((_) _))
> +                          (let-values (((_) _)) (#%plain-app local-field-set:id _ _)))))
>                     ...)]
>                   [(private-field:id ...)
>                    (#%plain-app
>                     values
>                     (#%plain-lambda ()
> +                      (quote ((~datum declare-field-use) _))
>                       (let-values (((_) _)) (#%plain-app local-private-get:id _))
> -                      (let-values (((_) _))
> -                        (let-values (((_) _)) (#%plain-app local-private-set:id _ _))))
> +                      (begin
> +                        (quote ((~datum declare-field-assignment) _))
> +                        (let-values (((_) _))
> +                          (let-values (((_) _)) (#%plain-app local-private-set:id _ _)))))
>                     ...)]
>                   [(inherit-field:id ...)
>                    (#%plain-app
>                     values
>                     (#%plain-lambda ()
> +                      (quote ((~datum declare-inherit-use) _))
>                       (let-values (((_) _)) (#%plain-app local-inherit-get:id _))
>                       (let-values (((_) _))
>                         (let-values (((_) _)) (#%plain-app local-inherit-set:id _ _))))
>                     ...)]
>                   [(init:id ...)
> -                   (#%plain-app values (#%plain-lambda () local-init:id) ...)]
> +                   (#%plain-app
> +                    values
> +                    (#%plain-lambda ()
> +                      ;; check-not-unsafe-undefined
> +                      (#%plain-app _ local-init:id _)) ...)]
>                   [(init-rest:id ...)
> -                   (#%plain-app values (#%plain-lambda () local-init-rest:id) ...)]
> +                   (#%plain-app
> +                    values
> +                    (#%plain-lambda ()
> +                      ;; check-not-unsafe-undefined
> +                      (#%plain-app _ local-init-rest:id _)) ...)]
>                   [(inherit:id ...)
>                    (#%plain-app
>                     values
>                     (#%plain-lambda ()
> +                      (quote ((~datum declare-this-escapes)))
>                       (#%plain-app (#%plain-app local-inherit:id _) _))
>                     ...)]
>                   [(override:id ...)
>                    (#%plain-app
>                     values
>                     (#%plain-lambda ()
> +                      (quote ((~datum declare-this-escapes)))
>                       (#%plain-app (#%plain-app local-override:id _) _)
> +                      (quote ((~datum declare-this-escapes)))
>                       (#%plain-app local-super:id _))
>                     ...)]
>                   [(augment:id ...)
>                    (#%plain-app
>                     values
>                     (#%plain-lambda ()
> +                      (quote ((~datum declare-this-escapes)))
>                       (~or (#%plain-app local-augment:id _)
>                            (#%plain-app (#%plain-app local-augment:id _) _))
> +                      (quote ((~datum declare-this-escapes)))
>                       (let-values ([(_) (#%plain-app local-inner:id _)])
>                         (if _ (#%plain-app _ _) _)))
>                     ...)])

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

claire alvis | 16 Apr 00:13 2014
Picon

Catching the undefined value

The push below includes changes to letrec expressions, internal definitions, units, classes, and certain ill-formed shared expressions so that they no longer leak the `undefined' value.  If a variable bound to the undefined value is referenced at runtime, an exception is raised.  

We are aware that these changes are not backwards compatible.  We've deliberately put them in the development branch to get a sense of how much of a problem that is.

Internal libraries that depend on having `undefined' as an initialization value now import the racket/unsafe/undefined library but should always keep it from leaking.  The unsafe library provides the internal `unsafe-undefined' value and the internal function `check-not-unsafe-undefined' that errors if given the `unsafe-undefined' value but otherwise acts like the identity function.  We extremely discourage the external use of racket/unsafe/undefined and it will not play nicely with anything that uses letrec.

Programs that cannot be refactored to not use `undefined' should instead use the "better" undefined value from the racket/undefined collect.  This `undefined' value can still leak out of shared expressions when using mutable pairs.

For those interested in the implementation details:
- A new compiler pass wraps check-not-unsafe-undefined around any letrec-bound variable references that could possibly leak the undefined value.  It runs a simple analysis to determine which variable references need such checks.  From the benchmarks we've run, it looks like a relatively low number of variable references actually need checks.  However, these checks do have the potential to disable certain optimizations such as inlining of variables with checked references.
- The change to classes is more experimental.  Any instance of a class that could possibly reference a field before it is assigned is chaperoned.  The chaperone watches for a reference to the internal undefined value.  The class macro performs its own analysis to determine which classes need to be chaperoned. 

TL;DR you should not see unsafe-undefined ever again, but you may still see the "better" undefined when using (libraries that use) racket/undefined.

Claire



On Tue, Apr 15, 2014 at 5:38 PM, <mflatt-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org> wrote:
mflatt has updated `master' from 69984fb231 to a283f3d804.
  http://git.racket-lang.org/plt/69984fb231..a283f3d804

=====[ 19 Commits ]=====================================================


~~~~~~~~~~

72c958d Claire Alvis <claire.alvis-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2013-05-07 09:36
:
| all necessary changes to check references to uninitialized letrec variables
|
| includes a new pass, letrec_check, two new primitives, and
| changes to packages that grabbed the letrec undefined value
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

Gmane