<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"><base></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>If what you want is lazy struct, would something like this work?</div><div><br></div><div><div><font face="Courier New">#lang racket/base</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">(require racket/splicing</font></div><div><font face="Courier New">         racket/promise</font></div><div><font face="Courier New">         (for-syntax racket/base</font></div><div><font face="Courier New">                     racket/struct-info</font></div><div><font face="Courier New">                     syntax/parse</font></div><div><font face="Courier New">                     racket/syntax))</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">(module+ test</font></div><div><font face="Courier New">  (require rackunit)</font></div><div><font face="Courier New">  (lazy-struct object (a b c))</font></div><div><font face="Courier New">  (define obj (object #:loader (λ (field)</font></div><div><font face="Courier New">                                 (printf "calculating ~a\n" field)</font></div><div><font face="Courier New">                                 field)))</font></div><div><font face="Courier New">  (let ([out (open-output-string)])</font></div><div><font face="Courier New">    (parameterize ([current-output-port out])</font></div><div><font face="Courier New">      (check-equal? (get-output-string out) "")</font></div><div><font face="Courier New">      (check-equal? (object-a obj) 'a)</font></div><div><font face="Courier New">      (check-equal? (get-output-string out) "calculating a\n")</font></div><div><font face="Courier New">      (check-equal? (object-a obj) 'a)</font></div><div><font face="Courier New">      (check-equal? (get-output-string out) "calculating a\n")</font></div><div><font face="Courier New">      (check-match obj (object 'a 'b 'c))</font></div><div><font face="Courier New">      (check-equal? (get-output-string out) "calculating a\ncalculating b\ncalculating c\n")</font></div><div><font face="Courier New">      (close-output-port out)</font></div><div><font face="Courier New">      ))</font></div><div><font face="Courier New">  )</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">(define-syntax lazy-struct</font></div><div><font face="Courier New">  (lambda (stx)</font></div><div><font face="Courier New">    (syntax-parse stx</font></div><div><font face="Courier New">      [(lazy-struct name:id (field:id ...) . options)</font></div><div><font face="Courier New">       #:with (~var struct:name) (format-id #'name "struct:~a" #'name #:source #'name)</font></div><div><font face="Courier New">       #:with name? (format-id #'name "~a?" #'name #:source #'name)</font></div><div><font face="Courier New">       #:with (name-field ...) (for/list ([field-id (in-list (syntax->list #'(field ...)))])</font></div><div><font face="Courier New">                                 (format-id #'name "~a-~a" #'name field-id #:source #'name))</font></div><div><font face="Courier New">       #:with (old-name-field ...) (generate-temporaries #'(name-field ...))</font></div><div><font face="Courier New">       #'(splicing-local [(splicing-local [(struct name (field ...) . options)]</font></div><div><font face="Courier New">                            (define old-name name)</font></div><div><font face="Courier New">                            (define old-struct:name struct:name)</font></div><div><font face="Courier New">                            (define old-name? name?)</font></div><div><font face="Courier New">                            (define old-name-field name-field)</font></div><div><font face="Courier New">                            ...</font></div><div><font face="Courier New">                            (define (make-name #:loader loader)</font></div><div><font face="Courier New">                              (old-name (delay (loader 'field)) ...)))]</font></div><div><font face="Courier New">           (define name? old-name?)</font></div><div><font face="Courier New">           (define struct:name old-struct:name)</font></div><div><font face="Courier New">           (define (name-field name)</font></div><div><font face="Courier New">             (force (old-name-field name)))</font></div><div><font face="Courier New">           ...</font></div><div><font face="Courier New">           (define-syntax name</font></div><div><font face="Courier New">             (make-struct-desc #:descriptor #'struct:name</font></div><div><font face="Courier New">                               #:constructor #'make-name</font></div><div><font face="Courier New">                               #:predicate #'name?</font></div><div><font face="Courier New">                               #:accessors (reverse (list #'name-field ...))</font></div><div><font face="Courier New">                               #:mutators (list (begin 'name-field #f) ...)</font></div><div><font face="Courier New">                               #:super #t)))])))</font></div><div><font face="Courier New"><br></font></div><div><font face="Courier New">(begin-for-syntax</font></div><div><font face="Courier New">  (define (make-struct-desc #:descriptor [descriptor-id #f]</font></div><div><font face="Courier New">                            #:constructor constructor-id</font></div><div><font face="Courier New">                            #:predicate [predicate-id #f]</font></div><div><font face="Courier New">                            #:accessors [accessors '(#f)]</font></div><div><font face="Courier New">                            #:mutators [mutators (map (λ (x) #f) accessors)]</font></div><div><font face="Courier New">                            #:super [super #f])</font></div><div><font face="Courier New">    (with-syntax ([constructor constructor-id])</font></div><div><font face="Courier New">      (proc+struct-info</font></div><div><font face="Courier New">       (lambda (stx)</font></div><div><font face="Courier New">         (syntax-parse stx</font></div><div><font face="Courier New">           [(name . stuff)</font></div><div><font face="Courier New">            (quasisyntax/loc stx</font></div><div><font face="Courier New">              (#,(syntax/loc #'name constructor) . stuff))]</font></div><div><font face="Courier New">           [name (syntax/loc stx constructor)]))</font></div><div><font face="Courier New">       (list descriptor-id constructor-id predicate-id accessors mutators super))))</font></div><div><font face="Courier New">  (struct proc+struct-info (proc struct-info) #:transparent</font></div><div><font face="Courier New">    #:property prop:procedure (struct-field-index proc)</font></div><div><font face="Courier New">    #:property prop:struct-info (λ (this) (proc+struct-info-struct-info this)))</font></div><div><font face="Courier New">  )</font></div></div><div><br></div><br><div><div>On Aug 15, 2014, at 2:16 PM, Roman Klochkov <<a href="mailto:kalimehtar@mail.ru">kalimehtar@mail.ru</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">I want to have lazy-load struct. In C++ it is called proxy reference (when dereferencing return new (or cached) object loaded on demand)<br><br>Ideally, it would be like<br>(lazy-struct obj (a b c) #:loader load-data)<br><br>then<br><br>(define my-obj (make-ref obj "unique-id"))<br><br>(displayln (obj-a my-obj)) ;; here content of my-obj should be loaded via load-data.<br><br>And match pattern would also work.<br><br>Now I made API with (get-field my-obj 'a), but is not Racketish.<br><br>Fri, 15 Aug 2014 08:45:59 -0400 от "Alexander D. Knauth" <<a href="mailto:alexander@knauth.org">alexander@knauth.org</a>>:<br><blockquote style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(8, 87, 166); margin: 10px; padding: 0px 0px 0px 10px;"><div id=""><div class="js-helper js-readmsg-msg"><base target="_self" href="https://e.mail.ru/"><div id="style_14081067690000000643_BODY"><br>Why not just define a new version of object-a that does that?<br>You probably have a good reason, but what is it?<span class="Apple-converted-space"> </span><br>Is it to change the result of struct->vector, allow (object a b c) as a match pattern to match ref, or what?<span class="Apple-converted-space"> </span><br><br>On Aug 15, 2014, at 6:42 AM, Roman Klochkov <<a href="x-msg://3/compose?To=kalimehtar@mail.ru">kalimehtar@mail.ru</a>> wrote:<br><br>> I have<br>> (struct object (a b c))<br>> (struct reference (id data))<br>><span class="Apple-converted-space"> </span><br>> Let `ref' -- an instance of `reference'.<br>><span class="Apple-converted-space"> </span><br>> I want, that (object-a ref) call my own (ref-get object-a ref)<br>><span class="Apple-converted-space"> </span><br>> (define (ref-get accessor ref)<br>> (unless (weak-box-value (ref-data ref))<br>> (set-ref-data! ref (make-weak-box (load-data (ref-id ref)))))<br>> (accessor (weak-box-value (ref-data ref))))<br>><span class="Apple-converted-space"> </span><br>> Is it possible?<span class="Apple-converted-space"> </span><br>> I found `impersonate-struct', but it is not struct itself (no `id' field).<span class="Apple-converted-space"> </span><br>> I can add `prop:impersonator-of',. but how to redirect accessors?<br>><span class="Apple-converted-space"> </span><br>> --<span class="Apple-converted-space"> </span><br>> Roman Klochkov<br>> ____________________<br>> Racket Users list:<br>><span class="Apple-converted-space"> </span><a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br><br></div><base target="_self" href="https://e.mail.ru/"></div></div></blockquote><br><br>--<span class="Apple-converted-space"> </span><br>Roman Klochkov</div></blockquote></div><br></body></html>