Matthew Flatt | 26 Feb 18:26 2015
Picon

toward a new Racket macro expander

I've been working on a new macro expander for Racket, and I'm starting
to think that it will work. The new expander is not completely
compatible with the current expander --- and that will be an issue if
we eventually go forward with the change --- but most existing code
still works.

Here's a report on my current experiment:

 http://www.cs.utah.edu/~mflatt/scope-sets/

The goals for a new expander are

 1. to replace a complicated representation of syntax objects with a
    simpler one (and, as a result, avoid some performance and
    submodule-re-expansion problems that have been too difficult to fix
    with the current expander);

 2. to find a simpler model of binding than the current one, so that
    it's easier to explain and reason about scope and macros; and

 3. to implement the new expander in Racket instead of C.

I have possibly succeeded on 1, possibly succeeded to some degree on 2,
and temporarily given up on 3.

(I know it sounds crazy to continue with a C implementation of macro
expansion. Goals 1 and 2 were impossible for me without being able to
try ideas at scale, though, and it was too daunting to tackle a full
reimplementation of the expander and a restructuring of the VM at the
same time. Continuing in the comfortable-for-only-me C environment was
(Continue reading)

John Clements | 4 Feb 23:56 2015
Picon

Testing, please ignore

Wait, you didn't ignore it! Okay, this should be the last message that goes through on old dev. We'll see if I'm so cheerful in five minutes.

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
John Clements | 4 Feb 08:04 2015
Picon

Switching groups tomorrow

The plan is to throw the switch tomorrow, to switch from our existing mailing list to the new google group. If you haven't yet subscribed to the new one, you can do it now at

   https://groups.google.com/forum/#!forum/racket-dev/join

(thanks to Vincent for the refined URL).

If all goes well, those that have already switched should not notice any outage; thanks to advice from Eli, it appears that the dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org front door can continue to work. Thanks, Eli!

Those that have not switched will ... well, you'll stop getting the developers list. I'll add batches from the existing list over time, but there's a cap on the number of adds per day, so you'll be missing parts of the stream.

Cross your fingers, and thanks for your patience!

John Clements

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Gustavo Massaccesi | 2 Feb 22:41 2015
Picon

Github repo is two commits behind

* openssl: recognize version "1.0.1j" #8265c9 (3 days ago) <-- latest
commit in git.racket-lang

* pretty-print: fix for a current inspector that sees through
internals #8d49a9 (3 days ago)

* fix reified-syntax-class-curry (missing role argument) #302986 (3
days ago) <-- Latest commit in github

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

Dan Liebgold | 2 Feb 21:14 2015
Picon

file change notifications

Hi -

I'm doing a little profiling of Racket 6.1 on windows. It seems like cancelling a filesystem-change-evt can take many seconds, and one is cancelled for the addon-dir directory (which defaults to my roaming profile) during every run. I think it interacts badly with my virus checker.

Is there a way to disable this? I'm not using the addon-dir, so any notifications shouldn't be important.

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Eric Dobson | 31 Jan 07:29 2015
Picon

Re: [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, <mflatt-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.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 <mflatt <at> 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 <mflatt <at> 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
<at> <at> -123,7 +123,7 <at> <at> would create only <at> filepath{compiled/b_rkt.zo} and

  <at> ; ----------------------------------------------------------------------

- <at> section{Dependency Files}
+ <at> section[#:tag "Dependency Files"]{Dependency Files}

 In addition to a bytecode file, <at> exec{raco make} creates a file
  <at> filepath{compiled/ <at> nonterm{name}_ <at> nonterm{ext}.dep} that records
<at> <at> -538,7 +538,7 <at> <at> messages are instances of a <at> racket[parallel-compile-event] prefab structure:

  <at> 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 <at> racket[compile-event] as document in
<at> <at> -550,25 +550,36 <at> <at> field is a <at> racket[compile-event] as document in

  <at> defmodule[compiler/cm-accomplice]

- <at> defproc[(register-external-file [file (and path? complete-path?)]) void?]{
+ <at> defproc[(register-external-file [file (and path? complete-path?)]
+                                 [#:indirect? indirect? any/c #f])
+         void?]{

-Logs a message (see <at> racket[log-message]) at level <at> racket['info] to
-a logger named <at> racket['cm-accomplice]. The
-message data is a <at> racketidfont{file-dependency} prefab structure type
-with two fields; the first field's value is <at> racket[file] and the second
-field's value is <at> racket[#f] (to indicate a non-module dependency).
+Logs a message (see <at> racket[log-message]) at level <at> racket['info] to a
+logger named <at> racket['cm-accomplice]. The message data is a
+ <at> racketidfont{file-dependency} prefab structure type with two fields;
+the first field's value is <at> racket[file] and the second field's value
+is <at> racket[#f] (to indicate a non-module dependency). If the
+ <at> racket[indirect?] argument is true, the data is more specifically an
+instance of a <at> racketidfont{file-dependency/indirect} prefab structure
+type that is a subtype of <at> racketidfont{file-dependency} with no new
+fields.

 A compilation manager implemented by <at> racketmodname[compiler/cm] looks
-for such messages to register an external dependency. The compilation
-manager records (in a <at> 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 <at> 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 checker, that the dependency is
+indirect (and should not imply a direct package dependency).

 The <at> racket[include] macro, for example, calls this procedure with the
 path of an included file as it expands an <at> racket[include] form.}

- <at> defproc[(register-external-module [file (and path? complete-path?)]) void?]{
+ <at> defproc[(register-external-module [file (and path? complete-path?)]
+                                   [#:indirect? indirect? any/c #f])
+         void?]{

 Like <at> racket[register-external-file], but logs a message with a
  <at> racketidfont{file-dependency} prefab structure type whose second

pkgs/racket-doc/scribblings/raco/setup.scrbl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- OLD/pkgs/racket-doc/scribblings/raco/setup.scrbl
+++ NEW/pkgs/racket-doc/scribblings/raco/setup.scrbl
<at> <at> -744,13 +744,14 <at> <at> Optional <at> filepath{info.rkt} fields trigger additional actions by
    module. More specifically, used modules are determined when
    deleting a <at> filepath{.dep} file, which would have been created to
    accompany a <at> filepath{.zo} file when the <at> filepath{.zo} was built
-   by <at> exec{raco setup}. If the <at> filepath{.dep} file indicates another
-   module, that module's <at> filepath{.zo} is deleted only if it also has
-   an accompanying <at> filepath{.dep} file. In that case, the
-    <at> filepath{.dep} file is deleted, and additional used modules are
-   deleted based on the used module's <at> filepath{.dep} file, etc.
-   Supplying a specific list of collections to <at> exec{raco setup} disables
-   this dependency-based deletion of compiled files.}
+   by <at> exec{raco setup} or <at> exec{raco make} (see
+    <at> secref["Dependency\x20Files"]). If the <at> filepath{.dep} file
+   indicates another module, that module's <at> filepath{.zo} is deleted
+   only if it also has an accompanying <at> filepath{.dep} file. In that
+   case, the <at> filepath{.dep} file is deleted, and additional used
+   modules are deleted based on the used module's <at> filepath{.dep}
+   file, etc. Supplying a specific list of collections to <at> exec{raco
+   setup} disables this dependency-based deletion of compiled files.}

 ]

<at> <at> -816,9 +817,10 <at> <at> with fewer dependencies.
  <at> subsection{How Dependency Checking Works}

 Dependency checking uses <at> filepath{.zo} files, associated
- <at> filepath{.dep} files, and the documentation index. Dynamic
-references, such as through <at> racket[dynamic-require], are not visible
-to the dependency checker; only dependencies via <at> racket[require],
+ <at> filepath{.dep} files (see <at> secref["Dependency Files"]), and the
+documentation index. Dynamic references, such as through
+ <at> racket[dynamic-require], are not visible to the dependency checker;
+only dependencies via <at> racket[require],
  <at> racket[define-runtime-module-path-index], and other forms that
 cooperate with <at> racket[raco make] are visible for dependency checking.


pkgs/racket-doc/scribblings/reference/syntax.scrbl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- OLD/pkgs/racket-doc/scribblings/reference/syntax.scrbl
+++ NEW/pkgs/racket-doc/scribblings/reference/syntax.scrbl
<at> <at> -3005,10 +3005,10 <at> <at> submodule). Introduced submodules have the names
  <at> racket[lazy-require-] <at> racket[_n] <at> racketidfont{-} <at> racket[_m], where
  <at> racket[_n] is a phase-level number and <at> racket[_m] is a number.

-When the use of a lazily-required function triggers module loading,
- <at> racket[register-external-module] declares a potential compilation
-dependency (in case the function is used in the process of compiling a
-module).
+When the use of a lazily-required function triggers module loading, it
+also triggers a use of <at> racket[register-external-module] to declare an
+indirect compilation dependency (in case the function is used in the
+process of compiling a module).

  <at> examples[#:eval lazy-require-eval
 (lazy-require

racket/collects/compiler/cm-accomplice.rkt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- OLD/racket/collects/compiler/cm-accomplice.rkt
+++ NEW/racket/collects/compiler/cm-accomplice.rkt
<at> <at> -3,16 +3,18 <at> <at>
 (provide register-external-file
          register-external-module)

-(define (register-external-file f)
-  (register-external 'register-external-file f #f))
-(define (register-external-module f)
-  (register-external 'register-external-module f #t))
+(define (register-external-file f #:indirect? [indirect? #f])
+  (register-external 'register-external-file f #f indirect?))
+(define (register-external-module f #:indirect? [indirect? #f])
+  (register-external 'register-external-module f #t indirect?))

-(define (register-external who f module?)
+(define (register-external who f module? indirect?)
   (unless (and (path? f) (complete-path? f))
     (raise-type-error who "complete path" f))
   (log-message (current-logger)
                'info
                'cm-accomplice
                (format "file dependency: ~s" f)
-               `#s(file-dependency ,f ,module?)))
+               (if indirect?
+                   `#s((file-dependency/indirect file-dependency 2) ,f ,module?)
+                   `#s(file-dependency ,f ,module?))))

racket/collects/compiler/cm.rkt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- OLD/racket/collects/compiler/cm.rkt
+++ NEW/racket/collects/compiler/cm.rkt
<at> <at> -231,9 +231,13 <at> <at>
 (define (get-dep-sha1s deps up-to-date collection-cache read-src-syntax mode roots must-exist? seen)
   (let ([l (for/fold ([l null]) ([dep (in-list deps)])
              (and l
+                  ;; (cons 'indirect dep) => indirect dependency (for pkg-dep checking)
                   ;; (cons 'ext rel-path) => a non-module file, check source
                   ;; rel-path => a module file name, check cache
-                  (let* ([ext? (and (pair? dep) (eq? 'ext (car dep)))]
+                  (let* ([dep (if (and (pair? dep) (eq? 'indirect (car dep)))
+                                  (cdr dep)
+                                  dep)]
+                         [ext? (and (pair? dep) (eq? 'ext (car dep)))]
                          [p (collects-relative*->path (if ext? (cdr dep) dep) collection-cache)])
                     (cond
                      [ext? (let ([v (get-source-sha1 p)])
<at> <at> -273,19 +277,26 <at> <at>
                                          external-module-deps ; can create cycles if misused!
                                          reader-deps))]
         [external-deps (remove-duplicates external-deps)])
+    (define (path*->collects-relative/maybe-indirect dep)
+      (if (and (pair? dep) (eq? 'indirect (car dep)))
+          (cons 'indirect (path*->collects-relative (cdr dep)))
+          (path*->collects-relative dep)))
     (with-compile-output dep-path
       (lambda (op tmp-path)
         (let ([deps (append
-                     (map path*->collects-relative deps)
+                     (map path*->collects-relative/maybe-indirect deps)
                      (map (lambda (x)
-                            (cons 'ext (path*->collects-relative x)))
+                            (define d (path*->collects-relative/maybe-indirect x))
+                            (if (and (pair? d) (eq? 'indirect d))
+                                (cons 'indirect (cons 'ext (cdr d)))
+                                (cons 'ext d)))
                           external-deps))])
-        (write (list* (version)
-                      (cons (or src-sha1 (get-source-sha1 path))
-                            (get-dep-sha1s deps up-to-date collection-cache read-src-syntax mode roots #t #hash()))
-                      deps)
-               op)
-        (newline op))))))
+          (write (list* (version)
+                        (cons (or src-sha1 (get-source-sha1 path))
+                              (get-dep-sha1s deps up-to-date collection-cache read-src-syntax mode roots #t #hash()))
+                        deps)
+                 op)
+          (newline op))))))

 (define (format-time sec)
   (let ([d (seconds->date sec)])
<at> <at> -311,6 +322,7 <at> <at>
 (define-struct ext-reader-guard (proc top)
   #:property prop:procedure (struct-field-index proc))
 (define-struct file-dependency (path module?) #:prefab)
+(define-struct (file-dependency/indirect file-dependency) () #:prefab)

 (define (compile-zo* mode roots path src-sha1 read-src-syntax zo-name up-to-date collection-cache)
   ;; The `path' argument has been converted to .rkt or .ss form,
<at> <at> -322,10 +334,14 <at> <at>
   (define reader-deps null)
   (define deps-sema (make-semaphore 1))
   (define done-key (gensym))
-  (define (external-dep! p module?)
+  (define (external-dep! p module? indirect?)
+    (define bstr (path->bytes p))
+    (define dep (if indirect?
+                    (cons 'indirect bstr)
+                    bstr))
     (if module?
-        (set! external-module-deps (cons (path->bytes p) external-module-deps))
-        (set! external-deps (cons (path->bytes p) external-deps))))
+        (set! external-module-deps (cons dep external-module-deps))
+        (set! external-deps (cons dep external-deps))))
   (define (reader-dep! p)
     (call-with-semaphore
      deps-sema
<at> <at> -386,7 +402,8 <at> <at>
                    (file-dependency? (vector-ref l 2))
                    (path? (file-dependency-path (vector-ref l 2))))
           (external-dep! (file-dependency-path (vector-ref l 2))
-                         (file-dependency-module? (vector-ref l 2))))
+                         (file-dependency-module? (vector-ref l 2))
+                         (file-dependency/indirect? (vector-ref l 2))))
         (loop))))

   ;; Write the code and dependencies:
<at> <at> -627,9 +644,13 <at> <at>
               ;; If `sha1-only?', then `maybe-compile-zo' returns a #f or thunk:
               (maybe-compile-zo sha1-only? deps mode roots path orig-path read-src-syntax up-to-date collection-cache new-seen)]
              [(ormap
-               (lambda (p)
+               (lambda (raw-p)
+                 ;; (cons 'indirect dep) => indirect dependency (for pkg-dep checking)
                  ;; (cons 'ext rel-path) => a non-module file (check date)
                  ;; rel-path => a module file name (check transitive dates)
+                 (define p (if (and (pair? raw-p) (eq? 'indirect (car raw-p)))
+                               (cdr raw-p)
+                               raw-p))
                  (define ext? (and (pair? p) (eq? 'ext (car p))))
                  (define d (collects-relative*->path (if ext? (cdr p) p) collection-cache))
                  (define t

racket/collects/racket/lazy-require.rkt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- OLD/racket/collects/racket/lazy-require.rkt
+++ NEW/racket/collects/racket/lazy-require.rkt
<at> <at> -110,4 +110,4 <at> <at>
                  modpath
                  (variable-reference->resolved-module-path vr))))])
     (when (path? path)
-      (register-external-module path))))
+      (register-external-module path #:indirect? #t))))

racket/collects/setup/private/pkg-deps.rkt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- OLD/racket/collects/setup/private/pkg-deps.rkt
+++ NEW/racket/collects/setup/private/pkg-deps.rkt
<at> <at> -489,6 +489,7 <at> <at>
             ;; Treat everything in ".dep" as 'build mode...
             (define deps (cddr (call-with-input-file* (build-path dir f) read)))
             (for ([dep (in-list deps)])
+              ;; Note: indirect dependencies (which start with 'indirect) are ignored
               (when (and (pair? dep)
                          (eq? 'collects (car dep)))
                 (define path-strs (map bytes->string/utf-8 (cdr dep)))

_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Alexander D. Knauth | 30 Jan 22:24 2015

Re: A proposal for parametric opaque types in Typed Racket


On Jan 30, 2015, at 3:59 PM, Alexis King <lexi.lambda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

No, the typechecker can’t make any assumptions about the results of opaque types. If you explicitly instantiate a Posn with the type Real, the typechecker should only guarantee the result will be Real. Annotate the type as (U 1 2), though, and obviously it would need to ensure that remains invariant.

How about this program:
untyped.rkt:
#lang racket
(provide (all-defined-out))
(define (make-posn x y) (list 3 y)) ; bad
typed.rkt:
#lang typed/racket
; make Posn parametric
(define-type (Posn X Y) (List X Y))
(require/typed "untyped.rkt"
               [make-posn (All (X Y) X Y -> (Posn X Y))])
(: p : (Posn Real Real))
(define p (make-posn 1 2))
This gives this error:
. . make-posn: broke its contract
  promised: X3
  produced: 3
  in: the car of
      the range of
      (parametric->/c
       (X3 Y4)
       (->*
        (X3 Y4)
        ()
        (values (cons/c X3 (cons/c Y4 g6)))))
  contract from: (interface for make-posn)
  blaming: (interface for make-posn)
   (assuming the contract is correct)
  at: …./typed.rkt:5.16

I think it’s a good thing that it checks that it actually gives you the value that you gave it, and not just something like 3 even if it happens to match the type you want.  And I think parametric opaque types should behave in a similar way, and to do that you would need the opaque value to be wrapped in another opaque structure, which would store either the contracts or the set of values that would pass the contracts or something like that.  


On Jan 30, 2015, at 12:30, Alexander D. Knauth <alexander-9dBIAfr+9LAdnm+yROfE0A@public.gmane.org> wrote:


On Jan 30, 2015, at 1:53 PM, Alexis King <lexi.lambda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

No, it doesn’t need to be wrapped in an opaque structure. Wrapping it in an opaque structure would add a layer of indirection for absolutely no gain. Remember, the value itself is already, by definition, opaque. The only way typed code can manipulate the value is by passing it to other functions imported via require/typed.

This means that contracts only need to be generated wherever those functions are called. This can be done without wrapping or unwrapping anything because all the information required to generate those contracts is known at expansion-time. The typechecker simply needs to insert the relevant contracts at the relevant locations.

Imagine a program like this:
#lang typed/racket
(require typed/lang/posn)
(: p : (Posn Real Real)) ; I’m assuming Posn is parametric over 2 tvars, not 1
(define p (posn 1 2))
(: x : Real)
(define x (posn-x p))
As far as the type checker would check, it would check that the result of posn-x is a Real, but I think that the runtime contract it should also check that it returns 1, because posn could have been instantiated as (Posn 1 2).
#lang typed/racket
(require typed/lang/posn/mutable) ; like typed/lang/posn, but providing mutation too
(: p : (Posn Real Real))
(define p (posn 1 2))
(: x : Real)
(define x (posn-x p))
(set-posn-x! p 3)
(: x2 : Real)
(define x2 (posn-x p))
Here, even though the type checker only cares that it’s a number, it should check that x2 definition returns either 1 or 3, since both were provided as x values for the posn p.

For it to keep track of these at runtime, (and it would have to be runtime) the contracts would have to be with the actual posn value in an opaque structure, which would have contracts sort of like (new-∀/c) that would check these things, although I don’t think it would have to wrap the inner values, but just record them so that when posn-x is called on one of these things, it checks that it was one of the values that was passed in to either a constructor or setter function.  

On Jan 30, 2015, at 07:27, Alexander D. Knauth <alexander-9dBIAfr+9LAdnm+yROfE0A@public.gmane.org> wrote:
 
On Thu, Jan 29, 2015, at 09:03 PM, Alexis King wrote:
It isn’t wrapped in an opaque structure. That wasn’t a part of my proposal, and while I didn’t think of it until you brought it up, I still think it’s unnecessary and doesn’t add any convenience.
 
I think the opaque structures would be necessary for the kind of "sharing wrappers between functions" that you describe just before section 2.1, except that instead of the sub-values being wrapped on the untyped side, the whole thing is wrapped on the typed side, and there is a contract that wraps it and unwraps it when it goes from untyped to typed and back.  
 
For parametric types, they have to also work if the type was constrained to the exact set of values that were provided, which means that if you provide two numbers, say 1 and 2, it has to return a posn with not just any two numbers, but values of the type (U 1 2), since A could have been constrained to (U 1 2).  So it has to be wrapped somehow, and I think wrapping it on the typed side makes more sense.  
 
Perhaps I’m not understanding you properly, but your “one-length string” idea sounds like it has little to do with this opaque type problem and more to do with the fact that you want refinement types in Typed Racket. I do, too! But I don’t think hacking the opaque type system is going to help you with that.
 
Well, yeah, refinement types would be the "real" solution for this particular example, but if I do want to constrain it to strings of length 1, opaque types are the only option for now, and they actually work fine.  My point was you couldn't do this type of thing with the opaque structures and you would probably get weird errors if you tried.  (See below because there might be a solution?)
 
(Also, as for the box example, I’m actually a little surprised that doesn’t contract error. Seems like a bug to me, but perhaps I’m missing some idiosyncrasies of the type system. Either way, it’s precisely that kind of craziness I was referring to when I compared casting parametric opaque types to casting mutable types.)
 
There is a bug report for it here, and the solution proposed by Sam Tobin-Hochstadt would be for cast to generate 2 contracts, one for the original type, one for the new type, but that never got implemented.  
 
Actually now that I think about it the two-contract solution might be able to solve the previous problem, since the original contract could unwrap the value before it is passed to the new contract?  I'm not sure though.  The value inside the cast would be from the typed side, then it is passed through the orig contract as if it were going to the typed side,

This was a typo, I meant to say “as if it were going to the untyped side"

which would unwrap it, and then that unwrapped value would be passed to the new contract as if it were flowing from the untyped side to the typed side.  
 
 
On Jan 29, 2015, at 20:50, Alexander D. Knauth <alexander-9dBIAfr+9LAdnm+yROfE0A@public.gmane.org> wrote:
 
 
On Jan 29, 2015, at 11:34 PM, Alexis King <lexi.lambda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
 
But the problem is that if it’s an opaque type then it can’t unwrap it once the value is returned from make-posn.
 
Yes, that’s precisely the problem. Your point about implementing everything as single-valued structs on the typed side is an interesting one, though I don’t think it ultimately solves any problems. The fact that the typed side knowsnothingabout the contents of the value is what makes this such a tricky problem.
 
As for this:
 
But then you couldn’t do any operations on it except those that you use import with require/typed, right?
 
That’s completely correct. That’s why it’s “opaque.”
 
And what happens if you use cast on one of these things?
 
That’s a little more interesting. Usingcaston an object of this type would never fail (unless, of course, it didn’t actually satisfy the basicposn?predicate), but it would possibly introduce failures in the future since it would affect the contracts generated forposn-xandposn-y, for example.
 
To make that more clear, casting a(Posn Real)to a(Posn String)would work fine until you tried to callposn-xon the instance, in which case it would raise a contract error. Note that this isn’t really any different from casting mutable data types.
 
But if it were wrapped in an opaque structure, then that structure wouldn’t satisfy the posn? predicate, unless of course the posn? predicate has a contract that unwraps it.  So all of the operations on it would have to have contracts that would unwrap it.  This might actually make sense if the type is meant to be actually opaque, but if it’s an opaque type that represents a normal non-opaque value, then it will still work as an opaque type, but it won’t be a normal non-opaque value anymore on the typed side.  
 
But the reason I asked about cast was because normally I can use cast with a value that has an opaque type, but it’s wrapped on the typed side in this opaque structure, then the contracts on the cast would see this opaque structure instead of the actual value.  
 
I’m thinking of an opaque typed representing a string with length 1, which I can use as long as I use either (cast x String) or (assert x string?) whenever I pass it to a string operation.  But if it were an opaque type, I don’t think I could do that.  There could be a 1string->string function that could take one of these 1strings and convert it to a string, but that seems like it should be unnecessary, but made necessary by this opaque structure thing.  
 
And for “this isn’t really any different from casting mutable data types,” look at this:
#lang typed/racket
(: b : (Boxof Number))
(define b (box 1))
(set-box! (cast b (Boxof (U Number String))) "I am a string")
(ann (unbox b) Number) ;"I am a string” ; not a contract error
 
 
 
On Jan 29, 2015, at 20:20, Alexander D. Knauth <alexander-9dBIAfr+9LAdnm+yROfE0A@public.gmane.org> wrote:
 
Furthermore, even if the wrappers were shared between functions, untyped code would recieved wrapped values, which would render them quite useless.
 
If it’s not an opaque type, but something like a list, then this works, and the untyped code receiving wrapped values isn’t a problem here:
#lang typed/racket
; make Posn parametric
(define-type (Posn A) (List A A))
(provide Posn)
(require/typed/provide
 "untyped.rkt"
 [make-posn (All (A) A A -> (Posn A))]
 [posn-x (All (A) (Posn A) -> A)]
 [posn-y (All (A) (Posn A) -> A)]
 [real-posn? [(Posn Any) -> Boolean]])
> (define p (make-posn 1 2))
(make-posn #<A6> #<A6>) ; a printf that I put in make-posn from “untyped.rkt"
> p
- : (Listof Positive-Byte) [more precisely: (List Positive-Byte Positive-Byte)]
'(1 2) ; unwrapped
> (posn-x p)
- : Integer [more precisely: Positive-Byte]
1
> (posn-y p)
- : Integer [more precisely: Positive-Byte]
2
> (real-posn? p)
- : Boolean
#t
 
Even though for a short time it's wrapped, it’s unwrapped as soon as make-posn returns, and then after that if it flows into untyped code again it’s not wrapped and functions like real-posn? work fine.  
 
But the problem is that if it’s an opaque type then it can’t unwrap it once the value is returned from make-posn.
 
And I don’t think parametric opaque types could solve this unless all posns themselves were wrapped with an opaque struct on the typed side, which I guess does make sense now that I think about it.  But then you couldn’t do any operations on it except those that you use import with require/typed, right?  Or not?  And what happens if you use cast on one of these things?
 
 
On Jan 29, 2015, at 9:25 PM, Alexis King <lexi.lambda-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
 
I recently ran into a problem in which opaque types (types imported from untyped code) cannot by parameterized by Typed Racket. I initially encountered this problem in my attempt to port 2htdp/image to TR.
 
After some further consideration, I’m interested in adding support to make something like this possible, which would certainly have additional benefits beyond this specific use-case. I’ve outlined my proposal here:
 
Any feedback, suggestions, or advice would be appreciated, especially from those who are familiar with Typed Racket’s internals.
 
Thank you,
Alexis
_________________________
 Racket Developers list:


_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
John Clements | 30 Jan 16:28 2015
Picon

Switching to Google groups: many thanks, keep it coming

I want to thank 60 of you for signing up for the new google group manually; limitations on bulk adds and bulk invites mean that transferring people by hand will be time-consuming. (On the other hand, I'll probably get really good at google's CAPTCHAs...)

Anyhow, if you have a moment and haven't yet done so, visit this link

    https://groups.google.com/forum/#!forum/racket-dev/join

to sign up for the new group. At the urging of several list participants, I'm going to wait a few more days for people to add themselves.

Thanks again!

John Clements
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Alexis King | 30 Jan 03:25 2015
Picon

A proposal for parametric opaque types in Typed Racket

I recently ran into a problem in which opaque types (types imported from untyped code) cannot by parameterized by Typed Racket. I initially encountered this problem in my attempt to port 2htdp/image to TR.

After some further consideration, I’m interested in adding support to make something like this possible, which would certainly have additional benefits beyond this specific use-case. I’ve outlined my proposal here:

Any feedback, suggestions, or advice would be appreciated, especially from those who are familiar with Typed Racket’s internals.

Thank you,
Alexis
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
John Clements | 29 Jan 01:47 2015
Picon

Switching to Google Groups

Dear developers,

PLT would like to get out of the mailing-list administration game.

Accordingly, we’re planning to switch to Google Groups. Rather than starting with our largest list, the Racket Users list, we’ve chosen to begin with the dev list, because … well, you’re probably more tolerant, if^H^H when something goes wrong.

We would like the transition to be as smooth as possible, and we can use your help with this.  Specifically, Google has a daily cap on the number of e-mail addresses that can be bulk-added to a mailing list. For this reason, it would speed the transition greatly if you could take a moment to sign up for the new group yourself, using this URL:

https://groups.google.com/forum/#!forum/racket-dev

We plan to disable signup for the old group now, and to halt delivery of mail to the existing group address tomorrow. You can post to the new group (after signing up) by sending mail to

racket-dev-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org

We plan to manually add or invite the members who do not add themselves, but the daily cap will mean that these users are likely to miss one or more days of postings to this list. Naturally, those posts will be archived, as part of the group.

The archive of the existing list will continue to exist, though new messages will not be added to it.

Let us know if you run into problems!

Many thanks,

John Clements & PLT
_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev
Byron Davies | 29 Jan 00:21 2015
Picon

Re: dev Digest, Vol 72, Issue 31

My apologies, especially to Matt, for letting this thread go cold.  I was busy preparing a Racket-based demo for this morning -- and it went very well.  As mentioned, I'm working on weakest precondition analysis for finding latent faults in programs. Our goal is to do this for all kinds of software, including machine language, but for proof of concept I'm doing it *in* Racket *on* Racket programs.  Racket's language building tools, including syntax and the syntax browser, have been very useful for this problem.

Regarding transparency, thank you, Matt, for suggesting an alternative approach.  I've played with your examples a bit, trying to see how I could use this during debugging.  I have also read the Reflection and Security chapter in the reference to learn more about inspectors in general.

Your code, commented:

(define orig-i (current-inspector))  ; saves the original inspector
(define sub-i (make-inspector orig-i))  ;make a new inspector whose parent is the original inspector

(current-inspector sub-i)  ;makes the new inspector the current inspector
(struct a (x))  ; creates a structure using the new inspector as the default inspector
(define v (a 1))  ; creates an instance of the new structure
(current-inspector orig-i) ;reverts the inspector to the original (the parent of the new inspector)

I see how this works, but I'm a little confused about why it works.  I see that the new inspector is a child of the old one, and I read in the reference chapter that access is determined not by the inspector in force at creation time, but by the parent of that inspector, i.e., the old inspector. I can't find any description of the "power" of an inspector, except that the parent is more powerful.

Are there degrees of power? Or if you have access to the parent do you have all the power you can have? I see that the inspector gives you access to the data in a structure instance, but does it also give you access to meta-data, so that I know that the name of the first field in struct a is x?

I also don't understand how the root inspector works.  I have found that setting (current-inspector root-inspector) delivers endless left parens for the (a 1) example, presumably because the display function recursively tries to inspect the components of the struct, all the way down.

Finally, does this also work for classes?

Date: Thu, 22 Jan 2015 05:36:18 -0700

From: Matthew Flatt <mflatt-sDh8Nw2yj/+Vc3sceRu5cw@public.gmane.org>
To: Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
Cc: dev <at> racket-lang.org
Subject: Re: [racket-devFull transparency
Message-ID: <20150122123620.2DAA16501A2-t8PTB6f7IWE44o9QpHrwMJQCsf4PZ8us@public.gmane.org>
Content-Type: text/plain; charset=UTF-8

I don't think you want to do anything with the compiler or macros.
Instead, it's a matter of having a sufficiently powerful inspector
(which is the concept of "inspectability" turned into a language
construct).

If you have just

 (struct a (x))
 (a 1)

then the result will print as `#<a>`. But if you use

 (define orig-i (current-inspector))
 (define sub-i (make-inspector orig-i))

 (current-inspector sub-i)
 (struct a (x))
 (define v (a 1))
 (current-inspector orig-i)

 v

Then, the result will print as `(a 1)`. That's because the structure
declaration is creates under an inspector `sub-i` (which is the current
inspector at the time) that is subordinate to the inspector `orig-i`
that is in place when the structure instance is printed.

The current inspector is determined dynamically, which means that if
you're loading some code, you can set the inspector while loading the
code. For example, if "a.rkt" is

 #lang racket/base
 (provide v)

 (struct a (x))
 (define v (a 1))

then

 (define v
   (parameterize ([current-inspector (make-inspector)])
     (dynamic-require "a.rkt" 'v)))
 v

will print the `a` instance transparently.


To protect libraries, there's no safe way to access a root inspector
that controls all structure types when you start Racket. Nothing is
safe from unsafe code, though, and here's an unsafe way to access the
root inspector:

 #lang racket/base
 (require ffi/unsafe)

 (define-cstruct _Scheme_Inspector
   ([stag _short]
    [keyex _short]
    [depth _int]
    [superior _racket]))

 (define root-inspector
   (Scheme_Inspector-superior
    ((get-ffi-obj 'scheme_get_initial_inspector
                  #f
                  (_fun -> (_gcable _Scheme_Inspector-pointer))))))

Using `root-inspector`, you can inspect any structure instance.

At Wed, 21 Jan 2015 23:46:10 -0700, Byron Davies wrote:
> Nice parry!  What may be straightforward to you may not be so obvious to
> me.  But I'll take a look.
>
> I'm deep into a project using Racket for weakest precondition analysis.
> Every time I'm debugging it seems like I have to write another
> special-purpose accessor, or export some existing accessor up through
> multiple levels in order to get at the data I need at the top-level.  I
> remember how easy it was with the Lisp Machine to navigate through data no
> matter what it was.
>
> The Lisp Machine offered total transparency, with no real way to protect
> data, to the benefit of the developer.  Racket offers total opacity, to the
> benefit of code security.  I'm hoping there's a middle ground, where
transparency can be turned on and off.
>
> Byron
>
> On Wed, Jan 21, 2015 at 12:20 PM, Matthias Felleisen <matthias-1vnkWVZi4QY@public.gmane.orgedu>
> wrote:
>
> >
> > Sounds like a straightforward change to the existing macros. Why don't you
> > create a fork and experiment?
> >
> >
> > On Jan 21, 2015, at 1:15 PM, Byron Davies <byrondavies <at> starshine.us>
> > wrote:
> >
> > > Or, more conservatively, every struct and object in a given package,
> > file, or set of files.
> > >
> > > On Wed, Jan 21, 2015 at 11:03 AM, Byron Davies <byrondavies <at> starshine.us>
> > wrote:
> > > Would it be easy to create a compiler flag that would make every struct
> > and object transparent?  This would then make it easy to create a Lisp
> > Machine-style Inspector that would be able to roam through every data
> > structure during debugging.
> > >
> > > Byron

On Thu, Jan 22, 2015 at 5:36 AM, <dev-request-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org> wrote:
Send dev mailing list submissions to
        dev <at> racket-lang.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.racket-lang.org/dev/listinfo
or, via email, send a message with subject or body 'help' to
        dev-request-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org

You can reach the person managing the list at
        dev-owner-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of dev digest..."


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


Today's Topics:

   1. Full transparency (Byron Davies)
   2. Re: Full transparency (Byron Davies)
   3. Re: Full transparency (Matthias Felleisen)
   4. Re: Full transparency (Byron Davies)
   5. Literal constants (Jens Axel S?gaard)
   6. Re: Full transparency (Matthew Flatt)


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

Message: 1
Date: Wed, 21 Jan 2015 11:03:49 -0700
From: Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
To: dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org
Subject: [racket-dev] Full transparency
Message-ID:
        <CAAQ2ZgmJ1LiZBCRxoDY9as=BnTjtPaY2CKcp3CvG+5rqMX2D=g <at> mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Would it be easy to create a compiler flag that would make every struct and
object transparent?  This would then make it easy to create a Lisp
Machine-style Inspector that would be able to roam through every data
structure during debugging.

Byron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20150121/211388c2/attachment-0001.html>

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

Message: 2
Date: Wed, 21 Jan 2015 11:15:04 -0700
From: Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
To: dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org
Subject: Re: [racket-dev] Full transparency
Message-ID:
        <CAAQ2Zgkp1xyHah7h5BOANTFvKH4ZiQM70v4CLcaEv7G_dp=a_A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Content-Type: text/plain; charset="utf-8"

Or, more conservatively, every struct and object in a given package, file,
or set of files.

On Wed, Jan 21, 2015 at 11:03 AM, Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
wrote:

> Would it be easy to create a compiler flag that would make every struct
> and object transparent?  This would then make it easy to create a Lisp
> Machine-style Inspector that would be able to roam through every data
> structure during debugging.
>
> Byron
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20150121/5cdd98ac/attachment-0001.html>

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

Message: 3
Date: Wed, 21 Jan 2015 14:20:44 -0500
From: Matthias Felleisen <matthias-1vnkWVZi4QaVc3sceRu5cw@public.gmane.org>
To: Byron Davies <byrondavies <at> starshine.us>
Cc: dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org
Subject: Re: [racket-dev] Full transparency
Message-ID: <DEE2064C-8018-42E4-B082-A143D2D43720-1vnkWVZi4QaVc3sceRu5cw@public.gmane.org>
Content-Type: text/plain; charset=us-ascii


Sounds like a straightforward change to the existing macros. Why don't you create a fork and experiment?


On Jan 21, 2015, at 1:15 PM, Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org> wrote:

> Or, more conservatively, every struct and object in a given package, file, or set of files.
>
> On Wed, Jan 21, 2015 at 11:03 AM, Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org> wrote:
> Would it be easy to create a compiler flag that would make every struct and object transparent?  This would then make it easy to create a Lisp Machine-style Inspector that would be able to roam through every data structure during debugging.
>
> Byron
>
>
> _________________________
>  Racket Developers list:
http://lists.racket-lang.org/dev




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

Message: 4
Date: Wed, 21 Jan 2015 23:46:10 -0700
From: Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
To: Matthias Felleisen <matthias <at> ccs.neu.edu>
Cc: dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org
Subject: Re: [racket-dev] Full transparency
Message-ID:
        <CAAQ2Zgkht1qLKbT-C3SuQEUhSaPpTR8zCR4+ywA0yybpyejuEA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Content-Type: text/plain; charset="utf-8"

Nice parry!  What may be straightforward to you may not be so obvious to
me.  But I'll take a look.

I'm deep into a project using Racket for weakest precondition analysis.
Every time I'm debugging it seems like I have to write another
special-purpose accessor, or export some existing accessor up through
multiple levels in order to get at the data I need at the top-level.  I
remember how easy it was with the Lisp Machine to navigate through data no
matter what it was.

The Lisp Machine offered total transparency, with no real way to protect
data, to the benefit of the developer.  Racket offers total opacity, to the
benefit of code security.  I'm hoping there's a middle ground, where
transparency can be turned on and off.

Byron

On Wed, Jan 21, 2015 at 12:20 PM, Matthias Felleisen <matthias-1vnkWVZi4QaVc3sceRu5cw@public.gmane.org>
wrote:

>
> Sounds like a straightforward change to the existing macros. Why don't you
> create a fork and experiment?
>
>
> On Jan 21, 2015, at 1:15 PM, Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
> wrote:
>
> > Or, more conservatively, every struct and object in a given package,
> file, or set of files.
> >
> > On Wed, Jan 21, 2015 at 11:03 AM, Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
> wrote:
> > Would it be easy to create a compiler flag that would make every struct
> and object transparent?  This would then make it easy to create a Lisp
> Machine-style Inspector that would be able to roam through every data
> structure during debugging.
> >
> > Byron
> >
> >
> > _________________________
> >  Racket Developers list:
> >  http://lists.racket-lang.org/dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20150121/a72aa3f8/attachment-0001.html>

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

Message: 5
Date: Thu, 22 Jan 2015 11:24:25 +0100
From: Jens Axel S?gaard <jensaxel-2WZPQIjRgZTk1uMJSBkQmQ@public.gmane.org>
To: "dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org" <dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org>
Subject: [racket-dev] Literal constants
Message-ID:
        <CABefVgzAMjrhYDMCke-1Oo_ynZ7AAovh06ePe3WG-YKKqFTGCg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Content-Type: text/plain; charset=UTF-8

This program returns #f - I was expecting to see #t.

    #lang racket
    (define a '(1 2 3))
    (define b '(1 2 3))
    (eq? a b)

Why not guarantee uniqueness of  literals occurring in the same module?

/Jens Axel


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

Message: 6
Date: Thu, 22 Jan 2015 05:36:18 -0700
From: Matthew Flatt <mflatt-5tRRK8xpKLc@public.gmane.orgh.edu>
To: Byron Davies <byrondavies <at> starshine.us>
Cc: dev-GvBox1K3Ixw1Q5oZIJT9Xw@public.gmane.org
Subject: Re: [racket-dev] Full transparency
Message-ID: <20150122123620.2DAA16501A2-t8PTB6f7IWE44o9QpHrwMJQCsf4PZ8us@public.gmane.org>
Content-Type: text/plain; charset=UTF-8

I don't think you want to do anything with the compiler or macros.
Instead, it's a matter of having a sufficiently powerful inspector
(which is the concept of "inspectability" turned into a language
construct).

If you have just

 (struct a (x))
 (a 1)

then the result will print as `#<a>`. But if you use

 (define orig-i (current-inspector))
 (define sub-i (make-inspector orig-i))

 (current-inspector sub-i)
 (struct a (x))
 (define v (a 1))
 (current-inspector orig-i)

 v

Then, the result will print as `(a 1)`. That's because the structure
declaration is creates under an inspector `sub-i` (which is the current
inspector at the time) that is subordinate to the inspector `orig-i`
that is in place when the structure instance is printed.

The current inspector is determined dynamically, which means that if
you're loading some code, you can set the inspector while loading the
code. For example, if "a.rkt" is

 #lang racket/base
 (provide v)

 (struct a (x))
 (define v (a 1))

then

 (define v
   (parameterize ([current-inspector (make-inspector)])
     (dynamic-require "a.rkt" 'v)))
 v

will print the `a` instance transparently.


To protect libraries, there's no safe way to access a root inspector
that controls all structure types when you start Racket. Nothing is
safe from unsafe code, though, and here's an unsafe way to access the
root inspector:

 #lang racket/base
 (require ffi/unsafe)

 (define-cstruct _Scheme_Inspector
   ([stag _short]
    [keyex _short]
    [depth _int]
    [superior _racket]))

 (define root-inspector
   (Scheme_Inspector-superior
    ((get-ffi-obj 'scheme_get_initial_inspector
                  #f
                  (_fun -> (_gcable _Scheme_Inspector-pointer))))))

Using `root-inspector`, you can inspect any structure instance.

At Wed, 21 Jan 2015 23:46:10 -0700, Byron Davies wrote:
> Nice parry!  What may be straightforward to you may not be so obvious to
> me.  But I'll take a look.
>
> I'm deep into a project using Racket for weakest precondition analysis.
> Every time I'm debugging it seems like I have to write another
> special-purpose accessor, or export some existing accessor up through
> multiple levels in order to get at the data I need at the top-level.  I
> remember how easy it was with the Lisp Machine to navigate through data no
> matter what it was.
>
> The Lisp Machine offered total transparency, with no real way to protect
> data, to the benefit of the developer.  Racket offers total opacity, to the
> benefit of code security.  I'm hoping there's a middle ground, where
> transparency can be turned on and off.
>
> Byron
>
> On Wed, Jan 21, 2015 at 12:20 PM, Matthias Felleisen <matthias-1vnkWVZi4QaVc3sceRu5cw@public.gmane.org>
> wrote:
>
> >
> > Sounds like a straightforward change to the existing macros. Why don't you
> > create a fork and experiment?
> >
> >
> > On Jan 21, 2015, at 1:15 PM, Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
> > wrote:
> >
> > > Or, more conservatively, every struct and object in a given package,
> > file, or set of files.
> > >
> > > On Wed, Jan 21, 2015 at 11:03 AM, Byron Davies <byrondavies-TNG3/wf5oiU3tL2svhKZZQ@public.gmane.org>
> > wrote:
> > > Would it be easy to create a compiler flag that would make every struct
> > and object transparent?  This would then make it easy to create a Lisp
> > Machine-style Inspector that would be able to roam through every data
> > structure during debugging.
> > >
> > > Byron
> > >
> > >
> > > _________________________
> > >  Racket Developers list:
> > >  http://lists.racket-lang.org/dev
> >
> >
> _________________________
>   Racket Developers list:
>   http://lists.racket-lang.org/dev


End of dev Digest, Vol 72, Issue 31
***********************************

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

Gmane