From drewdudash at gmail.com Fri Aug 1 09:35:54 2014 From: drewdudash at gmail.com (Andrew Dudash) Date: Fri, 1 Aug 2014 09:35:54 -0400 Subject: [racket] "upload file" button in a Racket web server In-Reply-To: References: Message-ID: There's the following. #lang web-server/insta (require web-server/formlets) (define (start req) (send/formlet (file-upload))) But this doesn't support dragging and dropping images. You can add support for that with JavaScript, but I don't think there's anything like it in a Racket library. (I'd love to be proven wrong if anyone knows of one.) On Thu, Jul 31, 2014 at 10:21 PM, Mitchell Wand wrote: > Many web pages have an "upload file" button that allows the user to > drag&drop a file onto the button, and then hitting the button sends the > file to the server. > > Is there any way of doing this in a Racket web server? If not, how close > can we come? > > --Mitch > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.mccarthy at gmail.com Fri Aug 1 10:24:55 2014 From: jay.mccarthy at gmail.com (Jay McCarthy) Date: Fri, 1 Aug 2014 10:24:55 -0400 Subject: [racket] "upload file" button in a Racket web server In-Reply-To: References: Message-ID: There's nothing that a normal Web app can do that Racket can't. Whatever you see in the UI is just HTML + JS. The exact same HTML and JS will work in Racket as well. The actual upload code is something like:
And on the server you will get a binding:file object: http://docs.racket-lang.org/web-server/http.html?q=form%3Afile#%28def._%28%28lib._web-server%2Fhttp%2Frequest-structs..rkt%29._binding~3afile%29%29 The drag&drop into the box sounds to me like it is just done by your browser when you use a "file" input, as above. Jay On Fri, Aug 1, 2014 at 9:35 AM, Andrew Dudash wrote: > There's the following. > > #lang web-server/insta > > (require web-server/formlets) > > (define (start req) > (send/formlet (file-upload))) > > But this doesn't support dragging and dropping images. You can add support > for that with JavaScript, but I don't think there's anything like it in a > Racket library. (I'd love to be proven wrong if anyone knows of one.) > > > > On Thu, Jul 31, 2014 at 10:21 PM, Mitchell Wand wrote: >> >> Many web pages have an "upload file" button that allows the user to >> drag&drop a file onto the button, and then hitting the button sends the file >> to the server. >> >> Is there any way of doing this in a Racket web server? If not, how close >> can we come? >> >> --Mitch >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -- Jay McCarthy http://jeapostrophe.github.io "Wherefore, be not weary in well-doing, for ye are laying the foundation of a great work. And out of small things proceedeth that which is great." - D&C 64:33 From alexander at knauth.org Fri Aug 1 12:23:21 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 12:23:21 -0400 Subject: [racket] is there any way to tell syntax-parse to parse a pattern within a parametization ? Message-ID: Is there any way to tell syntax-parse to parse a pattern within a parametization ? For example in something like this: (define within-y? (make-parameter #f)) (define-syntax-class x [pattern _ #:when (within-y?)]) (define-syntax-class y [pattern :x]) (define (parse stx) (syntax-parse stx [:y #t])) How do I tell it to parse the y syntax-class within a (parameterize ([within-y? #t]) ?) form? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ianj at ccs.neu.edu Fri Aug 1 12:45:34 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 1 Aug 2014 12:45:34 -0400 (EDT) Subject: [racket] is there any way to tell syntax-parse to parse a pattern within a parametization ? In-Reply-To: <30399784.591011406911374462.JavaMail.root@zimbra> Message-ID: <12986537.591061406911534412.JavaMail.root@zimbra> Two things: 1) syntax-classes can take parameters, so you can pass an argument to x that is a boolean, within-y?. You can't create a parameterization scope because this is all within the parsing code for syntax-parse. You could mutate a box or parameter with a ~do pattern and reset it after the patterns you want within that "scope," but c'mon. Don't do that. (define-syntax-class (x within-y?) (pattern _ #:when within-y?)) (define-syntax-class y (pattern (~var dummy (x #t)))) [the use-case of nothing to the left of a : to indicate non-binding is something that should be extended to parameterized syntax-classes, probably.] 2) If you're communicating between macros and not syntax-classes, you want to use syntax-parameters. (require racket/stxparam) (define-syntax-parameter within-y? #f) (define-syntax-rule (y body) (syntax-parameterize ([within-y? #t]) body)) (define-syntax-class x (pattern _ #:when (syntax-parameter-value #'within-y?))) -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "racket users list" Sent: Friday, August 1, 2014 12:23:21 PM GMT -05:00 US/Canada Eastern Subject: [racket] is there any way to tell syntax-parse to parse a pattern within a parametization ? Is there any way to tell syntax-parse to parse a pattern within a parametization ? For example in something like this: (define within-y? (make-parameter #f)) (define-syntax-class x [pattern _ #:when (within-y?)]) (define-syntax-class y [pattern :x]) (define (parse stx) (syntax-parse stx [:y #t])) How do I tell it to parse the y syntax-class within a (parameterize ([within-y? #t]) ?) form? ____________________ Racket Users list: http://lists.racket-lang.org/users From alexander at knauth.org Fri Aug 1 12:55:15 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 12:55:15 -0400 Subject: [racket] is there any way to tell syntax-parse to parse a pattern within a parametization ? In-Reply-To: <12986537.591061406911534412.JavaMail.root@zimbra> References: <12986537.591061406911534412.JavaMail.root@zimbra> Message-ID: Oh, I had forgotten that syntax-classes could take arguments. Thanks! On Aug 1, 2014, at 12:45 PM, J. Ian Johnson wrote: > Two things: > 1) syntax-classes can take parameters, so you can pass an argument to x that is a boolean, within-y?. You can't create a parameterization scope because this is all within the parsing code for syntax-parse. You could mutate a box or parameter with a ~do pattern and reset it after the patterns you want within that "scope," but c'mon. Don't do that. > > (define-syntax-class (x within-y?) > (pattern _ #:when within-y?)) > > (define-syntax-class y > (pattern (~var dummy (x #t)))) > > [the use-case of nothing to the left of a : to indicate non-binding is something that should be extended to parameterized syntax-classes, probably.] > > 2) If you're communicating between macros and not syntax-classes, you want to use syntax-parameters. > > (require racket/stxparam) > (define-syntax-parameter within-y? #f) > > (define-syntax-rule (y body) (syntax-parameterize ([within-y? #t]) body)) > (define-syntax-class x > (pattern _ #:when (syntax-parameter-value #'within-y?))) > > -Ian > ----- Original Message ----- > From: "Alexander D. Knauth" > To: "racket users list" > Sent: Friday, August 1, 2014 12:23:21 PM GMT -05:00 US/Canada Eastern > Subject: [racket] is there any way to tell syntax-parse to parse a pattern within a parametization ? > > > Is there any way to tell syntax-parse to parse a pattern within a parametization ? > > > For example in something like this: > (define within-y? (make-parameter #f)) > (define-syntax-class x > [pattern _ #:when (within-y?)]) > (define-syntax-class y > [pattern :x]) > (define (parse stx) > (syntax-parse stx > [:y #t])) > > > How do I tell it to parse the y syntax-class within a (parameterize ([within-y? #t]) ?) form? > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From stamourv at ccs.neu.edu Fri Aug 1 16:49:59 2014 From: stamourv at ccs.neu.edu (Vincent St-Amour) Date: Fri, 01 Aug 2014 16:49:59 -0400 Subject: [racket] weird error with typed racket, submodules, and math/array In-Reply-To: <99800C48-1869-4457-BA85-BD52A467600B@knauth.org> References: <00396F9C-6982-4FD1-B956-01CE5C55218F@knauth.org> <87r411yp0b.wl%stamourv@ccs.neu.edu> <99800C48-1869-4457-BA85-BD52A467600B@knauth.org> Message-ID: <878un8gcjs.wl%stamourv@ccs.neu.edu> Hmm, that's odd. I do remember that workaround working at some point, but maybe it doesn't anymore. In the meantime, not using submodules with TR sounds like the best solution. Vincent At Thu, 31 Jul 2014 21:39:38 -0400, Alexander D. Knauth wrote: > > [1 ] > I just tried that but got an even weirder error: > #lang typed/racket > (require math/array) > (module+ test > (require math/array) > (require/typed math/array > [unsafe-list->array (All (a) [Indexes (Listof a) -> (Array a)])]) > (array #[#[#f #f #f] > #[#f #f #f] > #[#f #f #f]]) > ) > ;unsafe-list->array2: unbound identifier; > ; also, no #%top syntax transformer is bound in: unsafe-list->array2 > > On Jul 31, 2014, at 9:31 PM, Vincent St-Amour wrote: > > > At Thu, 31 Jul 2014 19:48:31 -0400, > > Alexander D. Knauth wrote: > >> > >> And also I just curious, how does type checking work with module+ anyway? > > > > The short answer is that it doesn't work reliably. > > > > There's a bug in the expander that affects (IIRC) how TR determines > > whether a module is typed or not. Until that's fixed, TR thinks that > > your submodule is untyped (at least as far as imports go). > > > > A workaround that I've used is to use `require/typed` inside the > > submodule. > > > > Vincent > > [2 ] > From alexander at knauth.org Fri Aug 1 17:12:00 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 17:12:00 -0400 Subject: [racket] getting one macro to tell another macro to define something Message-ID: <89959EF0-3340-4107-ABB5-AE48CF019AC1@knauth.org> Is there any way to do something like this and have it work?: #lang racket (require racket/stxparam (for-syntax syntax/parse racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-syntax sender (lambda (stx) (syntax-parse stx [(sender def) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs #'def) #'(void)]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (set->list defs)]) #'(begin def ...))]))) (syntax-parameterize ([current-defs (mutable-set)]) (sender (define x 1)) (reciever) x) Right now, x is undefined. I?m guessing that that?s because it has the wrong syntax marks, but is there any way around that? (Other that doing (datum->syntax stx (syntax->datum ?)) on everything?) From ianj at ccs.neu.edu Fri Aug 1 17:37:49 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 1 Aug 2014 17:37:49 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <11120068.595471406928856438.JavaMail.root@zimbra> Message-ID: <8248412.595491406929069946.JavaMail.root@zimbra> It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. In this case, sender would be (define-syntax (sender stx) (syntax-case stx () [(_ def) #'(begin-for-syntax (set-add! (syntax-parameter-value #'current-defs) #'def))])) You would need your test to instead use splicing-syntax-parameterize to get the use of sender at the top level. You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. All together this is #lang racket (require racket/stxparam racket/splicing (for-syntax syntax/parse racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-syntax (sender stx) (syntax-case stx () [(_ def) #`(begin-for-syntax (set-add! (syntax-parameter-value #'current-defs) #'def))])) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (set-map defs syntax-local-introduce)]) #'(begin def ...))]))) (splicing-syntax-parameterize ([current-defs (mutable-set)]) (sender (define x 1)) (reciever) x) -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "racket users list" Sent: Friday, August 1, 2014 5:12:00 PM GMT -05:00 US/Canada Eastern Subject: [racket] getting one macro to tell another macro to define something Is there any way to do something like this and have it work?: #lang racket (require racket/stxparam (for-syntax syntax/parse racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-syntax sender (lambda (stx) (syntax-parse stx [(sender def) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs #'def) #'(void)]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (set->list defs)]) #'(begin def ...))]))) (syntax-parameterize ([current-defs (mutable-set)]) (sender (define x 1)) (reciever) x) Right now, x is undefined. I?m guessing that that?s because it has the wrong syntax marks, but is there any way around that? (Other that doing (datum->syntax stx (syntax->datum ?)) on everything?) ____________________ Racket Users list: http://lists.racket-lang.org/users From ryanc at ccs.neu.edu Fri Aug 1 17:39:14 2014 From: ryanc at ccs.neu.edu (Ryan Culpepper) Date: Fri, 01 Aug 2014 17:39:14 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <89959EF0-3340-4107-ABB5-AE48CF019AC1@knauth.org> References: <89959EF0-3340-4107-ABB5-AE48CF019AC1@knauth.org> Message-ID: <53DC0902.9030104@ccs.neu.edu> Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. Here are the two places that need changing: (define-syntax sender (lambda (stx) (syntax-parse stx [(sender def) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs (syntax-local-introduce #'def)) #'(void)]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) #'(begin def ...))]))) Ryan On 08/01/2014 05:12 PM, Alexander D. Knauth wrote: > Is there any way to do something like this and have it work?: > #lang racket > (require racket/stxparam > (for-syntax syntax/parse > racket/set)) > ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) > (define-syntax-parameter current-defs #f) > (define-syntax sender > (lambda (stx) > (syntax-parse stx > [(sender def) > (define defs (syntax-parameter-value #'current-defs)) > (set-add! defs #'def) > #'(void)]))) > (define-syntax reciever > (lambda (stx) > (syntax-parse stx > [(reciever) > (define defs (syntax-parameter-value #'current-defs)) > (with-syntax ([(def ...) (set->list defs)]) > #'(begin def ...))]))) > > (syntax-parameterize ([current-defs (mutable-set)]) > (sender (define x 1)) > (reciever) > x) > > Right now, x is undefined. > > I?m guessing that that?s because it has the wrong syntax marks, but is there any way around that? > (Other that doing (datum->syntax stx (syntax->datum ?)) on everything?) > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From icfp.publicity at googlemail.com Fri Aug 1 17:53:41 2014 From: icfp.publicity at googlemail.com (David Van Horn) Date: Fri, 1 Aug 2014 17:53:41 -0400 Subject: [racket] ICFP 2014 Final Call for Participation Message-ID: [ Early registration ends 3 Aug; Invited speakers and conference program have been announced. ] ===================================================================== Final Call for Participation ICFP 2014 19th ACM SIGPLAN International Conference on Functional Programming and affiliated events August 31 - September 6, 2014 Gothenburg, Swedenhttp://icfpconference.org/icfp2014/ ===================================================================== ICFP provides a forum for researchers and developers to hear about the latest work on the design, implementations, principles, and uses of functional programming. The conference covers the entire spectrum of work, from practice to theory, including its peripheries. A full week dedicated to functional programming: 1 conference, 1 symposium, 10 workshops, tutorials, programming contest results, student research competition * Program: http://icfpconference.org/icfp2014/program.html * Accepted Papers: http://icfpconference.org/icfp2014/accepted.html * Local arrangements (including travel and accommodation): http://icfpconference.org/icfp2014/local.html * Registration is available via: https://regmaster4.com/2014conf/ICFP14/register.php Early registration is due 3 August, 2014. * Programming contest, 25-28 July, 2014: http://icfpcontest.org/ * Follow @icfp_conference on twitter for the latest news: http://twitter.com/#!/icfp_conference Keynote speakers: * Kathleen Fisher (Tufts University): Using Formal Methods to Enable More Secure Vehicles: DARPA's HACMS Program * Robert Bruce Findler (Northwestern University): Behavioral Software Contracts * Stephanie Weirich (University of Pennsylvania): Depending on Types There are several events affiliated with ICFP: Sunday, August 31 ACM SIGPLAN Workshop on Generic Programming ACM SIGPLAN Workshop on Higher-order Programming with Effects Monday, September 1 ? Wednesday, September 3 ICFP Thursday, September 4 ACM SIGPLAN Commercial Users of Functional Programming: Day 1, Tutorials ACM SIGPLAN Haskell Symposium: Day 1 ACM SIGPLAN Workshop on Functional High-Performance Computing ACM SIGPLAN ML Family Workshop Friday, September 5 ACM SIGPLAN Commercial Users of Functional Programming: Day 2, Tutorials ACM SIGPLAN Haskell Symposium: Day 2 ACM SIGPLAN OCaml Workshop ACM SIGPLAN Erlang Workshop Saturday, September 6 ACM SIGPLAN Commercial Users of Functional Programming: Day 3, Talks ACM SIGPLAN Haskell Implementors Workshop ACM SIGPLAN Workshop on Functional Art, Music, Modeling and Design Conference Organizers General Chair: Johan Jeuring, Utrecht University Program Chair: Manuel Chakravarty, University of New South Wales Local Arrangements Chair: Bj?rn von Sydow, Chalmers University Industrial Relations Chair: Anil Madhavapeddy, University of Cambridge Workshop Co-Chairs: Tom Schrijvers, Ghent University Sam Tobin-Hochstadt, Indiana University Programming Contest Co-Chairs: Duncan Coutts, Well Typed LLP Nicolas Wu, University of Oxford Student Research Competition Chair: Meng Wang, Chalmers University Publicity Chair: David Van Horn, University of Maryland Video Chair: Iavor Diatchki, Galois Malcolm Wallace, Standard Chartered Bank Industrial partners: Platinum partners Jane Street Capital Gold partners Google Microsoft Research Mozilla Oracle Labs Standard Chartered Bank Silver partners Bloomberg Credit Suisse CyberPoint Erlang Solutions Facebook Galois Klarna Lexifi Twitter Bronze partners Alephcloud IntelliFactory Opera Software QuviQ Systeor Vest AS ===================================================================== -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Fri Aug 1 17:55:57 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 17:55:57 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <8248412.595491406929069946.JavaMail.root@zimbra> References: <8248412.595491406929069946.JavaMail.root@zimbra> Message-ID: <1342DB9B-3D4D-4A08-B51E-3A4518A60393@knauth.org> On Aug 1, 2014, at 5:37 PM, J. Ian Johnson wrote: > It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. The reason I can?t do that is because in the real program, sender is actually a match-expander. > You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... On Aug 1, 2014, at 5:39 PM, Ryan Culpepper wrote: > Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. ... Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? #lang racket (require racket/stxparam (for-syntax syntax/parse racket/syntax racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-match-expander sender (lambda (stx) (syntax-parse stx [(sender x) #:with tmp (generate-temporary #'x) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs (syntax-local-introduce #'(define x tmp))) #'tmp]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) #'(begin def ...))]))) (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ;x3: unbound identifier; ; also, no #%top syntax transformer is bound in: x3 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ianj at ccs.neu.edu Fri Aug 1 18:20:57 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 1 Aug 2014 18:20:57 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <1342DB9B-3D4D-4A08-B51E-3A4518A60393@knauth.org> Message-ID: <22276688.595771406931657728.JavaMail.root@zimbra> Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "racket users list" Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. The reason I can?t do that is because in the real program, sender is actually a match-expander. You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. ... Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? #lang racket (require racket/stxparam (for-syntax syntax/parse racket/syntax racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-match-expander sender (lambda (stx) (syntax-parse stx [(sender x) #:with tmp (generate-temporary #'x) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs (syntax-local-introduce #'(define x tmp))) #'tmp]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) #'(begin def ...))]))) (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ;x3: unbound identifier; ; also, no #%top syntax transformer is bound in: x3 ____________________ Racket Users list: http://lists.racket-lang.org/users From alexander at knauth.org Fri Aug 1 18:31:59 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 18:31:59 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <22276688.595771406931657728.JavaMail.root@zimbra> References: <22276688.595771406931657728.JavaMail.root@zimbra> Message-ID: <80CF9521-3259-4DB4-B5EB-EE05193869D5@knauth.org> Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: > Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). > The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. > > Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. > -Ian > ----- Original Message ----- > From: "Alexander D. Knauth" > To: "racket users list" > Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern > Subject: Re: [racket] getting one macro to tell another macro to define something > > > > > > On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: > > > It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. > > > > The reason I can?t do that is because in the real program, sender is actually a match-expander. > > > You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... > > > > > On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: > > > Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. > ... > > > Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. > > I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? > > > > #lang racket > (require racket/stxparam > (for-syntax syntax/parse > racket/syntax > racket/set)) > ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) > (define-syntax-parameter current-defs #f) > (define-match-expander sender > (lambda (stx) > (syntax-parse stx > [(sender x) > #:with tmp (generate-temporary #'x) > (define defs (syntax-parameter-value #'current-defs)) > (set-add! defs (syntax-local-introduce #'(define x tmp))) > #'tmp]))) > (define-syntax reciever > (lambda (stx) > (syntax-parse stx > [(reciever) > (define defs (syntax-parameter-value #'current-defs)) > (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) > #'(begin def ...))]))) > > > (syntax-parameterize ([current-defs (mutable-set)]) > (match-define (sender x) 1) > (reciever) > x) > > > ;x3: unbound identifier; > ; also, no #%top syntax transformer is bound in: x3 > > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From ianj at ccs.neu.edu Fri Aug 1 18:45:30 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 1 Aug 2014 18:45:30 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <24359260.596011406932989610.JavaMail.root@zimbra> Message-ID: <29806605.596031406933130307.JavaMail.root@zimbra> Well one problem is expander application his its own mark to deal with, so you can't cancel the mark on x. https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157 Another problem is expecting the implementation of match-define to not have any inner macros that would change syntax-local-introduce to a less helpful extent. What would be ideal is if racket/match could change some "parameter" so that syntax-local-introduce used the introducer defined in the above link, since the generated temporary does not have x's mark that x has annihilated. Instead x's mark will be added to tmp after the transformer returns, and there's nothing you can do about it :( -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: > Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). > The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. > > Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. > -Ian > ----- Original Message ----- > From: "Alexander D. Knauth" > To: "racket users list" > Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern > Subject: Re: [racket] getting one macro to tell another macro to define something > > > > > > On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: > > > It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. > > > > The reason I can?t do that is because in the real program, sender is actually a match-expander. > > > You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... > > > > > On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: > > > Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. > ... > > > Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. > > I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? > > > > #lang racket > (require racket/stxparam > (for-syntax syntax/parse > racket/syntax > racket/set)) > ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) > (define-syntax-parameter current-defs #f) > (define-match-expander sender > (lambda (stx) > (syntax-parse stx > [(sender x) > #:with tmp (generate-temporary #'x) > (define defs (syntax-parameter-value #'current-defs)) > (set-add! defs (syntax-local-introduce #'(define x tmp))) > #'tmp]))) > (define-syntax reciever > (lambda (stx) > (syntax-parse stx > [(reciever) > (define defs (syntax-parameter-value #'current-defs)) > (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) > #'(begin def ...))]))) > > > (syntax-parameterize ([current-defs (mutable-set)]) > (match-define (sender x) 1) > (reciever) > x) > > > ;x3: unbound identifier; > ; also, no #%top syntax transformer is bound in: x3 > > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From alexander at knauth.org Fri Aug 1 19:17:53 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 19:17:53 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <29806605.596031406933130307.JavaMail.root@zimbra> References: <29806605.596031406933130307.JavaMail.root@zimbra> Message-ID: <256E764A-27B1-45AA-B83D-4DABC6FB4167@knauth.org> I found this on line 2327 of racket/src/racket/src/env.c: static Scheme_Object * local_introduce(int argc, Scheme_Object *argv[]) { Scheme_Comp_Env *env; Scheme_Object *s; env = scheme_current_thread->current_local_env; if (!env) not_currently_transforming("syntax-local-introduce"); s = argv[0]; if (!SCHEME_STXP(s)) scheme_wrong_contract("syntax-local-introduce", "syntax?", 0, argc, argv); if (scheme_current_thread->current_local_mark) s = scheme_add_remove_mark(s, scheme_current_thread->current_local_mark); return s; } What would happen if match-expander-transform somehow set scheme_current_thread->current_local_mark to the mark produced by the new syntax-introducer? And would that even be possible? (without fundamental changes to racket) On Aug 1, 2014, at 6:45 PM, J. Ian Johnson wrote: > Well one problem is expander application his its own mark to deal with, so you can't cancel the mark on x. > > https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157 > > Another problem is expecting the implementation of match-define to not have any inner macros that would change syntax-local-introduce to a less helpful extent. > What would be ideal is if racket/match could change some "parameter" so that syntax-local-introduce used the introducer defined in the above link, since the generated temporary does not have x's mark that x has annihilated. Instead x's mark will be added to tmp after the transformer returns, and there's nothing you can do about it :( > > -Ian > ----- Original Message ----- > From: "Alexander D. Knauth" > To: "J. Ian Johnson" > Cc: "racket users list" > Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern > Subject: Re: [racket] getting one macro to tell another macro to define something > > Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? > > On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: > >> Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). >> The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. >> >> Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. >> -Ian >> ----- Original Message ----- >> From: "Alexander D. Knauth" >> To: "racket users list" >> Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern >> Subject: Re: [racket] getting one macro to tell another macro to define something >> >> >> >> >> >> On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >> >> >> It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. >> >> >> >> The reason I can?t do that is because in the real program, sender is actually a match-expander. >> >> >> You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... >> >> >> >> >> On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: >> >> >> Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. >> ... >> >> >> Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. >> >> I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? >> >> >> >> #lang racket >> (require racket/stxparam >> (for-syntax syntax/parse >> racket/syntax >> racket/set)) >> ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) >> (define-syntax-parameter current-defs #f) >> (define-match-expander sender >> (lambda (stx) >> (syntax-parse stx >> [(sender x) >> #:with tmp (generate-temporary #'x) >> (define defs (syntax-parameter-value #'current-defs)) >> (set-add! defs (syntax-local-introduce #'(define x tmp))) >> #'tmp]))) >> (define-syntax reciever >> (lambda (stx) >> (syntax-parse stx >> [(reciever) >> (define defs (syntax-parameter-value #'current-defs)) >> (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) >> #'(begin def ...))]))) >> >> >> (syntax-parameterize ([current-defs (mutable-set)]) >> (match-define (sender x) 1) >> (reciever) >> x) >> >> >> ;x3: unbound identifier; >> ; also, no #%top syntax transformer is bound in: x3 >> >> >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ianj at ccs.neu.edu Fri Aug 1 19:30:10 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 1 Aug 2014 19:30:10 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <256E764A-27B1-45AA-B83D-4DABC6FB4167@knauth.org> Message-ID: <21215525.596411406935810279.JavaMail.root@zimbra> Well, I just hacked racket/match to allow match-expanders to take a third argument that is the introducer for the application. No permutation of mark applications works, I think since syntax-local-introduce does not include all the marks from the top use of match-define all the way through internal macros to the transformer call. I'm currently looking into getting a delta-introducer sent to the transformer that has the delta between the original match syntax and the match-expander syntax, but I'm fighting the implementation in actually getting the orig-stx parameter set to the right thing. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Friday, August 1, 2014 7:17:53 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something I found this on line 2327 of racket/src/racket/src/env.c: static Scheme_Object * local_introduce ( int argc , Scheme_Object * argv []) { Scheme_Comp_Env * env ; Scheme_Object * s ; env = scheme_current_thread -> current_local_env ; if ( ! env ) not_currently_transforming ( "syntax-local-introduce" ); s = argv [ 0 ]; if ( ! SCHEME_STXP ( s )) scheme_wrong_contract ( "syntax-local-introduce" , "syntax?" , 0 , argc , argv ); if ( scheme_current_thread -> current_local_mark ) s = scheme_add_remove_mark ( s , scheme_current_thread -> current_local_mark ); return s ; } What would happen if match-expander-transform somehow set scheme_current_thread -> current_local_mark to the mark produced by the new syntax-introducer? And would that even be possible? (without fundamental changes to racket) On Aug 1, 2014, at 6:45 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Well one problem is expander application his its own mark to deal with, so you can't cancel the mark on x. https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157 Another problem is expecting the implementation of match-define to not have any inner macros that would change syntax-local-introduce to a less helpful extent. What would be ideal is if racket/match could change some "parameter" so that syntax-local-introduce used the introducer defined in the above link, since the generated temporary does not have x's mark that x has annihilated. Instead x's mark will be added to tmp after the transformer returns, and there's nothing you can do about it :( -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "racket users list" Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. The reason I can?t do that is because in the real program, sender is actually a match-expander. You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. ... Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? #lang racket (require racket/stxparam (for-syntax syntax/parse racket/syntax racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-match-expander sender (lambda (stx) (syntax-parse stx [(sender x) #:with tmp (generate-temporary #'x) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs (syntax-local-introduce #'(define x tmp))) #'tmp]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) #'(begin def ...))]))) (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ;x3: unbound identifier; ; also, no #%top syntax transformer is bound in: x3 ____________________ Racket Users list: http://lists.racket-lang.org/users From ianj at ccs.neu.edu Fri Aug 1 19:47:04 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 1 Aug 2014 19:47:04 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <21215525.596411406935810279.JavaMail.root@zimbra> Message-ID: <10535795.596451406936824002.JavaMail.root@zimbra> Okay, define-forms.rkt had some uses of parse outside of gen-match's "go" which sets the parameter, so I fixed that. Now it turns out the docs are imprecise for make-syntax-delta-introducer's first argument. It wants an identifier rather than an arbitrary piece of syntax. Not sure why that's necessary. I'm going to stop and wait for ryanc or mflatt to respond to this thread. I'm out of ideas. -Ian ----- Original Message ----- From: "J. Ian Johnson" To: "Alexander D. Knauth" Cc: "racket users list" , "J. Ian Johnson" Sent: Friday, August 1, 2014 7:30:10 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something Well, I just hacked racket/match to allow match-expanders to take a third argument that is the introducer for the application. No permutation of mark applications works, I think since syntax-local-introduce does not include all the marks from the top use of match-define all the way through internal macros to the transformer call. I'm currently looking into getting a delta-introducer sent to the transformer that has the delta between the original match syntax and the match-expander syntax, but I'm fighting the implementation in actually getting the orig-stx parameter set to the right thing. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Friday, August 1, 2014 7:17:53 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something I found this on line 2327 of racket/src/racket/src/env.c: static Scheme_Object * local_introduce ( int argc , Scheme_Object * argv []) { Scheme_Comp_Env * env ; Scheme_Object * s ; env = scheme_current_thread -> current_local_env ; if ( ! env ) not_currently_transforming ( "syntax-local-introduce" ); s = argv [ 0 ]; if ( ! SCHEME_STXP ( s )) scheme_wrong_contract ( "syntax-local-introduce" , "syntax?" , 0 , argc , argv ); if ( scheme_current_thread -> current_local_mark ) s = scheme_add_remove_mark ( s , scheme_current_thread -> current_local_mark ); return s ; } What would happen if match-expander-transform somehow set scheme_current_thread -> current_local_mark to the mark produced by the new syntax-introducer? And would that even be possible? (without fundamental changes to racket) On Aug 1, 2014, at 6:45 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Well one problem is expander application his its own mark to deal with, so you can't cancel the mark on x. https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157 Another problem is expecting the implementation of match-define to not have any inner macros that would change syntax-local-introduce to a less helpful extent. What would be ideal is if racket/match could change some "parameter" so that syntax-local-introduce used the introducer defined in the above link, since the generated temporary does not have x's mark that x has annihilated. Instead x's mark will be added to tmp after the transformer returns, and there's nothing you can do about it :( -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "racket users list" Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. The reason I can?t do that is because in the real program, sender is actually a match-expander. You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. ... Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? #lang racket (require racket/stxparam (for-syntax syntax/parse racket/syntax racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-match-expander sender (lambda (stx) (syntax-parse stx [(sender x) #:with tmp (generate-temporary #'x) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs (syntax-local-introduce #'(define x tmp))) #'tmp]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) #'(begin def ...))]))) (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ;x3: unbound identifier; ; also, no #%top syntax transformer is bound in: x3 ____________________ Racket Users list: http://lists.racket-lang.org/users From ianj at ccs.neu.edu Fri Aug 1 20:12:16 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 1 Aug 2014 20:12:16 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <10535795.596451406936824002.JavaMail.root@zimbra> Message-ID: <33160795.596501406938336494.JavaMail.root@zimbra> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. Do you have a different example that doesn't fail in this way? -Ian ----- Original Message ----- From: "J. Ian Johnson" To: "J. Ian Johnson" Cc: "racket users list" , "Alexander D. Knauth" Sent: Friday, August 1, 2014 7:47:04 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something Okay, define-forms.rkt had some uses of parse outside of gen-match's "go" which sets the parameter, so I fixed that. Now it turns out the docs are imprecise for make-syntax-delta-introducer's first argument. It wants an identifier rather than an arbitrary piece of syntax. Not sure why that's necessary. I'm going to stop and wait for ryanc or mflatt to respond to this thread. I'm out of ideas. -Ian ----- Original Message ----- From: "J. Ian Johnson" To: "Alexander D. Knauth" Cc: "racket users list" , "J. Ian Johnson" Sent: Friday, August 1, 2014 7:30:10 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something Well, I just hacked racket/match to allow match-expanders to take a third argument that is the introducer for the application. No permutation of mark applications works, I think since syntax-local-introduce does not include all the marks from the top use of match-define all the way through internal macros to the transformer call. I'm currently looking into getting a delta-introducer sent to the transformer that has the delta between the original match syntax and the match-expander syntax, but I'm fighting the implementation in actually getting the orig-stx parameter set to the right thing. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Friday, August 1, 2014 7:17:53 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something I found this on line 2327 of racket/src/racket/src/env.c: static Scheme_Object * local_introduce ( int argc , Scheme_Object * argv []) { Scheme_Comp_Env * env ; Scheme_Object * s ; env = scheme_current_thread -> current_local_env ; if ( ! env ) not_currently_transforming ( "syntax-local-introduce" ); s = argv [ 0 ]; if ( ! SCHEME_STXP ( s )) scheme_wrong_contract ( "syntax-local-introduce" , "syntax?" , 0 , argc , argv ); if ( scheme_current_thread -> current_local_mark ) s = scheme_add_remove_mark ( s , scheme_current_thread -> current_local_mark ); return s ; } What would happen if match-expander-transform somehow set scheme_current_thread -> current_local_mark to the mark produced by the new syntax-introducer? And would that even be possible? (without fundamental changes to racket) On Aug 1, 2014, at 6:45 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Well one problem is expander application his its own mark to deal with, so you can't cancel the mark on x. https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157 Another problem is expecting the implementation of match-define to not have any inner macros that would change syntax-local-introduce to a less helpful extent. What would be ideal is if racket/match could change some "parameter" so that syntax-local-introduce used the introducer defined in the above link, since the generated temporary does not have x's mark that x has annihilated. Instead x's mark will be added to tmp after the transformer returns, and there's nothing you can do about it :( -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "racket users list" Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. The reason I can?t do that is because in the real program, sender is actually a match-expander. You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. ... Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? #lang racket (require racket/stxparam (for-syntax syntax/parse racket/syntax racket/set)) ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) (define-syntax-parameter current-defs #f) (define-match-expander sender (lambda (stx) (syntax-parse stx [(sender x) #:with tmp (generate-temporary #'x) (define defs (syntax-parameter-value #'current-defs)) (set-add! defs (syntax-local-introduce #'(define x tmp))) #'tmp]))) (define-syntax reciever (lambda (stx) (syntax-parse stx [(reciever) (define defs (syntax-parameter-value #'current-defs)) (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) #'(begin def ...))]))) (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ;x3: unbound identifier; ; also, no #%top syntax transformer is bound in: x3 ____________________ Racket Users list: http://lists.racket-lang.org/users From alexander at knauth.org Fri Aug 1 20:46:47 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 20:46:47 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <33160795.596501406938336494.JavaMail.root@zimbra> References: <33160795.596501406938336494.JavaMail.root@zimbra> Message-ID: <05BE0503-2AED-43FB-B662-45E8772183C9@knauth.org> What do you mean? Shouldn?t it go something like this: (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (match-define x3 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) (define x x3) x) The match-define form never defines ?x? as anything, but the receiver should, right? On Aug 1, 2014, at 8:12 PM, J. Ian Johnson wrote: > Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. > > Do you have a different example that doesn't fail in this way? > -Ian From alexander at knauth.org Fri Aug 1 21:13:50 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 1 Aug 2014 21:13:50 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <05BE0503-2AED-43FB-B662-45E8772183C9@knauth.org> References: <33160795.596501406938336494.JavaMail.root@zimbra> <05BE0503-2AED-43FB-B662-45E8772183C9@knauth.org> Message-ID: <34367C93-29F1-402F-94B9-FC43D2926BE3@knauth.org> On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth wrote: > What do you mean? > Shouldn?t it go something like this: > (syntax-parameterize ([current-defs (mutable-set)]) > (match-define (sender x) 1) > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (match-define x3 1) > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (define x3 (match 1 [x3 x3])) I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) (define-values (x3) (match 1 [(sender x) (values x3)])) Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (define x3 (match 1 [x3 x3])) > (define x x3) > x) > > The match-define form never defines ?x? as anything, but the receiver should, right? > > On Aug 1, 2014, at 8:12 PM, J. Ian Johnson wrote: > >> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. >> >> Do you have a different example that doesn't fail in this way? >> -Ian > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From henry.lenzi at gmail.com Fri Aug 1 23:44:19 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Sat, 2 Aug 2014 00:44:19 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <8738dhie7u.wl%stamourv@ccs.neu.edu> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> Message-ID: Hello everyone - First of all, a big Thank You to all of you and for taking the time for responding. I'll have to set aside sometime during this weekend to see if I can understand the ideas you've been so kind to offer. However, I should confess that I've made some progress with way simpler stuff which I hope to post later on. Like I've said, this is stupid software. Anyways, none of this is final. It really just used a plain text solution, since the format if a recipe is so rigid. The question of expanding the symbols from files to run-time was easier than I thought. The idea of using modules might have the nice collateral effect if some sort of primitive type (or syntax) checking for free. I like the idea someone offered of using modules for medication definitions. Actually, one module per definition makes it very easy for future users to add new medications. The ease of syntax is important because it allows for the customization by non-sophisticated users (physicians, nurses). Cheers, Henry Lenzi. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kalimehtar at mail.ru Sat Aug 2 06:12:46 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sat, 02 Aug 2014 14:12:46 +0400 Subject: [racket] =?utf-8?q?Destructors_in_Racket?= Message-ID: <1406974366.781553260@f94.i.mail.ru> I have a structure, that has a filestream inside it. File have to be cosed, when the structure is not used anymore (so gargbage collected). Is the best way to do (require ffi/unsafe) (register-finalizer my-obj ? ?(lambda (x) (close-output-port (obj-file x)))) ? It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my program actually doesn't use FFI? -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Sat Aug 2 06:57:32 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Sat, 2 Aug 2014 11:57:32 +0100 Subject: [racket] Destructors in Racket In-Reply-To: <1406974366.781553260@f94.i.mail.ru> References: <1406974366.781553260@f94.i.mail.ru> Message-ID: <0FA5F327-E736-42E8-9529-DDF6E1620289@cs.utah.edu> No, use the safe "will executors" API, instead. The unsafe finalizer API is for low-level, atomic finalization. Closing a port can flush buffers and more, and it's not a good idea to do that in an unsafe atomic context. > On Aug 2, 2014, at 11:12 AM, Roman Klochkov wrote: > > I have a structure, that has a filestream inside it. File have to be cosed, when the structure is not used anymore (so gargbage collected). > > Is the best way to do > (require ffi/unsafe) > (register-finalizer my-obj > (lambda (x) (close-output-port (obj-file x)))) > > ? > > It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my program actually doesn't use FFI? > > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From kalimehtar at mail.ru Sat Aug 2 07:15:43 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sat, 02 Aug 2014 15:15:43 +0400 Subject: [racket] =?utf-8?q?Destructors_in_Racket?= In-Reply-To: <0FA5F327-E736-42E8-9529-DDF6E1620289@cs.utah.edu> References: <1406974366.781553260@f94.i.mail.ru> <0FA5F327-E736-42E8-9529-DDF6E1620289@cs.utah.edu> Message-ID: <1406978143.418489117@f354.i.mail.ru> Then how? Suppose I have (struct obj (file)) (define my-obj (obj (open-output-file "out.dat"))) What I have to write to close the file, when my-obj will be GC'ed? I can write (define will (make-will-executor)) (will-register will my-obj?(lambda (x) (close-output-port (obj-file x)))) But as far as I understand, it will not be called until `will-execute' or `will-try-execute' will be manually called? Then how to call will-try-execute when GC is collecting my-obj? Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt : >No, use the safe "will executors" API, instead. > >The unsafe finalizer API is for low-level, atomic finalization. Closing a port can flush buffers and more, and it's not a good idea to do that in an unsafe atomic context. > >> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >> >> I have a structure, that has a filestream inside it. File have to be cosed, when the structure is not used anymore (so gargbage collected). >> >> Is the best way to do >> (require ffi/unsafe) >> (register-finalizer my-obj >> (lambda (x) (close-output-port (obj-file x)))) >> >> ? >> >> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my program actually doesn't use FFI? >> >> >> -- >> Roman Klochkov >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From robby at eecs.northwestern.edu Sat Aug 2 08:00:04 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Sat, 2 Aug 2014 07:00:04 -0500 Subject: [racket] Destructors in Racket In-Reply-To: <1406978143.418489117@f354.i.mail.ru> References: <1406974366.781553260@f94.i.mail.ru> <0FA5F327-E736-42E8-9529-DDF6E1620289@cs.utah.edu> <1406978143.418489117@f354.i.mail.ru> Message-ID: One way is to set up a separate thread to do that. The reason they are not called automatically is sometimes running the procedure passed to will-register needs to access some shared state and so your program must be allowed to be in control of the timing of the executor. In this case, it sounds like you can run the executor at any time, so just creating a thread to close the port inside my-obj should work fine. Robby On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov wrote: > Then how? > > Suppose I have > (struct obj (file)) > (define my-obj (obj (open-output-file "out.dat"))) > > What I have to write to close the file, when my-obj will be GC'ed? > > I can write > (define will (make-will-executor)) > (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) > > But as far as I understand, it will not be called until `will-execute' or > `will-try-execute' will be manually called? > > Then how to call will-try-execute when GC is collecting my-obj? > > > Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt : > > No, use the safe "will executors" API, instead. > > The unsafe finalizer API is for low-level, atomic finalization. Closing a > port can flush buffers and more, and it's not a good idea to do that in an > unsafe atomic context. > >> On Aug 2, 2014, at 11:12 AM, Roman Klochkov wrote: >> >> I have a structure, that has a filestream inside it. File have to be >> cosed, when the structure is not used anymore (so gargbage collected). >> >> Is the best way to do >> (require ffi/unsafe) >> (register-finalizer my-obj >> (lambda (x) (close-output-port (obj-file x)))) >> >> ? >> >> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >> program actually doesn't use FFI? >> >> >> -- >> Roman Klochkov >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > > -- > Roman Klochkov > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From kalimehtar at mail.ru Sat Aug 2 08:31:46 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sat, 02 Aug 2014 16:31:46 +0400 Subject: [racket] =?utf-8?q?Destructors_in_Racket?= In-Reply-To: References: <1406974366.781553260@f94.i.mail.ru> <1406978143.418489117@f354.i.mail.ru> Message-ID: <1406982706.127112181@f315.i.mail.ru> So I can write (define (make-obj stream) ? ?(define res??(obj (open-output-file "out.dat"))) ???(define will (make-will-executor)) ? ?(will-register will res (lambda (x) (close-output-port (obj-file x)))) ? ?(thread (lambda () (let loop () (will-try-execute will) (sleep 1) (loop))))) to make my objects? Additional threads don't hinder performance, do they? Or should I somehow figure out if the thread is already running, don't run it and use common `will' for all objects? Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler : >One way is to set up a separate thread to do that. > >The reason they are not called automatically is sometimes running the >procedure passed to will-register needs to access some shared state >and so your program must be allowed to be in control of the timing of >the executor. > >In this case, it sounds like you can run the executor at any time, so >just creating a thread to close the port inside my-obj should work >fine. > >Robby > > >On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >> Then how? >> >> Suppose I have >> (struct obj (file)) >> (define my-obj (obj (open-output-file "out.dat"))) >> >> What I have to write to close the file, when my-obj will be GC'ed? >> >> I can write >> (define will (make-will-executor)) >> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) >> >> But as far as I understand, it will not be called until `will-execute' or >> `will-try-execute' will be manually called? >> >> Then how to call will-try-execute when GC is collecting my-obj? >> >> >> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt < mflatt at cs.utah.edu >: >> >> No, use the safe "will executors" API, instead. >> >> The unsafe finalizer API is for low-level, atomic finalization. Closing a >> port can flush buffers and more, and it's not a good idea to do that in an >> unsafe atomic context. >> >>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>> >>> I have a structure, that has a filestream inside it. File have to be >>> cosed, when the structure is not used anymore (so gargbage collected). >>> >>> Is the best way to do >>> (require ffi/unsafe) >>> (register-finalizer my-obj >>> (lambda (x) (close-output-port (obj-file x)))) >>> >>> ? >>> >>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>> program actually doesn't use FFI? >>> >>> >>> -- >>> Roman Klochkov >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> >> -- >> Roman Klochkov >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From robby at eecs.northwestern.edu Sat Aug 2 08:38:08 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Sat, 2 Aug 2014 07:38:08 -0500 Subject: [racket] Destructors in Racket In-Reply-To: <1406982706.127112181@f315.i.mail.ru> References: <1406974366.781553260@f94.i.mail.ru> <1406978143.418489117@f354.i.mail.ru> <1406982706.127112181@f315.i.mail.ru> Message-ID: Probably you want to do something like this, I guess. It creates a single thread that just waits until anything registered with an-executor is garbage and then runs the executors. They will run asynchronously, but perhaps that's okay for your usecase. Robby #lang racket (define an-executor (make-will-executor)) (void (thread (? () (let loop () (will-execute an-executor) (loop))))) (define a-box (box #f)) (will-register an-executor a-box (? (x) (printf "a-box is now garbage\n"))) (collect-garbage) (collect-garbage) (collect-garbage) (printf "breaking the link\n") (set! a-box #f) (collect-garbage) (collect-garbage) (collect-garbage) On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov wrote: > So I can write > > (define (make-obj stream) > (define res (obj (open-output-file "out.dat"))) > (define will (make-will-executor)) > (will-register will res (lambda (x) (close-output-port (obj-file x)))) > (thread (lambda () (let loop () (will-try-execute will) (sleep 1) > (loop))))) > > to make my objects? Additional threads don't hinder performance, do they? > > Or should I somehow figure out if the thread is already running, don't run > it and use common `will' for all objects? > > Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler > : > > One way is to set up a separate thread to do that. > > The reason they are not called automatically is sometimes running the > procedure passed to will-register needs to access some shared state > and so your program must be allowed to be in control of the timing of > the executor. > > In this case, it sounds like you can run the executor at any time, so > just creating a thread to close the port inside my-obj should work > fine. > > Robby > > > On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov wrote: >> Then how? >> >> Suppose I have >> (struct obj (file)) >> (define my-obj (obj (open-output-file "out.dat"))) >> >> What I have to write to close the file, when my-obj will be GC'ed? >> >> I can write >> (define will (make-will-executor)) >> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) >> >> But as far as I understand, it will not be called until `will-execute' or >> `will-try-execute' will be manually called? >> >> Then how to call will-try-execute when GC is collecting my-obj? >> >> >> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt : >> >> No, use the safe "will executors" API, instead. >> >> The unsafe finalizer API is for low-level, atomic finalization. Closing a >> port can flush buffers and more, and it's not a good idea to do that in an >> unsafe atomic context. >> >>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov wrote: >>> >>> I have a structure, that has a filestream inside it. File have to be >>> cosed, when the structure is not used anymore (so gargbage collected). >>> >>> Is the best way to do >>> (require ffi/unsafe) >>> (register-finalizer my-obj >>> (lambda (x) (close-output-port (obj-file x)))) >>> >>> ? >>> >>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>> program actually doesn't use FFI? >>> >>> >>> -- >>> Roman Klochkov >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> >> -- >> Roman Klochkov >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> > > > > -- > Roman Klochkov From oev-racket at sibmail.com Sat Aug 2 11:47:32 2014 From: oev-racket at sibmail.com (Evgeny Odegov) Date: Sat, 02 Aug 2014 22:47:32 +0700 Subject: [racket] Destructors in Racket In-Reply-To: References: <1406974366.781553260@f94.i.mail.ru> <1406978143.418489117@f354.i.mail.ru> <1406982706.127112181@f315.i.mail.ru> Message-ID: <53DD0814.70700@sibmail.com> In the example, the value is box and triggering occurs almost immediately after set!. But in case of another kind of value, triggering doesn't occur or take much longer. Why? (Or maybe I do something wrong?) > Probably you want to do something like this, I guess. It creates a > single thread that just waits until anything registered with > an-executor is garbage and then runs the executors. They will run > asynchronously, but perhaps that's okay for your usecase. > > Robby > > #lang racket > (define an-executor (make-will-executor)) > (void > (thread > (? () > (let loop () > (will-execute an-executor) > (loop))))) > > (define a-box (box #f)) > (will-register an-executor > a-box > (? (x) (printf "a-box is now garbage\n"))) > (collect-garbage) (collect-garbage) (collect-garbage) > (printf "breaking the link\n") > (set! a-box #f) > (collect-garbage) (collect-garbage) (collect-garbage) > > On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov wrote: >> So I can write >> >> (define (make-obj stream) >> (define res (obj (open-output-file "out.dat"))) >> (define will (make-will-executor)) >> (will-register will res (lambda (x) (close-output-port (obj-file x)))) >> (thread (lambda () (let loop () (will-try-execute will) (sleep 1) >> (loop))))) >> >> to make my objects? Additional threads don't hinder performance, do they? >> >> Or should I somehow figure out if the thread is already running, don't run >> it and use common `will' for all objects? >> >> Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler >> : >> >> One way is to set up a separate thread to do that. >> >> The reason they are not called automatically is sometimes running the >> procedure passed to will-register needs to access some shared state >> and so your program must be allowed to be in control of the timing of >> the executor. >> >> In this case, it sounds like you can run the executor at any time, so >> just creating a thread to close the port inside my-obj should work >> fine. >> >> Robby >> >> >> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov wrote: >>> Then how? >>> >>> Suppose I have >>> (struct obj (file)) >>> (define my-obj (obj (open-output-file "out.dat"))) >>> >>> What I have to write to close the file, when my-obj will be GC'ed? >>> >>> I can write >>> (define will (make-will-executor)) >>> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) >>> >>> But as far as I understand, it will not be called until `will-execute' or >>> `will-try-execute' will be manually called? >>> >>> Then how to call will-try-execute when GC is collecting my-obj? >>> >>> >>> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt : >>> >>> No, use the safe "will executors" API, instead. >>> >>> The unsafe finalizer API is for low-level, atomic finalization. Closing a >>> port can flush buffers and more, and it's not a good idea to do that in an >>> unsafe atomic context. >>> >>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov wrote: >>>> >>>> I have a structure, that has a filestream inside it. File have to be >>>> cosed, when the structure is not used anymore (so gargbage collected). >>>> >>>> Is the best way to do >>>> (require ffi/unsafe) >>>> (register-finalizer my-obj >>>> (lambda (x) (close-output-port (obj-file x)))) >>>> >>>> ? >>>> >>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>>> program actually doesn't use FFI? >>>> >>>> >>>> -- >>>> Roman Klochkov >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> -- >>> Roman Klochkov >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >> >> >> -- >> Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From kalimehtar at mail.ru Sat Aug 2 13:12:50 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sat, 02 Aug 2014 21:12:50 +0400 Subject: [racket] =?utf-8?q?Destructors_in_Racket?= In-Reply-To: References: <1406974366.781553260@f94.i.mail.ru> <1406982706.127112181@f315.i.mail.ru> Message-ID: <1406999570.977378605@f413.i.mail.ru> Here we have a thread per every module, that use such approach. It is better,than a thread per object, but ... How many such threads can Racket run without performance degrading? Maybe better make common module for such purpose? Hmm..., I think I should make one... Sat, 2 Aug 2014 07:38:08 -0500 ?? Robby Findler : >Probably you want to do something like this, I guess. It creates a >single thread that just waits until anything registered with >an-executor is garbage and then runs the executors. They will run >asynchronously, but perhaps that's okay for your usecase. > >Robby > >#lang racket >(define an-executor (make-will-executor)) >(void >?(thread >??(? () >????(let loop () >??????(will-execute an-executor) >??????(loop))))) > >(define a-box (box #f)) >(will-register an-executor >???????????????a-box >???????????????(? (x) (printf "a-box is now garbage\n"))) >(collect-garbage) (collect-garbage) (collect-garbage) >(printf "breaking the link\n") >(set! a-box #f) >(collect-garbage) (collect-garbage) (collect-garbage) > >On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >> So I can write >> >> (define (make-obj stream) >> (define res (obj (open-output-file "out.dat"))) >> (define will (make-will-executor)) >> (will-register will res (lambda (x) (close-output-port (obj-file x)))) >> (thread (lambda () (let loop () (will-try-execute will) (sleep 1) >> (loop))))) >> >> to make my objects? Additional threads don't hinder performance, do they? >> >> Or should I somehow figure out if the thread is already running, don't run >> it and use common `will' for all objects? >> >> Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler >> < robby at eecs.northwestern.edu >: >> >> One way is to set up a separate thread to do that. >> >> The reason they are not called automatically is sometimes running the >> procedure passed to will-register needs to access some shared state >> and so your program must be allowed to be in control of the timing of >> the executor. >> >> In this case, it sounds like you can run the executor at any time, so >> just creating a thread to close the port inside my-obj should work >> fine. >> >> Robby >> >> >> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>> Then how? >>> >>> Suppose I have >>> (struct obj (file)) >>> (define my-obj (obj (open-output-file "out.dat"))) >>> >>> What I have to write to close the file, when my-obj will be GC'ed? >>> >>> I can write >>> (define will (make-will-executor)) >>> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) >>> >>> But as far as I understand, it will not be called until `will-execute' or >>> `will-try-execute' will be manually called? >>> >>> Then how to call will-try-execute when GC is collecting my-obj? >>> >>> >>> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt < mflatt at cs.utah.edu >: >>> >>> No, use the safe "will executors" API, instead. >>> >>> The unsafe finalizer API is for low-level, atomic finalization. Closing a >>> port can flush buffers and more, and it's not a good idea to do that in an >>> unsafe atomic context. >>> >>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>> >>>> I have a structure, that has a filestream inside it. File have to be >>>> cosed, when the structure is not used anymore (so gargbage collected). >>>> >>>> Is the best way to do >>>> (require ffi/unsafe) >>>> (register-finalizer my-obj >>>> (lambda (x) (close-output-port (obj-file x)))) >>>> >>>> ? >>>> >>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>>> program actually doesn't use FFI? >>>> >>>> >>>> -- >>>> Roman Klochkov >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> >>> -- >>> Roman Klochkov >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >> >> >> >> -- >> Roman Klochkov -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From kalimehtar at mail.ru Sat Aug 2 13:13:54 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sat, 02 Aug 2014 21:13:54 +0400 Subject: [racket] =?utf-8?q?Destructors_in_Racket?= In-Reply-To: <53DD0814.70700@sibmail.com> References: <1406974366.781553260@f94.i.mail.ru> <53DD0814.70700@sibmail.com> Message-ID: <1406999634.495192056@f413.i.mail.ru> > But in case of another kind of value What another kiind? Small numbers and some chars are not garbage collected. Sat, 02 Aug 2014 22:47:32 +0700 ?? Evgeny Odegov : >In the example, the value is box and triggering occurs almost >immediately after set!. >But in case of another kind of value, triggering doesn't occur or take >much longer. >Why? (Or maybe I do something wrong?) > >> Probably you want to do something like this, I guess. It creates a >> single thread that just waits until anything registered with >> an-executor is garbage and then runs the executors. They will run >> asynchronously, but perhaps that's okay for your usecase. >> >> Robby >> >> #lang racket >> (define an-executor (make-will-executor)) >> (void >> (thread >> (? () >> (let loop () >> (will-execute an-executor) >> (loop))))) >> >> (define a-box (box #f)) >> (will-register an-executor >> a-box >> (? (x) (printf "a-box is now garbage\n"))) >> (collect-garbage) (collect-garbage) (collect-garbage) >> (printf "breaking the link\n") >> (set! a-box #f) >> (collect-garbage) (collect-garbage) (collect-garbage) >> >> On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>> So I can write >>> >>> (define (make-obj stream) >>> (define res (obj (open-output-file "out.dat"))) >>> (define will (make-will-executor)) >>> (will-register will res (lambda (x) (close-output-port (obj-file x)))) >>> (thread (lambda () (let loop () (will-try-execute will) (sleep 1) >>> (loop))))) >>> >>> to make my objects? Additional threads don't hinder performance, do they? >>> >>> Or should I somehow figure out if the thread is already running, don't run >>> it and use common `will' for all objects? >>> >>> Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler >>> < robby at eecs.northwestern.edu >: >>> >>> One way is to set up a separate thread to do that. >>> >>> The reason they are not called automatically is sometimes running the >>> procedure passed to will-register needs to access some shared state >>> and so your program must be allowed to be in control of the timing of >>> the executor. >>> >>> In this case, it sounds like you can run the executor at any time, so >>> just creating a thread to close the port inside my-obj should work >>> fine. >>> >>> Robby >>> >>> >>> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>> Then how? >>>> >>>> Suppose I have >>>> (struct obj (file)) >>>> (define my-obj (obj (open-output-file "out.dat"))) >>>> >>>> What I have to write to close the file, when my-obj will be GC'ed? >>>> >>>> I can write >>>> (define will (make-will-executor)) >>>> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) >>>> >>>> But as far as I understand, it will not be called until `will-execute' or >>>> `will-try-execute' will be manually called? >>>> >>>> Then how to call will-try-execute when GC is collecting my-obj? >>>> >>>> >>>> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt < mflatt at cs.utah.edu >: >>>> >>>> No, use the safe "will executors" API, instead. >>>> >>>> The unsafe finalizer API is for low-level, atomic finalization. Closing a >>>> port can flush buffers and more, and it's not a good idea to do that in an >>>> unsafe atomic context. >>>> >>>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>>> >>>>> I have a structure, that has a filestream inside it. File have to be >>>>> cosed, when the structure is not used anymore (so gargbage collected). >>>>> >>>>> Is the best way to do >>>>> (require ffi/unsafe) >>>>> (register-finalizer my-obj >>>>> (lambda (x) (close-output-port (obj-file x)))) >>>>> >>>>> ? >>>>> >>>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>>>> program actually doesn't use FFI? >>>>> >>>>> >>>>> -- >>>>> Roman Klochkov >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>> >>>> >>>> -- >>>> Roman Klochkov >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>>> >>> >>> >>> -- >>> Roman Klochkov >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > >____________________ >??Racket Users list: >?? http://lists.racket-lang.org/users > -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From kalimehtar at mail.ru Sat Aug 2 14:04:04 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sat, 02 Aug 2014 22:04:04 +0400 Subject: [racket] =?utf-8?q?Destructors_in_Racket?= In-Reply-To: <1406999570.977378605@f413.i.mail.ru> References: <1406974366.781553260@f94.i.mail.ru> <1406999570.977378605@f413.i.mail.ru> Message-ID: <1407002644.29699203@f352.i.mail.ru> Ready. Package `finalizer' on pkgs.racket-lang.org Sat, 02 Aug 2014 21:12:50 +0400 ?? Roman Klochkov : >Here we have a thread per every module, that use such approach. It is better,than a thread per object, but ... >How many such threads can Racket run without performance degrading? > >Maybe better make common module for such purpose? Hmm..., I think I should make one... > > >Sat, 2 Aug 2014 07:38:08 -0500 ?? Robby Findler : >>Probably you want to do something like this, I guess. It creates a >>single thread that just waits until anything registered with >>an-executor is garbage and then runs the executors. They will run >>asynchronously, but perhaps that's okay for your usecase. >> >>Robby >> >>#lang racket >>(define an-executor (make-will-executor)) >>(void >>?(thread >>??(? () >>????(let loop () >>??????(will-execute an-executor) >>??????(loop))))) >> >>(define a-box (box #f)) >>(will-register an-executor >>???????????????a-box >>???????????????(? (x) (printf "a-box is now garbage\n"))) >>(collect-garbage) (collect-garbage) (collect-garbage) >>(printf "breaking the link\n") >>(set! a-box #f) >>(collect-garbage) (collect-garbage) (collect-garbage) >> >>On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>> So I can write >>> >>> (define (make-obj stream) >>> (define res (obj (open-output-file "out.dat"))) >>> (define will (make-will-executor)) >>> (will-register will res (lambda (x) (close-output-port (obj-file x)))) >>> (thread (lambda () (let loop () (will-try-execute will) (sleep 1) >>> (loop))))) >>> >>> to make my objects? Additional threads don't hinder performance, do they? >>> >>> Or should I somehow figure out if the thread is already running, don't run >>> it and use common `will' for all objects? >>> >>> Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler >>> < robby at eecs.northwestern.edu >: >>> >>> One way is to set up a separate thread to do that. >>> >>> The reason they are not called automatically is sometimes running the >>> procedure passed to will-register needs to access some shared state >>> and so your program must be allowed to be in control of the timing of >>> the executor. >>> >>> In this case, it sounds like you can run the executor at any time, so >>> just creating a thread to close the port inside my-obj should work >>> fine. >>> >>> Robby >>> >>> >>> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>> Then how? >>>> >>>> Suppose I have >>>> (struct obj (file)) >>>> (define my-obj (obj (open-output-file "out.dat"))) >>>> >>>> What I have to write to close the file, when my-obj will be GC'ed? >>>> >>>> I can write >>>> (define will (make-will-executor)) >>>> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) >>>> >>>> But as far as I understand, it will not be called until `will-execute' or >>>> `will-try-execute' will be manually called? >>>> >>>> Then how to call will-try-execute when GC is collecting my-obj? >>>> >>>> >>>> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt < mflatt at cs.utah.edu >: >>>> >>>> No, use the safe "will executors" API, instead. >>>> >>>> The unsafe finalizer API is for low-level, atomic finalization. Closing a >>>> port can flush buffers and more, and it's not a good idea to do that in an >>>> unsafe atomic context. >>>> >>>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>>> >>>>> I have a structure, that has a filestream inside it. File have to be >>>>> cosed, when the structure is not used anymore (so gargbage collected). >>>>> >>>>> Is the best way to do >>>>> (require ffi/unsafe) >>>>> (register-finalizer my-obj >>>>> (lambda (x) (close-output-port (obj-file x)))) >>>>> >>>>> ? >>>>> >>>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>>>> program actually doesn't use FFI? >>>>> >>>>> >>>>> -- >>>>> Roman Klochkov >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>> >>>> >>>> >>>> -- >>>> Roman Klochkov >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>>> >>> >>> >>> >>> -- >>> Roman Klochkov > > >-- >Roman Klochkov >____________________ >??Racket Users list: >?? http://lists.racket-lang.org/users > -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From oev-racket at sibmail.com Sat Aug 2 14:05:50 2014 From: oev-racket at sibmail.com (Evgeny Odegov) Date: Sun, 03 Aug 2014 01:05:50 +0700 Subject: [racket] Destructors in Racket In-Reply-To: <1406999634.495192056@f413.i.mail.ru> References: <1406974366.781553260@f94.i.mail.ru> <53DD0814.70700@sibmail.com> <1406999634.495192056@f413.i.mail.ru> Message-ID: <53DD287E.7010904@sibmail.com> Well, it turns out that objects like #(1 2 3) or '(1 2 3) are not collected (optimizations?), but (vector 1 2 3) and (list 1 2 3) are collected normally. It so happens that I tried #(1 2 3) and '(1 2 3) first and came to the wrong conclusions :) > > But in case of another kind of value > > What another kiind? Small numbers and some chars are not garbage collected. > > > Sat, 02 Aug 2014 22:47:32 +0700 ?? Evgeny Odegov : >> In the example, the value is box and triggering occurs almost >> immediately after set!. >> But in case of another kind of value, triggering doesn't occur or take >> much longer. >> Why? (Or maybe I do something wrong?) >> >>> Probably you want to do something like this, I guess. It creates a >>> single thread that just waits until anything registered with >>> an-executor is garbage and then runs the executors. They will run >>> asynchronously, but perhaps that's okay for your usecase. >>> >>> Robby >>> >>> #lang racket >>> (define an-executor (make-will-executor)) >>> (void >>> (thread >>> (? () >>> (let loop () >>> (will-execute an-executor) >>> (loop))))) >>> >>> (define a-box (box #f)) >>> (will-register an-executor >>> a-box >>> (? (x) (printf "a-box is now garbage\n"))) >>> (collect-garbage) (collect-garbage) (collect-garbage) >>> (printf "breaking the link\n") >>> (set! a-box #f) >>> (collect-garbage) (collect-garbage) (collect-garbage) >>> >>> On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>> So I can write >>>> >>>> (define (make-obj stream) >>>> (define res (obj (open-output-file "out.dat"))) >>>> (define will (make-will-executor)) >>>> (will-register will res (lambda (x) (close-output-port (obj-file x)))) >>>> (thread (lambda () (let loop () (will-try-execute will) (sleep 1) >>>> (loop))))) >>>> >>>> to make my objects? Additional threads don't hinder performance, do they? >>>> >>>> Or should I somehow figure out if the thread is already running, don't run >>>> it and use common `will' for all objects? >>>> >>>> Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler >>>> < robby at eecs.northwestern.edu >: >>>> >>>> One way is to set up a separate thread to do that. >>>> >>>> The reason they are not called automatically is sometimes running the >>>> procedure passed to will-register needs to access some shared state >>>> and so your program must be allowed to be in control of the timing of >>>> the executor. >>>> >>>> In this case, it sounds like you can run the executor at any time, so >>>> just creating a thread to close the port inside my-obj should work >>>> fine. >>>> >>>> Robby >>>> >>>> >>>> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>>> Then how? >>>>> >>>>> Suppose I have >>>>> (struct obj (file)) >>>>> (define my-obj (obj (open-output-file "out.dat"))) >>>>> >>>>> What I have to write to close the file, when my-obj will be GC'ed? >>>>> >>>>> I can write >>>>> (define will (make-will-executor)) >>>>> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) >>>>> >>>>> But as far as I understand, it will not be called until `will-execute' or >>>>> `will-try-execute' will be manually called? >>>>> >>>>> Then how to call will-try-execute when GC is collecting my-obj? >>>>> >>>>> >>>>> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt < mflatt at cs.utah.edu >: >>>>> >>>>> No, use the safe "will executors" API, instead. >>>>> >>>>> The unsafe finalizer API is for low-level, atomic finalization. Closing a >>>>> port can flush buffers and more, and it's not a good idea to do that in an >>>>> unsafe atomic context. >>>>> >>>>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>>>>> >>>>>> I have a structure, that has a filestream inside it. File have to be >>>>>> cosed, when the structure is not used anymore (so gargbage collected). >>>>>> >>>>>> Is the best way to do >>>>>> (require ffi/unsafe) >>>>>> (register-finalizer my-obj >>>>>> (lambda (x) (close-output-port (obj-file x)))) >>>>>> >>>>>> ? >>>>>> >>>>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>>>>> program actually doesn't use FFI? >>>>>> >>>>>> >>>>>> -- >>>>>> Roman Klochkov >>>>>> ____________________ >>>>>> Racket Users list: >>>>>> http://lists.racket-lang.org/users >>>>> >>>>> -- >>>>> Roman Klochkov >>>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>>> >>>> >>>> -- >>>> Roman Klochkov >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> > From ryanc at ccs.neu.edu Sat Aug 2 14:34:38 2014 From: ryanc at ccs.neu.edu (Ryan Culpepper) Date: Sat, 02 Aug 2014 14:34:38 -0400 Subject: [racket] Racket v6.1 Message-ID: <53DD2F3E.2000501@ccs.neu.edu> PLT Design Inc. announces the release of Racket version 6.1 at http://racket-lang.org/ The MAJOR INNOVATION concerns local recursive variable definitions. Instead of initializing variables with an `undefined' value, Racket raises an exception when such a variable is used before its definition. (Thanks to Claire Alvis for adapting Dybvig's "Fixing Letrec" work.) Since programs are rarely intended to produce #, raising an exception provides early and improved feedback. Module-level variables have always triggered such an exception when used too early, and this change finally gives local bindings --- including class fields --- the same meaning. This change is backwards-incompatible with prior releases of Racket. Aside from exposing a few bugs, the change will mainly affect programs that include (define undefined (letrec ([x x]) x)) to obtain the # value. In its stead, Racket provides the same value via the `racket/undefined' library (which was introduced in the previous release). Programmers are encouraged to use it in place of the pattern above to obtain the "undefined" value. The release also includes the following SMALL CHANGES: * PLUMBERS generalize the flush-on-exit capability of primitive output ports to enable arbitrary flushing actions and to give programmers control over the timing of flushes (i.e., a composable `atexit'). New functions include `current-plumber', `plumber-add-flush!', and `plumber-flush-all'. * CONTRACTS: the contract system's random testing facility has been strengthened so that it can easily find simple mistakes in contracted data structure implementations (e.g. an accidental reverse of a conditional in a heap invariant check). * REDEX: the semantics of mis-match patterns (variables followed by _!_) inside ellipses has changed in a backwards-incompatible way. This change simplifies the patterns' semantics and increases the usefulness of these patterns. * TEACHING LANGUAGES: `check-random' is an addition to the preferred unit testing framework in the teaching languages. It enables the testing of students' functions that use random-number generation. (Thanks to David Van Horn (UMaryland) for proposing this idea.) * Upgraded and normalized versions of GRAPHICS LIBRARIES and dependencies (Pango, Cairo, GLib, etc.) that are bundled with Racket on Windows and Mac OS X. For example, FreeType support is consistently enabled. * TYPED RACKET: its standard library includes contracted exports from the Racket standard library, such as the formatting combinators of `racket/format'. It also supports Racket's asynchronous channels; see the `typed/racket/async-channel' library. * SSL: The openssl library supports forward secrecy via DHE and ECDHE cipher suites (thanks to Edward Lee) and Server Name Indication (thanks to Jay Kominek). * The `mzlib/class100' library has been REMOVED. Use `racket/class' instead. Feedback Welcome From tonyg at ccs.neu.edu Sat Aug 2 21:08:45 2014 From: tonyg at ccs.neu.edu (Tony Garnock-Jones) Date: Sat, 02 Aug 2014 18:08:45 -0700 Subject: [racket] Additional use for the new plumber mechanism Message-ID: <53DD8B9D.5070405@ccs.neu.edu> Hi all, I discovered today that the PortAudio library [1] requires you to call Pa_Terminate on pain of possible kernel resource leaks. The plumber mechanism can be used to ensure Pa_Terminate is called before process exit. I had been having trouble imagining uses for the new "plumber" mechanism [2] besides things like flushing buffers, doing clean disconnects from network services, and committing or rolling-back transactions. This new example is an interesting variation. (Thanks again, Matthew!) Cheers, Tony [1] http://www.portaudio.com/ [2] http://www.cs.utah.edu/plt/snapshots/current/doc/reference/plumbers.html (I couldn't find the documentation for it on racket-lang.org!) From kalimehtar at mail.ru Sun Aug 3 05:15:19 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sun, 03 Aug 2014 13:15:19 +0400 Subject: [racket] =?utf-8?q?Performance=2E_Higher-order_function?= Message-ID: <1407057319.566019875@f258.i.mail.ru> Are higher order function always slow? Made small test: test1 -- unfamous set-in-the-loop accumulating test2 -- built-in build-string test3 -- manually written build-string with the same code as in test1 ---- (define (test1 n) (define res (make-string n)) ? ? (for ([i (in-range n)]) ? ? ? ? (string-set! res i (integer->char i))) res) (define (test2 n) ? ? (build-string n integer->char)) (define (build-string1 n proc) ? ? (define res (make-string n)) ? ? (for ([i (in-range n)]) ? ? ? ? (string-set! res i (proc i))) ? ? res) (define (test3 n) ? ? (build-string1 n integer->char)) (time (for ([i 100000]) (test1 100))) (time (for ([i 100000]) (test1 100))) (time (for ([i 100000]) (test1 100))) (displayln "") (time (for ([i 100000]) (test2 100))) (time (for ([i 100000]) (test2 100))) (time (for ([i 100000]) (test2 100))) (displayln "") (time (for ([i 100000]) (test3 100))) (time (for ([i 100000]) (test3 100))) (time (for ([i 100000]) (test3 100))) ---- Tested on Linux x32 $ /usr/racket/bin/racket? Welcome to Racket v6.1. > (enter! "test")? cpu time: 360 real time: 469 gc time: 64 cpu time: 212 real time: 209 gc time: 0 cpu time: 208 real time: 208 gc time: 0 cpu time: 400 real time: 402 gc time: 0 cpu time: 380 real time: 382 gc time: 4 cpu time: 384 real time: 383 gc time: 0 cpu time: 524 real time: 529 gc time: 4 cpu time: 468 real time: 470 gc time: 8 cpu time: 412 real time: 414 gc time: 12 --- So I see, that build-string version is about two times slower, than set-in-the-loop. Why so much? I expected about 10-20% difference. -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Sun Aug 3 12:22:57 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 12:22:57 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <34367C93-29F1-402F-94B9-FC43D2926BE3@knauth.org> References: <33160795.596501406938336494.JavaMail.root@zimbra> <05BE0503-2AED-43FB-B662-45E8772183C9@knauth.org> <34367C93-29F1-402F-94B9-FC43D2926BE3@knauth.org> Message-ID: <804300D1-ED89-4543-9FB4-91BAFE4E6E88@knauth.org> What if match-define did something like this to store the parsed pat in a syntax-property?: (define-syntax (match-define stx) (syntax-parse stx [(_ pat rhs:expr) (let ([p (parse-id #'pat)]) (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] [vars (bound-vars p)]) (quasisyntax/loc stx (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars)])))))])) And parse did something like this: (define (parse stx) (or (syntax-property stx ?parsed-pat) (let () ... ))) On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth wrote: > > On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth wrote: > >> What do you mean? >> Shouldn?t it go something like this: >> (syntax-parameterize ([current-defs (mutable-set)]) >> (match-define (sender x) 1) >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (match-define x3 1) >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (define x3 (match 1 [x3 x3])) > I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) > (define-values (x3) (match 1 [(sender x) (values x3)])) > Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (define x3 (match 1 [x3 x3])) >> (define x x3) >> x) >> >> The match-define form never defines ?x? as anything, but the receiver should, right? >> >> On Aug 1, 2014, at 8:12 PM, J. Ian Johnson wrote: >> >>> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. >>> >>> Do you have a different example that doesn't fail in this way? >>> -Ian >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucier at math.purdue.edu Sun Aug 3 12:26:49 2014 From: lucier at math.purdue.edu (Bradley Lucier) Date: Sun, 3 Aug 2014 12:26:49 -0400 Subject: [racket] Teaching logical thinking via programming in Scheme Message-ID: Many people on this list think deeply about pedagogy; perhaps the following article published in the Notices of the American Mathematical Society, which advocates teaching logical thinking via Scheme programming before advancing to the usual university mathematics curriculum (calculus, etc.), may be of interest. http://www.ams.org/notices/201406/rnoti-p597.pdf Brad From ianj at ccs.neu.edu Sun Aug 3 12:32:39 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Sun, 3 Aug 2014 12:32:39 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <804300D1-ED89-4543-9FB4-91BAFE4E6E88@knauth.org> Message-ID: <15782525.602341407083559269.JavaMail.root@zimbra> Try it and report back. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something What if match-define did something like this to store the parsed pat in a syntax-property?: (define-syntax (match-define stx) (syntax-parse stx [(_ pat rhs:expr) (let ([p (parse-id #'pat)]) (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] [vars (bound-vars p)]) (quasisyntax/loc stx (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars)])))))])) And parse did something like this: (define (parse stx) (or (syntax-property stx ?parsed-pat) (let () ... ))) On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: What do you mean? Shouldn?t it go something like this: (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (match-define x3 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) (define-values (x3) (match 1 [(sender x) (values x3)])) Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) (define x x3) x) The match-define form never defines ?x? as anything, but the receiver should, right? On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. Do you have a different example that doesn't fail in this way? -Ian ____________________ Racket Users list: http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users From matthias at ccs.neu.edu Sun Aug 3 13:15:57 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 13:15:57 -0400 Subject: [racket] Performance. Higher-order function In-Reply-To: <1407057319.566019875@f258.i.mail.ru> References: <1407057319.566019875@f258.i.mail.ru> Message-ID: Because build-string calls an unknown function 1000 x 100000 times, and an unknown function call is expensive. Racket could possible collapse all modules and perform additional in-lining optimizations eventually, which may help here. But it doesn't yet. -- Matthias On Aug 3, 2014, at 5:15 AM, Roman Klochkov wrote: > Are higher order function always slow? > > Made small test: > test1 -- unfamous set-in-the-loop accumulating > test2 -- built-in build-string > test3 -- manually written build-string with the same code as in test1 > ---- > (define (test1 n) > (define res (make-string n)) > (for ([i (in-range n)]) > (string-set! res i (integer->char i))) > res) > > (define (test2 n) > (build-string n integer->char)) > > (define (build-string1 n proc) > (define res (make-string n)) > (for ([i (in-range n)]) > (string-set! res i (proc i))) > res) > > (define (test3 n) > (build-string1 n integer->char)) > > (time (for ([i 100000]) (test1 100))) > (time (for ([i 100000]) (test1 100))) > (time (for ([i 100000]) (test1 100))) > (displayln "") > (time (for ([i 100000]) (test2 100))) > (time (for ([i 100000]) (test2 100))) > (time (for ([i 100000]) (test2 100))) > (displayln "") > (time (for ([i 100000]) (test3 100))) > (time (for ([i 100000]) (test3 100))) > (time (for ([i 100000]) (test3 100))) > ---- > Tested on Linux x32 > > $ /usr/racket/bin/racket > Welcome to Racket v6.1. > > (enter! "test") > cpu time: 360 real time: 469 gc time: 64 > cpu time: 212 real time: 209 gc time: 0 > cpu time: 208 real time: 208 gc time: 0 > > cpu time: 400 real time: 402 gc time: 0 > cpu time: 380 real time: 382 gc time: 4 > cpu time: 384 real time: 383 gc time: 0 > > cpu time: 524 real time: 529 gc time: 4 > cpu time: 468 real time: 470 gc time: 8 > cpu time: 412 real time: 414 gc time: 12 > > --- > > So I see, that build-string version is about two times slower, than set-in-the-loop. Why so much? I expected about 10-20% difference. > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Sun Aug 3 13:18:28 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 13:18:28 -0400 Subject: [racket] Teaching logical thinking via programming in Scheme In-Reply-To: References: Message-ID: Thanks for pointing it out. Since the person is possibly still at Brown, I may try to contact him and see whether there is common ground. Much appreciated -- Matthias On Aug 3, 2014, at 12:26 PM, Bradley Lucier wrote: > Many people on this list think deeply about pedagogy; perhaps the following article published in the Notices of the American Mathematical Society, which advocates teaching logical thinking via Scheme programming before advancing to the usual university mathematics curriculum (calculus, etc.), may be of interest. > > http://www.ams.org/notices/201406/rnoti-p597.pdf > > Brad > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From alexander at knauth.org Sun Aug 3 13:31:07 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 13:31:07 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <15782525.602341407083559269.JavaMail.root@zimbra> References: <15782525.602341407083559269.JavaMail.root@zimbra> Message-ID: <628C4DA3-8502-4AE1-9DAA-3D9ED3DD46FD@knauth.org> I tried it but got weird errors like this: idle-rest: undefined; cannot use before initialization And this: wrkr: undefined; cannot use before initialization https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern On Aug 3, 2014, at 12:32 PM, J. Ian Johnson wrote: > Try it and report back. > -Ian > ----- Original Message ----- > From: "Alexander D. Knauth" > To: "J. Ian Johnson" > Cc: "racket users list" > Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern > Subject: Re: [racket] getting one macro to tell another macro to define something > > > What if match-define did something like this to store the parsed pat in a syntax-property?: > > (define-syntax (match-define stx) > (syntax-parse stx > [(_ pat rhs:expr) > (let ([p (parse-id #'pat)]) > (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] > [vars (bound-vars p)]) > (quasisyntax/loc stx > (define-values vars (match*/derived (rhs) #,stx > [(pat) (values . vars)])))))])) > And parse did something like this: > > (define (parse stx) > (or > (syntax-property stx ?parsed-pat) > (let () > ... > ))) > > > On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: > > > > On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: > > > > What do you mean? > Shouldn?t it go something like this: > (syntax-parameterize ([current-defs (mutable-set)]) > (match-define (sender x) 1) > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (match-define x3 1) > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (define x3 (match 1 [x3 x3])) > I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) > (define-values (x3) (match 1 [(sender x) (values x3)])) > Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? > > > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (define x3 (match 1 [x3 x3])) > > (define x x3) > x) > > The match-define form never defines ?x? as anything, but the receiver should, right? > > On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: > > > > Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. > > Do you have a different example that doesn't fail in this way? > -Ian > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Sun Aug 3 13:40:57 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 13:40:57 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <628C4DA3-8502-4AE1-9DAA-3D9ED3DD46FD@knauth.org> References: <15782525.602341407083559269.JavaMail.root@zimbra> <628C4DA3-8502-4AE1-9DAA-3D9ED3DD46FD@knauth.org> Message-ID: <3EC12BB8-2BDC-4885-98E3-2EDE60CC5A6E@ccs.neu.edu> That means you are defining and using recursive variables before the initialization is done. On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: > I tried it but got weird errors like this: > idle-rest: undefined; > cannot use before initialization > And this: > wrkr: undefined; > cannot use before initialization > https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern > > On Aug 3, 2014, at 12:32 PM, J. Ian Johnson wrote: > >> Try it and report back. >> -Ian >> ----- Original Message ----- >> From: "Alexander D. Knauth" >> To: "J. Ian Johnson" >> Cc: "racket users list" >> Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern >> Subject: Re: [racket] getting one macro to tell another macro to define something >> >> >> What if match-define did something like this to store the parsed pat in a syntax-property?: >> >> (define-syntax (match-define stx) >> (syntax-parse stx >> [(_ pat rhs:expr) >> (let ([p (parse-id #'pat)]) >> (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] >> [vars (bound-vars p)]) >> (quasisyntax/loc stx >> (define-values vars (match*/derived (rhs) #,stx >> [(pat) (values . vars)])))))])) >> And parse did something like this: >> >> (define (parse stx) >> (or >> (syntax-property stx ?parsed-pat) >> (let () >> ... >> ))) >> >> >> On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >> >> >> >> On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >> >> >> >> What do you mean? >> Shouldn?t it go something like this: >> (syntax-parameterize ([current-defs (mutable-set)]) >> (match-define (sender x) 1) >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (match-define x3 1) >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (define x3 (match 1 [x3 x3])) >> I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) >> (define-values (x3) (match 1 [(sender x) (values x3)])) >> Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? >> >> >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (define x3 (match 1 [x3 x3])) >> >> (define x x3) >> x) >> >> The match-define form never defines ?x? as anything, but the receiver should, right? >> >> On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >> >> >> >> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. >> >> Do you have a different example that doesn't fail in this way? >> -Ian >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Sun Aug 3 13:50:56 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 13:50:56 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <3EC12BB8-2BDC-4885-98E3-2EDE60CC5A6E@ccs.neu.edu> References: <15782525.602341407083559269.JavaMail.root@zimbra> <628C4DA3-8502-4AE1-9DAA-3D9ED3DD46FD@knauth.org> <3EC12BB8-2BDC-4885-98E3-2EDE60CC5A6E@ccs.neu.edu> Message-ID: <52DD1108-A28E-4117-8199-1AB33EEA3A5F@knauth.org> But I never defined or used those variables. All I did was save the parsed pattern in a syntax-property and have the parse function look at that syntax-property. On Aug 3, 2014, at 1:40 PM, Matthias Felleisen wrote: > > That means you are defining and using recursive variables before the initialization is done. > > > On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: > >> I tried it but got weird errors like this: >> idle-rest: undefined; >> cannot use before initialization >> And this: >> wrkr: undefined; >> cannot use before initialization >> https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern >> >> On Aug 3, 2014, at 12:32 PM, J. Ian Johnson wrote: >> >>> Try it and report back. >>> -Ian >>> ----- Original Message ----- >>> From: "Alexander D. Knauth" >>> To: "J. Ian Johnson" >>> Cc: "racket users list" >>> Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern >>> Subject: Re: [racket] getting one macro to tell another macro to define something >>> >>> >>> What if match-define did something like this to store the parsed pat in a syntax-property?: >>> >>> (define-syntax (match-define stx) >>> (syntax-parse stx >>> [(_ pat rhs:expr) >>> (let ([p (parse-id #'pat)]) >>> (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] >>> [vars (bound-vars p)]) >>> (quasisyntax/loc stx >>> (define-values vars (match*/derived (rhs) #,stx >>> [(pat) (values . vars)])))))])) >>> And parse did something like this: >>> >>> (define (parse stx) >>> (or >>> (syntax-property stx ?parsed-pat) >>> (let () >>> ... >>> ))) >>> >>> >>> On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >>> >>> >>> >>> On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >>> >>> >>> >>> What do you mean? >>> Shouldn?t it go something like this: >>> (syntax-parameterize ([current-defs (mutable-set)]) >>> (match-define (sender x) 1) >>> (reciever) >>> x) >>> ; => >>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>> (match-define x3 1) >>> (reciever) >>> x) >>> ; => >>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>> (define x3 (match 1 [x3 x3])) >>> I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) >>> (define-values (x3) (match 1 [(sender x) (values x3)])) >>> Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? >>> >>> >>> (reciever) >>> x) >>> ; => >>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>> (define x3 (match 1 [x3 x3])) >>> >>> (define x x3) >>> x) >>> >>> The match-define form never defines ?x? as anything, but the receiver should, right? >>> >>> On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >>> >>> >>> >>> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. >>> >>> Do you have a different example that doesn't fail in this way? >>> -Ian >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Sun Aug 3 13:53:49 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 13:53:49 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <52DD1108-A28E-4117-8199-1AB33EEA3A5F@knauth.org> References: <15782525.602341407083559269.JavaMail.root@zimbra> <628C4DA3-8502-4AE1-9DAA-3D9ED3DD46FD@knauth.org> <3EC12BB8-2BDC-4885-98E3-2EDE60CC5A6E@ccs.neu.edu> <52DD1108-A28E-4117-8199-1AB33EEA3A5F@knauth.org> Message-ID: <7BDD55CC-B484-4F7F-8B8D-08384817CEFE@ccs.neu.edu> From where I sit your syntactic abstraction generates code of this shape: ---> (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars ;; <---- This introduces vars ___and___ uses them before the right-hand side is evaluated. -- Matthias On Aug 3, 2014, at 1:50 PM, Alexander D. Knauth wrote: > But I never defined or used those variables. > All I did was save the parsed pattern in a syntax-property and have the parse function look at that syntax-property. > > On Aug 3, 2014, at 1:40 PM, Matthias Felleisen wrote: > >> >> That means you are defining and using recursive variables before the initialization is done. >> >> >> On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: >> >>> I tried it but got weird errors like this: >>> idle-rest: undefined; >>> cannot use before initialization >>> And this: >>> wrkr: undefined; >>> cannot use before initialization >>> https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern >>> >>> On Aug 3, 2014, at 12:32 PM, J. Ian Johnson wrote: >>> >>>> Try it and report back. >>>> -Ian >>>> ----- Original Message ----- >>>> From: "Alexander D. Knauth" >>>> To: "J. Ian Johnson" >>>> Cc: "racket users list" >>>> Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern >>>> Subject: Re: [racket] getting one macro to tell another macro to define something >>>> >>>> >>>> What if match-define did something like this to store the parsed pat in a syntax-property?: >>>> >>>> (define-syntax (match-define stx) >>>> (syntax-parse stx >>>> [(_ pat rhs:expr) >>>> (let ([p (parse-id #'pat)]) >>>> (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] >>>> [vars (bound-vars p)]) >>>> (quasisyntax/loc stx >>>> (define-values vars (match*/derived (rhs) #,stx >>>> [(pat) (values . vars)])))))])) >>>> And parse did something like this: >>>> >>>> (define (parse stx) >>>> (or >>>> (syntax-property stx ?parsed-pat) >>>> (let () >>>> ... >>>> ))) >>>> >>>> >>>> On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >>>> >>>> >>>> >>>> On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >>>> >>>> >>>> >>>> What do you mean? >>>> Shouldn?t it go something like this: >>>> (syntax-parameterize ([current-defs (mutable-set)]) >>>> (match-define (sender x) 1) >>>> (reciever) >>>> x) >>>> ; => >>>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>>> (match-define x3 1) >>>> (reciever) >>>> x) >>>> ; => >>>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>>> (define x3 (match 1 [x3 x3])) >>>> I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) >>>> (define-values (x3) (match 1 [(sender x) (values x3)])) >>>> Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? >>>> >>>> >>>> (reciever) >>>> x) >>>> ; => >>>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>>> (define x3 (match 1 [x3 x3])) >>>> >>>> (define x x3) >>>> x) >>>> >>>> The match-define form never defines ?x? as anything, but the receiver should, right? >>>> >>>> On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >>>> >>>> >>>> >>>> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. >>>> >>>> Do you have a different example that doesn't fail in this way? >>>> -Ian >>>> >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>>> >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Sun Aug 3 13:58:44 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 13:58:44 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <7BDD55CC-B484-4F7F-8B8D-08384817CEFE@ccs.neu.edu> References: <15782525.602341407083559269.JavaMail.root@zimbra> <628C4DA3-8502-4AE1-9DAA-3D9ED3DD46FD@knauth.org> <3EC12BB8-2BDC-4885-98E3-2EDE60CC5A6E@ccs.neu.edu> <52DD1108-A28E-4117-8199-1AB33EEA3A5F@knauth.org> <7BDD55CC-B484-4F7F-8B8D-08384817CEFE@ccs.neu.edu> Message-ID: But it was doing that already with no problem. All I _changed_ was that I added a syntax-property to pat so that it didn?t have to parse it more than once. Why would it work before but not with the syntax-property? On Aug 3, 2014, at 1:53 PM, Matthias Felleisen wrote: > > From where I sit your syntactic abstraction generates code of this shape: > > ---> (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars ;; <---- > > This introduces vars ___and___ uses them before the right-hand side is evaluated. > > -- Matthias > > > > > On Aug 3, 2014, at 1:50 PM, Alexander D. Knauth wrote: > >> But I never defined or used those variables. >> All I did was save the parsed pattern in a syntax-property and have the parse function look at that syntax-property. >> >> On Aug 3, 2014, at 1:40 PM, Matthias Felleisen wrote: >> >>> >>> That means you are defining and using recursive variables before the initialization is done. >>> >>> >>> On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: >>> >>>> I tried it but got weird errors like this: >>>> idle-rest: undefined; >>>> cannot use before initialization >>>> And this: >>>> wrkr: undefined; >>>> cannot use before initialization >>>> https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern >>>> >>>> On Aug 3, 2014, at 12:32 PM, J. Ian Johnson wrote: >>>> >>>>> Try it and report back. >>>>> -Ian >>>>> ----- Original Message ----- >>>>> From: "Alexander D. Knauth" >>>>> To: "J. Ian Johnson" >>>>> Cc: "racket users list" >>>>> Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern >>>>> Subject: Re: [racket] getting one macro to tell another macro to define something >>>>> >>>>> >>>>> What if match-define did something like this to store the parsed pat in a syntax-property?: >>>>> >>>>> (define-syntax (match-define stx) >>>>> (syntax-parse stx >>>>> [(_ pat rhs:expr) >>>>> (let ([p (parse-id #'pat)]) >>>>> (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] >>>>> [vars (bound-vars p)]) >>>>> (quasisyntax/loc stx >>>>> (define-values vars (match*/derived (rhs) #,stx >>>>> [(pat) (values . vars)])))))])) >>>>> And parse did something like this: >>>>> >>>>> (define (parse stx) >>>>> (or >>>>> (syntax-property stx ?parsed-pat) >>>>> (let () >>>>> ... >>>>> ))) >>>>> >>>>> >>>>> On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >>>>> >>>>> >>>>> >>>>> On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >>>>> >>>>> >>>>> >>>>> What do you mean? >>>>> Shouldn?t it go something like this: >>>>> (syntax-parameterize ([current-defs (mutable-set)]) >>>>> (match-define (sender x) 1) >>>>> (reciever) >>>>> x) >>>>> ; => >>>>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>>>> (match-define x3 1) >>>>> (reciever) >>>>> x) >>>>> ; => >>>>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>>>> (define x3 (match 1 [x3 x3])) >>>>> I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) >>>>> (define-values (x3) (match 1 [(sender x) (values x3)])) >>>>> Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? >>>>> >>>>> >>>>> (reciever) >>>>> x) >>>>> ; => >>>>> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >>>>> (define x3 (match 1 [x3 x3])) >>>>> >>>>> (define x x3) >>>>> x) >>>>> >>>>> The match-define form never defines ?x? as anything, but the receiver should, right? >>>>> >>>>> On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >>>>> >>>>> >>>>> >>>>> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. >>>>> >>>>> Do you have a different example that doesn't fail in this way? >>>>> -Ian >>>>> >>>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>>> >>>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>>> >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ianj at ccs.neu.edu Sun Aug 3 13:59:06 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Sun, 3 Aug 2014 13:59:06 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <7BDD55CC-B484-4F7F-8B8D-08384817CEFE@ccs.neu.edu> Message-ID: <17714635.602801407088746591.JavaMail.root@zimbra> This is the problem of not introducing the right marks. He wants (define-values (x) (match blah [x x])) but is getting (define-values (x) (match blah [x-barf x])) Just pre-parsing won't get you all the way. You need to have a way to introduce to x-barf the marks between the outer match-define application and the inner match-expander transformer application. P.S. your match-define/values calls parse-id within the bound-vars call. You want to use the syntax-property there too. -Ian ----- Original Message ----- From: "Matthias Felleisen" To: "Alexander D. Knauth" Cc: "J. Ian Johnson" , "racket users list" Sent: Sunday, August 3, 2014 1:53:49 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something >From where I sit your syntactic abstraction generates code of this shape: ---> (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars ;; <---- This introduces vars ___and___ uses them before the right-hand side is evaluated. -- Matthias On Aug 3, 2014, at 1:50 PM, Alexander D. Knauth wrote: But I never defined or used those variables. All I did was save the parsed pattern in a syntax-property and have the parse function look at that syntax-property. On Aug 3, 2014, at 1:40 PM, Matthias Felleisen < matthias at ccs.neu.edu > wrote: That means you are defining and using recursive variables before the initialization is done. On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: I tried it but got weird errors like this: idle-rest: undefined; cannot use before initialization And this: wrkr: undefined; cannot use before initialization https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern On Aug 3, 2014, at 12:32 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Try it and report back. -Ian ----- Original Message ----- From: "Alexander D. Knauth" < alexander at knauth.org > To: "J. Ian Johnson" < ianj at ccs.neu.edu > Cc: "racket users list" < users at racket-lang.org > Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something What if match-define did something like this to store the parsed pat in a syntax-property?: (define-syntax (match-define stx) (syntax-parse stx [(_ pat rhs:expr) (let ([p (parse-id #'pat)]) (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] [vars (bound-vars p)]) (quasisyntax/loc stx (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars)])))))])) And parse did something like this: (define (parse stx) (or (syntax-property stx ?parsed-pat) (let () ... ))) On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: What do you mean? Shouldn?t it go something like this: (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (match-define x3 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) (define-values (x3) (match 1 [(sender x) (values x3)])) Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) (define x x3) x) The match-define form never defines ?x? as anything, but the receiver should, right? On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. Do you have a different example that doesn't fail in this way? -Ian ____________________ Racket Users list: http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users From alexander at knauth.org Sun Aug 3 14:12:42 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 14:12:42 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <17714635.602801407088746591.JavaMail.root@zimbra> References: <17714635.602801407088746591.JavaMail.root@zimbra> Message-ID: <0C076163-E1D3-4CEB-A359-706005E2933B@knauth.org> Oh. I have no idea what to do then. I can?t even do syntax-local-introduce or (datum->syntax stx (syntax->datum stx)) on it because it?s not a syntax object. On Aug 3, 2014, at 1:59 PM, J. Ian Johnson wrote: > This is the problem of not introducing the right marks. He wants > (define-values (x) (match blah [x x])) > > but is getting > > (define-values (x) (match blah [x-barf x])) > > Just pre-parsing won't get you all the way. You need to have a way to introduce to x-barf the marks between the outer match-define application and the inner match-expander transformer application. > P.S. your match-define/values calls parse-id within the bound-vars call. You want to use the syntax-property there too. > -Ian > ----- Original Message ----- > From: "Matthias Felleisen" > To: "Alexander D. Knauth" > Cc: "J. Ian Johnson" , "racket users list" > Sent: Sunday, August 3, 2014 1:53:49 PM GMT -05:00 US/Canada Eastern > Subject: Re: [racket] getting one macro to tell another macro to define something > > > > > From where I sit your syntactic abstraction generates code of this shape: > > > ---> (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars ;; <---- > > > This introduces vars ___and___ uses them before the right-hand side is evaluated. > > > -- Matthias > > > > > > > > > > On Aug 3, 2014, at 1:50 PM, Alexander D. Knauth wrote: > > > > > But I never defined or used those variables. > All I did was save the parsed pattern in a syntax-property and have the parse function look at that syntax-property. > > > On Aug 3, 2014, at 1:40 PM, Matthias Felleisen < matthias at ccs.neu.edu > wrote: > > > > > > > That means you are defining and using recursive variables before the initialization is done. > > > > > On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: > > > > > I tried it but got weird errors like this: > > idle-rest: undefined; > cannot use before initialization > And this: > > wrkr: undefined; > cannot use before initialization > https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern > > > On Aug 3, 2014, at 12:32 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: > > > Try it and report back. > -Ian > ----- Original Message ----- > From: "Alexander D. Knauth" < alexander at knauth.org > > To: "J. Ian Johnson" < ianj at ccs.neu.edu > > Cc: "racket users list" < users at racket-lang.org > > Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern > Subject: Re: [racket] getting one macro to tell another macro to define something > > > What if match-define did something like this to store the parsed pat in a syntax-property?: > > (define-syntax (match-define stx) > (syntax-parse stx > [(_ pat rhs:expr) > (let ([p (parse-id #'pat)]) > (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] > [vars (bound-vars p)]) > (quasisyntax/loc stx > (define-values vars (match*/derived (rhs) #,stx > [(pat) (values . vars)])))))])) > And parse did something like this: > > (define (parse stx) > (or > (syntax-property stx ?parsed-pat) > (let () > ... > ))) > > > On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: > > > > On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: > > > > What do you mean? > Shouldn?t it go something like this: > (syntax-parameterize ([current-defs (mutable-set)]) > (match-define (sender x) 1) > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (match-define x3 1) > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (define x3 (match 1 [x3 x3])) > I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) > (define-values (x3) (match 1 [(sender x) (values x3)])) > Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? > > > (reciever) > x) > ; => > (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) > (define x3 (match 1 [x3 x3])) > > (define x x3) > x) > > The match-define form never defines ?x? as anything, but the receiver should, right? > > On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: > > > > Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. > > Do you have a different example that doesn't fail in this way? > -Ian > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > From henry.lenzi at gmail.com Sun Aug 3 15:29:10 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Sun, 3 Aug 2014 16:29:10 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> Message-ID: ; Hello all -- ; So here's how I solve all those little problems regarding symbols and evaluation of medication definitions. ; Would you please bear with me? I apologize for the length. ; This is the approach I've taken. I've chosen no to use any macrology or parser/lexer technique because I don't grok them and they ; don't really seem necessary, for reasons explained in the code comments. ; I have not decided to hash tables, for the following reason: there's a part of the code (the drug definitions, the instructions), that ; should be easy enough for non-programmers to edit. If they are kept very simple, it's possible, because the users have to edit those ; files. So, even though it is source code, it's not as intimidating as editing source code if hash tables. ; Another aspect is that I hope modules provided some sort of safety in terms of syntax checking. That is to say, if you used make a ; typo in the medication part of the DSL, the system will (hopefully) bork because no such module exists. I believe this also creates ; an opportunity for "syntax validation" if a proper input phase is designed. But Lisp/Scheme being a dynamic language, the run-time ; will bork immediately once it sees funny things. This is a way to guarantee the DSL is correct, which we get for free by using Racket. ; A fourth aspect is that, if each drug is kept a different module (which I haven't done here, BTW), then we can make for easier ; internationalization, by keeping modules by languages, e.g., hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project too, ; so it's best to design with that in mind. ; Final comment regards "database". We get "database" for free, by registering prescriptions with patient register numbers. The OS ; takes care of pretty musch anything else. And there's no need for atomicity and concurrency. Like I said, this is stupid code. ; ; #lang racket ; code-review-for-racketeers-2014-08-03-a.rkt ; ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea is that the physician ; has two options: 1) he or she opens Notepad and writes the prescription file (Recipe.text); ; 2) or, the software asks for inputs and writes the file (this will not be covered in this ; exercise). The written prescription in the shorthand DSL would look like below, with the ; exception of a first field with patient ID data not included (to be done later). ; The prescription has a rigid syntax would look like this (line breaks included): ; 1- ; hctz25 30 pl 1xd ; ; 2- ; simva20 30 pl 1xn ; Needed for EVAL, used later on (define-namespace-anchor a) ; These definitions should be in a different module. ; This way we get syntax checking for free. ; MED - medication. Includes dosage. (define hctz25 "Hydrochlorothiazide 25mg") (define simva20 "Simvastatin 20mg") ; FORM - whether the patient will take home pills, a tube, a flask, capsules (define pl "pills") ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 pills 2x a day, etc. (define 1xd "Take 1 pill P.O. 1x/day") (define 1xn "Take 1 pill P.O. 1x at night") ; INSTs - special instructions. INST is just a prefix INST+MED without the dosage. (define INSTOMZ "half an hour before breakfast, with a glass of water") ; Formatters - simple for now, but should be a function of the space available. (define line "-----------") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The main part of a prescription DSL is pretty rigid in syntax, being composed of blocks of theses parts: ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. ; Please note that, in this DSL, the MED part includes the drug dosage (e.g., HCTZ25, where ; the HCTZ designates the drug, and the 25 the dosage). ; An example would be: ; HCTZ25 30 PL 1XD ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills ; Take 1 pill P.O. 1X day ; INST are special instructions. They basically are more detailed explanation to the patient about ; how to use the medication properly. Not always there's a INST in the prescription DSL. ; INSTs are, in fact, a PREFIX for the MED without the dose. For example, OMZ20 is Omeprazol 20mg. ; The instruction for OMZ would be INSTOMZ ("half an hour before breakfast, with a glass of water"). ; In this case, the DSL line would be: ; OMZ20 30 PL 1XD INSTOMZ ; meaning: Omeprazol 20mg ------------------- 30 pills ; Take 1 pill P.O. 1X day ; half an hour before breakfast, with ; a glass of water ; Questions regarding proper formatting of INST are not addressed at this moment. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Now follows a description of some problems I encountered and the choices made in solving them: ; (define in (open-input-file "Recipe.txt")) ; If you just (string-split (read-line in)) you'll get: ; => '("hctz25" "30" "cp" "1xd") ; and that will not evaluate the symbols to their string descritptions. ; Because of that, you need to do a: ; > (map string->symbol (string-split (read-line in))) ; which will evaluate to ; => '(hctz25 |30| cp 1xd) ; This would be ideal to MAP EVAL to, but the problem is the |30| ; So, the idea is SET!ing that list to a name we can call easily, i.e., ; med-line-holder, because then we can extract the pieces (since we can't do list ; surgery easily, such a "replace the the element at position 1 with so-and-so element"). ; Since the prescription syntax is pretty rigid, we can get away with this ; simple approach. (define med-line-holder '()) ; initial value of med-line-holder is an empty list (define med-name-holder '()) (define med-quant-holder '()) (define med-form-holder '()) (define med-pos-holder '()) (define med-inst-holder '()) ; remember, not always INSTructions happen in a DSL prescription . (define in (open-input-file "Recipe.txt")) (port-count-lines! in) (define (clpr) (close-input-port in)) ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) ; This is obtained from a plain text file. When it is read, it becomes something ; like this: '(hctz25 |30| cp 1xd) (define (set-med-line-holder) (set! med-line-holder (map string->symbol (string-split (read-line in))))) (define (set-med-name-holder) ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL (set! med-name-holder (eval (car med-line-holder) (namespace-anchor->namespace a)))) (define (set-med-quant-holder) ; the CADR of the med-line-holder ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) (namespace-anchor->namespace a)))) (define (set-med-form-holder) ; the CADDR of the med-line-holder - gets the FORM, e.g., pills, etc. ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) (set! med-form-holder (eval (caddr med-line-holder) (namespace-anchor->namespace a)))) (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - gets the POS, e.g., 1xd ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) (set! med-pos-holder (eval (cadddr med-line-holder) (namespace-anchor->namespace a)))) (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) (set! med-pos-holder (eval (last med-line-holder) (namespace-anchor->namespace a)))) ; One problem here regards the optional INST instructions. ; How to create a SETter function that will only SET! med-inst-holder ; if there's an INST instruction? Note that INST is a prefix. A real instruction is, e.g., ; INSTOMZ (for OMZ20). (define (look-for-line) (if (regexp-match #px"\\d\\-" (read-line in)) (begin (set-med-line-holder) (set-med-name-holder) (set-med-quant-holder) (set-med-form-holder) (set-med-pos-holder)) 'NO-LINE)) (define (display-stuff) (newline) (display med-line-holder) (newline) (display med-name-holder) (newline) (display med-quant-holder) (newline) (display med-form-holder) (newline) (display med-pos-holder) (newline)) ; The problem remains of what to do with the eventual INST. ; Successive calls to (look-for-line) would read the next lines. ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, ; if it hits a line with no text in Recipe.txt (look-for-line) ;(display-stuff) (define (output-a-line) (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" med-pos-holder "\n"))) (define (format-a-line) (display (output-a-line))) ;(define (output-a-line) ; (display (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" ; med-pos-holder "\n")))) (newline) ;(output-a-line) (format-a-line) ; PROBLEMS ; 1) How do we find out how many lines to (look-for-line)? ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not ; only it makes for easy visual understanding, but it may be used to provide a hint ; for this problem. ; Possible approaches: ; - Maybe this can be solved with REGEXPS? This information could provide a sentinel ; variable for an iterator function? ; - Is there some sort if line counting function? (Note that I have set ; (port-count-lines! in) somewhere above in the code. ; 2) How do we know we've reached the end of the file? ; 3) How to deal with the not-always-present INST? ; - How do we check for INSTs? With a REGEXP? ; - Choosing between INSTs with REGEXPS is not necessary, as they will be loaded in a module, ; so the system will "know" which one to choose. ; 4) Another idea would be "slurp" the whole of the prescription, and then deal with evaluation. How? ; (define f1 ; (file->string ; "C:\\Path\\to\\sources\\Recipe.txt")) ;> (string-normalize-spaces f1) ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" ; ; That's all for now, folks! ; Many thanks for all the help so far, Racketeers! ; Cheers, ; Henry Lenzi On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: > Hello everyone - > > First of all, a big Thank You to all of you and for taking the time for > responding. > > I'll have to set aside sometime during this weekend to see if I can > understand the ideas you've been so kind to offer. > > However, I should confess that I've made some progress with way simpler > stuff which I hope to post later on. Like I've said, this is stupid > software. Anyways, none of this is final. > > It really just used a plain text solution, since the format if a recipe is > so rigid. The question of expanding the symbols from files to run-time was > easier than I thought. > > The idea of using modules might have the nice collateral effect if some sort > of primitive type (or syntax) checking for free. I like the idea someone > offered of using modules for medication definitions. Actually, one module > per definition makes it very easy for future users to add new medications. > The ease of syntax is important because it allows for the customization by > non-sophisticated users (physicians, nurses). > > Cheers, > Henry Lenzi. From henry.lenzi at gmail.com Sun Aug 3 15:30:00 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Sun, 3 Aug 2014 16:30:00 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> Message-ID: Uh oh, the GOOG botched formatting. Sorry about that! On Sun, Aug 3, 2014 at 4:29 PM, Henry Lenzi wrote: > ; Hello all -- > ; So here's how I solve all those little problems regarding symbols > and evaluation of medication definitions. > ; Would you please bear with me? I apologize for the length. > ; This is the approach I've taken. I've chosen no to use any macrology > or parser/lexer technique because I don't grok them and they > ; don't really seem necessary, for reasons explained in the code comments. > ; I have not decided to hash tables, for the following reason: there's > a part of the code (the drug definitions, the instructions), that > ; should be easy enough for non-programmers to edit. If they are kept > very simple, it's possible, because the users have to edit those > ; files. So, even though it is source code, it's not as intimidating > as editing source code if hash tables. > ; Another aspect is that I hope modules provided some sort of safety > in terms of syntax checking. That is to say, if you used make a > ; typo in the medication part of the DSL, the system will (hopefully) > bork because no such module exists. I believe this also creates > ; an opportunity for "syntax validation" if a proper input phase is > designed. But Lisp/Scheme being a dynamic language, the run-time > ; will bork immediately once it sees funny things. This is a way to > guarantee the DSL is correct, which we get for free by using Racket. > ; A fourth aspect is that, if each drug is kept a different module > (which I haven't done here, BTW), then we can make for easier > ; internationalization, by keeping modules by languages, e.g., > hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project > too, > ; so it's best to design with that in mind. > ; Final comment regards "database". We get "database" for free, by > registering prescriptions with patient register numbers. The OS > ; takes care of pretty musch anything else. And there's no need for > atomicity and concurrency. Like I said, this is stupid code. > ; > ; > #lang racket > > ; code-review-for-racketeers-2014-08-03-a.rkt > ; > ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea > is that the physician > ; has two options: 1) he or she opens Notepad and writes the > prescription file (Recipe.text); > ; 2) or, the software asks for inputs and writes the file (this will > not be covered in this > ; exercise). The written prescription in the shorthand DSL would look > like below, with the > ; exception of a first field with patient ID data not included (to be > done later). > ; The prescription has a rigid syntax would look like this (line > breaks included): > ; 1- > ; hctz25 30 pl 1xd > ; > ; 2- > ; simva20 30 pl 1xn > > > ; Needed for EVAL, used later on > (define-namespace-anchor a) > > ; These definitions should be in a different module. > ; This way we get syntax checking for free. > ; MED - medication. Includes dosage. > (define hctz25 "Hydrochlorothiazide 25mg") > (define simva20 "Simvastatin 20mg") > ; FORM - whether the patient will take home pills, a tube, a flask, capsules > (define pl "pills") > ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 > pills 2x a day, etc. > (define 1xd "Take 1 pill P.O. 1x/day") > (define 1xn "Take 1 pill P.O. 1x at night") > ; INSTs - special instructions. INST is just a prefix INST+MED without > the dosage. > (define INSTOMZ "half an hour before breakfast, with a glass of water") > ; Formatters - simple for now, but should be a function of the space available. > (define line "-----------") > > > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ; The main part of a prescription DSL is pretty rigid in syntax, being > composed of blocks of theses parts: > ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. > ; Please note that, in this DSL, the MED part includes the drug dosage > (e.g., HCTZ25, where > ; the HCTZ designates the drug, and the 25 the dosage). > ; An example would be: > ; HCTZ25 30 PL 1XD > ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills > ; Take 1 pill P.O. 1X day > ; INST are special instructions. They basically are more detailed > explanation to the patient about > ; how to use the medication properly. Not always there's a INST in the > prescription DSL. > ; INSTs are, in fact, a PREFIX for the MED without the dose. For > example, OMZ20 is Omeprazol 20mg. > ; The instruction for OMZ would be INSTOMZ ("half an hour before > breakfast, with a glass of water"). > ; In this case, the DSL line would be: > ; OMZ20 30 PL 1XD INSTOMZ > ; meaning: Omeprazol 20mg ------------------- 30 pills > ; Take 1 pill P.O. 1X day > ; half an hour before breakfast, with > ; a glass of water > ; Questions regarding proper formatting of INST are not addressed at > this moment. > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ; Now follows a description of some problems I encountered and the > choices made in solving them: > ; (define in (open-input-file "Recipe.txt")) > ; If you just (string-split (read-line in)) you'll get: > ; => '("hctz25" "30" "cp" "1xd") > ; and that will not evaluate the symbols to their string descritptions. > ; Because of that, you need to do a: > ; > (map string->symbol (string-split (read-line in))) > ; which will evaluate to > ; => '(hctz25 |30| cp 1xd) > ; This would be ideal to MAP EVAL to, but the problem is the |30| > ; So, the idea is SET!ing that list to a name we can call easily, i.e., > ; med-line-holder, because then we can extract the pieces (since we > can't do list > ; surgery easily, such a "replace the the element at position 1 with > so-and-so element"). > ; Since the prescription syntax is pretty rigid, we can get away with this > ; simple approach. > > (define med-line-holder '()) ; initial value of med-line-holder is an empty list > (define med-name-holder '()) > (define med-quant-holder '()) > (define med-form-holder '()) > (define med-pos-holder '()) > (define med-inst-holder '()) ; remember, not always INSTructions > happen in a DSL prescription . > > (define in (open-input-file "Recipe.txt")) > (port-count-lines! in) > (define (clpr) (close-input-port in)) > > ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) > ; This is obtained from a plain text file. When it is read, it becomes something > ; like this: '(hctz25 |30| cp 1xd) > (define (set-med-line-holder) > (set! med-line-holder (map string->symbol (string-split (read-line in))))) > > (define (set-med-name-holder) > ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL > (set! med-name-holder (eval (car med-line-holder) > (namespace-anchor->namespace a)))) > > (define (set-med-quant-holder) ; the CADR of the med-line-holder > ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) > (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) > (namespace-anchor->namespace a)))) > > (define (set-med-form-holder) ; the CADDR of the med-line-holder - > gets the FORM, e.g., pills, etc. > ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) > (set! med-form-holder (eval (caddr med-line-holder) > (namespace-anchor->namespace a)))) > > (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - > gets the POS, e.g., 1xd > ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) > (set! med-pos-holder (eval (cadddr med-line-holder) > (namespace-anchor->namespace a)))) > > > (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST > ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) > (set! med-pos-holder (eval (last med-line-holder) > (namespace-anchor->namespace a)))) > > ; One problem here regards the optional INST instructions. > ; How to create a SETter function that will only SET! med-inst-holder > ; if there's an INST instruction? Note that INST is a prefix. A real > instruction is, e.g., > ; INSTOMZ (for OMZ20). > (define (look-for-line) > (if (regexp-match #px"\\d\\-" (read-line in)) > (begin > (set-med-line-holder) > (set-med-name-holder) > (set-med-quant-holder) > (set-med-form-holder) > (set-med-pos-holder)) > 'NO-LINE)) > > (define (display-stuff) > (newline) > (display med-line-holder) (newline) > (display med-name-holder) (newline) > (display med-quant-holder) (newline) > (display med-form-holder) (newline) > (display med-pos-holder) (newline)) > ; The problem remains of what to do with the eventual INST. > > > ; Successive calls to (look-for-line) would read the next lines. > ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, > ; if it hits a line with no text in Recipe.txt > (look-for-line) > ;(display-stuff) > > > (define (output-a-line) > (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" > med-pos-holder "\n"))) > > (define (format-a-line) > (display (output-a-line))) > > ;(define (output-a-line) > ; (display (string-join (list med-name-holder line med-quant-holder > med-form-holder "\n" > ; med-pos-holder "\n")))) > (newline) > ;(output-a-line) > > (format-a-line) > > > > ; PROBLEMS > ; 1) How do we find out how many lines to (look-for-line)? > ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not > ; only it makes for easy visual understanding, but it may be used > to provide a hint > ; for this problem. > ; Possible approaches: > ; - Maybe this can be solved with REGEXPS? This information could > provide a sentinel > ; variable for an iterator function? > ; - Is there some sort if line counting function? (Note that I have set > ; (port-count-lines! in) somewhere above in the code. > ; 2) How do we know we've reached the end of the file? > ; 3) How to deal with the not-always-present INST? > ; - How do we check for INSTs? With a REGEXP? > ; - Choosing between INSTs with REGEXPS is not necessary, as they > will be loaded in a module, > ; so the system will "know" which one to choose. > ; 4) Another idea would be "slurp" the whole of the prescription, and > then deal with evaluation. How? > ; (define f1 > ; (file->string > ; "C:\\Path\\to\\sources\\Recipe.txt")) > ;> (string-normalize-spaces f1) > ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" > ; > ; That's all for now, folks! > ; Many thanks for all the help so far, Racketeers! > ; Cheers, > ; Henry Lenzi > > > > > On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >> Hello everyone - >> >> First of all, a big Thank You to all of you and for taking the time for >> responding. >> >> I'll have to set aside sometime during this weekend to see if I can >> understand the ideas you've been so kind to offer. >> >> However, I should confess that I've made some progress with way simpler >> stuff which I hope to post later on. Like I've said, this is stupid >> software. Anyways, none of this is final. >> >> It really just used a plain text solution, since the format if a recipe is >> so rigid. The question of expanding the symbols from files to run-time was >> easier than I thought. >> >> The idea of using modules might have the nice collateral effect if some sort >> of primitive type (or syntax) checking for free. I like the idea someone >> offered of using modules for medication definitions. Actually, one module >> per definition makes it very easy for future users to add new medications. >> The ease of syntax is important because it allows for the customization by >> non-sophisticated users (physicians, nurses). >> >> Cheers, >> Henry Lenzi. From henry.lenzi at gmail.com Sun Aug 3 15:40:42 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Sun, 3 Aug 2014 16:40:42 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> Message-ID: It's best if I use pasteracket ("Hank's medication thingy") http://pasterack.org/pastes/14535 -- Henry Lenzi On Sun, Aug 3, 2014 at 4:30 PM, Henry Lenzi wrote: > Uh oh, the GOOG botched formatting. Sorry about that! > > On Sun, Aug 3, 2014 at 4:29 PM, Henry Lenzi wrote: >> ; Hello all -- >> ; So here's how I solve all those little problems regarding symbols >> and evaluation of medication definitions. >> ; Would you please bear with me? I apologize for the length. >> ; This is the approach I've taken. I've chosen no to use any macrology >> or parser/lexer technique because I don't grok them and they >> ; don't really seem necessary, for reasons explained in the code comments. >> ; I have not decided to hash tables, for the following reason: there's >> a part of the code (the drug definitions, the instructions), that >> ; should be easy enough for non-programmers to edit. If they are kept >> very simple, it's possible, because the users have to edit those >> ; files. So, even though it is source code, it's not as intimidating >> as editing source code if hash tables. >> ; Another aspect is that I hope modules provided some sort of safety >> in terms of syntax checking. That is to say, if you used make a >> ; typo in the medication part of the DSL, the system will (hopefully) >> bork because no such module exists. I believe this also creates >> ; an opportunity for "syntax validation" if a proper input phase is >> designed. But Lisp/Scheme being a dynamic language, the run-time >> ; will bork immediately once it sees funny things. This is a way to >> guarantee the DSL is correct, which we get for free by using Racket. >> ; A fourth aspect is that, if each drug is kept a different module >> (which I haven't done here, BTW), then we can make for easier >> ; internationalization, by keeping modules by languages, e.g., >> hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project >> too, >> ; so it's best to design with that in mind. >> ; Final comment regards "database". We get "database" for free, by >> registering prescriptions with patient register numbers. The OS >> ; takes care of pretty musch anything else. And there's no need for >> atomicity and concurrency. Like I said, this is stupid code. >> ; >> ; >> #lang racket >> >> ; code-review-for-racketeers-2014-08-03-a.rkt >> ; >> ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea >> is that the physician >> ; has two options: 1) he or she opens Notepad and writes the >> prescription file (Recipe.text); >> ; 2) or, the software asks for inputs and writes the file (this will >> not be covered in this >> ; exercise). The written prescription in the shorthand DSL would look >> like below, with the >> ; exception of a first field with patient ID data not included (to be >> done later). >> ; The prescription has a rigid syntax would look like this (line >> breaks included): >> ; 1- >> ; hctz25 30 pl 1xd >> ; >> ; 2- >> ; simva20 30 pl 1xn >> >> >> ; Needed for EVAL, used later on >> (define-namespace-anchor a) >> >> ; These definitions should be in a different module. >> ; This way we get syntax checking for free. >> ; MED - medication. Includes dosage. >> (define hctz25 "Hydrochlorothiazide 25mg") >> (define simva20 "Simvastatin 20mg") >> ; FORM - whether the patient will take home pills, a tube, a flask, capsules >> (define pl "pills") >> ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 >> pills 2x a day, etc. >> (define 1xd "Take 1 pill P.O. 1x/day") >> (define 1xn "Take 1 pill P.O. 1x at night") >> ; INSTs - special instructions. INST is just a prefix INST+MED without >> the dosage. >> (define INSTOMZ "half an hour before breakfast, with a glass of water") >> ; Formatters - simple for now, but should be a function of the space available. >> (define line "-----------") >> >> >> >> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >> ; The main part of a prescription DSL is pretty rigid in syntax, being >> composed of blocks of theses parts: >> ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. >> ; Please note that, in this DSL, the MED part includes the drug dosage >> (e.g., HCTZ25, where >> ; the HCTZ designates the drug, and the 25 the dosage). >> ; An example would be: >> ; HCTZ25 30 PL 1XD >> ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills >> ; Take 1 pill P.O. 1X day >> ; INST are special instructions. They basically are more detailed >> explanation to the patient about >> ; how to use the medication properly. Not always there's a INST in the >> prescription DSL. >> ; INSTs are, in fact, a PREFIX for the MED without the dose. For >> example, OMZ20 is Omeprazol 20mg. >> ; The instruction for OMZ would be INSTOMZ ("half an hour before >> breakfast, with a glass of water"). >> ; In this case, the DSL line would be: >> ; OMZ20 30 PL 1XD INSTOMZ >> ; meaning: Omeprazol 20mg ------------------- 30 pills >> ; Take 1 pill P.O. 1X day >> ; half an hour before breakfast, with >> ; a glass of water >> ; Questions regarding proper formatting of INST are not addressed at >> this moment. >> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >> ; Now follows a description of some problems I encountered and the >> choices made in solving them: >> ; (define in (open-input-file "Recipe.txt")) >> ; If you just (string-split (read-line in)) you'll get: >> ; => '("hctz25" "30" "cp" "1xd") >> ; and that will not evaluate the symbols to their string descritptions. >> ; Because of that, you need to do a: >> ; > (map string->symbol (string-split (read-line in))) >> ; which will evaluate to >> ; => '(hctz25 |30| cp 1xd) >> ; This would be ideal to MAP EVAL to, but the problem is the |30| >> ; So, the idea is SET!ing that list to a name we can call easily, i.e., >> ; med-line-holder, because then we can extract the pieces (since we >> can't do list >> ; surgery easily, such a "replace the the element at position 1 with >> so-and-so element"). >> ; Since the prescription syntax is pretty rigid, we can get away with this >> ; simple approach. >> >> (define med-line-holder '()) ; initial value of med-line-holder is an empty list >> (define med-name-holder '()) >> (define med-quant-holder '()) >> (define med-form-holder '()) >> (define med-pos-holder '()) >> (define med-inst-holder '()) ; remember, not always INSTructions >> happen in a DSL prescription . >> >> (define in (open-input-file "Recipe.txt")) >> (port-count-lines! in) >> (define (clpr) (close-input-port in)) >> >> ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) >> ; This is obtained from a plain text file. When it is read, it becomes something >> ; like this: '(hctz25 |30| cp 1xd) >> (define (set-med-line-holder) >> (set! med-line-holder (map string->symbol (string-split (read-line in))))) >> >> (define (set-med-name-holder) >> ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL >> (set! med-name-holder (eval (car med-line-holder) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-quant-holder) ; the CADR of the med-line-holder >> ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) >> (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-form-holder) ; the CADDR of the med-line-holder - >> gets the FORM, e.g., pills, etc. >> ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) >> (set! med-form-holder (eval (caddr med-line-holder) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - >> gets the POS, e.g., 1xd >> ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) >> (set! med-pos-holder (eval (cadddr med-line-holder) >> (namespace-anchor->namespace a)))) >> >> >> (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST >> ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) >> (set! med-pos-holder (eval (last med-line-holder) >> (namespace-anchor->namespace a)))) >> >> ; One problem here regards the optional INST instructions. >> ; How to create a SETter function that will only SET! med-inst-holder >> ; if there's an INST instruction? Note that INST is a prefix. A real >> instruction is, e.g., >> ; INSTOMZ (for OMZ20). >> (define (look-for-line) >> (if (regexp-match #px"\\d\\-" (read-line in)) >> (begin >> (set-med-line-holder) >> (set-med-name-holder) >> (set-med-quant-holder) >> (set-med-form-holder) >> (set-med-pos-holder)) >> 'NO-LINE)) >> >> (define (display-stuff) >> (newline) >> (display med-line-holder) (newline) >> (display med-name-holder) (newline) >> (display med-quant-holder) (newline) >> (display med-form-holder) (newline) >> (display med-pos-holder) (newline)) >> ; The problem remains of what to do with the eventual INST. >> >> >> ; Successive calls to (look-for-line) would read the next lines. >> ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, >> ; if it hits a line with no text in Recipe.txt >> (look-for-line) >> ;(display-stuff) >> >> >> (define (output-a-line) >> (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" >> med-pos-holder "\n"))) >> >> (define (format-a-line) >> (display (output-a-line))) >> >> ;(define (output-a-line) >> ; (display (string-join (list med-name-holder line med-quant-holder >> med-form-holder "\n" >> ; med-pos-holder "\n")))) >> (newline) >> ;(output-a-line) >> >> (format-a-line) >> >> >> >> ; PROBLEMS >> ; 1) How do we find out how many lines to (look-for-line)? >> ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not >> ; only it makes for easy visual understanding, but it may be used >> to provide a hint >> ; for this problem. >> ; Possible approaches: >> ; - Maybe this can be solved with REGEXPS? This information could >> provide a sentinel >> ; variable for an iterator function? >> ; - Is there some sort if line counting function? (Note that I have set >> ; (port-count-lines! in) somewhere above in the code. >> ; 2) How do we know we've reached the end of the file? >> ; 3) How to deal with the not-always-present INST? >> ; - How do we check for INSTs? With a REGEXP? >> ; - Choosing between INSTs with REGEXPS is not necessary, as they >> will be loaded in a module, >> ; so the system will "know" which one to choose. >> ; 4) Another idea would be "slurp" the whole of the prescription, and >> then deal with evaluation. How? >> ; (define f1 >> ; (file->string >> ; "C:\\Path\\to\\sources\\Recipe.txt")) >> ;> (string-normalize-spaces f1) >> ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" >> ; >> ; That's all for now, folks! >> ; Many thanks for all the help so far, Racketeers! >> ; Cheers, >> ; Henry Lenzi >> >> >> >> >> On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >>> Hello everyone - >>> >>> First of all, a big Thank You to all of you and for taking the time for >>> responding. >>> >>> I'll have to set aside sometime during this weekend to see if I can >>> understand the ideas you've been so kind to offer. >>> >>> However, I should confess that I've made some progress with way simpler >>> stuff which I hope to post later on. Like I've said, this is stupid >>> software. Anyways, none of this is final. >>> >>> It really just used a plain text solution, since the format if a recipe is >>> so rigid. The question of expanding the symbols from files to run-time was >>> easier than I thought. >>> >>> The idea of using modules might have the nice collateral effect if some sort >>> of primitive type (or syntax) checking for free. I like the idea someone >>> offered of using modules for medication definitions. Actually, one module >>> per definition makes it very easy for future users to add new medications. >>> The ease of syntax is important because it allows for the customization by >>> non-sophisticated users (physicians, nurses). >>> >>> Cheers, >>> Henry Lenzi. From gustavo at oma.org.ar Sun Aug 3 16:17:31 2014 From: gustavo at oma.org.ar (Gustavo Massaccesi) Date: Sun, 3 Aug 2014 17:17:31 -0300 Subject: [racket] Destructors in Racket In-Reply-To: <53DD287E.7010904@sibmail.com> References: <1406974366.781553260@f94.i.mail.ru> <53DD0814.70700@sibmail.com> <1406999634.495192056@f413.i.mail.ru> <53DD287E.7010904@sibmail.com> Message-ID: The difference is that every time that (list 1 2 3) is executed, you get a new different list. But with each '(1 2 3) you get every time the same list. The '(1 2 3) is referenced from the "source code" so it will not be collected. (A different copy of '(1 2 3) creates a different list, but always the same list.) Gustavo ;--- #lang racket/base (define (get-list-123) (list 1 2 3)) (define (get-quote-123) '(1 2 3)) (define (get-quote-bis-123) '(1 2 3)) (eq? (get-list-123) (get-list-123)) ;==> #f (eq? (get-quote-123) (get-quote-123)) ;==> #t (eq? (get-list-123) (get-quote-123)) ;==> #f (equal? (get-list-123) (get-quote-123)) ;==> #t (eq? (get-quote-123) (get-quote-bis-123)) ;==> #f (equal? (get-quote-123) (get-quote-bis-123)) ;==> #t ;--- On Sat, Aug 2, 2014 at 3:05 PM, Evgeny Odegov wrote: > Well, it turns out that objects like #(1 2 3) or '(1 2 3) > are not collected (optimizations?), but (vector 1 2 3) and > (list 1 2 3) are collected normally. It so happens that I tried #(1 2 3) > and '(1 2 3) first and came to the wrong conclusions :) > > > > >> > But in case of another kind of value >> >> What another kiind? Small numbers and some chars are not garbage >> collected. >> >> >> Sat, 02 Aug 2014 22:47:32 +0700 ?? Evgeny Odegov : >>> >>> In the example, the value is box and triggering occurs almost >>> immediately after set!. >>> But in case of another kind of value, triggering doesn't occur or take >>> much longer. >>> Why? (Or maybe I do something wrong?) >>> >>>> Probably you want to do something like this, I guess. It creates a >>>> single thread that just waits until anything registered with >>>> an-executor is garbage and then runs the executors. They will run >>>> asynchronously, but perhaps that's okay for your usecase. >>>> >>>> Robby >>>> >>>> #lang racket >>>> (define an-executor (make-will-executor)) >>>> (void >>>> (thread >>>> (? () >>>> (let loop () >>>> (will-execute an-executor) >>>> (loop))))) >>>> >>>> (define a-box (box #f)) >>>> (will-register an-executor >>>> a-box >>>> (? (x) (printf "a-box is now garbage\n"))) >>>> (collect-garbage) (collect-garbage) (collect-garbage) >>>> (printf "breaking the link\n") >>>> (set! a-box #f) >>>> (collect-garbage) (collect-garbage) (collect-garbage) >>>> >>>> On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov < kalimehtar at mail.ru > >>>> wrote: >>>>> >>>>> So I can write >>>>> >>>>> (define (make-obj stream) >>>>> (define res (obj (open-output-file "out.dat"))) >>>>> (define will (make-will-executor)) >>>>> (will-register will res (lambda (x) (close-output-port (obj-file >>>>> x)))) >>>>> (thread (lambda () (let loop () (will-try-execute will) (sleep 1) >>>>> (loop))))) >>>>> >>>>> to make my objects? Additional threads don't hinder performance, do >>>>> they? >>>>> >>>>> Or should I somehow figure out if the thread is already running, don't >>>>> run >>>>> it and use common `will' for all objects? >>>>> >>>>> Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler >>>>> < robby at eecs.northwestern.edu >: >>>>> >>>>> One way is to set up a separate thread to do that. >>>>> >>>>> The reason they are not called automatically is sometimes running the >>>>> procedure passed to will-register needs to access some shared state >>>>> and so your program must be allowed to be in control of the timing of >>>>> the executor. >>>>> >>>>> In this case, it sounds like you can run the executor at any time, so >>>>> just creating a thread to close the port inside my-obj should work >>>>> fine. >>>>> >>>>> Robby >>>>> >>>>> >>>>> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov < kalimehtar at mail.ru > >>>>> wrote: >>>>>> >>>>>> Then how? >>>>>> >>>>>> Suppose I have >>>>>> (struct obj (file)) >>>>>> (define my-obj (obj (open-output-file "out.dat"))) >>>>>> >>>>>> What I have to write to close the file, when my-obj will be GC'ed? >>>>>> >>>>>> I can write >>>>>> (define will (make-will-executor)) >>>>>> (will-register will my-obj (lambda (x) (close-output-port (obj-file >>>>>> x)))) >>>>>> >>>>>> But as far as I understand, it will not be called until `will-execute' >>>>>> or >>>>>> `will-try-execute' will be manually called? >>>>>> >>>>>> Then how to call will-try-execute when GC is collecting my-obj? >>>>>> >>>>>> >>>>>> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt < mflatt at cs.utah.edu >>>>>> >: >>>>>> >>>>>> No, use the safe "will executors" API, instead. >>>>>> >>>>>> The unsafe finalizer API is for low-level, atomic finalization. >>>>>> Closing a >>>>>> port can flush buffers and more, and it's not a good idea to do that >>>>>> in an >>>>>> unsafe atomic context. >>>>>> >>>>>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > >>>>>>> wrote: >>>>>>> >>>>>>> I have a structure, that has a filestream inside it. File have to be >>>>>>> cosed, when the structure is not used anymore (so gargbage >>>>>>> collected). >>>>>>> >>>>>>> Is the best way to do >>>>>>> (require ffi/unsafe) >>>>>>> (register-finalizer my-obj >>>>>>> (lambda (x) (close-output-port (obj-file x)))) >>>>>>> >>>>>>> ? >>>>>>> >>>>>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my >>>>>>> program actually doesn't use FFI? >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Roman Klochkov >>>>>>> ____________________ >>>>>>> Racket Users list: >>>>>>> http://lists.racket-lang.org/users >>>>>> >>>>>> >>>>>> -- >>>>>> Roman Klochkov >>>>>> >>>>>> ____________________ >>>>>> Racket Users list: >>>>>> http://lists.racket-lang.org/users >>>>>> >>>>> >>>>> -- >>>>> Roman Klochkov >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >> > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From alexander at knauth.org Sun Aug 3 16:29:27 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 16:29:27 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> Message-ID: <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> On Aug 3, 2014, at 3:29 PM, Henry Lenzi wrote: > ; Hello all -- > ; So here's how I solve all those little problems regarding symbols > and evaluation of medication definitions. > ; Would you please bear with me? I apologize for the length. > ; This is the approach I've taken. I've chosen no to use any macrology > or parser/lexer technique because I don't grok them and they > ; don't really seem necessary, for reasons explained in the code comments. > ; I have not decided to hash tables, for the following reason: there's > a part of the code (the drug definitions, the instructions), that > ; should be easy enough for non-programmers to edit. If they are kept > very simple, it's possible, because the users have to edit those > ; files. So, even though it is source code, it's not as intimidating > as editing source code if hash tables. > ; Another aspect is that I hope modules provided some sort of safety > in terms of syntax checking. That is to say, if you used make a > ; typo in the medication part of the DSL, the system will (hopefully) > bork because no such module exists. I believe this also creates > ; an opportunity for "syntax validation" if a proper input phase is > designed. But Lisp/Scheme being a dynamic language, the run-time > ; will bork immediately once it sees funny things. This is a way to > guarantee the DSL is correct, which we get for free by using Racket. > ; A fourth aspect is that, if each drug is kept a different module > (which I haven't done here, BTW), then we can make for easier > ; internationalization, by keeping modules by languages, e.g., > hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project > too, > ; so it's best to design with that in mind. > ; Final comment regards "database". We get "database" for free, by > registering prescriptions with patient register numbers. The OS > ; takes care of pretty musch anything else. And there's no need for > atomicity and concurrency. Like I said, this is stupid code. > ; > ; > #lang racket > > ; code-review-for-racketeers-2014-08-03-a.rkt > ; > ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea > is that the physician > ; has two options: 1) he or she opens Notepad and writes the > prescription file (Recipe.text); > ; 2) or, the software asks for inputs and writes the file (this will > not be covered in this > ; exercise). The written prescription in the shorthand DSL would look > like below, with the > ; exception of a first field with patient ID data not included (to be > done later). > ; The prescription has a rigid syntax would look like this (line > breaks included): > ; 1- > ; hctz25 30 pl 1xd > ; > ; 2- > ; simva20 30 pl 1xn > > > ; Needed for EVAL, used later on > (define-namespace-anchor a) > > ; These definitions should be in a different module. > ; This way we get syntax checking for free. > ; MED - medication. Includes dosage. > (define hctz25 "Hydrochlorothiazide 25mg") > (define simva20 "Simvastatin 20mg") > ; FORM - whether the patient will take home pills, a tube, a flask, capsules > (define pl "pills") > ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 > pills 2x a day, etc. > (define 1xd "Take 1 pill P.O. 1x/day") > (define 1xn "Take 1 pill P.O. 1x at night") > ; INSTs - special instructions. INST is just a prefix INST+MED without > the dosage. > (define INSTOMZ "half an hour before breakfast, with a glass of water") > ; Formatters - simple for now, but should be a function of the space available. > (define line "-----------") > > > > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ; The main part of a prescription DSL is pretty rigid in syntax, being > composed of blocks of theses parts: > ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. > ; Please note that, in this DSL, the MED part includes the drug dosage > (e.g., HCTZ25, where > ; the HCTZ designates the drug, and the 25 the dosage). > ; An example would be: > ; HCTZ25 30 PL 1XD > ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills > ; Take 1 pill P.O. 1X day > ; INST are special instructions. They basically are more detailed > explanation to the patient about > ; how to use the medication properly. Not always there's a INST in the > prescription DSL. > ; INSTs are, in fact, a PREFIX for the MED without the dose. For > example, OMZ20 is Omeprazol 20mg. > ; The instruction for OMZ would be INSTOMZ ("half an hour before > breakfast, with a glass of water"). > ; In this case, the DSL line would be: > ; OMZ20 30 PL 1XD INSTOMZ > ; meaning: Omeprazol 20mg ------------------- 30 pills > ; Take 1 pill P.O. 1X day > ; half an hour before breakfast, with > ; a glass of water > ; Questions regarding proper formatting of INST are not addressed at > this moment. > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; > ; Now follows a description of some problems I encountered and the > choices made in solving them: > ; (define in (open-input-file "Recipe.txt")) > ; If you just (string-split (read-line in)) you'll get: > ; => '("hctz25" "30" "cp" "1xd") > ; and that will not evaluate the symbols to their string descritptions. > ; Because of that, you need to do a: > ; > (map string->symbol (string-split (read-line in))) > ; which will evaluate to > ; => '(hctz25 |30| cp 1xd) > ; This would be ideal to MAP EVAL to, but the problem is the |30| What you want here is something like this: ;; Instead of (map string->symbol (string-split (read-line in))) (for/list ([thing (in-port read in)]) thing) ;; and then you can do (map eval ?) to that if you want. ;; Or you could do both at once like this: (for/list ([thing (in-port read in)]) (eval thing namespace)) > ; So, the idea is SET!ing that list to a name we can call easily, i.e., > ; med-line-holder, because then we can extract the pieces (since we > can't do list > ; surgery easily, such a "replace the the element at position 1 with > so-and-so element"). > ; Since the prescription syntax is pretty rigid, we can get away with this > ; simple approach. > > (define med-line-holder '()) ; initial value of med-line-holder is an empty list > (define med-name-holder '()) > (define med-quant-holder '()) > (define med-form-holder '()) > (define med-pos-holder '()) > (define med-inst-holder '()) ; remember, not always INSTructions > happen in a DSL prescription . > > (define in (open-input-file "Recipe.txt")) > (port-count-lines! in) > (define (clpr) (close-input-port in)) > > ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) > ; This is obtained from a plain text file. When it is read, it becomes something > ; like this: '(hctz25 |30| cp 1xd) > (define (set-med-line-holder) > (set! med-line-holder (map string->symbol (string-split (read-line in))))) > > (define (set-med-name-holder) > ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL > (set! med-name-holder (eval (car med-line-holder) > (namespace-anchor->namespace a)))) > > (define (set-med-quant-holder) ; the CADR of the med-line-holder > ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) > (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) > (namespace-anchor->namespace a)))) > > (define (set-med-form-holder) ; the CADDR of the med-line-holder - > gets the FORM, e.g., pills, etc. > ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) > (set! med-form-holder (eval (caddr med-line-holder) > (namespace-anchor->namespace a)))) > > (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - > gets the POS, e.g., 1xd > ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) > (set! med-pos-holder (eval (cadddr med-line-holder) > (namespace-anchor->namespace a)))) > > > (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST > ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) > (set! med-pos-holder (eval (last med-line-holder) > (namespace-anchor->namespace a)))) > > ; One problem here regards the optional INST instructions. > ; How to create a SETter function that will only SET! med-inst-holder > ; if there's an INST instruction? Note that INST is a prefix. A real > instruction is, e.g., > ; INSTOMZ (for OMZ20). > (define (look-for-line) > (if (regexp-match #px"\\d\\-" (read-line in)) > (begin > (set-med-line-holder) > (set-med-name-holder) > (set-med-quant-holder) > (set-med-form-holder) > (set-med-pos-holder)) > 'NO-LINE)) > > (define (display-stuff) > (newline) > (display med-line-holder) (newline) > (display med-name-holder) (newline) > (display med-quant-holder) (newline) > (display med-form-holder) (newline) > (display med-pos-holder) (newline)) > ; The problem remains of what to do with the eventual INST. > > > ; Successive calls to (look-for-line) would read the next lines. > ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, > ; if it hits a line with no text in Recipe.txt > (look-for-line) > ;(display-stuff) > > > (define (output-a-line) > (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" > med-pos-holder "\n"))) > > (define (format-a-line) > (display (output-a-line))) > > ;(define (output-a-line) > ; (display (string-join (list med-name-holder line med-quant-holder > med-form-holder "\n" > ; med-pos-holder "\n")))) > (newline) > ;(output-a-line) > > (format-a-line) > > > > ; PROBLEMS > ; 1) How do we find out how many lines to (look-for-line)? > ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not > ; only it makes for easy visual understanding, but it may be used > to provide a hint > ; for this problem. > ; Possible approaches: > ; - Maybe this can be solved with REGEXPS? This information could > provide a sentinel > ; variable for an iterator function? > ; - Is there some sort if line counting function? (Note that I have set > ; (port-count-lines! in) somewhere above in the code. > ; 2) How do we know we've reached the end of the file? > ; 3) How to deal with the not-always-present INST? > ; - How do we check for INSTs? With a REGEXP? > ; - Choosing between INSTs with REGEXPS is not necessary, as they > will be loaded in a module, > ; so the system will "know" which one to choose. > ; 4) Another idea would be "slurp" the whole of the prescription, and > then deal with evaluation. How? > ; (define f1 > ; (file->string > ; "C:\\Path\\to\\sources\\Recipe.txt")) > ;> (string-normalize-spaces f1) > ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" > ; > ; That's all for now, folks! > ; Many thanks for all the help so far, Racketeers! > ; Cheers, > ; Henry Lenzi > > > > > On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >> Hello everyone - >> >> First of all, a big Thank You to all of you and for taking the time for >> responding. >> >> I'll have to set aside sometime during this weekend to see if I can >> understand the ideas you've been so kind to offer. >> >> However, I should confess that I've made some progress with way simpler >> stuff which I hope to post later on. Like I've said, this is stupid >> software. Anyways, none of this is final. >> >> It really just used a plain text solution, since the format if a recipe is >> so rigid. The question of expanding the symbols from files to run-time was >> easier than I thought. >> >> The idea of using modules might have the nice collateral effect if some sort >> of primitive type (or syntax) checking for free. I like the idea someone >> offered of using modules for medication definitions. Actually, one module >> per definition makes it very easy for future users to add new medications. >> The ease of syntax is important because it allows for the customization by >> non-sophisticated users (physicians, nurses). >> >> Cheers, >> Henry Lenzi. > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From henry.lenzi at gmail.com Sun Aug 3 16:38:17 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Sun, 3 Aug 2014 17:38:17 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> Message-ID: Alexander -- Thanks. But what would "thing" be? On Sun, Aug 3, 2014 at 5:29 PM, Alexander D. Knauth wrote: > > On Aug 3, 2014, at 3:29 PM, Henry Lenzi wrote: > >> ; Hello all -- >> ; So here's how I solve all those little problems regarding symbols >> and evaluation of medication definitions. >> ; Would you please bear with me? I apologize for the length. >> ; This is the approach I've taken. I've chosen no to use any macrology >> or parser/lexer technique because I don't grok them and they >> ; don't really seem necessary, for reasons explained in the code comments. >> ; I have not decided to hash tables, for the following reason: there's >> a part of the code (the drug definitions, the instructions), that >> ; should be easy enough for non-programmers to edit. If they are kept >> very simple, it's possible, because the users have to edit those >> ; files. So, even though it is source code, it's not as intimidating >> as editing source code if hash tables. >> ; Another aspect is that I hope modules provided some sort of safety >> in terms of syntax checking. That is to say, if you used make a >> ; typo in the medication part of the DSL, the system will (hopefully) >> bork because no such module exists. I believe this also creates >> ; an opportunity for "syntax validation" if a proper input phase is >> designed. But Lisp/Scheme being a dynamic language, the run-time >> ; will bork immediately once it sees funny things. This is a way to >> guarantee the DSL is correct, which we get for free by using Racket. >> ; A fourth aspect is that, if each drug is kept a different module >> (which I haven't done here, BTW), then we can make for easier >> ; internationalization, by keeping modules by languages, e.g., >> hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project >> too, >> ; so it's best to design with that in mind. >> ; Final comment regards "database". We get "database" for free, by >> registering prescriptions with patient register numbers. The OS >> ; takes care of pretty musch anything else. And there's no need for >> atomicity and concurrency. Like I said, this is stupid code. >> ; >> ; >> #lang racket >> >> ; code-review-for-racketeers-2014-08-03-a.rkt >> ; >> ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea >> is that the physician >> ; has two options: 1) he or she opens Notepad and writes the >> prescription file (Recipe.text); >> ; 2) or, the software asks for inputs and writes the file (this will >> not be covered in this >> ; exercise). The written prescription in the shorthand DSL would look >> like below, with the >> ; exception of a first field with patient ID data not included (to be >> done later). >> ; The prescription has a rigid syntax would look like this (line >> breaks included): >> ; 1- >> ; hctz25 30 pl 1xd >> ; >> ; 2- >> ; simva20 30 pl 1xn >> >> >> ; Needed for EVAL, used later on >> (define-namespace-anchor a) >> >> ; These definitions should be in a different module. >> ; This way we get syntax checking for free. >> ; MED - medication. Includes dosage. >> (define hctz25 "Hydrochlorothiazide 25mg") >> (define simva20 "Simvastatin 20mg") >> ; FORM - whether the patient will take home pills, a tube, a flask, capsules >> (define pl "pills") >> ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 >> pills 2x a day, etc. >> (define 1xd "Take 1 pill P.O. 1x/day") >> (define 1xn "Take 1 pill P.O. 1x at night") >> ; INSTs - special instructions. INST is just a prefix INST+MED without >> the dosage. >> (define INSTOMZ "half an hour before breakfast, with a glass of water") >> ; Formatters - simple for now, but should be a function of the space available. >> (define line "-----------") >> >> >> >> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >> ; The main part of a prescription DSL is pretty rigid in syntax, being >> composed of blocks of theses parts: >> ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. >> ; Please note that, in this DSL, the MED part includes the drug dosage >> (e.g., HCTZ25, where >> ; the HCTZ designates the drug, and the 25 the dosage). >> ; An example would be: >> ; HCTZ25 30 PL 1XD >> ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills >> ; Take 1 pill P.O. 1X day >> ; INST are special instructions. They basically are more detailed >> explanation to the patient about >> ; how to use the medication properly. Not always there's a INST in the >> prescription DSL. >> ; INSTs are, in fact, a PREFIX for the MED without the dose. For >> example, OMZ20 is Omeprazol 20mg. >> ; The instruction for OMZ would be INSTOMZ ("half an hour before >> breakfast, with a glass of water"). >> ; In this case, the DSL line would be: >> ; OMZ20 30 PL 1XD INSTOMZ >> ; meaning: Omeprazol 20mg ------------------- 30 pills >> ; Take 1 pill P.O. 1X day >> ; half an hour before breakfast, with >> ; a glass of water >> ; Questions regarding proper formatting of INST are not addressed at >> this moment. >> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >> ; Now follows a description of some problems I encountered and the >> choices made in solving them: >> ; (define in (open-input-file "Recipe.txt")) >> ; If you just (string-split (read-line in)) you'll get: >> ; => '("hctz25" "30" "cp" "1xd") >> ; and that will not evaluate the symbols to their string descritptions. >> ; Because of that, you need to do a: >> ; > (map string->symbol (string-split (read-line in))) >> ; which will evaluate to >> ; => '(hctz25 |30| cp 1xd) >> ; This would be ideal to MAP EVAL to, but the problem is the |30| > > What you want here is something like this: > ;; Instead of (map string->symbol (string-split (read-line in))) > (for/list ([thing (in-port read in)]) thing) > ;; and then you can do (map eval ?) to that if you want. > ;; Or you could do both at once like this: > (for/list ([thing (in-port read in)]) > (eval thing namespace)) > >> ; So, the idea is SET!ing that list to a name we can call easily, i.e., >> ; med-line-holder, because then we can extract the pieces (since we >> can't do list >> ; surgery easily, such a "replace the the element at position 1 with >> so-and-so element"). >> ; Since the prescription syntax is pretty rigid, we can get away with this >> ; simple approach. >> >> (define med-line-holder '()) ; initial value of med-line-holder is an empty list >> (define med-name-holder '()) >> (define med-quant-holder '()) >> (define med-form-holder '()) >> (define med-pos-holder '()) >> (define med-inst-holder '()) ; remember, not always INSTructions >> happen in a DSL prescription . >> >> (define in (open-input-file "Recipe.txt")) >> (port-count-lines! in) >> (define (clpr) (close-input-port in)) >> >> ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) >> ; This is obtained from a plain text file. When it is read, it becomes something >> ; like this: '(hctz25 |30| cp 1xd) >> (define (set-med-line-holder) >> (set! med-line-holder (map string->symbol (string-split (read-line in))))) >> >> (define (set-med-name-holder) >> ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL >> (set! med-name-holder (eval (car med-line-holder) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-quant-holder) ; the CADR of the med-line-holder >> ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) >> (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-form-holder) ; the CADDR of the med-line-holder - >> gets the FORM, e.g., pills, etc. >> ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) >> (set! med-form-holder (eval (caddr med-line-holder) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - >> gets the POS, e.g., 1xd >> ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) >> (set! med-pos-holder (eval (cadddr med-line-holder) >> (namespace-anchor->namespace a)))) >> >> >> (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST >> ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) >> (set! med-pos-holder (eval (last med-line-holder) >> (namespace-anchor->namespace a)))) >> >> ; One problem here regards the optional INST instructions. >> ; How to create a SETter function that will only SET! med-inst-holder >> ; if there's an INST instruction? Note that INST is a prefix. A real >> instruction is, e.g., >> ; INSTOMZ (for OMZ20). >> (define (look-for-line) >> (if (regexp-match #px"\\d\\-" (read-line in)) >> (begin >> (set-med-line-holder) >> (set-med-name-holder) >> (set-med-quant-holder) >> (set-med-form-holder) >> (set-med-pos-holder)) >> 'NO-LINE)) >> >> (define (display-stuff) >> (newline) >> (display med-line-holder) (newline) >> (display med-name-holder) (newline) >> (display med-quant-holder) (newline) >> (display med-form-holder) (newline) >> (display med-pos-holder) (newline)) >> ; The problem remains of what to do with the eventual INST. >> >> >> ; Successive calls to (look-for-line) would read the next lines. >> ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, >> ; if it hits a line with no text in Recipe.txt >> (look-for-line) >> ;(display-stuff) >> >> >> (define (output-a-line) >> (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" >> med-pos-holder "\n"))) >> >> (define (format-a-line) >> (display (output-a-line))) >> >> ;(define (output-a-line) >> ; (display (string-join (list med-name-holder line med-quant-holder >> med-form-holder "\n" >> ; med-pos-holder "\n")))) >> (newline) >> ;(output-a-line) >> >> (format-a-line) >> >> >> >> ; PROBLEMS >> ; 1) How do we find out how many lines to (look-for-line)? >> ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not >> ; only it makes for easy visual understanding, but it may be used >> to provide a hint >> ; for this problem. >> ; Possible approaches: >> ; - Maybe this can be solved with REGEXPS? This information could >> provide a sentinel >> ; variable for an iterator function? >> ; - Is there some sort if line counting function? (Note that I have set >> ; (port-count-lines! in) somewhere above in the code. >> ; 2) How do we know we've reached the end of the file? >> ; 3) How to deal with the not-always-present INST? >> ; - How do we check for INSTs? With a REGEXP? >> ; - Choosing between INSTs with REGEXPS is not necessary, as they >> will be loaded in a module, >> ; so the system will "know" which one to choose. >> ; 4) Another idea would be "slurp" the whole of the prescription, and >> then deal with evaluation. How? >> ; (define f1 >> ; (file->string >> ; "C:\\Path\\to\\sources\\Recipe.txt")) >> ;> (string-normalize-spaces f1) >> ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" >> ; >> ; That's all for now, folks! >> ; Many thanks for all the help so far, Racketeers! >> ; Cheers, >> ; Henry Lenzi >> >> >> >> >> On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >>> Hello everyone - >>> >>> First of all, a big Thank You to all of you and for taking the time for >>> responding. >>> >>> I'll have to set aside sometime during this weekend to see if I can >>> understand the ideas you've been so kind to offer. >>> >>> However, I should confess that I've made some progress with way simpler >>> stuff which I hope to post later on. Like I've said, this is stupid >>> software. Anyways, none of this is final. >>> >>> It really just used a plain text solution, since the format if a recipe is >>> so rigid. The question of expanding the symbols from files to run-time was >>> easier than I thought. >>> >>> The idea of using modules might have the nice collateral effect if some sort >>> of primitive type (or syntax) checking for free. I like the idea someone >>> offered of using modules for medication definitions. Actually, one module >>> per definition makes it very easy for future users to add new medications. >>> The ease of syntax is important because it allows for the customization by >>> non-sophisticated users (physicians, nurses). >>> >>> Cheers, >>> Henry Lenzi. >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > From alexander at knauth.org Sun Aug 3 16:40:55 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 16:40:55 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> Message-ID: <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> On Aug 3, 2014, at 4:29 PM, Alexander D. Knauth wrote: > > On Aug 3, 2014, at 3:29 PM, Henry Lenzi wrote: > >> ; Hello all -- >> ; So here's how I solve all those little problems regarding symbols >> and evaluation of medication definitions. >> ; Would you please bear with me? I apologize for the length. >> ; This is the approach I've taken. I've chosen no to use any macrology >> or parser/lexer technique because I don't grok them and they >> ; don't really seem necessary, for reasons explained in the code comments. >> ; I have not decided to hash tables, for the following reason: there's >> a part of the code (the drug definitions, the instructions), that >> ; should be easy enough for non-programmers to edit. If they are kept >> very simple, it's possible, because the users have to edit those >> ; files. So, even though it is source code, it's not as intimidating >> as editing source code if hash tables. >> ; Another aspect is that I hope modules provided some sort of safety >> in terms of syntax checking. That is to say, if you used make a >> ; typo in the medication part of the DSL, the system will (hopefully) >> bork because no such module exists. I believe this also creates >> ; an opportunity for "syntax validation" if a proper input phase is >> designed. But Lisp/Scheme being a dynamic language, the run-time >> ; will bork immediately once it sees funny things. This is a way to >> guarantee the DSL is correct, which we get for free by using Racket. >> ; A fourth aspect is that, if each drug is kept a different module >> (which I haven't done here, BTW), then we can make for easier >> ; internationalization, by keeping modules by languages, e.g., >> hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project >> too, >> ; so it's best to design with that in mind. >> ; Final comment regards "database". We get "database" for free, by >> registering prescriptions with patient register numbers. The OS >> ; takes care of pretty musch anything else. And there's no need for >> atomicity and concurrency. Like I said, this is stupid code. >> ; >> ; >> #lang racket >> >> ; code-review-for-racketeers-2014-08-03-a.rkt >> ; >> ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea >> is that the physician >> ; has two options: 1) he or she opens Notepad and writes the >> prescription file (Recipe.text); >> ; 2) or, the software asks for inputs and writes the file (this will >> not be covered in this >> ; exercise). The written prescription in the shorthand DSL would look >> like below, with the >> ; exception of a first field with patient ID data not included (to be >> done later). >> ; The prescription has a rigid syntax would look like this (line >> breaks included): >> ; 1- >> ; hctz25 30 pl 1xd >> ; >> ; 2- >> ; simva20 30 pl 1xn >> >> >> ; Needed for EVAL, used later on >> (define-namespace-anchor a) >> >> ; These definitions should be in a different module. >> ; This way we get syntax checking for free. >> ; MED - medication. Includes dosage. >> (define hctz25 "Hydrochlorothiazide 25mg") >> (define simva20 "Simvastatin 20mg") >> ; FORM - whether the patient will take home pills, a tube, a flask, capsules >> (define pl "pills") >> ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 >> pills 2x a day, etc. >> (define 1xd "Take 1 pill P.O. 1x/day") >> (define 1xn "Take 1 pill P.O. 1x at night") >> ; INSTs - special instructions. INST is just a prefix INST+MED without >> the dosage. >> (define INSTOMZ "half an hour before breakfast, with a glass of water") >> ; Formatters - simple for now, but should be a function of the space available. >> (define line "-----------") >> >> >> >> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >> ; The main part of a prescription DSL is pretty rigid in syntax, being >> composed of blocks of theses parts: >> ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. >> ; Please note that, in this DSL, the MED part includes the drug dosage >> (e.g., HCTZ25, where >> ; the HCTZ designates the drug, and the 25 the dosage). >> ; An example would be: >> ; HCTZ25 30 PL 1XD >> ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills >> ; Take 1 pill P.O. 1X day >> ; INST are special instructions. They basically are more detailed >> explanation to the patient about >> ; how to use the medication properly. Not always there's a INST in the >> prescription DSL. >> ; INSTs are, in fact, a PREFIX for the MED without the dose. For >> example, OMZ20 is Omeprazol 20mg. >> ; The instruction for OMZ would be INSTOMZ ("half an hour before >> breakfast, with a glass of water"). >> ; In this case, the DSL line would be: >> ; OMZ20 30 PL 1XD INSTOMZ >> ; meaning: Omeprazol 20mg ------------------- 30 pills >> ; Take 1 pill P.O. 1X day >> ; half an hour before breakfast, with >> ; a glass of water >> ; Questions regarding proper formatting of INST are not addressed at >> this moment. >> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >> ; Now follows a description of some problems I encountered and the >> choices made in solving them: >> ; (define in (open-input-file "Recipe.txt")) >> ; If you just (string-split (read-line in)) you'll get: >> ; => '("hctz25" "30" "cp" "1xd") >> ; and that will not evaluate the symbols to their string descritptions. >> ; Because of that, you need to do a: >> ; > (map string->symbol (string-split (read-line in))) >> ; which will evaluate to >> ; => '(hctz25 |30| cp 1xd) >> ; This would be ideal to MAP EVAL to, but the problem is the |30| > > What you want here is something like this: > ;; Instead of (map string->symbol (string-split (read-line in))) > (for/list ([thing (in-port read in)]) thing) Actually come to think of it you can do this: (sequence->list in) Or this: (port->list read in) > ;; and then you can do (map eval ?) to that if you want. > ;; Or you could do both at once like this: > (for/list ([thing (in-port read in)]) > (eval thing namespace)) Or for that: (port->list (compose1 eval read) in) > >> ; So, the idea is SET!ing that list to a name we can call easily, i.e., >> ; med-line-holder, because then we can extract the pieces (since we >> can't do list >> ; surgery easily, such a "replace the the element at position 1 with >> so-and-so element?). look at list-set from unstable/list >> ; Since the prescription syntax is pretty rigid, we can get away with this >> ; simple approach. >> >> (define med-line-holder '()) ; initial value of med-line-holder is an empty list >> (define med-name-holder '()) >> (define med-quant-holder '()) >> (define med-form-holder '()) >> (define med-pos-holder '()) >> (define med-inst-holder '()) ; remember, not always INSTructions >> happen in a DSL prescription . >> >> (define in (open-input-file "Recipe.txt")) >> (port-count-lines! in) >> (define (clpr) (close-input-port in)) >> >> ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) >> ; This is obtained from a plain text file. When it is read, it becomes something >> ; like this: '(hctz25 |30| cp 1xd) >> (define (set-med-line-holder) >> (set! med-line-holder (map string->symbol (string-split (read-line in))))) >> >> (define (set-med-name-holder) >> ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL >> (set! med-name-holder (eval (car med-line-holder) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-quant-holder) ; the CADR of the med-line-holder >> ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) >> (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-form-holder) ; the CADDR of the med-line-holder - >> gets the FORM, e.g., pills, etc. >> ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) >> (set! med-form-holder (eval (caddr med-line-holder) >> (namespace-anchor->namespace a)))) >> >> (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - >> gets the POS, e.g., 1xd >> ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) >> (set! med-pos-holder (eval (cadddr med-line-holder) >> (namespace-anchor->namespace a)))) >> >> >> (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST >> ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) >> (set! med-pos-holder (eval (last med-line-holder) >> (namespace-anchor->namespace a)))) >> >> ; One problem here regards the optional INST instructions. >> ; How to create a SETter function that will only SET! med-inst-holder >> ; if there's an INST instruction? Note that INST is a prefix. A real >> instruction is, e.g., >> ; INSTOMZ (for OMZ20). >> (define (look-for-line) >> (if (regexp-match #px"\\d\\-" (read-line in)) >> (begin >> (set-med-line-holder) >> (set-med-name-holder) >> (set-med-quant-holder) >> (set-med-form-holder) >> (set-med-pos-holder)) >> 'NO-LINE)) >> >> (define (display-stuff) >> (newline) >> (display med-line-holder) (newline) >> (display med-name-holder) (newline) >> (display med-quant-holder) (newline) >> (display med-form-holder) (newline) >> (display med-pos-holder) (newline)) >> ; The problem remains of what to do with the eventual INST. >> >> >> ; Successive calls to (look-for-line) would read the next lines. >> ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, >> ; if it hits a line with no text in Recipe.txt >> (look-for-line) >> ;(display-stuff) >> >> >> (define (output-a-line) >> (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" >> med-pos-holder "\n"))) >> >> (define (format-a-line) >> (display (output-a-line))) >> >> ;(define (output-a-line) >> ; (display (string-join (list med-name-holder line med-quant-holder >> med-form-holder "\n" >> ; med-pos-holder "\n")))) >> (newline) >> ;(output-a-line) >> >> (format-a-line) >> >> >> >> ; PROBLEMS >> ; 1) How do we find out how many lines to (look-for-line)? >> ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not >> ; only it makes for easy visual understanding, but it may be used >> to provide a hint >> ; for this problem. >> ; Possible approaches: >> ; - Maybe this can be solved with REGEXPS? This information could >> provide a sentinel >> ; variable for an iterator function? >> ; - Is there some sort if line counting function? (Note that I have set >> ; (port-count-lines! in) somewhere above in the code. >> ; 2) How do we know we've reached the end of the file? >> ; 3) How to deal with the not-always-present INST? >> ; - How do we check for INSTs? With a REGEXP? >> ; - Choosing between INSTs with REGEXPS is not necessary, as they >> will be loaded in a module, >> ; so the system will "know" which one to choose. >> ; 4) Another idea would be "slurp" the whole of the prescription, and >> then deal with evaluation. How? >> ; (define f1 >> ; (file->string >> ; "C:\\Path\\to\\sources\\Recipe.txt")) >> ;> (string-normalize-spaces f1) >> ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" >> ; >> ; That's all for now, folks! >> ; Many thanks for all the help so far, Racketeers! >> ; Cheers, >> ; Henry Lenzi >> >> >> >> >> On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >>> Hello everyone - >>> >>> First of all, a big Thank You to all of you and for taking the time for >>> responding. >>> >>> I'll have to set aside sometime during this weekend to see if I can >>> understand the ideas you've been so kind to offer. >>> >>> However, I should confess that I've made some progress with way simpler >>> stuff which I hope to post later on. Like I've said, this is stupid >>> software. Anyways, none of this is final. >>> >>> It really just used a plain text solution, since the format if a recipe is >>> so rigid. The question of expanding the symbols from files to run-time was >>> easier than I thought. >>> >>> The idea of using modules might have the nice collateral effect if some sort >>> of primitive type (or syntax) checking for free. I like the idea someone >>> offered of using modules for medication definitions. Actually, one module >>> per definition makes it very easy for future users to add new medications. >>> The ease of syntax is important because it allows for the customization by >>> non-sophisticated users (physicians, nurses). >>> >>> Cheers, >>> Henry Lenzi. >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From matthias at ccs.neu.edu Sun Aug 3 17:52:31 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 17:52:31 -0400 Subject: [racket] Teaching logical thinking via programming in Scheme In-Reply-To: References: Message-ID: <494CB999-B069-480B-BDC4-5598A5DF591F@ccs.neu.edu> It seems to me that Igor Rivin's major flaw in thinking shows up on page 1 as a section title. In "The Consumer" the opinion piece makes the common mistake to introduce the undergraduate student as a consumer. He is not. The undergraduate student is the product that we, the professors, consume from the US K-12 system and that we deliver to employers and graduate schools. It just so happens that Universities and Colleges make their product pay for the value-enrichment process because their product has free will and choose where to put the new-found skills to use after graduation. In turn, the product makes the future employer pay for the process of obtaining a Bachelors degree. But otherwise Rivin has his heart at the right place and it is worth exploiting his ideas. -- Matthias On Aug 3, 2014, at 2:34 PM, Nadeem Abdul Hamid wrote: > Yes, thanks very much for sharing this. One of my "to do" items this fall is to put together a proposal at my college to have our HtDP course fit in as one of the "mathematics" options in the general education core. Any other suggestions, tips, or publications like this paper along the lines of arguing that HtDP (or functional programming, in general) provides students rigorous mathematical foundations and useful skills (at the college level) would be much appreciated. > > nadeem > > > > > -- > Nadeem Abdul Hamid > Associate Professor, Computer Science > Berry College, Mount Berry, GA 30149 > http://cs.berry.edu/~nhamid/ > > > On Sun, Aug 3, 2014 at 1:18 PM, Matthias Felleisen wrote: > > Thanks for pointing it out. Since the person is possibly still at Brown, I may try to contact him and see whether there is common ground. Much appreciated -- Matthias > > > > On Aug 3, 2014, at 12:26 PM, Bradley Lucier wrote: > > > Many people on this list think deeply about pedagogy; perhaps the following article published in the Notices of the American Mathematical Society, which advocates teaching logical thinking via Scheme programming before advancing to the usual university mathematics curriculum (calculus, etc.), may be of interest. > > > > http://www.ams.org/notices/201406/rnoti-p597.pdf > > > > Brad > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rcleis at me.com Sun Aug 3 18:29:24 2014 From: rcleis at me.com (Richard Cleis) Date: Sun, 03 Aug 2014 16:29:24 -0600 Subject: [racket] Performance. Higher-order function In-Reply-To: <1407057319.566019875@f258.i.mail.ru> References: <1407057319.566019875@f258.i.mail.ru> Message-ID: <42093854-F06C-49B0-8641-782D7A49071F@me.com> If I (define i->c integer->char), and use it in your test1, it becomes the slowest. That might mean that the "unknown function" response from Dr F applies to your function, too. In other words, I think this is another example of drawing ambiguous conclusions from tests that are too simple. I gave up on benchmarks long ago, because there are too many people outsmarting too many other people. Interesting, though (uh oh, I am getting sucked in): In v5.3.1 all of your tests are the same speed. I even added some tests that use 'currying' to perhaps prevent the conversion function from being "inspected" on every call, and those are the same speed, too. So it seems that the outsmarting peeps who wrote v6.1 optimized your first test, somehow, to make it twice as fast when it uses a "known function". I am somehow reminded of the Fortran days and "intrinsic functions", but don't know if that is the same issue as this one. rac On Aug 3, 2014, at 3:15 AM, Roman Klochkov wrote: > Are higher order function always slow? > > Made small test: > test1 -- unfamous set-in-the-loop accumulating > test2 -- built-in build-string > test3 -- manually written build-string with the same code as in test1 > ---- > (define (test1 n) > (define res (make-string n)) > (for ([i (in-range n)]) > (string-set! res i (integer->char i))) > res) > > (define (test2 n) > (build-string n integer->char)) > > (define (build-string1 n proc) > (define res (make-string n)) > (for ([i (in-range n)]) > (string-set! res i (proc i))) > res) > > (define (test3 n) > (build-string1 n integer->char)) > > (time (for ([i 100000]) (test1 100))) > (time (for ([i 100000]) (test1 100))) > (time (for ([i 100000]) (test1 100))) > (displayln "") > (time (for ([i 100000]) (test2 100))) > (time (for ([i 100000]) (test2 100))) > (time (for ([i 100000]) (test2 100))) > (displayln "") > (time (for ([i 100000]) (test3 100))) > (time (for ([i 100000]) (test3 100))) > (time (for ([i 100000]) (test3 100))) > ---- > Tested on Linux x32 > > $ /usr/racket/bin/racket > Welcome to Racket v6.1. > > (enter! "test") > cpu time: 360 real time: 469 gc time: 64 > cpu time: 212 real time: 209 gc time: 0 > cpu time: 208 real time: 208 gc time: 0 > > cpu time: 400 real time: 402 gc time: 0 > cpu time: 380 real time: 382 gc time: 4 > cpu time: 384 real time: 383 gc time: 0 > > cpu time: 524 real time: 529 gc time: 4 > cpu time: 468 real time: 470 gc time: 8 > cpu time: 412 real time: 414 gc time: 12 > > --- > > So I see, that build-string version is about two times slower, than set-in-the-loop. Why so much? I expected about 10-20% difference. > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From norman at astro.gla.ac.uk Sun Aug 3 18:46:28 2014 From: norman at astro.gla.ac.uk (Norman Gray) Date: Sun, 3 Aug 2014 23:46:28 +0100 Subject: [racket] Puzzled about type inference Message-ID: Greetings. Short version: I repeatedly find myself adding TR type annotations by trial-and-error -- I'm sure I'm missing something. I had a particularly acute case of this this afternoon. I have a bit of typed/racket/base code as follows: (: 1+ (Nonnegative-Integer -> Positive-Integer)) (define (1+ n) (+ n 1)) (define map1 #{map @ (Listof Nonnegative-Integer) (Vectorof Nonnegative-Integer)}) (define map2 #{map @ Nonnegative-Integer (Listof Nonnegative-Integer)}) (let* ((idx+level (map1 vector->list (cast '(#(1 2) #(3 4) #(5 6)) (Listof (Vectorof Nonnegative-Integer))))) (res (#{make-vector @ (U Nonnegative-Integer False)} (1+ (apply max (map2 car idx+level))) #f))) (for-each (?: ((p : (Listof Nonnegative-Integer))) (let ((i (car p)) (l (cadr p))) (vector-set! res i l))) idx+level) res) It doesn't much matter here what this does; but it typechecks and works OK. What I'm puzzled by is the amount of explicit type information I had to add, in order to get it to typecheck, and I confess that I added that type annotation by simply going round and round the compile cycle in DrRacket, adding more and more until Racket stopped complaining. Apart from anything else, the annotations end up making the code less readable than it might otherwise be. I can pretty much see why I have to instantiate the make-vector explicitly (it'd probably be asking a bit much for Racket to look around and spot that the only thing called in the third argument of vector-set! is a Nonnegative-Integer), and I can sort-of see why I have to cast the '(#(1 2) ...) list [Racket identifies '(#(1 2) #(3 4) #(5 6)) as (Listof (Vector Integer Integer)) which is more restricted than (Listof (Vectorof Real)), but less restricted than the actual (Listof (Vectorof Positive-Integer)) ]. But I can't really see why I have to spell out the instantiations of map1 and map2 (given the types of their arguments, I can unambiguously (?) deduce the type of the instantiation in both cases), and the type of the for-each argument, but I _don't_ have to spell out the type of idx+level. And I have to spell out the maps , but not the car in (map2 car idx+level). I can sort of see that type information propagates 'outwards', so that, for example, the type of map1 (specifically its domain) implies the type of idx+level, which the result of map1 is assigned to. Analogously, because the type of p is known, then the corresponding car can be instantiated unambiguously. However I don't have to instantiate vector->list, or the car argument to map2, so this appears to be type information propagating either 'inwards' from the type of map1/map2, or 'across' from the other argument. Working through that, and looking at the simple case of (map car (cast '((1 2) (3 4) (5 6)) (Listof (Listof Byte)))) , we have map's type as : (All (c a b ...) (case-> (-> (-> a c) (Pairof a (Listof a)) (Pairof c (Listof c))) (-> (-> a b ... b c) (Listof a) (Listof b) ... b (Listof c)))) Now, the type (Listof (Listof Byte)) fixes a in the first clause to be (Listof Byte), and thus, in the type of car : (All (a b) (case-> (-> (Pairof a b) a) (-> (Listof a) a))) , (Pairof a b) is (Listof Byte), meaning that a, here, must be Byte and thus the domain of car must be Byte, fixing c in the type of map. So there appears to be no ambiguity, and while the algorithm for the general case would clearly be entertainingly challenging (am I correct that this was Sam's PhD work?), I'm not seeing a fundamental blocker. In summary, I'm not saying anything's amiss here, but there are rather more 'sort-of's in the above account than I'm comfortable with. So: (a) Am I doing something wrong, or writing unidiomatically?; and (b) is there a heuristic to guide me in what annotation I actually need to add and what can be inferred, so it's all a bit less trial-and-error? All the best, Norman -- Norman Gray : http://nxg.me.uk SUPA School of Physics and Astronomy, University of Glasgow, UK From alexander at knauth.org Sun Aug 3 19:44:31 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 19:44:31 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <0C076163-E1D3-4CEB-A359-706005E2933B@knauth.org> References: <17714635.602801407088746591.JavaMail.root@zimbra> <0C076163-E1D3-4CEB-A359-706005E2933B@knauth.org> Message-ID: <44B9177B-2738-47A0-B3AB-9716C58908D4@knauth.org> I just thought: I could do syntax-local-introduce on the pattern before it gets passed to parse-id, and then do syntax-local-introduce on the bound-vars of that, except that it still doesn?t work. Well, I?m probably still missing the syntax-mark of the match*/derived form. Although I could write a sort of syntax-local-introduce/pattern that would recursively apply syntax-local-introduce to all of the identifiers in a parsed pattern. (define-syntax (match-define stx) (syntax-parse stx [(_ pat rhs:expr) (let ([p (parse-id (syntax-local-introduce #'pat))]) (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] [vars (map syntax-local-introduce (bound-vars p))]) (quasisyntax/loc stx (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars)])))))])) On Aug 3, 2014, at 2:12 PM, Alexander D. Knauth wrote: > Oh. > > I have no idea what to do then. I can?t even do syntax-local-introduce or (datum->syntax stx (syntax->datum stx)) on it because it?s not a syntax object. > > On Aug 3, 2014, at 1:59 PM, J. Ian Johnson wrote: > >> This is the problem of not introducing the right marks. He wants >> (define-values (x) (match blah [x x])) >> >> but is getting >> >> (define-values (x) (match blah [x-barf x])) >> >> Just pre-parsing won't get you all the way. You need to have a way to introduce to x-barf the marks between the outer match-define application and the inner match-expander transformer application. >> P.S. your match-define/values calls parse-id within the bound-vars call. You want to use the syntax-property there too. >> -Ian >> ----- Original Message ----- >> From: "Matthias Felleisen" >> To: "Alexander D. Knauth" >> Cc: "J. Ian Johnson" , "racket users list" >> Sent: Sunday, August 3, 2014 1:53:49 PM GMT -05:00 US/Canada Eastern >> Subject: Re: [racket] getting one macro to tell another macro to define something >> >> >> >> >> From where I sit your syntactic abstraction generates code of this shape: >> >> >> ---> (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars ;; <---- >> >> >> This introduces vars ___and___ uses them before the right-hand side is evaluated. >> >> >> -- Matthias >> >> >> >> >> >> >> >> >> >> On Aug 3, 2014, at 1:50 PM, Alexander D. Knauth wrote: >> >> >> >> >> But I never defined or used those variables. >> All I did was save the parsed pattern in a syntax-property and have the parse function look at that syntax-property. >> >> >> On Aug 3, 2014, at 1:40 PM, Matthias Felleisen < matthias at ccs.neu.edu > wrote: >> >> >> >> >> >> >> That means you are defining and using recursive variables before the initialization is done. >> >> >> >> >> On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: >> >> >> >> >> I tried it but got weird errors like this: >> >> idle-rest: undefined; >> cannot use before initialization >> And this: >> >> wrkr: undefined; >> cannot use before initialization >> https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern >> >> >> On Aug 3, 2014, at 12:32 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >> >> >> Try it and report back. >> -Ian >> ----- Original Message ----- >> From: "Alexander D. Knauth" < alexander at knauth.org > >> To: "J. Ian Johnson" < ianj at ccs.neu.edu > >> Cc: "racket users list" < users at racket-lang.org > >> Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern >> Subject: Re: [racket] getting one macro to tell another macro to define something >> >> >> What if match-define did something like this to store the parsed pat in a syntax-property?: >> >> (define-syntax (match-define stx) >> (syntax-parse stx >> [(_ pat rhs:expr) >> (let ([p (parse-id #'pat)]) >> (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] >> [vars (bound-vars p)]) >> (quasisyntax/loc stx >> (define-values vars (match*/derived (rhs) #,stx >> [(pat) (values . vars)])))))])) >> And parse did something like this: >> >> (define (parse stx) >> (or >> (syntax-property stx ?parsed-pat) >> (let () >> ... >> ))) >> >> >> On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >> >> >> >> On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: >> >> >> >> What do you mean? >> Shouldn?t it go something like this: >> (syntax-parameterize ([current-defs (mutable-set)]) >> (match-define (sender x) 1) >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (match-define x3 1) >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (define x3 (match 1 [x3 x3])) >> I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) >> (define-values (x3) (match 1 [(sender x) (values x3)])) >> Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? >> >> >> (reciever) >> x) >> ; => >> (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) >> (define x3 (match 1 [x3 x3])) >> >> (define x x3) >> x) >> >> The match-define form never defines ?x? as anything, but the receiver should, right? >> >> On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >> >> >> >> Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. >> >> Do you have a different example that doesn't fail in this way? >> -Ian >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> >> >> > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Sun Aug 3 19:51:56 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 19:51:56 -0400 Subject: [racket] Performance. Higher-order function In-Reply-To: <42093854-F06C-49B0-8641-782D7A49071F@me.com> References: <1407057319.566019875@f258.i.mail.ru> <42093854-F06C-49B0-8641-782D7A49071F@me.com> Message-ID: On Aug 3, 2014, at 6:29 PM, Richard Cleis wrote: > If I (define i->c integer->char), and use it in your test1, it becomes the slowest. > That might mean that the "unknown function" response from Dr F applies to your function, too. > In other words, I think this is another example of drawing ambiguous conclusions from tests that are too simple. > I gave up on benchmarks long ago, because there are too many people outsmarting too many other people. > > Interesting, though (uh oh, I am getting sucked in): > In v5.3.1 all of your tests are the same speed. > I even added some tests that use 'currying' to perhaps prevent the conversion function from being "inspected" on every call, and those are the same speed, too. > > So it seems that the outsmarting peeps who wrote v6.1 optimized your first test, somehow, to make it twice as fast when it uses a "known function". One major change in 6.1 is that local define no longer sets a function to "undefined" but instead uses a run-time check to catch bad uses. Dybvig reported a long time ago that this could enable more flow-style optimizations because the compiler no longer needs to split values (check for undefined). Enough about micro benchmarks, which really reveal little -- Matthias -------------- next part -------------- An HTML attachment was scrubbed... URL: From henry.lenzi at gmail.com Sun Aug 3 19:58:26 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Sun, 3 Aug 2014 20:58:26 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> Message-ID: Alexander's idea is interesting, but it onlt works if the prescription file is not numbered (which is actually more natural), such as if it were: hctz25 30 pl 1xd simva20 30 pl 1xn > (define in2 (open-input-file "Recipe3.txt")) > (port->list (compose1 eval read) in2) '("Hydrochlorothiazide 25mg" 30 "cps" "Take 1 pill P.O. 1x/day" "Simvastatin 20mg" 30 "cps" "Take 1 pill P.O. 1x at night") The issue would then be about extracting and joining 4 or 5 (if it has an INST instruction) items from that list. string-join, however, will bork at numbers. So it's kind of the same issue as previously than with |30|. in what regards the presence of INSTs, maybe this could be approached by first scanning the list for an INST instruction using REGEXPs, but I don't know how to do that yet. Thanks, Henry Lenzi On Sun, Aug 3, 2014 at 5:40 PM, Alexander D. Knauth wrote: > > On Aug 3, 2014, at 4:29 PM, Alexander D. Knauth wrote: > >> >> On Aug 3, 2014, at 3:29 PM, Henry Lenzi wrote: >> >>> ; Hello all -- >>> ; So here's how I solve all those little problems regarding symbols >>> and evaluation of medication definitions. >>> ; Would you please bear with me? I apologize for the length. >>> ; This is the approach I've taken. I've chosen no to use any macrology >>> or parser/lexer technique because I don't grok them and they >>> ; don't really seem necessary, for reasons explained in the code comments. >>> ; I have not decided to hash tables, for the following reason: there's >>> a part of the code (the drug definitions, the instructions), that >>> ; should be easy enough for non-programmers to edit. If they are kept >>> very simple, it's possible, because the users have to edit those >>> ; files. So, even though it is source code, it's not as intimidating >>> as editing source code if hash tables. >>> ; Another aspect is that I hope modules provided some sort of safety >>> in terms of syntax checking. That is to say, if you used make a >>> ; typo in the medication part of the DSL, the system will (hopefully) >>> bork because no such module exists. I believe this also creates >>> ; an opportunity for "syntax validation" if a proper input phase is >>> designed. But Lisp/Scheme being a dynamic language, the run-time >>> ; will bork immediately once it sees funny things. This is a way to >>> guarantee the DSL is correct, which we get for free by using Racket. >>> ; A fourth aspect is that, if each drug is kept a different module >>> (which I haven't done here, BTW), then we can make for easier >>> ; internationalization, by keeping modules by languages, e.g., >>> hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project >>> too, >>> ; so it's best to design with that in mind. >>> ; Final comment regards "database". We get "database" for free, by >>> registering prescriptions with patient register numbers. The OS >>> ; takes care of pretty musch anything else. And there's no need for >>> atomicity and concurrency. Like I said, this is stupid code. >>> ; >>> ; >>> #lang racket >>> >>> ; code-review-for-racketeers-2014-08-03-a.rkt >>> ; >>> ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea >>> is that the physician >>> ; has two options: 1) he or she opens Notepad and writes the >>> prescription file (Recipe.text); >>> ; 2) or, the software asks for inputs and writes the file (this will >>> not be covered in this >>> ; exercise). The written prescription in the shorthand DSL would look >>> like below, with the >>> ; exception of a first field with patient ID data not included (to be >>> done later). >>> ; The prescription has a rigid syntax would look like this (line >>> breaks included): >>> ; 1- >>> ; hctz25 30 pl 1xd >>> ; >>> ; 2- >>> ; simva20 30 pl 1xn >>> >>> >>> ; Needed for EVAL, used later on >>> (define-namespace-anchor a) >>> >>> ; These definitions should be in a different module. >>> ; This way we get syntax checking for free. >>> ; MED - medication. Includes dosage. >>> (define hctz25 "Hydrochlorothiazide 25mg") >>> (define simva20 "Simvastatin 20mg") >>> ; FORM - whether the patient will take home pills, a tube, a flask, capsules >>> (define pl "pills") >>> ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 >>> pills 2x a day, etc. >>> (define 1xd "Take 1 pill P.O. 1x/day") >>> (define 1xn "Take 1 pill P.O. 1x at night") >>> ; INSTs - special instructions. INST is just a prefix INST+MED without >>> the dosage. >>> (define INSTOMZ "half an hour before breakfast, with a glass of water") >>> ; Formatters - simple for now, but should be a function of the space available. >>> (define line "-----------") >>> >>> >>> >>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>> ; The main part of a prescription DSL is pretty rigid in syntax, being >>> composed of blocks of theses parts: >>> ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. >>> ; Please note that, in this DSL, the MED part includes the drug dosage >>> (e.g., HCTZ25, where >>> ; the HCTZ designates the drug, and the 25 the dosage). >>> ; An example would be: >>> ; HCTZ25 30 PL 1XD >>> ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills >>> ; Take 1 pill P.O. 1X day >>> ; INST are special instructions. They basically are more detailed >>> explanation to the patient about >>> ; how to use the medication properly. Not always there's a INST in the >>> prescription DSL. >>> ; INSTs are, in fact, a PREFIX for the MED without the dose. For >>> example, OMZ20 is Omeprazol 20mg. >>> ; The instruction for OMZ would be INSTOMZ ("half an hour before >>> breakfast, with a glass of water"). >>> ; In this case, the DSL line would be: >>> ; OMZ20 30 PL 1XD INSTOMZ >>> ; meaning: Omeprazol 20mg ------------------- 30 pills >>> ; Take 1 pill P.O. 1X day >>> ; half an hour before breakfast, with >>> ; a glass of water >>> ; Questions regarding proper formatting of INST are not addressed at >>> this moment. >>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>> ; Now follows a description of some problems I encountered and the >>> choices made in solving them: >>> ; (define in (open-input-file "Recipe.txt")) >>> ; If you just (string-split (read-line in)) you'll get: >>> ; => '("hctz25" "30" "cp" "1xd") >>> ; and that will not evaluate the symbols to their string descritptions. >>> ; Because of that, you need to do a: >>> ; > (map string->symbol (string-split (read-line in))) >>> ; which will evaluate to >>> ; => '(hctz25 |30| cp 1xd) >>> ; This would be ideal to MAP EVAL to, but the problem is the |30| >> >> What you want here is something like this: >> ;; Instead of (map string->symbol (string-split (read-line in))) >> (for/list ([thing (in-port read in)]) thing) > > Actually come to think of it you can do this: > (sequence->list in) > Or this: > (port->list read in) > >> ;; and then you can do (map eval ?) to that if you want. >> ;; Or you could do both at once like this: >> (for/list ([thing (in-port read in)]) >> (eval thing namespace)) > > Or for that: > (port->list (compose1 eval read) in) > >> >>> ; So, the idea is SET!ing that list to a name we can call easily, i.e., >>> ; med-line-holder, because then we can extract the pieces (since we >>> can't do list >>> ; surgery easily, such a "replace the the element at position 1 with >>> so-and-so element?). > > look at list-set from unstable/list > >>> ; Since the prescription syntax is pretty rigid, we can get away with this >>> ; simple approach. >>> >>> (define med-line-holder '()) ; initial value of med-line-holder is an empty list >>> (define med-name-holder '()) >>> (define med-quant-holder '()) >>> (define med-form-holder '()) >>> (define med-pos-holder '()) >>> (define med-inst-holder '()) ; remember, not always INSTructions >>> happen in a DSL prescription . >>> >>> (define in (open-input-file "Recipe.txt")) >>> (port-count-lines! in) >>> (define (clpr) (close-input-port in)) >>> >>> ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) >>> ; This is obtained from a plain text file. When it is read, it becomes something >>> ; like this: '(hctz25 |30| cp 1xd) >>> (define (set-med-line-holder) >>> (set! med-line-holder (map string->symbol (string-split (read-line in))))) >>> >>> (define (set-med-name-holder) >>> ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL >>> (set! med-name-holder (eval (car med-line-holder) >>> (namespace-anchor->namespace a)))) >>> >>> (define (set-med-quant-holder) ; the CADR of the med-line-holder >>> ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) >>> (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) >>> (namespace-anchor->namespace a)))) >>> >>> (define (set-med-form-holder) ; the CADDR of the med-line-holder - >>> gets the FORM, e.g., pills, etc. >>> ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) >>> (set! med-form-holder (eval (caddr med-line-holder) >>> (namespace-anchor->namespace a)))) >>> >>> (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - >>> gets the POS, e.g., 1xd >>> ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) >>> (set! med-pos-holder (eval (cadddr med-line-holder) >>> (namespace-anchor->namespace a)))) >>> >>> >>> (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST >>> ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) >>> (set! med-pos-holder (eval (last med-line-holder) >>> (namespace-anchor->namespace a)))) >>> >>> ; One problem here regards the optional INST instructions. >>> ; How to create a SETter function that will only SET! med-inst-holder >>> ; if there's an INST instruction? Note that INST is a prefix. A real >>> instruction is, e.g., >>> ; INSTOMZ (for OMZ20). >>> (define (look-for-line) >>> (if (regexp-match #px"\\d\\-" (read-line in)) >>> (begin >>> (set-med-line-holder) >>> (set-med-name-holder) >>> (set-med-quant-holder) >>> (set-med-form-holder) >>> (set-med-pos-holder)) >>> 'NO-LINE)) >>> >>> (define (display-stuff) >>> (newline) >>> (display med-line-holder) (newline) >>> (display med-name-holder) (newline) >>> (display med-quant-holder) (newline) >>> (display med-form-holder) (newline) >>> (display med-pos-holder) (newline)) >>> ; The problem remains of what to do with the eventual INST. >>> >>> >>> ; Successive calls to (look-for-line) would read the next lines. >>> ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, >>> ; if it hits a line with no text in Recipe.txt >>> (look-for-line) >>> ;(display-stuff) >>> >>> >>> (define (output-a-line) >>> (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" >>> med-pos-holder "\n"))) >>> >>> (define (format-a-line) >>> (display (output-a-line))) >>> >>> ;(define (output-a-line) >>> ; (display (string-join (list med-name-holder line med-quant-holder >>> med-form-holder "\n" >>> ; med-pos-holder "\n")))) >>> (newline) >>> ;(output-a-line) >>> >>> (format-a-line) >>> >>> >>> >>> ; PROBLEMS >>> ; 1) How do we find out how many lines to (look-for-line)? >>> ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not >>> ; only it makes for easy visual understanding, but it may be used >>> to provide a hint >>> ; for this problem. >>> ; Possible approaches: >>> ; - Maybe this can be solved with REGEXPS? This information could >>> provide a sentinel >>> ; variable for an iterator function? >>> ; - Is there some sort if line counting function? (Note that I have set >>> ; (port-count-lines! in) somewhere above in the code. >>> ; 2) How do we know we've reached the end of the file? >>> ; 3) How to deal with the not-always-present INST? >>> ; - How do we check for INSTs? With a REGEXP? >>> ; - Choosing between INSTs with REGEXPS is not necessary, as they >>> will be loaded in a module, >>> ; so the system will "know" which one to choose. >>> ; 4) Another idea would be "slurp" the whole of the prescription, and >>> then deal with evaluation. How? >>> ; (define f1 >>> ; (file->string >>> ; "C:\\Path\\to\\sources\\Recipe.txt")) >>> ;> (string-normalize-spaces f1) >>> ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" >>> ; >>> ; That's all for now, folks! >>> ; Many thanks for all the help so far, Racketeers! >>> ; Cheers, >>> ; Henry Lenzi >>> >>> >>> >>> >>> On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >>>> Hello everyone - >>>> >>>> First of all, a big Thank You to all of you and for taking the time for >>>> responding. >>>> >>>> I'll have to set aside sometime during this weekend to see if I can >>>> understand the ideas you've been so kind to offer. >>>> >>>> However, I should confess that I've made some progress with way simpler >>>> stuff which I hope to post later on. Like I've said, this is stupid >>>> software. Anyways, none of this is final. >>>> >>>> It really just used a plain text solution, since the format if a recipe is >>>> so rigid. The question of expanding the symbols from files to run-time was >>>> easier than I thought. >>>> >>>> The idea of using modules might have the nice collateral effect if some sort >>>> of primitive type (or syntax) checking for free. I like the idea someone >>>> offered of using modules for medication definitions. Actually, one module >>>> per definition makes it very easy for future users to add new medications. >>>> The ease of syntax is important because it allows for the customization by >>>> non-sophisticated users (physicians, nurses). >>>> >>>> Cheers, >>>> Henry Lenzi. >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > From ianj at ccs.neu.edu Sun Aug 3 20:04:37 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Sun, 3 Aug 2014 20:04:37 -0400 (EDT) Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <44B9177B-2738-47A0-B3AB-9716C58908D4@knauth.org> Message-ID: <10262843.604601407110677302.JavaMail.root@zimbra> This is why I tried a delta-introducer on between orig-stx (the syntax-time parameter in match) and mstx (in the application of the transformer), but even though the documentation for make-syntax-delta-introducer says it can take two arbitrary pieces of syntax to make an introducer, it barfs on non-identifiers. You might try dumpster-diving for the head identifier in orig-stx though. That might work. -Ian ----- Original Message ----- From: "Alexander D. Knauth" To: "J. Ian Johnson" Cc: "racket users list" , "Matthias Felleisen" Sent: Sunday, August 3, 2014 7:44:31 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something I just thought: I could do syntax-local-introduce on the pattern before it gets passed to parse-id, and then do syntax-local-introduce on the bound-vars of that, except that it still doesn?t work. Well, I?m probably still missing the syntax-mark of the match*/derived form. Although I could write a sort of syntax-local-introduce/pattern that would recursively apply syntax-local-introduce to all of the identifiers in a parsed pattern. (define-syntax (match-define stx) (syntax-parse stx [(_ pat rhs:expr) (let ([p (parse-id (syntax-local-introduce #'pat))]) (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] [vars (map syntax-local-introduce (bound-vars p))]) (quasisyntax/loc stx (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars)])))))])) On Aug 3, 2014, at 2:12 PM, Alexander D. Knauth < alexander at knauth.org > wrote: Oh. I have no idea what to do then. I can?t even do syntax-local-introduce or (datum->syntax stx (syntax->datum stx)) on it because it?s not a syntax object. On Aug 3, 2014, at 1:59 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: This is the problem of not introducing the right marks. He wants (define-values (x) (match blah [x x])) but is getting (define-values (x) (match blah [x-barf x])) Just pre-parsing won't get you all the way. You need to have a way to introduce to x-barf the marks between the outer match-define application and the inner match-expander transformer application. P.S. your match-define/values calls parse-id within the bound-vars call. You want to use the syntax-property there too. -Ian ----- Original Message ----- From: "Matthias Felleisen" < matthias at ccs.neu.edu > To: "Alexander D. Knauth" < alexander at knauth.org > Cc: "J. Ian Johnson" < ianj at ccs.neu.edu >, "racket users list" < users at racket-lang.org > Sent: Sunday, August 3, 2014 1:53:49 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something >From where I sit your syntactic abstraction generates code of this shape: ---> (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars ;; <---- This introduces vars ___and___ uses them before the right-hand side is evaluated. -- Matthias On Aug 3, 2014, at 1:50 PM, Alexander D. Knauth wrote: But I never defined or used those variables. All I did was save the parsed pattern in a syntax-property and have the parse function look at that syntax-property. On Aug 3, 2014, at 1:40 PM, Matthias Felleisen < matthias at ccs.neu.edu > wrote: That means you are defining and using recursive variables before the initialization is done. On Aug 3, 2014, at 1:31 PM, Alexander D. Knauth wrote: I tried it but got weird errors like this: idle-rest: undefined; cannot use before initialization And this: wrkr: undefined; cannot use before initialization https://github.com/AlexKnauth/racket/compare/match-define-save-parsed-pattern On Aug 3, 2014, at 12:32 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Try it and report back. -Ian ----- Original Message ----- From: "Alexander D. Knauth" < alexander at knauth.org > To: "J. Ian Johnson" < ianj at ccs.neu.edu > Cc: "racket users list" < users at racket-lang.org > Sent: Sunday, August 3, 2014 12:22:57 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket] getting one macro to tell another macro to define something What if match-define did something like this to store the parsed pat in a syntax-property?: (define-syntax (match-define stx) (syntax-parse stx [(_ pat rhs:expr) (let ([p (parse-id #'pat)]) (with-syntax ([pat (syntax-property #'pat 'parsed-pat p)] [vars (bound-vars p)]) (quasisyntax/loc stx (define-values vars (match*/derived (rhs) #,stx [(pat) (values . vars)])))))])) And parse did something like this: (define (parse stx) (or (syntax-property stx ?parsed-pat) (let () ... ))) On Aug 1, 2014, at 9:13 PM, Alexander D. Knauth < alexander at knauth.org > wrote: On Aug 1, 2014, at 8:46 PM, Alexander D. Knauth < alexander at knauth.org > wrote: What do you mean? Shouldn?t it go something like this: (syntax-parameterize ([current-defs (mutable-set)]) (match-define (sender x) 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (match-define x3 1) (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) I just looked at the macro stepper again and saw something similar to this: (I replaced match*/derived with match and () with []) (define-values (x3) (match 1 [(sender x) (values x3)])) Why doesn?t match-define reuse the expanded match pattern instead of expanding it twice? (reciever) x) ; => (syntax-parameterize ([current-defs (mutable-set #?(define x x3)]) (define x3 (match 1 [x3 x3])) (define x x3) x) The match-define form never defines ?x? as anything, but the receiver should, right? On Aug 1, 2014, at 8:12 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: Ah, okay, so... this macro expander you give is fundamentally flawed because match-define does an initial parse (which uses the match expander) to get the identifiers it is going to define. So, when you expand to x3 as the match pattern, you end up returning x3 as one of the values that the match-define -> define-values is going to define. It does not ever define "x" as anything because that was just arbitrary syntax that was given to the match expander. This x3 is x3 definition leads to a use-before-initialization error. Do you have a different example that doesn't fail in this way? -Ian ____________________ Racket Users list: http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users From matthias at ccs.neu.edu Sun Aug 3 20:22:37 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 20:22:37 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: Message-ID: In a sense, you put your finger on a sore spot of TR from R -- we are still figuring out how to help programmers along here. I rewrote your program like this: #lang typed/racket (: 1+ (Nonnegative-Integer -> Positive-Integer)) (define (1+ n) (+ n 1)) ;; entirely unnecessary but helped me read; IGNORE (define-type (Maybe ?) (U False ?)) (define-type NI Nonnegative-Integer) (define-type LNI (Listof NI)) (define-type VNI (Vectorof NI)) (let* ((idx+level (map #{vector->list @ NI} (cast '(#(1 2) #(3 4) #(5 6)) (Listof VNI)))) (res (#{make-vector @ [Maybe NI]} (1+ (apply max (map #{car @ NI LNI} idx+level))) #f))) (for-each (? ((p : LNI)) (let ((i (car p)) (l (cadr p))) (vector-set! res i l))) idx+level) res) ;; expect '#(#f 2 #f 4 #f 6) I focused on what the type checker really needs -- hints on how to specialize those functions, and only those, that depend on your initial insight that the TC needs a hand with make-vector. Then I checked on the maps and realized that I need to help the TC along with the instantiations of vector->list (how can it know with context-free reasoning what kind of vector it is) and the same for car (how can it know what kind of list you're getting here). [[ Also, I don't know why this code looks like it does. There are alternative: #lang typed/racket (: 1+ (Nonnegative-Integer -> Positive-Integer)) (define (1+ n) (+ n 1)) ;; entirely unnecessary but helped me read (define-type (Maybe ?) (U False ?)) (define-type NI Nonnegative-Integer) (define-type LNI (Listof NI)) (define-type VNI (Vectorof NI)) (let* ((i0 (cast '(#(1 2) #(3 4) #(5 6)) [Listof VNI])) (idx+level (map #{vector->list @ NI} i0)) (res (#{make-vector @ [Maybe NI]} (1+ (apply max (map #{car @ NI LNI} idx+level))) #f))) (for ((q : [Vectorof NI] (in-list i0))) (define i (vector-ref q 0)) (define l (vector-ref q 1)) (vector-set! res i l)) res) ]] On Aug 3, 2014, at 6:46 PM, Norman Gray wrote: > > Greetings. > > Short version: I repeatedly find myself adding TR type annotations by trial-and-error -- I'm sure I'm missing something. > > I had a particularly acute case of this this afternoon. I have a bit of typed/racket/base code as follows: > > (: 1+ (Nonnegative-Integer -> Positive-Integer)) > (define (1+ n) > (+ n 1)) > > (define map1 #{map @ (Listof Nonnegative-Integer) (Vectorof Nonnegative-Integer)}) > (define map2 #{map @ Nonnegative-Integer (Listof Nonnegative-Integer)}) > (let* ((idx+level (map1 vector->list > (cast '(#(1 2) #(3 4) #(5 6)) > (Listof (Vectorof Nonnegative-Integer))))) > (res (#{make-vector @ (U Nonnegative-Integer False)} (1+ (apply max (map2 car idx+level))) #f))) > (for-each (?: ((p : (Listof Nonnegative-Integer))) > (let ((i (car p)) > (l (cadr p))) > (vector-set! res i l))) > idx+level) > res) > > It doesn't much matter here what this does; but it typechecks and works OK. > > What I'm puzzled by is the amount of explicit type information I had to add, in order to get it to typecheck, and I confess that I added that type annotation by simply going round and round the compile cycle in DrRacket, adding more and more until Racket stopped complaining. Apart from anything else, the annotations end up making the code less readable than it might otherwise be. > > I can pretty much see why I have to instantiate the make-vector explicitly (it'd probably be asking a bit much for Racket to look around and spot that the only thing called in the third argument of vector-set! is a Nonnegative-Integer), and I can sort-of see why I have to cast the '(#(1 2) ...) list [Racket identifies '(#(1 2) #(3 4) #(5 6)) as (Listof (Vector Integer Integer)) which is more restricted than (Listof (Vectorof Real)), but less restricted than the actual (Listof (Vectorof Positive-Integer)) ]. > > But I can't really see why I have to spell out the instantiations of map1 and map2 (given the types of their arguments, I can unambiguously (?) deduce the type of the instantiation in both cases), and the type of the for-each argument, but I _don't_ have to spell out the type of idx+level. And I have to spell out the maps , but not the car in (map2 car idx+level). > > I can sort of see that type information propagates 'outwards', so that, for example, the type of map1 (specifically its domain) implies the type of idx+level, which the result of map1 is assigned to. Analogously, because the type of p is known, then the corresponding car can be instantiated unambiguously. > > However I don't have to instantiate vector->list, or the car argument to map2, so this appears to be type information propagating either 'inwards' from the type of map1/map2, or 'across' from the other argument. > > Working through that, and looking at the simple case of > > (map car (cast '((1 2) (3 4) (5 6)) (Listof (Listof Byte)))) , > > we have map's type as > > : (All (c a b ...) > (case-> > (-> (-> a c) (Pairof a (Listof a)) (Pairof c (Listof c))) > (-> (-> a b ... b c) (Listof a) (Listof b) ... b (Listof c)))) > > Now, the type (Listof (Listof Byte)) fixes a in the first clause to be (Listof Byte), and thus, in the type of car > > : (All (a b) (case-> (-> (Pairof a b) a) (-> (Listof a) a))) , > > (Pairof a b) is (Listof Byte), meaning that a, here, must be Byte and thus the domain of car must be Byte, fixing c in the type of map. So there appears to be no ambiguity, and while the algorithm for the general case would clearly be entertainingly challenging (am I correct that this was Sam's PhD work?), I'm not seeing a fundamental blocker. > > In summary, I'm not saying anything's amiss here, but there are rather more 'sort-of's in the above account than I'm comfortable with. > > So: (a) Am I doing something wrong, or writing unidiomatically?; and (b) is there a heuristic to guide me in what annotation I actually need to add and what can be inferred, so it's all a bit less trial-and-error? > > All the best, > > Norman > > > -- > Norman Gray : http://nxg.me.uk > SUPA School of Physics and Astronomy, University of Glasgow, UK > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From alexander at knauth.org Sun Aug 3 20:38:00 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 3 Aug 2014 20:38:00 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> Message-ID: <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> On Aug 3, 2014, at 7:58 PM, Henry Lenzi wrote: > Alexander's idea is interesting, but it onlt works if the > prescription file is not numbered (which is actually more natural), > such as if it were: > hctz25 30 pl 1xd > simva20 30 pl 1xn > >> (define in2 (open-input-file "Recipe3.txt")) >> (port->list (compose1 eval read) in2) > '("Hydrochlorothiazide 25mg" > 30 > "cps" > "Take 1 pill P.O. 1x/day" > "Simvastatin 20mg" > 30 > "cps" > "Take 1 pill P.O. 1x at night") > > The issue would then be about extracting and joining 4 or 5 (if it has > an INST instruction) items from that list. > string-join, however, will bork at numbers. So it's kind of the same > issue as previously than with |30|. Then just do this: (string-join (map ~a (port->list (compose1 eval read) in2)) instead. > > in what regards the presence of INSTs, maybe this could be approached > by first scanning the list for an INST instruction using REGEXPs, but > I don't know how to do that yet. > > > Thanks, > > Henry Lenzi > > On Sun, Aug 3, 2014 at 5:40 PM, Alexander D. Knauth > wrote: >> >> On Aug 3, 2014, at 4:29 PM, Alexander D. Knauth wrote: >> >>> >>> On Aug 3, 2014, at 3:29 PM, Henry Lenzi wrote: >>> >>>> ; Hello all -- >>>> ; So here's how I solve all those little problems regarding symbols >>>> and evaluation of medication definitions. >>>> ; Would you please bear with me? I apologize for the length. >>>> ; This is the approach I've taken. I've chosen no to use any macrology >>>> or parser/lexer technique because I don't grok them and they >>>> ; don't really seem necessary, for reasons explained in the code comments. >>>> ; I have not decided to hash tables, for the following reason: there's >>>> a part of the code (the drug definitions, the instructions), that >>>> ; should be easy enough for non-programmers to edit. If they are kept >>>> very simple, it's possible, because the users have to edit those >>>> ; files. So, even though it is source code, it's not as intimidating >>>> as editing source code if hash tables. >>>> ; Another aspect is that I hope modules provided some sort of safety >>>> in terms of syntax checking. That is to say, if you used make a >>>> ; typo in the medication part of the DSL, the system will (hopefully) >>>> bork because no such module exists. I believe this also creates >>>> ; an opportunity for "syntax validation" if a proper input phase is >>>> designed. But Lisp/Scheme being a dynamic language, the run-time >>>> ; will bork immediately once it sees funny things. This is a way to >>>> guarantee the DSL is correct, which we get for free by using Racket. >>>> ; A fourth aspect is that, if each drug is kept a different module >>>> (which I haven't done here, BTW), then we can make for easier >>>> ; internationalization, by keeping modules by languages, e.g., >>>> hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project >>>> too, >>>> ; so it's best to design with that in mind. >>>> ; Final comment regards "database". We get "database" for free, by >>>> registering prescriptions with patient register numbers. The OS >>>> ; takes care of pretty musch anything else. And there's no need for >>>> atomicity and concurrency. Like I said, this is stupid code. >>>> ; >>>> ; >>>> #lang racket >>>> >>>> ; code-review-for-racketeers-2014-08-03-a.rkt >>>> ; >>>> ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea >>>> is that the physician >>>> ; has two options: 1) he or she opens Notepad and writes the >>>> prescription file (Recipe.text); >>>> ; 2) or, the software asks for inputs and writes the file (this will >>>> not be covered in this >>>> ; exercise). The written prescription in the shorthand DSL would look >>>> like below, with the >>>> ; exception of a first field with patient ID data not included (to be >>>> done later). >>>> ; The prescription has a rigid syntax would look like this (line >>>> breaks included): >>>> ; 1- >>>> ; hctz25 30 pl 1xd >>>> ; >>>> ; 2- >>>> ; simva20 30 pl 1xn >>>> >>>> >>>> ; Needed for EVAL, used later on >>>> (define-namespace-anchor a) >>>> >>>> ; These definitions should be in a different module. >>>> ; This way we get syntax checking for free. >>>> ; MED - medication. Includes dosage. >>>> (define hctz25 "Hydrochlorothiazide 25mg") >>>> (define simva20 "Simvastatin 20mg") >>>> ; FORM - whether the patient will take home pills, a tube, a flask, capsules >>>> (define pl "pills") >>>> ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 >>>> pills 2x a day, etc. >>>> (define 1xd "Take 1 pill P.O. 1x/day") >>>> (define 1xn "Take 1 pill P.O. 1x at night") >>>> ; INSTs - special instructions. INST is just a prefix INST+MED without >>>> the dosage. >>>> (define INSTOMZ "half an hour before breakfast, with a glass of water") >>>> ; Formatters - simple for now, but should be a function of the space available. >>>> (define line "-----------") >>>> >>>> >>>> >>>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>>> ; The main part of a prescription DSL is pretty rigid in syntax, being >>>> composed of blocks of theses parts: >>>> ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. >>>> ; Please note that, in this DSL, the MED part includes the drug dosage >>>> (e.g., HCTZ25, where >>>> ; the HCTZ designates the drug, and the 25 the dosage). >>>> ; An example would be: >>>> ; HCTZ25 30 PL 1XD >>>> ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills >>>> ; Take 1 pill P.O. 1X day >>>> ; INST are special instructions. They basically are more detailed >>>> explanation to the patient about >>>> ; how to use the medication properly. Not always there's a INST in the >>>> prescription DSL. >>>> ; INSTs are, in fact, a PREFIX for the MED without the dose. For >>>> example, OMZ20 is Omeprazol 20mg. >>>> ; The instruction for OMZ would be INSTOMZ ("half an hour before >>>> breakfast, with a glass of water"). >>>> ; In this case, the DSL line would be: >>>> ; OMZ20 30 PL 1XD INSTOMZ >>>> ; meaning: Omeprazol 20mg ------------------- 30 pills >>>> ; Take 1 pill P.O. 1X day >>>> ; half an hour before breakfast, with >>>> ; a glass of water >>>> ; Questions regarding proper formatting of INST are not addressed at >>>> this moment. >>>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>>> ; Now follows a description of some problems I encountered and the >>>> choices made in solving them: >>>> ; (define in (open-input-file "Recipe.txt")) >>>> ; If you just (string-split (read-line in)) you'll get: >>>> ; => '("hctz25" "30" "cp" "1xd") >>>> ; and that will not evaluate the symbols to their string descritptions. >>>> ; Because of that, you need to do a: >>>> ; > (map string->symbol (string-split (read-line in))) >>>> ; which will evaluate to >>>> ; => '(hctz25 |30| cp 1xd) >>>> ; This would be ideal to MAP EVAL to, but the problem is the |30| >>> >>> What you want here is something like this: >>> ;; Instead of (map string->symbol (string-split (read-line in))) >>> (for/list ([thing (in-port read in)]) thing) >> >> Actually come to think of it you can do this: >> (sequence->list in) >> Or this: >> (port->list read in) >> >>> ;; and then you can do (map eval ?) to that if you want. >>> ;; Or you could do both at once like this: >>> (for/list ([thing (in-port read in)]) >>> (eval thing namespace)) >> >> Or for that: >> (port->list (compose1 eval read) in) >> >>> >>>> ; So, the idea is SET!ing that list to a name we can call easily, i.e., >>>> ; med-line-holder, because then we can extract the pieces (since we >>>> can't do list >>>> ; surgery easily, such a "replace the the element at position 1 with >>>> so-and-so element?). >> >> look at list-set from unstable/list >> >>>> ; Since the prescription syntax is pretty rigid, we can get away with this >>>> ; simple approach. >>>> >>>> (define med-line-holder '()) ; initial value of med-line-holder is an empty list >>>> (define med-name-holder '()) >>>> (define med-quant-holder '()) >>>> (define med-form-holder '()) >>>> (define med-pos-holder '()) >>>> (define med-inst-holder '()) ; remember, not always INSTructions >>>> happen in a DSL prescription . >>>> >>>> (define in (open-input-file "Recipe.txt")) >>>> (port-count-lines! in) >>>> (define (clpr) (close-input-port in)) >>>> >>>> ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) >>>> ; This is obtained from a plain text file. When it is read, it becomes something >>>> ; like this: '(hctz25 |30| cp 1xd) >>>> (define (set-med-line-holder) >>>> (set! med-line-holder (map string->symbol (string-split (read-line in))))) >>>> >>>> (define (set-med-name-holder) >>>> ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL >>>> (set! med-name-holder (eval (car med-line-holder) >>>> (namespace-anchor->namespace a)))) >>>> >>>> (define (set-med-quant-holder) ; the CADR of the med-line-holder >>>> ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) >>>> (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) >>>> (namespace-anchor->namespace a)))) >>>> >>>> (define (set-med-form-holder) ; the CADDR of the med-line-holder - >>>> gets the FORM, e.g., pills, etc. >>>> ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) >>>> (set! med-form-holder (eval (caddr med-line-holder) >>>> (namespace-anchor->namespace a)))) >>>> >>>> (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - >>>> gets the POS, e.g., 1xd >>>> ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) >>>> (set! med-pos-holder (eval (cadddr med-line-holder) >>>> (namespace-anchor->namespace a)))) >>>> >>>> >>>> (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST >>>> ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) >>>> (set! med-pos-holder (eval (last med-line-holder) >>>> (namespace-anchor->namespace a)))) >>>> >>>> ; One problem here regards the optional INST instructions. >>>> ; How to create a SETter function that will only SET! med-inst-holder >>>> ; if there's an INST instruction? Note that INST is a prefix. A real >>>> instruction is, e.g., >>>> ; INSTOMZ (for OMZ20). >>>> (define (look-for-line) >>>> (if (regexp-match #px"\\d\\-" (read-line in)) >>>> (begin >>>> (set-med-line-holder) >>>> (set-med-name-holder) >>>> (set-med-quant-holder) >>>> (set-med-form-holder) >>>> (set-med-pos-holder)) >>>> 'NO-LINE)) >>>> >>>> (define (display-stuff) >>>> (newline) >>>> (display med-line-holder) (newline) >>>> (display med-name-holder) (newline) >>>> (display med-quant-holder) (newline) >>>> (display med-form-holder) (newline) >>>> (display med-pos-holder) (newline)) >>>> ; The problem remains of what to do with the eventual INST. >>>> >>>> >>>> ; Successive calls to (look-for-line) would read the next lines. >>>> ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, >>>> ; if it hits a line with no text in Recipe.txt >>>> (look-for-line) >>>> ;(display-stuff) >>>> >>>> >>>> (define (output-a-line) >>>> (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" >>>> med-pos-holder "\n"))) >>>> >>>> (define (format-a-line) >>>> (display (output-a-line))) >>>> >>>> ;(define (output-a-line) >>>> ; (display (string-join (list med-name-holder line med-quant-holder >>>> med-form-holder "\n" >>>> ; med-pos-holder "\n")))) >>>> (newline) >>>> ;(output-a-line) >>>> >>>> (format-a-line) >>>> >>>> >>>> >>>> ; PROBLEMS >>>> ; 1) How do we find out how many lines to (look-for-line)? >>>> ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not >>>> ; only it makes for easy visual understanding, but it may be used >>>> to provide a hint >>>> ; for this problem. >>>> ; Possible approaches: >>>> ; - Maybe this can be solved with REGEXPS? This information could >>>> provide a sentinel >>>> ; variable for an iterator function? >>>> ; - Is there some sort if line counting function? (Note that I have set >>>> ; (port-count-lines! in) somewhere above in the code. >>>> ; 2) How do we know we've reached the end of the file? >>>> ; 3) How to deal with the not-always-present INST? >>>> ; - How do we check for INSTs? With a REGEXP? >>>> ; - Choosing between INSTs with REGEXPS is not necessary, as they >>>> will be loaded in a module, >>>> ; so the system will "know" which one to choose. >>>> ; 4) Another idea would be "slurp" the whole of the prescription, and >>>> then deal with evaluation. How? >>>> ; (define f1 >>>> ; (file->string >>>> ; "C:\\Path\\to\\sources\\Recipe.txt")) >>>> ;> (string-normalize-spaces f1) >>>> ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" >>>> ; >>>> ; That's all for now, folks! >>>> ; Many thanks for all the help so far, Racketeers! >>>> ; Cheers, >>>> ; Henry Lenzi >>>> >>>> >>>> >>>> >>>> On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >>>>> Hello everyone - >>>>> >>>>> First of all, a big Thank You to all of you and for taking the time for >>>>> responding. >>>>> >>>>> I'll have to set aside sometime during this weekend to see if I can >>>>> understand the ideas you've been so kind to offer. >>>>> >>>>> However, I should confess that I've made some progress with way simpler >>>>> stuff which I hope to post later on. Like I've said, this is stupid >>>>> software. Anyways, none of this is final. >>>>> >>>>> It really just used a plain text solution, since the format if a recipe is >>>>> so rigid. The question of expanding the symbols from files to run-time was >>>>> easier than I thought. >>>>> >>>>> The idea of using modules might have the nice collateral effect if some sort >>>>> of primitive type (or syntax) checking for free. I like the idea someone >>>>> offered of using modules for medication definitions. Actually, one module >>>>> per definition makes it very easy for future users to add new medications. >>>>> The ease of syntax is important because it allows for the customization by >>>>> non-sophisticated users (physicians, nurses). >>>>> >>>>> Cheers, >>>>> Henry Lenzi. >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From henry.lenzi at gmail.com Sun Aug 3 23:04:35 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Mon, 4 Aug 2014 00:04:35 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> Message-ID: Oh, OK. :-) -- Henry On Sun, Aug 3, 2014 at 9:38 PM, Alexander D. Knauth wrote: > > On Aug 3, 2014, at 7:58 PM, Henry Lenzi wrote: > >> Alexander's idea is interesting, but it onlt works if the >> prescription file is not numbered (which is actually more natural), >> such as if it were: >> hctz25 30 pl 1xd >> simva20 30 pl 1xn >> >>> (define in2 (open-input-file "Recipe3.txt")) >>> (port->list (compose1 eval read) in2) >> '("Hydrochlorothiazide 25mg" >> 30 >> "cps" >> "Take 1 pill P.O. 1x/day" >> "Simvastatin 20mg" >> 30 >> "cps" >> "Take 1 pill P.O. 1x at night") >> >> The issue would then be about extracting and joining 4 or 5 (if it has >> an INST instruction) items from that list. >> string-join, however, will bork at numbers. So it's kind of the same >> issue as previously than with |30|. > > Then just do this: (string-join (map ~a (port->list (compose1 eval read) in2)) instead. > >> >> in what regards the presence of INSTs, maybe this could be approached >> by first scanning the list for an INST instruction using REGEXPs, but >> I don't know how to do that yet. >> >> >> Thanks, >> >> Henry Lenzi >> >> On Sun, Aug 3, 2014 at 5:40 PM, Alexander D. Knauth >> wrote: >>> >>> On Aug 3, 2014, at 4:29 PM, Alexander D. Knauth wrote: >>> >>>> >>>> On Aug 3, 2014, at 3:29 PM, Henry Lenzi wrote: >>>> >>>>> ; Hello all -- >>>>> ; So here's how I solve all those little problems regarding symbols >>>>> and evaluation of medication definitions. >>>>> ; Would you please bear with me? I apologize for the length. >>>>> ; This is the approach I've taken. I've chosen no to use any macrology >>>>> or parser/lexer technique because I don't grok them and they >>>>> ; don't really seem necessary, for reasons explained in the code comments. >>>>> ; I have not decided to hash tables, for the following reason: there's >>>>> a part of the code (the drug definitions, the instructions), that >>>>> ; should be easy enough for non-programmers to edit. If they are kept >>>>> very simple, it's possible, because the users have to edit those >>>>> ; files. So, even though it is source code, it's not as intimidating >>>>> as editing source code if hash tables. >>>>> ; Another aspect is that I hope modules provided some sort of safety >>>>> in terms of syntax checking. That is to say, if you used make a >>>>> ; typo in the medication part of the DSL, the system will (hopefully) >>>>> bork because no such module exists. I believe this also creates >>>>> ; an opportunity for "syntax validation" if a proper input phase is >>>>> designed. But Lisp/Scheme being a dynamic language, the run-time >>>>> ; will bork immediately once it sees funny things. This is a way to >>>>> guarantee the DSL is correct, which we get for free by using Racket. >>>>> ; A fourth aspect is that, if each drug is kept a different module >>>>> (which I haven't done here, BTW), then we can make for easier >>>>> ; internationalization, by keeping modules by languages, e.g., >>>>> hctz25-en, hctz25-pt_br. I believe Dan has an interest in this project >>>>> too, >>>>> ; so it's best to design with that in mind. >>>>> ; Final comment regards "database". We get "database" for free, by >>>>> registering prescriptions with patient register numbers. The OS >>>>> ; takes care of pretty musch anything else. And there's no need for >>>>> atomicity and concurrency. Like I said, this is stupid code. >>>>> ; >>>>> ; >>>>> #lang racket >>>>> >>>>> ; code-review-for-racketeers-2014-08-03-a.rkt >>>>> ; >>>>> ; For this exercise, suppose a Recipe.txt file. Let?s suppose the idea >>>>> is that the physician >>>>> ; has two options: 1) he or she opens Notepad and writes the >>>>> prescription file (Recipe.text); >>>>> ; 2) or, the software asks for inputs and writes the file (this will >>>>> not be covered in this >>>>> ; exercise). The written prescription in the shorthand DSL would look >>>>> like below, with the >>>>> ; exception of a first field with patient ID data not included (to be >>>>> done later). >>>>> ; The prescription has a rigid syntax would look like this (line >>>>> breaks included): >>>>> ; 1- >>>>> ; hctz25 30 pl 1xd >>>>> ; >>>>> ; 2- >>>>> ; simva20 30 pl 1xn >>>>> >>>>> >>>>> ; Needed for EVAL, used later on >>>>> (define-namespace-anchor a) >>>>> >>>>> ; These definitions should be in a different module. >>>>> ; This way we get syntax checking for free. >>>>> ; MED - medication. Includes dosage. >>>>> (define hctz25 "Hydrochlorothiazide 25mg") >>>>> (define simva20 "Simvastatin 20mg") >>>>> ; FORM - whether the patient will take home pills, a tube, a flask, capsules >>>>> (define pl "pills") >>>>> ; POS - posology, whether the patient will take 1 pill 3x a day, or 2 >>>>> pills 2x a day, etc. >>>>> (define 1xd "Take 1 pill P.O. 1x/day") >>>>> (define 1xn "Take 1 pill P.O. 1x at night") >>>>> ; INSTs - special instructions. INST is just a prefix INST+MED without >>>>> the dosage. >>>>> (define INSTOMZ "half an hour before breakfast, with a glass of water") >>>>> ; Formatters - simple for now, but should be a function of the space available. >>>>> (define line "-----------") >>>>> >>>>> >>>>> >>>>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>>>> ; The main part of a prescription DSL is pretty rigid in syntax, being >>>>> composed of blocks of theses parts: >>>>> ; MEDICATION QUANTITY FORM POSOLOGY INSTRUCTION, or MED QUANT FORM POS INST. >>>>> ; Please note that, in this DSL, the MED part includes the drug dosage >>>>> (e.g., HCTZ25, where >>>>> ; the HCTZ designates the drug, and the 25 the dosage). >>>>> ; An example would be: >>>>> ; HCTZ25 30 PL 1XD >>>>> ; meaning: Hydrochlorothiazide 25mg -------------- 30 pills >>>>> ; Take 1 pill P.O. 1X day >>>>> ; INST are special instructions. They basically are more detailed >>>>> explanation to the patient about >>>>> ; how to use the medication properly. Not always there's a INST in the >>>>> prescription DSL. >>>>> ; INSTs are, in fact, a PREFIX for the MED without the dose. For >>>>> example, OMZ20 is Omeprazol 20mg. >>>>> ; The instruction for OMZ would be INSTOMZ ("half an hour before >>>>> breakfast, with a glass of water"). >>>>> ; In this case, the DSL line would be: >>>>> ; OMZ20 30 PL 1XD INSTOMZ >>>>> ; meaning: Omeprazol 20mg ------------------- 30 pills >>>>> ; Take 1 pill P.O. 1X day >>>>> ; half an hour before breakfast, with >>>>> ; a glass of water >>>>> ; Questions regarding proper formatting of INST are not addressed at >>>>> this moment. >>>>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; >>>>> ; Now follows a description of some problems I encountered and the >>>>> choices made in solving them: >>>>> ; (define in (open-input-file "Recipe.txt")) >>>>> ; If you just (string-split (read-line in)) you'll get: >>>>> ; => '("hctz25" "30" "cp" "1xd") >>>>> ; and that will not evaluate the symbols to their string descritptions. >>>>> ; Because of that, you need to do a: >>>>> ; > (map string->symbol (string-split (read-line in))) >>>>> ; which will evaluate to >>>>> ; => '(hctz25 |30| cp 1xd) >>>>> ; This would be ideal to MAP EVAL to, but the problem is the |30| >>>> >>>> What you want here is something like this: >>>> ;; Instead of (map string->symbol (string-split (read-line in))) >>>> (for/list ([thing (in-port read in)]) thing) >>> >>> Actually come to think of it you can do this: >>> (sequence->list in) >>> Or this: >>> (port->list read in) >>> >>>> ;; and then you can do (map eval ?) to that if you want. >>>> ;; Or you could do both at once like this: >>>> (for/list ([thing (in-port read in)]) >>>> (eval thing namespace)) >>> >>> Or for that: >>> (port->list (compose1 eval read) in) >>> >>>> >>>>> ; So, the idea is SET!ing that list to a name we can call easily, i.e., >>>>> ; med-line-holder, because then we can extract the pieces (since we >>>>> can't do list >>>>> ; surgery easily, such a "replace the the element at position 1 with >>>>> so-and-so element?). >>> >>> look at list-set from unstable/list >>> >>>>> ; Since the prescription syntax is pretty rigid, we can get away with this >>>>> ; simple approach. >>>>> >>>>> (define med-line-holder '()) ; initial value of med-line-holder is an empty list >>>>> (define med-name-holder '()) >>>>> (define med-quant-holder '()) >>>>> (define med-form-holder '()) >>>>> (define med-pos-holder '()) >>>>> (define med-inst-holder '()) ; remember, not always INSTructions >>>>> happen in a DSL prescription . >>>>> >>>>> (define in (open-input-file "Recipe.txt")) >>>>> (port-count-lines! in) >>>>> (define (clpr) (close-input-port in)) >>>>> >>>>> ; a med-line-holder is a list that has MED QUANT FORM POS (and sometimes INST) >>>>> ; This is obtained from a plain text file. When it is read, it becomes something >>>>> ; like this: '(hctz25 |30| cp 1xd) >>>>> (define (set-med-line-holder) >>>>> (set! med-line-holder (map string->symbol (string-split (read-line in))))) >>>>> >>>>> (define (set-med-name-holder) >>>>> ; (set! med-name-holder (eval (car med-line-holder))) ;; in the REPL >>>>> (set! med-name-holder (eval (car med-line-holder) >>>>> (namespace-anchor->namespace a)))) >>>>> >>>>> (define (set-med-quant-holder) ; the CADR of the med-line-holder >>>>> ; (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)))) >>>>> (set! med-quant-holder (eval (symbol->string (cadr med-line-holder)) >>>>> (namespace-anchor->namespace a)))) >>>>> >>>>> (define (set-med-form-holder) ; the CADDR of the med-line-holder - >>>>> gets the FORM, e.g., pills, etc. >>>>> ; (set! med-form-holder (eval (symbol->string (caddr med-line-holder)))) >>>>> (set! med-form-holder (eval (caddr med-line-holder) >>>>> (namespace-anchor->namespace a)))) >>>>> >>>>> (define (set-med-pos-holder) ; the CADDDR of the med-line-holder - >>>>> gets the POS, e.g., 1xd >>>>> ; (set! med-pos-holder (eval (symbol->string (cadddr med-line-holder)))) >>>>> (set! med-pos-holder (eval (cadddr med-line-holder) >>>>> (namespace-anchor->namespace a)))) >>>>> >>>>> >>>>> (define (set-med-inst-holder) ; the LAST of the med-line-holder - gets the INST >>>>> ; (set! med-pos-holder (eval (symbol->string (last med-line-holder)))) >>>>> (set! med-pos-holder (eval (last med-line-holder) >>>>> (namespace-anchor->namespace a)))) >>>>> >>>>> ; One problem here regards the optional INST instructions. >>>>> ; How to create a SETter function that will only SET! med-inst-holder >>>>> ; if there's an INST instruction? Note that INST is a prefix. A real >>>>> instruction is, e.g., >>>>> ; INSTOMZ (for OMZ20). >>>>> (define (look-for-line) >>>>> (if (regexp-match #px"\\d\\-" (read-line in)) >>>>> (begin >>>>> (set-med-line-holder) >>>>> (set-med-name-holder) >>>>> (set-med-quant-holder) >>>>> (set-med-form-holder) >>>>> (set-med-pos-holder)) >>>>> 'NO-LINE)) >>>>> >>>>> (define (display-stuff) >>>>> (newline) >>>>> (display med-line-holder) (newline) >>>>> (display med-name-holder) (newline) >>>>> (display med-quant-holder) (newline) >>>>> (display med-form-holder) (newline) >>>>> (display med-pos-holder) (newline)) >>>>> ; The problem remains of what to do with the eventual INST. >>>>> >>>>> >>>>> ; Successive calls to (look-for-line) would read the next lines. >>>>> ; Output would alternate between a DSL line, or a NO-LINE (from look-for-line, >>>>> ; if it hits a line with no text in Recipe.txt >>>>> (look-for-line) >>>>> ;(display-stuff) >>>>> >>>>> >>>>> (define (output-a-line) >>>>> (string-join (list med-name-holder line med-quant-holder med-form-holder "\n" >>>>> med-pos-holder "\n"))) >>>>> >>>>> (define (format-a-line) >>>>> (display (output-a-line))) >>>>> >>>>> ;(define (output-a-line) >>>>> ; (display (string-join (list med-name-holder line med-quant-holder >>>>> med-form-holder "\n" >>>>> ; med-pos-holder "\n")))) >>>>> (newline) >>>>> ;(output-a-line) >>>>> >>>>> (format-a-line) >>>>> >>>>> >>>>> >>>>> ; PROBLEMS >>>>> ; 1) How do we find out how many lines to (look-for-line)? >>>>> ; This is one of the resons I specified the "1-", "2-" in the Recipe.txt. Not >>>>> ; only it makes for easy visual understanding, but it may be used >>>>> to provide a hint >>>>> ; for this problem. >>>>> ; Possible approaches: >>>>> ; - Maybe this can be solved with REGEXPS? This information could >>>>> provide a sentinel >>>>> ; variable for an iterator function? >>>>> ; - Is there some sort if line counting function? (Note that I have set >>>>> ; (port-count-lines! in) somewhere above in the code. >>>>> ; 2) How do we know we've reached the end of the file? >>>>> ; 3) How to deal with the not-always-present INST? >>>>> ; - How do we check for INSTs? With a REGEXP? >>>>> ; - Choosing between INSTs with REGEXPS is not necessary, as they >>>>> will be loaded in a module, >>>>> ; so the system will "know" which one to choose. >>>>> ; 4) Another idea would be "slurp" the whole of the prescription, and >>>>> then deal with evaluation. How? >>>>> ; (define f1 >>>>> ; (file->string >>>>> ; "C:\\Path\\to\\sources\\Recipe.txt")) >>>>> ;> (string-normalize-spaces f1) >>>>> ;"1- hctz25 30 pl 1xd 2- simva20 30 pl 1xn" >>>>> ; >>>>> ; That's all for now, folks! >>>>> ; Many thanks for all the help so far, Racketeers! >>>>> ; Cheers, >>>>> ; Henry Lenzi >>>>> >>>>> >>>>> >>>>> >>>>> On Sat, Aug 2, 2014 at 12:44 AM, Henry Lenzi wrote: >>>>>> Hello everyone - >>>>>> >>>>>> First of all, a big Thank You to all of you and for taking the time for >>>>>> responding. >>>>>> >>>>>> I'll have to set aside sometime during this weekend to see if I can >>>>>> understand the ideas you've been so kind to offer. >>>>>> >>>>>> However, I should confess that I've made some progress with way simpler >>>>>> stuff which I hope to post later on. Like I've said, this is stupid >>>>>> software. Anyways, none of this is final. >>>>>> >>>>>> It really just used a plain text solution, since the format if a recipe is >>>>>> so rigid. The question of expanding the symbols from files to run-time was >>>>>> easier than I thought. >>>>>> >>>>>> The idea of using modules might have the nice collateral effect if some sort >>>>>> of primitive type (or syntax) checking for free. I like the idea someone >>>>>> offered of using modules for medication definitions. Actually, one module >>>>>> per definition makes it very easy for future users to add new medications. >>>>>> The ease of syntax is important because it allows for the customization by >>>>>> non-sophisticated users (physicians, nurses). >>>>>> >>>>>> Cheers, >>>>>> Henry Lenzi. >>>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>> >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > From matthias at ccs.neu.edu Sun Aug 3 23:12:52 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 3 Aug 2014 23:12:52 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: Message-ID: <2738E9A7-5EFD-4FC9-8083-2F4AEE30C380@ccs.neu.edu> After some reflection, here is how I think you should proceed: #lang typed/racket (: 1+ (Nonnegative-Integer -> Positive-Integer)) (define (1+ n) (+ n 1)) ;; entirely unnecessary but helped me read (define-type (Maybe ?) (U False ?)) (define-type NI Nonnegative-Integer) (define-type LNI (Listof NI)) (define-type VNI (Vectorof NI)) (define-type LVNI (Listof VNI)) (let* ((given : LVNI '(#(1 2) #(3 4) #(5 6))) (length : NI (1+ (apply max (map (lambda ({x : VNI}) (vector-ref x 0)) given)))) (result : [Vectorof [Maybe NI]] (make-vector length #f))) (for ((q : VNI (in-list given))) (vector-set! result (vector-ref q 0) (vector-ref q 1))) result) The above -- minus types -- is how I would probably write the code in Racket, following the style guide. (I would use three defines instead of let* but let's ignore this point.) I would use -- given as a parameter (I am guessing here) -- length to tell the reader that this is the new length of the vector -- result to spell out what this vector is about The for-loop would use a single line because it is short and brings across the idea. If I were to move this code to Typed Racket, I'd add a type declaration to each identifier just like in any other (explicitly, statically) typed programming language. That's what I did, and there was no problem checking and running your code. -- Matthias From neil at neilvandyke.org Sun Aug 3 23:18:14 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Sun, 03 Aug 2014 23:18:14 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> Message-ID: <53DEFB76.1010309@neilvandyke.org> I can see how someone might want to do tricks like this, to use the REPL as user interface, for tinkering, and that could be very interesting or clever. However, just to be clear to students and professionals who might stumble upon this thread... If I were actually doing this in production for pharmaceutical prescriptions/labeling/instructions, then I would be concerned about both program correctness and reducing potential for operator error to cause failures. If we were starting with those as key requirements for production use, then I think some of this technical discussion might be irrelevant to that, since the software might be implemented in a very different way. Neil V. From kalimehtar at mail.ru Sun Aug 3 23:42:53 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Mon, 04 Aug 2014 07:42:53 +0400 Subject: [racket] =?utf-8?q?Performance=2E_Higher-order_function?= In-Reply-To: References: <1407057319.566019875@f258.i.mail.ru> Message-ID: <1407123772.149158313@f121.i.mail.ru> > unknown function call is expensive So, higher order function always slow. Thus, to improve performance, one should use for/fold, for/list, ... and never use map, foldl, build-string, ... with lambda. Is it correct? Sun, 3 Aug 2014 13:15:57 -0400 ?? Matthias Felleisen : > >Because build-string calls an unknown function 1000 x 100000 times, and an unknown function call is expensive.? > >Racket could possible collapse all modules and perform additional in-lining optimizations eventually, which may help here. But it doesn't yet.? > >-- Matthias > > > >On Aug 3, 2014, at 5:15 AM, Roman Klochkov wrote: >>Are higher order function always slow? >>... >>--- >> >>So I see, that build-string version is about two times slower, than set-in-the-loop. Why so much? I expected about 10-20% difference. >>-- >>Roman Klochkov ____________________ >>?Racket Users list: >>? http://lists.racket-lang.org/users > -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From henry.lenzi at gmail.com Sun Aug 3 23:52:56 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Mon, 4 Aug 2014 00:52:56 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53DEFB76.1010309@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: Hello Neil - First of all, I am not attempting tricks. I am doing the best I can, the way I know how to (I will take the "clever" part as a compliment, however). I have a few rational requirements, which I have explained. Foremost among them is code simplicity. I saw no need so far for parsers or macrology - I have justified this on the basis of the DSL. As I had not been clear WRT the DSL before, I might have induced people to make an option for macros. Also, I see a need for a part of the program source-code to be easily customizable by users (such as, for example, a Swedish user being able to add his/her own definitions in simple module files, instead of tinkering with hash tables). What I'm sensing is that you seem to be concerned about bugs with Racket Scheme's EVAL. Is that it? I do not understand what the problem with EVAL is. Would you please state clearly what the problems are? I am a reasonably sophisticated reader. You can even point to papers. I might not read them now, but I even have books on stuff like denotational semantics (what I don't have is much time, sadly). Are you concered about using imperative style just on principle or have you detected a specific issue? Doesn't the fact that definitions are provided by modules reduce potential bugs? As I understand it, if I type, e.g., "hctz30" instead of "hctz25" the run-time environment will bork, as that would not be a symbol in the read table. Correct? Doesn't the DSL's rigid syntax reduce potential for bugs? Do you suggest a formal parser? If so, can you explain the case why a formal grammar would be a necessity? This is not a grammar/DSL that requires recursion (in the Chomskyan sense). I don't see the point. Perhaps I'm wrong. I would feel grateful if you cared to expand on that issue (if that is an issue). If there are too many bugs, can you cite one, two or maybe three that would be of concern? TIA, Henry Lenzi PS: I hope you realize that writing prescriptions by hand is a sure way to get even more "bugs"... On Mon, Aug 4, 2014 at 12:18 AM, Neil Van Dyke wrote: > I can see how someone might want to do tricks like this, to use the REPL as > user interface, for tinkering, and that could be very interesting or clever. > > However, just to be clear to students and professionals who might stumble > upon this thread... If I were actually doing this in production for > pharmaceutical prescriptions/labeling/instructions, then I would be > concerned about both program correctness and reducing potential for operator > error to cause failures. If we were starting with those as key requirements > for production use, then I think some of this technical discussion might be > irrelevant to that, since the software might be implemented in a very > different way. > > Neil V. > From henry.lenzi at gmail.com Mon Aug 4 00:10:01 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Mon, 4 Aug 2014 01:10:01 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: I would just like to add that this is only something very embrionary. There are a myriad ways to validate the user syntax when he/she provides input. We're just not there yet! ;-) Cheers, -- Henry On Mon, Aug 4, 2014 at 12:52 AM, Henry Lenzi wrote: > Hello Neil - > > First of all, I am not attempting tricks. I am doing the best I can, > the way I know how to (I will take the "clever" part as a compliment, > however). I have a few rational requirements, which I have explained. > Foremost among them is code simplicity. I saw no need so far for > parsers or macrology - I have justified this on the basis of the DSL. > As I had not been clear WRT the DSL before, I might have induced > people to make an option for macros. Also, I see a need for a part of > the program source-code to be easily customizable by users (such as, > for example, a Swedish user being able to add his/her own definitions > in simple module files, instead of tinkering with hash tables). > > What I'm sensing is that you seem to be concerned about bugs with > Racket Scheme's EVAL. Is that it? > I do not understand what the problem with EVAL is. Would you please > state clearly what the problems are? I am a reasonably sophisticated > reader. You can even point to papers. I might not read them now, but I > even have books on stuff like denotational semantics (what I don't > have is much time, sadly). > > Are you concered about using imperative style just on principle or > have you detected a specific issue? > > Doesn't the fact that definitions are provided by modules reduce > potential bugs? As I understand it, if I type, e.g., "hctz30" instead > of "hctz25" the run-time environment will bork, as that would not be a > symbol in the read table. Correct? > > Doesn't the DSL's rigid syntax reduce potential for bugs? Do you > suggest a formal parser? If so, can you explain the case why a formal > grammar would be a necessity? This is not a grammar/DSL that requires > recursion (in the Chomskyan sense). I don't see the point. Perhaps I'm > wrong. I would feel grateful if you cared to expand on that issue (if > that is an issue). > > If there are too many bugs, can you cite one, two or maybe three that > would be of concern? > > TIA, > Henry Lenzi > PS: I hope you realize that writing prescriptions by hand is a sure > way to get even more "bugs"... > > > On Mon, Aug 4, 2014 at 12:18 AM, Neil Van Dyke wrote: >> I can see how someone might want to do tricks like this, to use the REPL as >> user interface, for tinkering, and that could be very interesting or clever. >> >> However, just to be clear to students and professionals who might stumble >> upon this thread... If I were actually doing this in production for >> pharmaceutical prescriptions/labeling/instructions, then I would be >> concerned about both program correctness and reducing potential for operator >> error to cause failures. If we were starting with those as key requirements >> for production use, then I think some of this technical discussion might be >> irrelevant to that, since the software might be implemented in a very >> different way. >> >> Neil V. >> From alexander at knauth.org Mon Aug 4 00:23:47 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Mon, 4 Aug 2014 00:23:47 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: Would this work for what you want? If med.rkt contains this: #lang racket (provide (all-defined-out) #%datum #%top (rename-out [new-module-begin #%module-begin])) (define-syntax-rule (new-module-begin med-thing ...) (#%module-begin (display (~a med-thing ... #:separator " ")))) (define hctz25 "Hydrochlorothiazide 25mg") (define simva20 "Simvastatin 20mg") (define pl "pills") (define 1xd "Take 1 pill P.O. 1x/day") (define 1xn "Take 1 pill P.O. 1x at night") (define INSTOMZ "half an hour before breakfast, with a glass of water") (define line "-----------") And try-it.rkt contains this: #lang s-exp "med.rkt" hctz25 30 pl 1xd simva20 30 pl 1xn Then running try-it.rkt will produce the output: Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg 30 pills Take 1 pill P.O. 1x at night Or if new-module-begin is defined like this instead: (define-syntax-rule (new-module-begin med-thing ...) (#%module-begin (provide data) (define data (~a med-thing ... #:separator " ")))) Then doing (require ?try-it.rkt?) will import data as the string "Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg 30 pills Take 1 pill P.O. 1x at night". -------------- next part -------------- An HTML attachment was scrubbed... URL: From henry.lenzi at gmail.com Mon Aug 4 01:22:44 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Mon, 4 Aug 2014 02:22:44 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: Hello Alex -- This is nice, the problem is separating the output into the proper formatting. I feel this has to be done a step before the expansion into the string form. One thing I'm considering is that that the DSL is made of MED QUANT FORM POS or MED QUANT FOR POS INST, so 4 or 5 items. If we have a symbol list (before string expansion), than we can treat INST as the divider marker. Otherwise, there's a linebreak at every fourth item. I'm looking into how to to this using a position function: (define (position item list) (- (length list) (length (member item list)))) Knowing where the INST instructions occur help up decided whether we can break a line into the MED QUANT FORM POS or MED QUANT FORM POS INST forms (see the code snippet on http://pasterack.org/pastes/14535 ) Cheers, Henry On Mon, Aug 4, 2014 at 1:23 AM, Alexander D. Knauth wrote: > Would this work for what you want? > > If med.rkt contains this: > #lang racket > > (provide (all-defined-out) > #%datum #%top > (rename-out [new-module-begin #%module-begin])) > > (define-syntax-rule > (new-module-begin med-thing ...) > (#%module-begin (display (~a med-thing ... #:separator " ")))) > > (define hctz25 "Hydrochlorothiazide 25mg") > (define simva20 "Simvastatin 20mg") > (define pl "pills") > (define 1xd "Take 1 pill P.O. 1x/day") > (define 1xn "Take 1 pill P.O. 1x at night") > (define INSTOMZ "half an hour before breakfast, with a glass of water") > (define line "-----------") > > And try-it.rkt contains this: > #lang s-exp "med.rkt" > hctz25 30 pl 1xd > simva20 30 pl 1xn > > Then running try-it.rkt will produce the output: > Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg > 30 pills Take 1 pill P.O. 1x at night > > Or if new-module-begin is defined like this instead: > (define-syntax-rule > (new-module-begin med-thing ...) > (#%module-begin (provide data) (define data (~a med-thing ... #:separator > " ")))) > > Then doing (require ?try-it.rkt?) will import data as the string > "Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg > 30 pills Take 1 pill P.O. 1x at night". > > > From mflatt at cs.utah.edu Mon Aug 4 01:47:34 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 4 Aug 2014 06:47:34 +0100 Subject: [racket] Performance. Higher-order function In-Reply-To: <1407123772.149158313@f121.i.mail.ru> References: <1407057319.566019875@f258.i.mail.ru> <1407123772.149158313@f121.i.mail.ru> Message-ID: <20140804054737.013CB65018A@mail-svr1.cs.utah.edu> Well... a function call is expensive relative to some things, such as adding fixnums to produce a fixnum. My read of your initial results is that calling an unknown function is similar to the cost of one iteration in a loop that sets a character in a string. More precisely, decompiling the program shows that the compiler unrolls the loop in `test1` by 4 iterations, so one call to an unknown function is the same cost as 4 generic `<`s on fixnums, 4 generic `+ 1`s on fixnums, 4 `integer->char`s, 4 `string-set!s`, and one jump to a known function (to recur). The `build-string1` loop is similarly unrolled 4 times, and the call to `build-string1` is not inlined in `test3`, so we really can compare the unknown function call in `test3` to the overall loop overhead plus `string-set!`s of `test1`. And the fact that neither `build-string1` nor `test2 is inlined is consistent with `test2` and `test3` having the same performance. If I change the `for` body of `test1` with a constant, then the time is cut in half. So, a `string-set!` takes up about half of the time. Putting that all together, it looks like a call to an unknown function takes about twice the time of a `string-set!` --- which (due to various tag and bounds checks for the string assignment) costs the same as a small pile of generic arithmetic on fixnums. That could be considered expensive in a tight loop. I would hesitate to say that higher order functions are always slow, because many uses do more work around the call than set one character in a string. At Mon, 04 Aug 2014 07:42:53 +0400, Roman Klochkov wrote: > > unknown function call is expensive > > So, higher order function always slow. > Thus, to improve performance, one should use for/fold, for/list, ... and never > use map, foldl, build-string, ... with lambda. > Is it correct? > > Sun, 3 Aug 2014 13:15:57 -0400 ?? Matthias Felleisen : > > > >Because build-string calls an unknown function 1000 x 100000 times, and an > unknown function call is expensive.? > > > >Racket could possible collapse all modules and perform additional in-lining > optimizations eventually, which may help here. But it doesn't yet.? > > > >-- Matthias > > > > > > > >On Aug 3, 2014, at 5:15 AM, Roman Klochkov wrote: > >>Are higher order function always slow? > >>... > >>--- > >> > >>So I see, that build-string version is about two times slower, than > set-in-the-loop. Why so much? I expected about 10-20% difference. > >>-- > >>Roman Klochkov ____________________ > >>?Racket Users list: > >>? http://lists.racket-lang.org/users > > > > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Mon Aug 4 01:59:17 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 4 Aug 2014 06:59:17 +0100 Subject: [racket] Destructors in Racket In-Reply-To: <1406999570.977378605@f413.i.mail.ru> References: <1406974366.781553260@f94.i.mail.ru> <1406982706.127112181@f315.i.mail.ru> <1406999570.977378605@f413.i.mail.ru> Message-ID: <20140804055919.ADA3E6500BC@mail-svr1.cs.utah.edu> At Sat, 02 Aug 2014 21:12:50 +0400, Roman Klochkov wrote: > Here we have a thread per every module, that use such approach. It is > better,than a thread per object, but ... > How many such threads can Racket run without performance degrading? Many thousands. Each thread costs about 15 kilobytes by default on a 64-bit platform (it's possible to set parameters and bring that cost down to about 5k, I think), and that space will be the main cost for a thread that is blocked on a will executor. In particular, the thread will not even be considered by the scheduler until a will is ready to execute. For something like an output port, which is a fairly limited resource at the OS level, allocating a thread per port is probably no real cost. In case you are not already aware: If you are frequently allocating file ports, beware of relying on GC to reclaim them. GC works fine for plentiful resources, such as memory, but does not work well for relatively constrained resources, such as file handles. (That's not a Racket thing so much as a GC thing.) > Maybe better make common module for such purpose? Hmm..., I think I should make > one... > > > Sat, 2 Aug 2014 07:38:08 -0500 ?? Robby Findler : > >Probably you want to do something like this, I guess. It creates a > >single thread that just waits until anything registered with > >an-executor is garbage and then runs the executors. They will run > >asynchronously, but perhaps that's okay for your usecase. > > > >Robby > > > >#lang racket > >(define an-executor (make-will-executor)) > >(void > >?(thread > >??(? () > >????(let loop () > >??????(will-execute an-executor) > >??????(loop))))) > > > >(define a-box (box #f)) > >(will-register an-executor > >???????????????a-box > >???????????????(? (x) (printf "a-box is now garbage\n"))) > >(collect-garbage) (collect-garbage) (collect-garbage) > >(printf "breaking the link\n") > >(set! a-box #f) > >(collect-garbage) (collect-garbage) (collect-garbage) > > > >On Sat, Aug 2, 2014 at 7:31 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: > >> So I can write > >> > >> (define (make-obj stream) > >> (define res (obj (open-output-file "out.dat"))) > >> (define will (make-will-executor)) > >> (will-register will res (lambda (x) (close-output-port (obj-file x)))) > >> (thread (lambda () (let loop () (will-try-execute will) (sleep 1) > >> (loop))))) > >> > >> to make my objects? Additional threads don't hinder performance, do they? > >> > >> Or should I somehow figure out if the thread is already running, don't run > >> it and use common `will' for all objects? > >> > >> Sat, 2 Aug 2014 07:00:04 -0500 ?? Robby Findler > >> < robby at eecs.northwestern.edu >: > >> > >> One way is to set up a separate thread to do that. > >> > >> The reason they are not called automatically is sometimes running the > >> procedure passed to will-register needs to access some shared state > >> and so your program must be allowed to be in control of the timing of > >> the executor. > >> > >> In this case, it sounds like you can run the executor at any time, so > >> just creating a thread to close the port inside my-obj should work > >> fine. > >> > >> Robby > >> > >> > >> On Sat, Aug 2, 2014 at 6:15 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: > >>> Then how? > >>> > >>> Suppose I have > >>> (struct obj (file)) > >>> (define my-obj (obj (open-output-file "out.dat"))) > >>> > >>> What I have to write to close the file, when my-obj will be GC'ed? > >>> > >>> I can write > >>> (define will (make-will-executor)) > >>> (will-register will my-obj (lambda (x) (close-output-port (obj-file x)))) > >>> > >>> But as far as I understand, it will not be called until `will-execute' or > >>> `will-try-execute' will be manually called? > >>> > >>> Then how to call will-try-execute when GC is collecting my-obj? > >>> > >>> > >>> Sat, 2 Aug 2014 11:57:32 +0100 ?? Matthew Flatt < mflatt at cs.utah.edu >: > >>> > >>> No, use the safe "will executors" API, instead. > >>> > >>> The unsafe finalizer API is for low-level, atomic finalization. Closing a > >>> port can flush buffers and more, and it's not a good idea to do that in an > >>> unsafe atomic context. > >>> > >>>> On Aug 2, 2014, at 11:12 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: > >>>> > >>>> I have a structure, that has a filestream inside it. File have to be > >>>> cosed, when the structure is not used anymore (so gargbage collected). > >>>> > >>>> Is the best way to do > >>>> (require ffi/unsafe) > >>>> (register-finalizer my-obj > >>>> (lambda (x) (close-output-port (obj-file x)))) > >>>> > >>>> ? > >>>> > >>>> It seems doing right thing, but why `ffi/unsafe'? Is it OK, when my > >>>> program actually doesn't use FFI? > >>>> > >>>> > >>>> -- > >>>> Roman Klochkov > >>>> ____________________ > >>>> Racket Users list: > >>>> http://lists.racket-lang.org/users > >>> > >>> > >>> > >>> -- > >>> Roman Klochkov > >>> > >>> ____________________ > >>> Racket Users list: > >>> http://lists.racket-lang.org/users > >>> > >> > >> > >> > >> -- > >> Roman Klochkov > > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From neil at neilvandyke.org Mon Aug 4 02:12:17 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Mon, 04 Aug 2014 02:12:17 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: <53DF2441.4030409@neilvandyke.org> Henry Lenzi wrote at 08/03/2014 11:52 PM: > What I'm sensing is that you seem to be concerned about bugs with > Racket Scheme's EVAL. Is that it? > I do not understand what the problem with EVAL is. Would you please > state clearly what the problems are? Eval is one of the issues. Sorry I have to be very brief right now, but a few problems with eval in general are: * Prevents much static checking. * Likely increased difficulty debugging. * Often executes arbitrary code with privileges, which might be corrupted due to accident or attack, which can be very bad. * Prevents some optimization. * Crutch that prevents learning better idioms. Also, things like reading in a code file and looking for markers in it is something we sometimes do (especially in, say, Emacs editing mode, in which likely oopses are not so grave), but failure-prone. Also, the code I saw was not idiomatic in, say, how it uses globals. Anyway, it's good that Racket lets people experiment this way. The concern I have in my mind is that newbies reading language forums often get ideas about idiomatic programming from examples they see, and even copy&adapt examples they see (maybe even evolving it into production code, or blogging it where other newbies pick up on it...). People should experiment as much as they liked, but I think it would be good to if newbies knew when something they're looking at is an experiment rather than (yet) considered best practice. I appreciate your participation in the community, and your experimenting. Neil V. From kalimehtar at mail.ru Mon Aug 4 02:29:08 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Mon, 04 Aug 2014 10:29:08 +0400 Subject: [racket] =?utf-8?q?Performance=2E_Higher-order_function?= In-Reply-To: <20140804054737.013CB65018A@mail-svr1.cs.utah.edu> References: <1407057319.566019875@f258.i.mail.ru> <1407123772.149158313@f121.i.mail.ru> <20140804054737.013CB65018A@mail-svr1.cs.utah.edu> Message-ID: <1407133748.712987786@f186.i.mail.ru> Thank you! Now it's rather clear for me. Mon, 4 Aug 2014 06:47:34 +0100 ?? Matthew Flatt : >Well... a function call is expensive relative to some things, such as >adding fixnums to produce a fixnum. > > >My read of your initial results is that calling an unknown function is >similar to the cost of one iteration in a loop that sets a character in >a string. > >More precisely, decompiling the program shows that the compiler unrolls >the loop in `test1` by 4 iterations, so one call to an unknown function >is the same cost as 4 generic `<`s on fixnums, 4 generic `+ 1`s on >fixnums, 4 `integer->char`s, 4 `string-set!s`, and one jump to a known >function (to recur). > >The `build-string1` loop is similarly unrolled 4 times, and the call to >`build-string1` is not inlined in `test3`, so we really can compare the >unknown function call in `test3` to the overall loop overhead plus >`string-set!`s of `test1`. And the fact that neither `build-string1` >nor `test2 is inlined is consistent with `test2` and `test3` having the >same performance. > >If I change the `for` body of `test1` with a constant, then the time is >cut in half. So, a `string-set!` takes up about half of the time. > > >Putting that all together, it looks like a call to an unknown function >takes about twice the time of a `string-set!` --- which (due to various >tag and bounds checks for the string assignment) costs the same as a >small pile of generic arithmetic on fixnums. That could be considered >expensive in a tight loop. > >I would hesitate to say that higher order functions are always slow, >because many uses do more work around the call than set one character >in a string. > > >At Mon, 04 Aug 2014 07:42:53 +0400, Roman Klochkov wrote: >> > unknown function call is expensive >> >> So, higher order function always slow. >> Thus, to improve performance, one should use for/fold, for/list, ... and never >> use map, foldl, build-string, ... with lambda. >> Is it correct? >> >> Sun, 3 Aug 2014 13:15:57 -0400 ?? Matthias Felleisen < matthias at ccs.neu.edu >: >> > >> >Because build-string calls an unknown function 1000 x 100000 times, and an >> unknown function call is expensive.? >> > >> >Racket could possible collapse all modules and perform additional in-lining >> optimizations eventually, which may help here. But it doesn't yet.? >> > >> >-- Matthias >> > >> > >> > >> >On Aug 3, 2014, at 5:15 AM, Roman Klochkov wrote: >> >>Are higher order function always slow? >> >>... >> >>--- >> >> >> >>So I see, that build-string version is about two times slower, than >> set-in-the-loop. Why so much? I expected about 10-20% difference. >> >>-- >> >>Roman Klochkov ____________________ >> >>?Racket Users list: >> >>? http://lists.racket-lang.org/users >> > >> >> >> -- >> Roman Klochkov >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Mon Aug 4 02:40:23 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 4 Aug 2014 07:40:23 +0100 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: <20140804064026.3370C650181@mail-svr1.cs.utah.edu> At Mon, 4 Aug 2014 00:52:56 -0300, Henry Lenzi wrote: > What I'm sensing is that you seem to be concerned about bugs with > Racket Scheme's EVAL. Is that it? > I do not understand what the problem with EVAL is. Would you please > state clearly what the problems are? While he didn't say so explicitly, I don't think that Neil is worried about the implementation of `eval` within Racket. After all, `eval` is at the heart of the implementation, and any program that you give to Racket is going through `eval` whether or not the program calls the `eval` function. Speaking even more generally, I think "don't use `eval`" is intended in much the same spirit as "don't write machine code": Someone who says "don't write machine code" isn't worried about the correctness of your x86 processor. They're concerned that by programming in a relatively unstructured mode, you take on too much of the burden of accommodating the run-time environment at the bit level, whereas a higher-level language insulates you against may details. (Also, a compiler can usually produce faster machine code than a human.) Similarly, the problem with using `eval` is that you take on a burden of managing binding at a relatively low symbolic level, and you have to worry a lot about the dynamic context. As an extreme example, if you write (eval (list '+ x x)) intending to add `x` to itself, then you have to worry about whether `+` still means addition --- as opposed to having `+` given a different meaning by the time the `eval` is called. In contrast, #lang racket (define (f x) (+ x x)) means that `f` always adds its argument to itself, no matter what has happened before. (And that `f` will be way faster than using `eval`.) There are good and robust ways to use `eval` within Racket, just like there are good and robust ways to generate machine code. But it's exactly the job of a programming language to encode the good ways to do things, and that's why so many on this list are eager to see you write #lang prescription HCTZ25 30 CP 1XD instead of having "HCTZ25 30 CP 1XD" sit in a file that is sent in some pieces through `eval`. We've learned that's just better to encode things as languages. Now, for someone in your position, the difference in this specific case is subtle, because a doctor who writes HCTZ25 30 CP 1XD versus the "#lang prescription" above doesn't write `eval` either way. It would seem that as the implementor of the language, you're the one who properly has to deal with `eval`, and it makes sense for your language implementation to call `eval`. And yes... but it can be much better if you arrange for #lang prescription HCTZ25 30 CP 1XD to become to something like #lang racket/base (import prescription/defs) (hctz25 30 cp 1xd) where `prescripton/defs` contains (define hctz25 "Hydrochlorothiazide 25mg") ... That is, instead of dynamically making "HCTZ25 30 CP 1XD" have the effect of the Racket expression, actually compile it statically to the Racket expression. Then, you're saying what you mean at a much higher level what you intend to implement, and Racket can give you a lot more help. For example, if a doctor accidentally types #lang prescription HCTZ25 30 CP add1 then instead of getting a weird run-time error about trying to use a procedure as a string, then the doctor will get an error message that `add1` is not a known identifier --- assuming that you did not intend for `add1` to be included as part of the language. (If you intended to include `add1`, then I think we can find any number of bindings that you really do not intend for prescriptions authors to use.) Again, it's possible to arrange for just the right bindings to be in the namespace that you provide to `eval`. By always trying to write things in terms of a language (as reflected by a module), however, Racket can provide much better tools to help you say what you mean, and it can provide a lot more efficiently and automatically. There is a learning curve to doing this this way. We're working to make that curve flatter, but he have a ways to go ourselves. But hopefully that helps explain the general reaction to `eval` here. From antonio.menezes.leitao at ist.utl.pt Mon Aug 4 04:24:37 2014 From: antonio.menezes.leitao at ist.utl.pt (Antonio Menezes Leitao) Date: Mon, 4 Aug 2014 09:24:37 +0100 Subject: [racket] Bug in scribble's image-element? Message-ID: Hi, I'm trying to set the scale of an image-element for a SVG file but the generated html does not seem to reflect my settings. While looking at the code in shared/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt I noticed that the scale of an image-element affects the size of PNGs and GIFs but not SVGs. Is this the intended behavior? Is there another way to affect the scale of a SVG image? Best, Antonio. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jensaxel at soegaard.net Mon Aug 4 05:35:24 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Mon, 4 Aug 2014 11:35:24 +0200 Subject: [racket] Bug in scribble's image-element? In-Reply-To: References: Message-ID: It is not intended. I am not sure whether it simply doesn't work, or whether it is browser related. SVG images are currently inserted with an html tag where as the other images are inserted as . The width and height attributes are set in both cases. I can't remember why svg images were inserted with an object tag. According to http://caniuse.com/svg-img it seems support for svg image using the img tag is fine: http://caniuse.com/svg-img IE8 and old versions of IOS are missing from the list though. Scaling svg as objects might be trickier though. I am not sure what the Right Thing is: http://stackoverflow.com/questions/644896/how-do-i-scale-a-stubborn-svg-embedded-with-the-object-tag /Jens Axel 2014-08-04 10:24 GMT+02:00 Antonio Menezes Leitao : > Hi, > > I'm trying to set the scale of an image-element for a SVG file but the > generated html does not seem to reflect my settings. > > While looking at the code in > shared/pkgs/scribble-pkgs/scribble-lib/scribble/html-render.rkt I noticed > that the scale of an image-element affects the size of PNGs and GIFs but not > SVGs. Is this the intended behavior? Is there another way to affect the > scale of a SVG image? > > Best, > Antonio. > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -- -- Jens Axel S?gaard From neil at neilvandyke.org Mon Aug 4 06:00:25 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Mon, 04 Aug 2014 06:00:25 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <20140804064026.3370C650181@mail-svr1.cs.utah.edu> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> <20140804064026.3370C650181@mail-svr1.cs.utah.edu> Message-ID: <53DF59B9.5070005@neilvandyke.org> Matthew Flatt wrote at 08/04/2014 02:40 AM: > While he didn't say so explicitly, I don't think that Neil is worried > about the implementation of `eval` within Racket. After all, `eval` is > at the heart of the implementation, and any program that you give to > Racket is going through `eval` whether or not the program calls the > `eval` function. Correct. I breathe oxygen constantly, without thinking about it, but I'd never use a fuel-air explosive to mow my lawn. Neil V. From antonio.menezes.leitao at ist.utl.pt Mon Aug 4 08:20:24 2014 From: antonio.menezes.leitao at ist.utl.pt (Antonio Menezes Leitao) Date: Mon, 4 Aug 2014 13:20:24 +0100 Subject: [racket] Bug in scribble's image-element? In-Reply-To: References: Message-ID: On Mon, Aug 4, 2014 at 10:35 AM, Jens Axel S?gaard wrote: > It is not intended. I am not sure whether it simply doesn't work, or > whether > it is browser related. > > SVG images are currently inserted with an html tag where as the > other > images are inserted as . The width and height attributes are set in > both > cases. > Indeed. But in the case of PNGs and GIFs they have their width and height adjusted by the scale, while SVGs do not. I did not test other browsers, but recent versions of Chrome and IE seem to honor the scaled size. In fact, I'm currently using a patched html-render.rkt to generate documentation containing tons of tikz pictures, and it looks great. Each picture is converted to svg by pdflatex+standalone+pdf2svg and then included in an image-element with an appropriate scaling factor. Before, I was converting everything to PNGs but the documentation was taking inordinate amounts of disk space. Obviously, I would prefer to use an officially maintained version of Scribble that supports scaled SVGs. Best, Antonio. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Mon Aug 4 10:15:32 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Mon, 4 Aug 2014 10:15:32 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53DF59B9.5070005@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> <20140804064026.3370C650181@mail-svr1.cs.utah.edu> <53DF59B9.507 0005@neilvandyke.org> Message-ID: On Aug 4, 2014, at 6:00 AM, Neil Van Dyke wrote: > > Matthew Flatt wrote at 08/04/2014 02:40 AM: >> While he didn't say so explicitly, I don't think that Neil is worried >> about the implementation of `eval` within Racket. After all, `eval` is >> at the heart of the implementation, and any program that you give to >> Racket is going through `eval` whether or not the program calls the >> `eval` function. > > Correct. I breathe oxygen constantly, without thinking about it, but I'd never use a fuel-air explosive to mow my lawn. Off topic but I couldn't resist; see link/picture below from a recent trip to a workshop in Germany, where they use flamethrowers to burn off grass :-) http://www.ccs.neu.edu/home/matthias/Tmp/mowing-the-lawn-in-germany.jpeg -------------- next part -------------- An HTML attachment was scrubbed... URL: From lysseus at gmail.com Mon Aug 4 11:39:27 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Mon, 4 Aug 2014 08:39:27 -0700 Subject: [racket] big-bang bug when creating racket distribution executable? Message-ID: <58ADFB0A-93F3-4ABD-BE97-5433A54ABEEE@gmail.com> When you run big-bang in Dr Racket and the stop-when evaluates true the window remains open to display the final image (when specified) and must be manually closed by the user. However, running the racket executable created for distribution closes the window and returns you to terminal as soon as stop-when is returns true, thus bringing the execution to a jarring halt without adequately displaying the final image (it?s hard to tell whether it displays because the action is so quick). This appears to be the case for both Windows and Mac installers. Is this a bug or how the process is designed to work? Below is a link to some very basic racket code and a mac installer to demonstrate the effect: https://dl.dropboxusercontent.com/u/4859392/test5.rkt https://dl.dropboxusercontent.com/u/4859392/test5.dmg If this is how it?s designed to work, then stop-when, for executable distribution is probably not a desired handler for what I?m intending, as I seldom want the window to close automatically when big-bang terminates, but would prefer the user to close the window manually. I can probably achieve this with some finagling of the world state, but the two different behaviors between Dr Racket and distribution was surprising. ?Kevin From matthias at ccs.neu.edu Mon Aug 4 12:31:12 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Mon, 4 Aug 2014 12:31:12 -0400 Subject: [racket] big-bang bug when creating racket distribution executable? In-Reply-To: <58ADFB0A-93F3-4ABD-BE97-5433A54ABEEE@gmail.com> References: <58ADFB0A-93F3-4ABD-BE97-5433A54ABEEE@gmail.com> Message-ID: <17C36348-F17D-4164-8EF1-04BB52D7883F@ccs.neu.edu> I can confirm the behavior, which is visible under both *SL and Racket and all methods for creating executable. For a workaround, use this for now: #lang racket/gui (require 2htdp/universe 2htdp/image) (define (render ws) ws) (define (halt ws) #t) (big-bang (rectangle 600 400 'solid 'gold) (to-draw render) (stop-when halt render)) (yield (make-semaphore)) -- Matthias On Aug 4, 2014, at 11:39 AM, Kevin Forchione wrote: > When you run big-bang in Dr Racket and the stop-when evaluates true the window remains open to display the final image (when specified) and must be manually closed by the user. However, running the racket executable created for distribution closes the window and returns you to terminal as soon as stop-when is returns true, thus bringing the execution to a jarring halt without adequately displaying the final image (it?s hard to tell whether it displays because the action is so quick). This appears to be the case for both Windows and Mac installers. Is this a bug or how the process is designed to work? > > Below is a link to some very basic racket code and a mac installer to demonstrate the effect: > > https://dl.dropboxusercontent.com/u/4859392/test5.rkt > > https://dl.dropboxusercontent.com/u/4859392/test5.dmg > > If this is how it?s designed to work, then stop-when, for executable distribution is probably not a desired handler for what I?m intending, as I seldom want the window to close automatically when big-bang terminates, but would prefer the user to close the window manually. I can probably achieve this with some finagling of the world state, but the two different behaviors between Dr Racket and distribution was surprising. > > ?Kevin > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From lysseus at gmail.com Mon Aug 4 13:10:58 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Mon, 4 Aug 2014 10:10:58 -0700 Subject: [racket] big-bang bug when creating racket distribution executable? In-Reply-To: <17C36348-F17D-4164-8EF1-04BB52D7883F@ccs.neu.edu> References: <58ADFB0A-93F3-4ABD-BE97-5433A54ABEEE@gmail.com> <17C36348-F17D-4164-8EF1-04BB52D7883F@ccs.neu.edu> Message-ID: On Aug 4, 2014, at 9:31 AM, Matthias Felleisen wrote: > #lang racket/gui > > (require 2htdp/universe 2htdp/image) > > (define (render ws) ws) > > (define (halt ws) #t) > > (big-bang (rectangle 600 400 'solid 'gold) > (to-draw render) > (stop-when halt render)) > > (yield (make-semaphore)) > Thanks! That sorts it for me. And it signifies a gap in my understanding of event handling and threads that I?ll have to remedy. :) ?Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Mon Aug 4 14:09:59 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Mon, 4 Aug 2014 14:09:59 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: Then would something like this work? #lang racket (provide (all-defined-out) #%datum #%top (rename-out [new-module-begin #%module-begin])) (define-syntax-rule (new-module-begin med-thing ...) (#%module-begin (displayln (parse-meds (list med-thing ...))))) (define (parse-meds lst) (match lst [(list) ""] [(list-rest MED QUANT FORM POS (? inst? INST) rest) (~a MED " " line " " QUANT " " FORM "\n" POS "\n" INST "\n" (parse rest))] [(list-rest MED QUANT FORM POS rest) (~a MED " " line " " QUANT " " FORM "\n" POS "\n" (parse rest))])) (define hctz25 "Hydrochlorothiazide 25mg") (define simva20 "Simvastatin 20mg") (define pl "pills") (define 1xd "Take 1 pill P.O. 1x/day") (define 1xn "Take 1 pill P.O. 1x at night") (define INSTOMZ "half an hour before breakfast, with a glass of water") (define line "-----------") (define (inst? x) (equal? x INSTOMZ)) On Aug 4, 2014, at 1:22 AM, Henry Lenzi wrote: > Hello Alex -- > > This is nice, the problem is separating the output into the proper > formatting. I feel this has to be done a step before the expansion > into the string form. > One thing I'm considering is that that the DSL is made of MED QUANT > FORM POS or MED QUANT FOR POS INST, so 4 or 5 items. > If we have a symbol list (before string expansion), than we can treat > INST as the divider marker. Otherwise, there's a linebreak at every > fourth item. > > I'm looking into how to to this using a position function: > (define (position item list) > (- (length list) > (length (member item list)))) > > Knowing where the INST instructions occur help up decided whether we > can break a line into the > MED QUANT FORM > POS > or > MED QUANT FORM > POS > INST > > forms (see the code snippet on http://pasterack.org/pastes/14535 ) > > > Cheers, > > Henry > > On Mon, Aug 4, 2014 at 1:23 AM, Alexander D. Knauth > wrote: >> Would this work for what you want? >> >> If med.rkt contains this: >> #lang racket >> >> (provide (all-defined-out) >> #%datum #%top >> (rename-out [new-module-begin #%module-begin])) >> >> (define-syntax-rule >> (new-module-begin med-thing ...) >> (#%module-begin (display (~a med-thing ... #:separator " ")))) >> >> (define hctz25 "Hydrochlorothiazide 25mg") >> (define simva20 "Simvastatin 20mg") >> (define pl "pills") >> (define 1xd "Take 1 pill P.O. 1x/day") >> (define 1xn "Take 1 pill P.O. 1x at night") >> (define INSTOMZ "half an hour before breakfast, with a glass of water") >> (define line "-----------") >> >> And try-it.rkt contains this: >> #lang s-exp "med.rkt" >> hctz25 30 pl 1xd >> simva20 30 pl 1xn >> >> Then running try-it.rkt will produce the output: >> Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg >> 30 pills Take 1 pill P.O. 1x at night >> >> Or if new-module-begin is defined like this instead: >> (define-syntax-rule >> (new-module-begin med-thing ...) >> (#%module-begin (provide data) (define data (~a med-thing ... #:separator >> " ")))) >> >> Then doing (require ?try-it.rkt?) will import data as the string >> "Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg >> 30 pills Take 1 pill P.O. 1x at night". >> >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Mon Aug 4 14:16:18 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Mon, 4 Aug 2014 14:16:18 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: Oh sorry I meant this for parse-meds: (define (parse-meds lst) (match lst [(list) ""] [(list-rest MED QUANT FORM POS (? inst? INST) rest) (~a MED " " line " " QUANT " " FORM "\n" POS "\n" INST "\n" (parse-meds rest))] [(list-rest MED QUANT FORM POS rest) (~a MED " " line " " QUANT " " FORM "\n" POS "\n" (parse-meds rest))])) On Aug 4, 2014, at 2:09 PM, Alexander D. Knauth wrote: > Then would something like this work? > #lang racket > > (provide (all-defined-out) > #%datum #%top > (rename-out [new-module-begin #%module-begin])) > > (define-syntax-rule > (new-module-begin med-thing ...) > (#%module-begin (displayln (parse-meds (list med-thing ...))))) > > (define (parse-meds lst) > (match lst > [(list) ""] > [(list-rest MED QUANT FORM POS (? inst? INST) rest) > (~a MED " " line " " QUANT " " FORM "\n" POS "\n" INST "\n" (parse rest))] > [(list-rest MED QUANT FORM POS rest) > (~a MED " " line " " QUANT " " FORM "\n" POS "\n" (parse rest))])) > > (define hctz25 "Hydrochlorothiazide 25mg") > (define simva20 "Simvastatin 20mg") > (define pl "pills") > (define 1xd "Take 1 pill P.O. 1x/day") > (define 1xn "Take 1 pill P.O. 1x at night") > (define INSTOMZ "half an hour before breakfast, with a glass of water") > (define line "-----------") > > (define (inst? x) > (equal? x INSTOMZ)) > > > On Aug 4, 2014, at 1:22 AM, Henry Lenzi wrote: > >> Hello Alex -- >> >> This is nice, the problem is separating the output into the proper >> formatting. I feel this has to be done a step before the expansion >> into the string form. >> One thing I'm considering is that that the DSL is made of MED QUANT >> FORM POS or MED QUANT FOR POS INST, so 4 or 5 items. >> If we have a symbol list (before string expansion), than we can treat >> INST as the divider marker. Otherwise, there's a linebreak at every >> fourth item. >> >> I'm looking into how to to this using a position function: >> (define (position item list) >> (- (length list) >> (length (member item list)))) >> >> Knowing where the INST instructions occur help up decided whether we >> can break a line into the >> MED QUANT FORM >> POS >> or >> MED QUANT FORM >> POS >> INST >> >> forms (see the code snippet on http://pasterack.org/pastes/14535 ) >> >> >> Cheers, >> >> Henry >> >> On Mon, Aug 4, 2014 at 1:23 AM, Alexander D. Knauth >> wrote: >>> Would this work for what you want? >>> >>> If med.rkt contains this: >>> #lang racket >>> >>> (provide (all-defined-out) >>> #%datum #%top >>> (rename-out [new-module-begin #%module-begin])) >>> >>> (define-syntax-rule >>> (new-module-begin med-thing ...) >>> (#%module-begin (display (~a med-thing ... #:separator " ")))) >>> >>> (define hctz25 "Hydrochlorothiazide 25mg") >>> (define simva20 "Simvastatin 20mg") >>> (define pl "pills") >>> (define 1xd "Take 1 pill P.O. 1x/day") >>> (define 1xn "Take 1 pill P.O. 1x at night") >>> (define INSTOMZ "half an hour before breakfast, with a glass of water") >>> (define line "-----------") >>> >>> And try-it.rkt contains this: >>> #lang s-exp "med.rkt" >>> hctz25 30 pl 1xd >>> simva20 30 pl 1xn >>> >>> Then running try-it.rkt will produce the output: >>> Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg >>> 30 pills Take 1 pill P.O. 1x at night >>> >>> Or if new-module-begin is defined like this instead: >>> (define-syntax-rule >>> (new-module-begin med-thing ...) >>> (#%module-begin (provide data) (define data (~a med-thing ... #:separator >>> " ")))) >>> >>> Then doing (require ?try-it.rkt?) will import data as the string >>> "Hydrochlorothiazide 25mg 30 pills Take 1 pill P.O. 1x/day Simvastatin 20mg >>> 30 pills Take 1 pill P.O. 1x at night". >>> >>> >>> > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From jensaxel at soegaard.net Mon Aug 4 16:16:53 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Mon, 4 Aug 2014 22:16:53 +0200 Subject: [racket] Ready for the next phase - or how to shift the phase of a namespace In-Reply-To: References: <36B89052-5DAE-477C-B9B2-4C9E5915C0F6@ccs.neu.edu> Message-ID: For the archives the functions eval-for-meta ; evaluate expression in given phase and return result eval-for-syntax ; evaluate expression in phase 1 and return result eval-form-for-meta ; evaluate form in given phase eval-form-for-syntax ; evaluate form in phase 1 syntax-value ; return the value associated with a syntax binding in a given phase are available here: https://github.com/soegaard/meta/blob/master/expander/transformer.rkt /Jens Axel 2014-07-20 1:39 GMT+02:00 Jens Axel S?gaard : > 2014-07-20 1:19 GMT+02:00 Matthias Felleisen : >> >> Can't you just put forms2 into a constructed module that requires the desired module at the phase where you want it? -- Matthias > > That would be tricky. I am writing an interpreter that evaluates > Racket bytecode represented as zo-structures. > > The main entry is: > > ; eval-zo : compilation-top [namespace] -> values(s) > (define (eval-zo zo [ns (make-start-namespace)]) > (unless (compilation-top? zo) > (error 'eval-zo "expected a compilation-top, got ~a" zo)) > ; evaluation always occur within a top-level namespace > (parameterize ([current-namespace ns]) > (eval-top zo))) > > The structure of the interpreter is a straight forward recursive descent. > The "phase 0" forms and expressions are done and works fine. > I have also managed to evaluate the stxs part of the prefix. > The instruction I need shift-phase for is seq-for-syntax. > > From the docs on begin-for-syntax: > Evaluation of an expr within begin-for-syntax is parameterized to > set current-namespace as in let-syntax. > From the docs on (let-syntax ([id trans-expr] ...) body ...+) > The evaluation of each trans-expr is parameterized to > set current-namespace to a namespace that shares > bindings and variables with the namespace being used to > expand the let-syntax form, except that its base phase is one greater. > > > Here is what I'd like to write: > > (define (eval-form form globs stack closed stx-ht) > (match form > ... > [(struct seq-for-syntax (forms prefix max-let-depth dummy)) > ; push the prefix > (define array (eval-prefix prefix stx-ht)) > (define new-stack (mlist array stack)) > ; shift phase and evalate each form > (parameterize ([current-namespace (shift-phase (current-namespace) +1)]) > (for ([form (in-list forms)]) > (let-syntaxes ([() (begin (eval-form (car forms) globs > new-stack closed stx-ht) > (values))]) > (void))))] > > /Jens Axel > >> On Jul 19, 2014, at 3:52 PM, Jens Axel S?gaard wrote: >> >>> I am looking for a way to change the base phase of a namespace. >>> Or perhaps to make a new namespace with the same mappings except a >>> shift in phases. >>> I hope I have missed a trick, but I couldn't find a >>> namespace-shift-phase in the docs. >>> >>> Consider the following program which defines a variable x to 0, 1, 2, and, 3 >>> in phases 0, 1, 2, and, 3 respectively. It does so by evalunting the >>> forms in forms. >>> >>> Then it displays the values of x in phases 1 and 2 with the results 1 and 2. >>> It does so by evaluating the forms in forms2. >>> >>> I'd like to shift the base phase of the namespace (or make a copy with >>> new base phase), >>> so evaluating the forms in forms2 again will give results 2 and 3. >>> >>> #lang racket >>> (define (eval* forms [ns (current-namespace)]) >>> (for ([form forms]) >>> (displayln (~a "> " form)) >>> (eval form ns))) >>> >>> (define forms '((module m0 racket (provide x) (define x 0)) >>> (module m1 racket (provide x) (define x 1)) >>> (module m2 racket (provide x) (define x 2)) >>> (module m3 racket (provide x) (define x 3)) >>> (require (for-meta 0 'm0)) >>> (require (for-meta 1 'm1)) >>> (require (for-meta 2 'm2)) >>> (require (for-meta 3 'm3)))) >>> >>> (define forms2 '(; display the value of x in phase 1 >>> (define-syntaxes () (begin (displayln x) (values))) >>> ; display the value of x in phase 2 >>> (define-syntaxes () (begin (let-syntaxes ([() (begin >>> (displayln x) (values))]) >>> (void)) (values))))) >>> >>> (define ns (make-base-empty-namespace)) >>> (parameterize ([current-namespace ns]) >>> ; setup the namespace >>> (namespace-require '(for-meta 0 racket/base)) >>> (namespace-require '(for-meta 1 racket/base)) >>> (namespace-require '(for-meta 2 racket/base)) >>> (namespace-require '(for-meta 3 racket/base)) >>> ; declare and require the modules >>> (eval* forms) >>> ; display the value of x in phase 1 and 2 >>> (eval* forms2) ; displays 1 and 2 >>> ; (namespace-shift-phase ns +1) ; on the wish list >>> ; (eval* forms2) ; would display 2 and 3 >>> ) >>> >>> The output is: >>> >>>> (module m0 racket (provide x) (define x 0)) >>>> (module m1 racket (provide x) (define x 1)) >>>> (module m2 racket (provide x) (define x 2)) >>>> (module m3 racket (provide x) (define x 3)) >>>> (require (for-meta 0 (quote m0))) >>>> (require (for-meta 1 (quote m1))) >>>> (require (for-meta 2 (quote m2))) >>>> (require (for-meta 3 (quote m3))) >>>> (define-syntaxes () (begin (displayln x) (values))) >>> 1 >>>> (define-syntaxes () (begin (let-syntaxes ((() (begin (displayln x) (values)))) (void)) (values))) >>> 2 >>> >>> -- >>> Jens Axel S?gaard >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> > > > > -- > -- > Jens Axel S?gaard -- -- Jens Axel S?gaard From jensaxel at soegaard.net Mon Aug 4 16:23:11 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Mon, 4 Aug 2014 22:23:11 +0200 Subject: [racket] Racket VM in Racket Message-ID: Hi All, To see how Racket's bytecodes work I have implemented an evaluator in Racket. The best feature is the extensive amount of comments. https://github.com/soegaard/meta/blob/master/runtime/racket-eval.rkt Comments and patches are welcome, Jens Axel S?gaard From samth at cs.indiana.edu Mon Aug 4 17:18:18 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Mon, 4 Aug 2014 14:18:18 -0700 Subject: [racket] Puzzled about type inference In-Reply-To: <2738E9A7-5EFD-4FC9-8083-2F4AEE30C380@ccs.neu.edu> References: <2738E9A7-5EFD-4FC9-8083-2F4AEE30C380@ccs.neu.edu> Message-ID: Here's how I would annotate the original program, using Matthias' type definitions: ``` #lang typed/racket (: 1+ (Nonnegative-Integer -> Positive-Integer)) (define (1+ n) (+ n 1)) ;; entirely unnecessary but helped me read; IGNORE (define-type (Maybe ?) (U False ?)) (define-type NI Nonnegative-Integer) (define-type LNI (Listof NI)) (define-type VNI (Vectorof NI)) (let* ((idx+level : (Listof LNI) (map #{vector->list @ NI} (ann '(#(1 2) #(3 4) #(5 6)) (Listof VNI)))) (res : (Vectorof (Maybe NI)) (make-vector (1+ (apply max (map #{car @ NI LNI} idx+level))) #f))) (for-each (? ((p : LNI)) (let ((i (car p)) (l (cadr p))) (vector-set! res i l))) idx+level) res) ;; expect '#(#f 2 #f 4 #f 6) ``` The most signficant differences are (1) I'm not using `cast`, which should be avoided when possible. `cast` is a runtime operation, and might be hiding arbitrary bugs. (2) I've annotated the `let`-bound variables, which makes life easier on the rest of the type checker and helps improve error messages. There are a few things that make this program require more annotations than I'd like. 1. TR doesn't handle automatically inferring type arguments when polymorphic functions (like `map`) are given polymorphic arguments like `vector->list`. While fixing this would require work, it just needs to be done -- there's no reason we shouldn't be able to make this work. 2. Inference doesn't allow TR to figure out that it should use Nonnegative-Integer for the contents of the vectors, and so it falls back on guessing that it should type them as integers. If Typed Racket knew about immutable vectors, then we could do better here, similarly if inference worked better. Sam On Sun, Aug 3, 2014 at 8:12 PM, Matthias Felleisen wrote: > > After some reflection, here is how I think you should proceed: > > #lang typed/racket > > (: 1+ (Nonnegative-Integer -> Positive-Integer)) > (define (1+ n) > (+ n 1)) > > ;; entirely unnecessary but helped me read > (define-type (Maybe ?) (U False ?)) > (define-type NI Nonnegative-Integer) > (define-type LNI (Listof NI)) > (define-type VNI (Vectorof NI)) > (define-type LVNI (Listof VNI)) > > (let* ((given : LVNI '(#(1 2) #(3 4) #(5 6))) > (length : NI (1+ (apply max (map (lambda ({x : VNI}) (vector-ref x 0)) given)))) > (result : [Vectorof [Maybe NI]] (make-vector length #f))) > (for ((q : VNI (in-list given))) > (vector-set! result (vector-ref q 0) (vector-ref q 1))) > result) > > > The above -- minus types -- is how I would probably write the code in Racket, following the style guide. (I would use three defines instead of let* but let's ignore this point.) I would use > -- given as a parameter (I am guessing here) > -- length to tell the reader that this is the new length of the vector > -- result to spell out what this vector is about > > The for-loop would use a single line because it is short and brings across the idea. > > If I were to move this code to Typed Racket, I'd add a type declaration to each identifier just like in any other (explicitly, statically) typed programming language. That's what I did, and there was no problem checking and running your code. > > -- Matthias > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From henry.lenzi at gmail.com Mon Aug 4 19:21:56 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Mon, 4 Aug 2014 20:21:56 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53DEFB76.1010309@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: I was just wondering, Neil. what your experience in "production for pharmaceutical prescriptions/labeling/instructions" software would be. I'd be glad to read some stuff you've published or other software solutions, if it's not proprietary software. If it is, what companies have you worked for in the health sector? Regards, Henry Lenzi On Mon, Aug 4, 2014 at 12:18 AM, Neil Van Dyke wrote: > I can see how someone might want to do tricks like this, to use the REPL as > user interface, for tinkering, and that could be very interesting or clever. > > However, just to be clear to students and professionals who might stumble > upon this thread... If I were actually doing this in production for > pharmaceutical prescriptions/labeling/instructions, then I would be > concerned about both program correctness and reducing potential for operator > error to cause failures. If we were starting with those as key requirements > for production use, then I think some of this technical discussion might be > irrelevant to that, since the software might be implemented in a very > different way. > > Neil V. > From henry.lenzi at gmail.com Mon Aug 4 19:43:04 2014 From: henry.lenzi at gmail.com (Henry Lenzi) Date: Mon, 4 Aug 2014 20:43:04 -0300 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53DF2441.4030409@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> <53DF2441.4030409@neilvandyke.org> Message-ID: Hi Neil -- Thanks for the answer. Let's see... * Prevents much static checking. ----> not really an issue in this case (I don't see it). * Likely increased difficulty debugging ---> true. * Often executes arbitrary code with privileges, which might be corrupted due to accident or attack, which can be very bad. --> That's bad. But see my comment about the environment I'm in. User input validation helps here. * Prevents some optimization. ---> not really necessary. Prescriptions are short, to worry about optimizations here, with today's machines, doesn't seem a real issue. * Crutch that prevents learning better idioms. ---> then whatever happend to symbolic computation? Are we to program like Perl people do? It seems there are very good reasons to avoid eval. However, they seem to apply to larger systems in a different environment. I'm not out to write a large system for a large hospital service in a secure setting. By the way, if you guys had any idea of the buggy stuff people sell to the health sector. The atrocious VB, MFC C++, Java... I'm not even goint to mention security.. The use of EVAL does not seem to hamper the creation of a syntax-validation parser, at a latter time. Best regards, Henry Lenzi On Mon, Aug 4, 2014 at 3:12 AM, Neil Van Dyke wrote: > Henry Lenzi wrote at 08/03/2014 11:52 PM: > >> What I'm sensing is that you seem to be concerned about bugs with >> Racket Scheme's EVAL. Is that it? >> I do not understand what the problem with EVAL is. Would you please >> state clearly what the problems are? > > > Eval is one of the issues. Sorry I have to be very brief right now, but a > few problems with eval in general are: > * Prevents much static checking. > * Likely increased difficulty debugging. > * Often executes arbitrary code with privileges, which might be corrupted > due to accident or attack, which can be very bad. > * Prevents some optimization. > * Crutch that prevents learning better idioms. > > Also, things like reading in a code file and looking for markers in it is > something we sometimes do (especially in, say, Emacs editing mode, in which > likely oopses are not so grave), but failure-prone. > > Also, the code I saw was not idiomatic in, say, how it uses globals. > > Anyway, it's good that Racket lets people experiment this way. The concern > I have in my mind is that newbies reading language forums often get ideas > about idiomatic programming from examples they see, and even copy&adapt > examples they see (maybe even evolving it into production code, or blogging > it where other newbies pick up on it...). People should experiment as much > as they liked, but I think it would be good to if newbies knew when > something they're looking at is an experiment rather than (yet) considered > best practice. > > I appreciate your participation in the community, and your experimenting. > > Neil V. > From neil at neilvandyke.org Mon Aug 4 20:07:29 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Mon, 04 Aug 2014 20:07:29 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> Message-ID: <53E02041.7080202@neilvandyke.org> Henry Lenzi wrote at 08/04/2014 07:21 PM: > I was just wondering, Neil. what your experience in "production for > pharmaceutical prescriptions/labeling/instructions" software would be. > > I'd be glad to read some stuff you've published or other software > solutions, if it's not proprietary software. If it is, what companies > have you worked for in the health sector? There have been many decades of work in software engineering for military/aerospace/datacommunications, which gives some background that can also be applied to, say, medical informatics. For one example familiar to me, I worked on software tools and methodology that were used for things like (to give one specific, public example) designing the cockpit system for a particular model of military aircraft. Some of my colleagues from back then later went to work on medical devices, which share some requirements for correctness and robustness. The fields of medicine have ongoing tremendous accomplishments. Many of the roles, such as physicians and pharma scientists, require immense training and discipline. Still, as medical fields get more into areas of informatics and of process, my understanding is that they are currently learning from more established fields. For one example: the widely-publicized finding that hospital staff following a "pre-flight checklist" each time when hooking up a patient lowered infection rates greatly. That's many decades behind what people who work on aviation process have further found about process. I'm not sure how to connect this general to individual computer programming practices, except to say that, in clusters of people who have done such-and-such kind of production work, I think that there is often general agreement about some of the best practices and pitfalls. For an example bringing us back to this email thread, many people on this email list come from different backgrounds of software development, to be enthusiasts of an especially powerful dynamic language platform, yet it seems that the majority(?) of us arrived at a wariness of "eval" independently, even though I'm not aware of any textbook that says "don't use eval" (textbooks often accidentally suggest the opposite). BTW, "Don't use eval" is just one tip of many, and I didn't intend to spend so much text on it in this thread. Neil V. From neil at neilvandyke.org Mon Aug 4 20:43:15 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Mon, 04 Aug 2014 20:43:15 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> <53DF2441.4030409@neilvandyke.org> Message-ID: <53E028A3.2070000@neilvandyke.org> Henry Lenzi wrote at 08/04/2014 07:43 PM: > By the way, if you guys had any idea of the buggy stuff people sell to > the health sector. The atrocious VB, MFC C++, Java... I'm not even > goint to mention security.. Heh. I have seen some of that, and actually suggested to one of my consulting clients that they consider diversifying into this application domain. I suspect that one "dream team" would have a mix of domain experts, people who understand the legacy/contemporary software systems and history, a couple top architects/gurus, and solid software engineers and human factors engineers who are sharp and flexible enough to work within the framework that the architects/gurus lead. (I separate out architects/gurus for this particular field because there seems to be a need to shake things up right now with technical direction. However, I *don't* mean an antiquated chief programmer model, which I think led many to view software development as top-down management of clerical workers, especially in corporate MIS-like shops, and which I suspect has been a big contributor to many gazillion-dollar IT failures.) Neil V. From asumu at ccs.neu.edu Tue Aug 5 02:21:48 2014 From: asumu at ccs.neu.edu (Asumu Takikawa) Date: Tue, 5 Aug 2014 02:21:48 -0400 Subject: [racket] Ubuntu PPA update for 6.1 Message-ID: <20140805062148.GN20640@localhost> Hi all, The Ubuntu PPA for Racket has been updated to v6.1: https://launchpad.net/~plt/+archive/ubuntu/racket There are only packages for trusty and precise this time (the others have been deprecated on the build server). Let me know if you have any issues. I may not respond very quickly though due to travel. Cheers, Asumu From norman at astro.gla.ac.uk Tue Aug 5 05:36:15 2014 From: norman at astro.gla.ac.uk (Norman Gray) Date: Tue, 5 Aug 2014 10:36:15 +0100 Subject: [racket] Puzzled about type inference In-Reply-To: References: Message-ID: Matthias and Sam, hello. This has been a very useful brief thread for me, and also, I suspect, for others. On 2014 Aug 4, at 01:22, Matthias Felleisen wrote: > In a sense, you put your finger on a sore spot of TR from R -- we are still figuring out how to help programmers along here. Such help would be most valuable! > ;; entirely unnecessary but helped me read; IGNORE > (define-type (Maybe ?) (U False ?)) > (define-type NI Nonnegative-Integer) > (define-type LNI (Listof NI)) > (define-type VNI (Vectorof NI)) This is clearly a good idiom/pattern: very local, and telegraphically short, abbreviations for useful types. > Then I checked on the maps and realized that I need to help the TC along with the instantiations of vector->list (how can it know with context-free reasoning what kind of vector it is) and the same for car (how can it know what kind of list you're getting here). So this returns to the question of what the TC can and cannot be expected to work out for itself, and I see that Sam had a couple of remarks on this later. > (let* ((given : LVNI '(#(1 2) #(3 4) #(5 6))) > (length : NI (1+ (apply max (map (lambda ({x : VNI}) (vector-ref x 0)) given)))) > (result : [Vectorof [Maybe NI]] (make-vector length #f))) > (for ((q : VNI (in-list given))) > (vector-set! result (vector-ref q 0) (vector-ref q 1))) > result) > > The above -- minus types -- is how I would probably write the code in Racket, following the style guide. (I would use three defines instead of let* but let's ignore this point.) That looks _much_ nicer than what I had, and is still perfectly readable. > If I were to move this code to Typed Racket, I'd add a type declaration to each identifier just like in any other (explicitly, statically) typed programming language. That's what I did, and there was no problem checking and running your code. So the pattern I see there, which both you and Sam have illustrated, is: * annotate as far 'down' the tree as possible, so that type information can propagate upwards in the parse tree * If one liberally uses named bindings (recommended on other style grounds, in any case), then each of these is a natural location for a type annotation * when a polymorphic-typed function takes polymorphic arguments, annotate the arguments, not the function (that is, I see that, in (map car '(foo ...)) both you and Sam annotated the car, not the map); this is in harmony with 'annotate as far down as possible', for some value of 'down'. Sam said: > The most signficant differences are (1) I'm not using `cast`, which > should be avoided when possible. `cast` is a runtime operation, and > might be hiding arbitrary bugs. (2) I've annotated the `let`-bound > variables, which makes life easier on the rest of the type checker and > helps improve error messages. Ah, now this is something I've meant to ask about: what's the difference between ann and cast? The manual says: > (ann e t) > Ensure that e has type t, or some subtype. The entire expression has type t. This is legal only in expression contexts. > (cast e t) > The entire expression has the type t, while e may have any type. The value of the entire expression is the value returned by e, protected by a contract ensuring that it has type t. This is legal only in expression contexts. I've never been sure whether the difference between "Ensure that e has type t" (which sounds rather runtime-y) and "The entire expression has the type t" is significant. The only difference I could parse from this is that `cast` includes a contract, which would appear to make it _safer_ than `ann`, in the sense that if this were accidentally given a wrong-typed value than it would cause an immediate error. I presume that the difference is that `ann` is about static type analysis, whereas `cast` is for the situation where that static analysis can't be done. Would I be correct that in the above case I can and should write (ann '(#(1 2) #(3 4) #(5 6)) (Listof VNI) since this is saying that this expression has a more specific type than the TC would work out by itself, and it can verify that the restriction is possible. In the real program, these numbers appear from a SQL query, and so this list is actually of type (Listof (Vectorof (U Integer String))), so that I should indeed be writing (cast (query-rows ...) (Listof VNI)) because these numbers are coming in, dynamically, from _outside_ the reach of the static TC, and so the annotation needs to be dynamically verified at this point. That is: `cast` is for the 'boundary' of the type system, whereas `ann` is for adding detail within it? Ah -- I think I've just had a little epiphany. In which case, it might be useful to transplant a little of that into the ann/cast section of the manual. The examples shown there don't really bring out the distinction to the naive reader. (Just by the way, `assert` seems to be doing rather similar work to these two, and while I can appreciate a distinction, from the text, I'd struggle to express it compactly -- a compare-and-contrast explanation in the manual would be very illuminating) (Does this imply that when TR code is called from untyped code, the arguments are implicitly `cast` at call-time?) > There are a few things that make this program require more annotations > than I'd like. > > 1. TR doesn't handle automatically inferring type arguments when > polymorphic functions (like `map`) are given polymorphic arguments > like `vector->list`. While fixing this would require work, it just > needs to be done -- there's no reason we shouldn't be able to make > this work. Righto -- that's what I wondered, whether it was 'just a matter of code' or whether there was something fundamentally more complicated about this, which I wasn't understanding. Thanks, both, for your careful explanations. Best wishes, Norman -- Norman Gray : http://nxg.me.uk SUPA School of Physics and Astronomy, University of Glasgow, UK From alexander at knauth.org Tue Aug 5 09:11:52 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Tue, 5 Aug 2014 09:11:52 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: Message-ID: <3959075B-D796-4F24-A5C9-19B0EF706AFA@knauth.org> First of all, thank you all of you, I have had similar problems with not knowing what to annotate and what not to. On Aug 5, 2014, at 5:36 AM, Norman Gray wrote: > >> If I were to move this code to Typed Racket, I'd add a type declaration to each identifier just like in any other (explicitly, statically) typed programming language. That's what I did, and there was no problem checking and running your code. > > So the pattern I see there, which both you and Sam have illustrated, is: > > * annotate as far 'down' the tree as possible, so that type information can propagate upwards in the parse tree > > * If one liberally uses named bindings (recommended on other style grounds, in any case), then each of these is a natural location for a type annotation > > * when a polymorphic-typed function takes polymorphic arguments, annotate the arguments, not the function (that is, I see that, in (map car '(foo ...)) both you and Sam annotated the car, not the map); this is in harmony with 'annotate as far down as possible', for some value of 'down'. > > Sam said: > >> The most signficant differences are (1) I'm not using `cast`, which >> should be avoided when possible. `cast` is a runtime operation, and >> might be hiding arbitrary bugs. (2) I've annotated the `let`-bound >> variables, which makes life easier on the rest of the type checker and >> helps improve error messages. > > Ah, now this is something I've meant to ask about: what's the difference between ann and cast? The difference is that cast checks the type with a contract (even if it already has that type or some subtype), while ann checks at type check time that it has the type given (or some subtype) and gives a compile-time type-check error if it doesn?t. > > The manual says: > >> (ann e t) >> Ensure that e has type t, or some subtype. The entire expression has type t. This is legal only in expression contexts. > >> (cast e t) >> The entire expression has the type t, while e may have any type. The value of the entire expression is the value returned by e, protected by a contract ensuring that it has type t. This is legal only in expression contexts. > > I've never been sure whether the difference between "Ensure that e has type t" (which sounds rather runtime-y) and "The entire expression has the type t" is significant. The only difference I could parse from this is that `cast` includes a contract, which would appear to make it _safer_ than `ann`, in the sense that if this were accidentally given a wrong-typed value than it would cause an immediate error. Ann doesn?t do anything at runtime. And cast is not safer than ann; ann gives you a type-check error at compile-time, while cast gives you a contract violation at runtime. And actually I think cast could be considered slightly unsafe because there are ways of using it that can fool the type-checker into thinking values have types that they don?t have: http://bugs.racket-lang.org/query/?cmd=view%20audit-trail&database=default&pr=13626&return_url=http%3A%2F%2Fbugs.racket-lang.org%2Fquery%2F%3Fdatabase%3Ddefault%3Bdebug%3D%3BState%3Dany%3Bignoreclosed%3DIgnore%2520Closed%3BSynopsis%3Dcast%2520is%2520unsound%3Bmultitext%3D%3Bcolumns%3DState%3Bcolumns%3DSynopsis%3Bcolumns%3DCategory%3Bcolumns%3DLast-Modified%3Bcolumns%3DRelease%3Bcmd%3Dsubmit%2520query%3Bsortby%3DNumber > > I presume that the difference is that `ann` is about static type analysis, whereas `cast` is for the situation where that static analysis can't be done. Would I be correct that in the above case I can and should write > > (ann '(#(1 2) #(3 4) #(5 6)) (Listof VNI) > > since this is saying that this expression has a more specific type than the TC would work out by itself, and it can verify that the restriction is possible. In the real program, these numbers appear from a SQL query, and so this list is actually of type (Listof (Vectorof (U Integer String))), so that I should indeed be writing > > (cast (query-rows ...) (Listof VNI)) > > because these numbers are coming in, dynamically, from _outside_ the reach of the static TC, and so the annotation needs to be dynamically verified at this point. That is: `cast` is for the 'boundary' of the type system, whereas `ann` is for adding detail within it? Well ann can?t add any detail, it can only make types less specific. Although it can be useful to solidify the types of mutable things such as vectors and boxes, and I?ve found that sometimes it seems to be necessary for annotating the types of sequences in for loops. And for mutable things like vectors and boxes, sometimes you?ll want a less specific type. And it can be useful for debugging so that it gives you a type-check error if something doesn?t have the type you think it does. Though there might be uses of it that I don?t know about yet. > > Ah -- I think I've just had a little epiphany. In which case, it might be useful to transplant a little of that into the ann/cast section of the manual. The examples shown there don't really bring out the distinction to the naive reader. I agree. I had trouble with this too when I started trying to do stuff in typed racket. > (Just by the way, `assert` seems to be doing rather similar work to these two, and while I can appreciate a distinction, from the text, I'd struggle to express it compactly -- a compare-and-contrast explanation in the manual would be very illuminating) > > (Does this imply that when TR code is called from untyped code, the arguments are implicitly `cast` at call-time?) > >> There are a few things that make this program require more annotations >> than I'd like. >> >> 1. TR doesn't handle automatically inferring type arguments when >> polymorphic functions (like `map`) are given polymorphic arguments >> like `vector->list`. While fixing this would require work, it just >> needs to be done -- there's no reason we shouldn't be able to make >> this work. > > Righto -- that's what I wondered, whether it was 'just a matter of code' or whether there was something fundamentally more complicated about this, which I wasn't understanding. > > Thanks, both, for your careful explanations. > > Best wishes, > > Norman > > > -- > Norman Gray : http://nxg.me.uk > SUPA School of Physics and Astronomy, University of Glasgow, UK > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From matthias at ccs.neu.edu Tue Aug 5 09:23:00 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Tue, 5 Aug 2014 09:23:00 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: Message-ID: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> In principle your email summarizes it all. I would like to add two comments though: --- 1. There was no contradiction between Sam's email (happy birthday Sam) and mine. My initial reaction was to fix up your program in a 'least intrusive' manner. That's why I left in the cast and simply pinpointed those places in the program where the type checker really needs help. When I found the open DrRacket buffer again, I saw the code in a whole new light, especially in violation of my (untyped) coding style and once I recognized the delta, I realized that I really wanted to write the program according to the Typed Racket philosophy: add type declarations to variables and fields and function and method signatures. That should work. No code rewrites necessary. Period. -- Sam's reply points out that this is basically possible for your code, without the style-based rewrite. [We confirmed this point in an off-line exchange.] --- 2. Well, the 'period' part leads my to my second comment. While we have achieved our goal -- mostly, kind of -- for mostly functional Racket, we're not there yet. On occasion, we do need to insert casts. Worse, we do need to rewrite code. Worst, the type annotations are more of a burden than the TR slogan leads us to believe. Yes, type annotations are helpful for any future reader of the program, especially if they are correct. They bring across intentions, and with good function and type names, extensions. You need little more to 'get' the code. In a sense, type annotations explicate design documentation the way the HtDP design recipe suggests. [And yes, we also need tests to illustrate abstract statements and property-checking would be even better.] The code truly explains itself -- when combined with the rules from the Style guide (which we don't always follow and couldn't in the past). But, type annotations become really heavy in some cases (polymorphism) and simply labor in others. ____(: s String) (define s "hello world")___ anyone? So Sam injected _local type inference_ into the original TR. LOCAL means just that -- within a maximal S-expression TR tries to restore missing type declarations. Sometimes it works, sometimes it fails. We know from experience that MODULE-GLOBAL inference (Hindley Milner a la ML or Hindley-Milner soft type a la Fagan/Wright) doesn't work. Error messages are bad and cost more time than the reduction in labor is worth. Bottom line is then, TR is in an actual state and then there is the ideal that some of us have in our head where local type inference does a lot more and becomes almost as good as GLOBAL ti in terms of convenience. It is critical to keep this in mind. TR isn'f finished and it will continue to move from 'actual' to 'ideal'. Having said that, this thread definitely points out (1) we need to fix some of the write-ups about TR and (2) we should add sections about TR to the Style guide. We will do so ... -- Matthias On Aug 5, 2014, at 5:36 AM, Norman Gray wrote: > > Matthias and Sam, hello. > > This has been a very useful brief thread for me, and also, I suspect, for others. > > On 2014 Aug 4, at 01:22, Matthias Felleisen wrote: > >> In a sense, you put your finger on a sore spot of TR from R -- we are still figuring out how to help programmers along here. > > Such help would be most valuable! > >> ;; entirely unnecessary but helped me read; IGNORE >> (define-type (Maybe ?) (U False ?)) >> (define-type NI Nonnegative-Integer) >> (define-type LNI (Listof NI)) >> (define-type VNI (Vectorof NI)) > > This is clearly a good idiom/pattern: very local, and telegraphically short, abbreviations for useful types. > >> Then I checked on the maps and realized that I need to help the TC along with the instantiations of vector->list (how can it know with context-free reasoning what kind of vector it is) and the same for car (how can it know what kind of list you're getting here). > > So this returns to the question of what the TC can and cannot be expected to work out for itself, and I see that Sam had a couple of remarks on this later. > >> (let* ((given : LVNI '(#(1 2) #(3 4) #(5 6))) >> (length : NI (1+ (apply max (map (lambda ({x : VNI}) (vector-ref x 0)) given)))) >> (result : [Vectorof [Maybe NI]] (make-vector length #f))) >> (for ((q : VNI (in-list given))) >> (vector-set! result (vector-ref q 0) (vector-ref q 1))) >> result) >> >> The above -- minus types -- is how I would probably write the code in Racket, following the style guide. (I would use three defines instead of let* but let's ignore this point.) > > That looks _much_ nicer than what I had, and is still perfectly readable. > >> If I were to move this code to Typed Racket, I'd add a type declaration to each identifier just like in any other (explicitly, statically) typed programming language. That's what I did, and there was no problem checking and running your code. > > So the pattern I see there, which both you and Sam have illustrated, is: > > * annotate as far 'down' the tree as possible, so that type information can propagate upwards in the parse tree > > * If one liberally uses named bindings (recommended on other style grounds, in any case), then each of these is a natural location for a type annotation > > * when a polymorphic-typed function takes polymorphic arguments, annotate the arguments, not the function (that is, I see that, in (map car '(foo ...)) both you and Sam annotated the car, not the map); this is in harmony with 'annotate as far down as possible', for some value of 'down'. > > Sam said: > >> The most signficant differences are (1) I'm not using `cast`, which >> should be avoided when possible. `cast` is a runtime operation, and >> might be hiding arbitrary bugs. (2) I've annotated the `let`-bound >> variables, which makes life easier on the rest of the type checker and >> helps improve error messages. > > Ah, now this is something I've meant to ask about: what's the difference between ann and cast? > > The manual says: > >> (ann e t) >> Ensure that e has type t, or some subtype. The entire expression has type t. This is legal only in expression contexts. > >> (cast e t) >> The entire expression has the type t, while e may have any type. The value of the entire expression is the value returned by e, protected by a contract ensuring that it has type t. This is legal only in expression contexts. > > I've never been sure whether the difference between "Ensure that e has type t" (which sounds rather runtime-y) and "The entire expression has the type t" is significant. The only difference I could parse from this is that `cast` includes a contract, which would appear to make it _safer_ than `ann`, in the sense that if this were accidentally given a wrong-typed value than it would cause an immediate error. > > I presume that the difference is that `ann` is about static type analysis, whereas `cast` is for the situation where that static analysis can't be done. Would I be correct that in the above case I can and should write > > (ann '(#(1 2) #(3 4) #(5 6)) (Listof VNI) > > since this is saying that this expression has a more specific type than the TC would work out by itself, and it can verify that the restriction is possible. In the real program, these numbers appear from a SQL query, and so this list is actually of type (Listof (Vectorof (U Integer String))), so that I should indeed be writing > > (cast (query-rows ...) (Listof VNI)) > > because these numbers are coming in, dynamically, from _outside_ the reach of the static TC, and so the annotation needs to be dynamically verified at this point. That is: `cast` is for the 'boundary' of the type system, whereas `ann` is for adding detail within it? > > Ah -- I think I've just had a little epiphany. In which case, it might be useful to transplant a little of that into the ann/cast section of the manual. The examples shown there don't really bring out the distinction to the naive reader. (Just by the way, `assert` seems to be doing rather similar work to these two, and while I can appreciate a distinction, from the text, I'd struggle to express it compactly -- a compare-and-contrast explanation in the manual would be very illuminating) > > (Does this imply that when TR code is called from untyped code, the arguments are implicitly `cast` at call-time?) > >> There are a few things that make this program require more annotations >> than I'd like. >> >> 1. TR doesn't handle automatically inferring type arguments when >> polymorphic functions (like `map`) are given polymorphic arguments >> like `vector->list`. While fixing this would require work, it just >> needs to be done -- there's no reason we shouldn't be able to make >> this work. > > Righto -- that's what I wondered, whether it was 'just a matter of code' or whether there was something fundamentally more complicated about this, which I wasn't understanding. > > Thanks, both, for your careful explanations. > > Best wishes, > > Norman > > > -- > Norman Gray : http://nxg.me.uk > SUPA School of Physics and Astronomy, University of Glasgow, UK > From gustavo at oma.org.ar Tue Aug 5 10:44:12 2014 From: gustavo at oma.org.ar (Gustavo Massaccesi) Date: Tue, 5 Aug 2014 11:44:12 -0300 Subject: [racket] Performance. Higher-order function In-Reply-To: <1407123772.149158313@f121.i.mail.ru> References: <1407057319.566019875@f258.i.mail.ru> <1407123772.149158313@f121.i.mail.ru> Message-ID: I made another test, using begin-encourage-inlining. I copied the definition of build-string and compare the "normal" version with the "inlined" version in Racket 6.1 "racket" version: cpu time: 1326 real time: 1334 gc time: 78 cpu time: 1248 real time: 1262 gc time: 31 cpu time: 1264 real time: 1264 gc time: 15 "normal" version: cpu time: 1248 real time: 1250 gc time: 16 cpu time: 1263 real time: 1282 gc time: 31 cpu time: 1264 real time: 1250 gc time: 15 "inlined" version: cpu time: 546 real time: 570 gc time: 16 cpu time: 546 real time: 582 gc time: 0 cpu time: 562 real time: 550 gc time: 16 The fist two versions have almost the same time, as expected because it's a copy. The last version is much faster. The functions build-vector, build-string and build-list look like good candidates for begin-encourage-inlining. They are too long for the automatic inlining heuristic, but they are not very long. They also use an argument as a function, so knowing the function and perhaps inlining it can make some further improvement. Additionally, the function checks the type of the arguments. But if I remove the checks, the time almost doesn't change. These checks are fast. Gustavo ;--- test.rkt --- #lang racket/base (require "build-string.rkt") (define (test2 n) (build-string n integer->char)) (define (test4 n) (build-string-normal n integer->char)) (define (test5 n) (build-string-inline n integer->char)) (time (for ([i 100000]) (test2 100))) (time (for ([i 100000]) (test2 100))) (time (for ([i 100000]) (test2 100))) (newline) (time (for ([i 100000]) (test4 100))) (time (for ([i 100000]) (test4 100))) (time (for ([i 100000]) (test4 100))) (newline) (time (for ([i 100000]) (test5 100))) (time (for ([i 100000]) (test5 100))) (time (for ([i 100000]) (test5 100))) ;------ ;-- build-string.rkt --- #lang racket/base (require racket/performance-hint) (provide (all-defined-out)) (define (build-string-normal n fcn) (unless (exact-nonnegative-integer? n) (raise-argument-error 'build-string "exact-nonnegative-integer?" n)) (unless (and (procedure? fcn) (procedure-arity-includes? fcn 1)) (raise-argument-error 'build-string "(exact-nonnegative-integer? . -> . char?)" fcn)) (let ([str (make-string n)]) (let loop ((i 0)) (if (= i n) str (begin (string-set! str i (fcn i)) (loop (add1 i))))))) (begin-encourage-inline (define (build-string-inline n fcn) (unless (exact-nonnegative-integer? n) (raise-argument-error 'build-string "exact-nonnegative-integer?" n)) (unless (and (procedure? fcn) (procedure-arity-includes? fcn 1)) (raise-argument-error 'build-string "(exact-nonnegative-integer? . -> . char?)" fcn)) (let ([str (make-string n)]) (let loop ((i 0)) (if (= i n) str (begin (string-set! str i (fcn i)) (loop (add1 i))))))) ) ; ------ On Mon, Aug 4, 2014 at 12:42 AM, Roman Klochkov wrote: >> unknown function call is expensive > > So, higher order function always slow. > Thus, to improve performance, one should use for/fold, for/list, ... and > never use map, foldl, build-string, ... with lambda. > Is it correct? > > Sun, 3 Aug 2014 13:15:57 -0400 ?? Matthias Felleisen : > > > Because build-string calls an unknown function 1000 x 100000 times, and an > unknown function call is expensive. > > Racket could possible collapse all modules and perform additional in-lining > optimizations eventually, which may help here. But it doesn't yet. > > -- Matthias > > > > On Aug 3, 2014, at 5:15 AM, Roman Klochkov wrote: > > Are higher order function always slow? > ... > > --- > > So I see, that build-string version is about two times slower, than > set-in-the-loop. Why so much? I expected about 10-20% difference. > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > > > -- > Roman Klochkov > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From davidcnelson at gmail.com Tue Aug 5 11:47:37 2014 From: davidcnelson at gmail.com (David Nelson) Date: Tue, 5 Aug 2014 10:47:37 -0500 Subject: [racket] racket/gui: changing the background color Message-ID: I am working on a manufacturing system to asynchronously program and test 16 USB devices. The main display is a grid of "slot" displays. Each slot display currently is a group box with the slot number in big digits, a status message in normal sized text, and a guage to display the progress. I'd like to change the background color of the group box for each slot depending on the status. E.g. red for a problem, green for success, yellow - in progress, etc.. The problem is that setting a background color only seems to be possible with a canvas%. I seem to have two options: 1) Use a canvas for the slot and draw all of the contents. 2) Create a subclass of panel% that can position a canvas behind the rest of the children. In the previous implementation option #1 was used because I needed to work around another issue. We used a collection of BeagleBones with small LCD displays to drive the slots, one computer per slot. I had to roll my own classes to deal with the display physically rotated 90 degrees from normal. (The X server did not support rotating the display.) I used a canvas filling the top-level frame, and then my rotated-text% and progress-bar% classes used absolute positioning and sizing. The draw operation on the canvas filled the background, applied a rotation transformation to the dc and then for each child it applied the appropriate translation to the position of the child and told the child object to draw with the rotated & translated device context. Comments or suggestions? -- David -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbastos at toledo.com Tue Aug 5 15:56:48 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Tue, 5 Aug 2014 16:56:48 -0300 Subject: [racket] on contract violation after adding 1471 strings to a BST Message-ID: After studying chapter 14 of HtDP, I decided to try putting strings into a BST. The code below works with a few strings. I have a file with 22064 strings --- one per line. Up until 1471 words, it works. With 1472 it yields a contract violation. > (length (read-words)) 22064 > (create-bst-word-from-list (take (read-words) 1471)) # > (create-bst-word-from-list (take (read-words) 1472)) node-word: contract violation expected: node? given: # context...: /home/dbastos/public_html/rkt/functions.rkt:974:0: create-bst-word /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list /home/dbastos/public_html/rkt/functions.rkt:987:0: create-bst-word-from-list... > It seems node-word says I gave it a #. Perhaps my list of words contains a #, but when I search for it, I do not find it. > (define ls (read-words)) > (length ls) 22064 > (length (filter string? ls)) 22064 > (filter void? ls) () So I'm perplexed. (define-struct node (word left right)) (define (create-bst-word bst str) (cond ((false? bst) (make-node str false false)) ((string? str (node-word bst)) ;; insert at the right (make-node (node-word bst) (node-left bst) (create-bst-word (node-right bst) str))))) (define (create-bst-word-from-list ls) (cond ((empty? ls) false) (else (create-bst-word (create-bst-word-from-list (rest ls)) (first ls))))) (define (read-lines in) (let* ((ln (read-line in))) (cond ((eof-object? ln) empty) (else (cons ln (read-lines in)))))) (define (read-words) (call-with-input-file "words" read-lines)) Thank you in advance for any information. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jensaxel at soegaard.net Tue Aug 5 16:06:47 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Tue, 5 Aug 2014 22:06:47 +0200 Subject: [racket] on contract violation after adding 1471 strings to a BST In-Reply-To: References: Message-ID: What happens in create-bst-word, when the word to inserted is the same as (node-word bst) ? /Jens Axel 2014-08-05 21:56 GMT+02:00 Daniel Bastos : > After studying chapter 14 of HtDP, I decided to try putting strings into a > BST. The code below works with a few strings. I have a file with 22064 > strings --- one per line. Up until 1471 words, it works. With 1472 it yields > a contract violation. > >> (length (read-words)) > 22064 > >> (create-bst-word-from-list (take (read-words) 1471)) > # > >> (create-bst-word-from-list (take (read-words) 1472)) > node-word: contract violation > expected: node? > given: # > context...: > /home/dbastos/public_html/rkt/functions.rkt:974:0: create-bst-word > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list > /home/dbastos/public_html/rkt/functions.rkt:987:0: > create-bst-word-from-list... > >> > > It seems node-word says I gave it a #. Perhaps my list of words > contains a #, but when I search for it, I do not find it. > >> (define ls (read-words)) >> (length ls) > 22064 >> (length (filter string? ls)) > 22064 >> (filter void? ls) > () > > So I'm perplexed. > > (define-struct node (word left right)) > > (define (create-bst-word bst str) > (cond > ((false? bst) > (make-node str false false)) > ((string (make-node (node-word bst) > (create-bst-word (node-left bst) str) > (node-right bst))) > ((string>? str (node-word bst)) ;; insert at the right > (make-node (node-word bst) > (node-left bst) > (create-bst-word (node-right bst) str))))) > > (define (create-bst-word-from-list ls) > (cond > ((empty? ls) false) > (else > (create-bst-word (create-bst-word-from-list (rest ls)) (first ls))))) > > (define (read-lines in) > (let* ((ln (read-line in))) > (cond > ((eof-object? ln) empty) > (else (cons ln (read-lines in)))))) > > (define (read-words) > (call-with-input-file "words" read-lines)) > > Thank you in advance for any information. > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -- -- Jens Axel S?gaard From dbastos at toledo.com Tue Aug 5 16:25:35 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Tue, 5 Aug 2014 17:25:35 -0300 Subject: [racket] on contract violation after adding 1471 strings to a BST In-Reply-To: References: Message-ID: On Tue, Aug 5, 2014 at 5:06 PM, Jens Axel S?gaard wrote: > What happens in create-bst-word, when the word to inserted is the same > as (node-word bst) ? Aha! I see. It returns void because there is no case for when the string is equal. > (void? (create-bst-word (create-bst-word false "dan") "dan")) #t I patched it with an else-case now. (define (create-bst-word bst str) (cond ((false? bst) (make-node str false false)) ((string? str (node-word bst)) ;; insert at the right (make-node (node-word bst) (node-left bst) (create-bst-word (node-right bst) str))) (else (make-node (node-word bst) (node-left bst) (node-right bst))))) > (void? (create-bst-word (create-bst-word false "dan") "dan")) #f Thank you. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Tue Aug 5 16:43:21 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Tue, 5 Aug 2014 16:43:21 -0400 Subject: [racket] on contract violation after adding 1471 strings to a BST In-Reply-To: References: Message-ID: <2551FF3D-E2F7-42D8-ABE7-75DF9E350CC5@ccs.neu.edu> Warning: you switched from a teaching language to full Racket. The former would have caught this mistake, which is why we designed them for HtDP. Racket is for grown-up parenthesis eaters -- who want the behavior of cond that you just experienced, or so I am told. -- Matthias On Aug 5, 2014, at 4:25 PM, Daniel Bastos wrote: > On Tue, Aug 5, 2014 at 5:06 PM, Jens Axel S?gaard wrote: > What happens in create-bst-word, when the word to inserted is the same > as (node-word bst) ? > > Aha! I see. It returns void because there is no case for when the string is equal. > > > (void? (create-bst-word (create-bst-word false "dan") "dan")) > #t > > I patched it with an else-case now. > > (define (create-bst-word bst str) > (cond > ((false? bst) > (make-node str false false)) > ((string (make-node (node-word bst) > (create-bst-word (node-left bst) str) > (node-right bst))) > ((string>? str (node-word bst)) ;; insert at the right > (make-node (node-word bst) > (node-left bst) > (create-bst-word (node-right bst) str))) > (else (make-node (node-word bst) > (node-left bst) > (node-right bst))))) > > > (void? (create-bst-word (create-bst-word false "dan") "dan")) > #f > > Thank you. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From lysseus at gmail.com Tue Aug 5 16:44:59 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Tue, 5 Aug 2014 13:44:59 -0700 Subject: [racket] syntax-parse question Message-ID: I?m interested in using syntax-parse to restructure the form (x (y ? (z ?) ?)) but my coding of syntax-parse appears to be matching the (z ?) as a y. I must be doing something wrong! Here?s the code: #lang racket (require (for-syntax syntax/parse)) (define-syntax (x stx) (syntax-parse stx [(_ (y ... (z ...) ...)) #'(xf (yf y ... (zf z ...) ...))])) (define (xf . xs) (list xs)) (define (yf . ys) (list ys)) (define (zf . zs) (list zs)) (x (1 2 3 (4 5 6) 7 8)) Which is expanding to: Expansion finished (module anonymous-module racket (#%module-begin (require (for-syntax syntax/parse)) (define-syntax (x stx) (syntax-parse stx [(_ (y ... (z ...) ...)) #'(xf (yf y ... (zf z ...) ...))])) (define (xf . xs) (list xs)) (define (yf . ys) (list ys)) (define (zf . zs) (list zs)) (xf (yf 1 2 3 (4 5 6) 7 8)))) I?m expecting (xf (yf 123 (zf 4 5 6) 7 8)))) ?Kevin From dbastos at toledo.com Tue Aug 5 16:45:18 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Tue, 5 Aug 2014 17:45:18 -0300 Subject: [racket] on contract violation after adding 1471 strings to a BST In-Reply-To: <2551FF3D-E2F7-42D8-ABE7-75DF9E350CC5@ccs.neu.edu> References: <2551FF3D-E2F7-42D8-ABE7-75DF9E350CC5@ccs.neu.edu> Message-ID: Thanks for pointing this out. On Tue, Aug 5, 2014 at 5:43 PM, Matthias Felleisen wrote: > Warning: you switched from a teaching language to full Racket. > The former would have caught this mistake, which is why we > designed them for HtDP. Racket is for grown-up parenthesis > eaters -- who want the behavior of cond that you just experienced, > or so I am told. -- Matthias -------------- next part -------------- An HTML attachment was scrubbed... URL: From jensaxel at soegaard.net Tue Aug 5 17:21:20 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Tue, 5 Aug 2014 23:21:20 +0200 Subject: [racket] syntax-parse question In-Reply-To: References: Message-ID: Is this a step in the right direction? (define-syntax (x stx) (syntax-parse stx [(_ (y ... (z ...) w ...)) #'(xf (yf y ... (zf z ...) w ...))])) The pattern (z ...) ... will match a sequence of lists such as (4 5 6) (7 8) but it won't match (4 5 6) 7 8 from your example. /Jens Axel 2014-08-05 22:44 GMT+02:00 Kevin Forchione : > I?m interested in using syntax-parse to restructure the form (x (y ? (z ?) ?)) but my coding of syntax-parse appears to be matching the (z ?) as a y. I must be doing something wrong! > > Here?s the code: > > #lang racket > > (require (for-syntax syntax/parse)) > > (define-syntax (x stx) > (syntax-parse stx > [(_ (y ... (z ...) ...)) > #'(xf (yf y ... (zf z ...) ...))])) > > (define (xf . xs) (list xs)) > (define (yf . ys) (list ys)) > (define (zf . zs) (list zs)) > > (x (1 2 3 (4 5 6) 7 8)) > > Which is expanding to: > > Expansion finished > (module anonymous-module racket > (#%module-begin > (require (for-syntax syntax/parse)) > (define-syntax (x stx) > (syntax-parse > stx > [(_ (y ... (z ...) ...)) > #'(xf (yf y ... (zf z ...) ...))])) > (define (xf . xs) (list xs)) > (define (yf . ys) (list ys)) > (define (zf . zs) (list zs)) > (xf (yf 1 2 3 (4 5 6) 7 8)))) > > I?m expecting (xf (yf 123 (zf 4 5 6) 7 8)))) > > ?Kevin > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- -- Jens Axel S?gaard From norman at astro.gla.ac.uk Tue Aug 5 18:00:47 2014 From: norman at astro.gla.ac.uk (Norman Gray) Date: Tue, 5 Aug 2014 23:00:47 +0100 Subject: [racket] Puzzled about type inference In-Reply-To: <3959075B-D796-4F24-A5C9-19B0EF706AFA@knauth.org> References: <3959075B-D796-4F24-A5C9-19B0EF706AFA@knauth.org> Message-ID: Alexander, hello. On 2014 Aug 5, at 14:11, "Alexander D. Knauth" wrote: > Well ann can?t add any detail, it can only make types less specific. Aha: I was thinking of this the wrong way round. If I type, say, #(1 2) into TR, it determines its type as > #(1 2) - : (Vector Integer Integer) '#(1 2) Compared to that, > (ann #(1 2) (Vectorof Positive-Integer)) - : (Vectorof Positive-Integer) '#(1 2) ...is more specific. But your explanation makes me realise that the most specific possible type is (Vector 1 2) (of limited utility), and that (Vector (U 1 2) (U 1 2), (Vector Integer Integer) and (Vectorof Positive-Integer) are just samples of the many possible less specific ones, and it happens that the less-specific one that TR guesses I want is not the one I actually want. Which is why I have to use `ann`. Simple, really -- cor, it's wall-to-wall epiphanies today.... All the best, Norman -- Norman Gray : http://nxg.me.uk SUPA School of Physics and Astronomy, University of Glasgow, UK From norman at astro.gla.ac.uk Tue Aug 5 18:00:57 2014 From: norman at astro.gla.ac.uk (Norman Gray) Date: Tue, 5 Aug 2014 23:00:57 +0100 Subject: [racket] Puzzled about type inference In-Reply-To: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: Matthias, hello. On 2014 Aug 5, at 14:23, Matthias Felleisen wrote: > --- 1. There was no contradiction between Sam's email (happy birthday Sam) and mine. On the contrary, I thought it was useful to see, between three alternatives, the contrast between a minimally- and a maximally-rewritten version. > add type declarations to variables and fields and function and method signatures. A good motto, which I shall endeavour to remember. > Bottom line is then, TR is in an actual state and then there is the ideal that some of us have in our head where local type inference does a lot more and becomes almost as good as GLOBAL ti in terms of convenience. It is critical to keep this in mind. TR isn'f finished and it will continue to move from 'actual' to 'ideal'. Keep on keeping on! In case anyone's interested, the actual code ended up looking as below. Thanks, all, for a most illuminating thread. Best wishes, Norman ---- (define-type LevelN Positive-Integer) (define-type Backup-Log (Vectorof (Maybe LevelN))) (require/typed db [#:opaque Handle connection?] [query-value (Handle String SQLType * -> SQLType)] [query-rows (Handle String SQLType * -> (Listof (Vectorof SQLType)))]) [...] (: get-latest-backups/filesystem (case-> (Handle String -> Backup-Log) (Handle String String -> Backup-Log))) (define (get-latest-backups/filesystem db fs [refdate #f]) ;; I can't see any way to do this in a single SQL statement (let ((parent0 (query-value db "select parent0 from backups where filesystem=$1 and created<$2 order by created desc limit 1" fs (or refdate (reftime/iso8601))))) (define-type VIL (Vector Positive-Integer LevelN)) (define idx+level : (Listof VIL) (cast (query-rows db ; only idx=0 can have a level=0 backup "select idx, level from backups where parent0=$1 and idx > 0" parent0) (Listof VIL))) (define length : Positive-Integer (1+ (apply max (map (? ([x : VIL]) (vector-ref x 0)) idx+level)))) (define result : Backup-Log (make-vector length #f)) (for ((q : VIL (in-list idx+level))) (vector-set! result (vector-ref q 0) (vector-ref q 1))) result)) -- Norman Gray : http://nxg.me.uk SUPA School of Physics and Astronomy, University of Glasgow, UK From raould at gmail.com Tue Aug 5 18:06:23 2014 From: raould at gmail.com (Raoul Duke) Date: Tue, 5 Aug 2014 15:06:23 -0700 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: >> add type declarations to variables and fields and function and method signatures. > > A good motto, which I shall endeavour to remember. what i do not get about TR and other languages (ocaml, haskell, etc.) is: there are these rules of thumb that you must somehow learn to keep yourself out of the weeds, but you only get to learn them the long and hard way. why don't the runtimes/ides (1) have a switch that says "hey, force me, the user, to put in type annotations by hand in the critical places, ok? so i don't have to suffer so much down the road, ok?" (2) put the inferred annotations into the code as it goes along so i can see what kind of crazy talk the inference engine is having with itself? From alexander at knauth.org Tue Aug 5 18:13:13 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Tue, 5 Aug 2014 18:13:13 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >>> add type declarations to variables and fields and function and method signatures. >> >> A good motto, which I shall endeavour to remember. > > what i do not get about TR and other languages (ocaml, haskell, etc.) > is: there are these rules of thumb that you must somehow learn to keep > yourself out of the weeds, but you only get to learn them the long and > hard way. why don't the runtimes/ides > > (1) have a switch that says "hey, force me, the user, to put in type > annotations by hand in the critical places, ok? so i don't have to > suffer so much down the road, ok?" > > (2) put the inferred annotations into the code as it goes along so i > can see what kind of crazy talk the inference engine is having with > itself? I?m just wondering, would it be possible for DrRacket to do something where you can right-click a variable or expression or something and one of the options is to see what the inferred type is? > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From matthias at ccs.neu.edu Mon Aug 4 10:10:07 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Mon, 4 Aug 2014 10:10:07 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53DF59B9.5070005@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> <87ha211h09.wl%stamourv@ccs.neu.edu> <53D6A8AD.506@neilvandyke.org> <87bns919is.wl%stamourv@ccs.neu.edu> <8738dhie7u.wl%stamourv@ccs.neu.edu> <31FA57A2-7B5D-4BC3-A42C-53D60EBCE4FD@knauth.org> <2D45AFCD-6AEB-4E69-BE36-8D1A7FAD8F62@knauth.org> <20048DBF-2A56-4518-A842-605C8041B70E@knauth.org> <53DEFB76.1010309@neilvandyke.org> <20140804064026.3370C650181@mail-svr1.cs.utah.edu> <53DF59B9.507 0005@neilvandyke.org> Message-ID: On Aug 4, 2014, at 6:00 AM, Neil Van Dyke wrote: > > Matthew Flatt wrote at 08/04/2014 02:40 AM: >> While he didn't say so explicitly, I don't think that Neil is worried >> about the implementation of `eval` within Racket. After all, `eval` is >> at the heart of the implementation, and any program that you give to >> Racket is going through `eval` whether or not the program calls the >> `eval` function. > > Correct. I breathe oxygen constantly, without thinking about it, but I'd never use a fuel-air explosive to mow my lawn. Off topic but I couldn't resist; see picture below from a recent trip to a workshop in Germany, where they use flamethrowers to burn off grass :-) -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: IMG_3964.jpeg Type: image/jpeg Size: 616968 bytes Desc: not available URL: From neil at neilvandyke.org Tue Aug 5 18:55:18 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Tue, 05 Aug 2014 18:55:18 -0400 Subject: [racket] users Digest, Vol 107, Issue 99 In-Reply-To: References: Message-ID: <53E160D6.8040504@neilvandyke.org> Adam Emanon wrote at 07/28/2014 12:35 PM: > Is there a way to sign up for a weekly digest? Several emails per day > is too much for me. If not, I'll have to unsubscribe for now. I don't see one right now (just a daily digest), but the list can also be viewed through a few different Web interfaces, as well as RSS and a Usenet-like newsgroup, so perhaps you'd like one of those? See the various links in the middle of the page: http://lists.racket-lang.org/ Neil V. From norman at astro.gla.ac.uk Tue Aug 5 19:10:09 2014 From: norman at astro.gla.ac.uk (Norman Gray) Date: Wed, 6 Aug 2014 00:10:09 +0100 Subject: [racket] lists vs strings In-Reply-To: <20140727135114.260b811b@epsilon> References: <20140727135114.260b811b@epsilon> Message-ID: <8F858B6F-9DCA-4E7C-A645-A7F359E5FB21@astro.gla.ac.uk> jseb, hello. On 2014 Jul 27, at 12:51, jseb wrote: > But i read that quote character is an alias for ?list?. Are there cases > where it has different meaning ? (oh no, magic again :/ ). No, it's not an alias for 'list'; instead, it's syntactic sugar for 'quote' which is a form which, when evaluated, gives you back exactly what you gave it. > (quote (1 + list)) '(1 + list) > (quote +) '+ A possibly better way to think of it is that quote precedes a lisp 'literal' -- the thing after it is not expanded in any way. These are two slightly informal ways of explaining this. With Scheme-family languages (eg Racket) it's a _really_ good idea to be _very_ secure in your understanding of how expressions are evaluated. The 'Racket Essentials' chapter in the Guide works through that in some detail. There's actually very little magic in Schemes -- generally much less than there is in other languages, I feel -- but it can quite often look like magic if you're uncertain how the few rigid rules are applied. > If it's strictly an alias, this one shoud returns the same result: > >> (list list + 1 2) > '(# # 1 2) That evaluates all five expressions in the expression (namely "list", "list" again, "+", "1" and "2"). The first three evaluate to procedures, and the last two evaluate to themselves. Then it invokes the procedure "list" (the first expression inside the parentheses, which must, as in this case, be a procedure) with the remaining (four) values as arguments. The result, as you can see, is a list of two procedures and two numbers. But this is a case where getting the basics right at the beginning pays dividends later. Happy reading... Norman ---- (By the way, Racketeers, currently returns a 404) -- Norman Gray : http://nxg.me.uk SUPA School of Physics and Astronomy, University of Glasgow, UK From robby at eecs.northwestern.edu Tue Aug 5 19:20:43 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Tue, 5 Aug 2014 18:20:43 -0500 Subject: [racket] Puzzled about type inference In-Reply-To: References: <3959075B-D796-4F24-A5C9-19B0EF706AFA@knauth.org> Message-ID: On Tue, Aug 5, 2014 at 5:00 PM, Norman Gray wrote: > Simple, really -- cor, it's wall-to-wall epiphanies today.... This made my day. What better purpose could there possibly be for a mailing list than wall-to-wall epiphanies! Robby From matthias at ccs.neu.edu Tue Aug 5 20:53:42 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Tue, 5 Aug 2014 20:53:42 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: You guys came up with some wonderful ideas. I think this particular one is easy to implement when the program type checks. But when it doesn't, what do you show? -- Matthias On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: > > On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: > >>>> add type declarations to variables and fields and function and method signatures. >>> >>> A good motto, which I shall endeavour to remember. >> >> what i do not get about TR and other languages (ocaml, haskell, etc.) >> is: there are these rules of thumb that you must somehow learn to keep >> yourself out of the weeds, but you only get to learn them the long and >> hard way. why don't the runtimes/ides >> >> (1) have a switch that says "hey, force me, the user, to put in type >> annotations by hand in the critical places, ok? so i don't have to >> suffer so much down the road, ok?" >> >> (2) put the inferred annotations into the code as it goes along so i >> can see what kind of crazy talk the inference engine is having with >> itself? > > I?m just wondering, would it be possible for DrRacket to do something where you can right-click a variable or expression or something and one of the options is to see what the inferred type is? > >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From matthias at ccs.neu.edu Tue Aug 5 20:54:57 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Tue, 5 Aug 2014 20:54:57 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: (1) is already done. You must declare the types of all identifiers, in particular, variables, functions, fields, methods and structs as a whole. (2) is doable -- when the ti succeeds and I think we should at least provide the opption. On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >>> add type declarations to variables and fields and function and method signatures. >> >> A good motto, which I shall endeavour to remember. > > what i do not get about TR and other languages (ocaml, haskell, etc.) > is: there are these rules of thumb that you must somehow learn to keep > yourself out of the weeds, but you only get to learn them the long and > hard way. why don't the runtimes/ides > > (1) have a switch that says "hey, force me, the user, to put in type > annotations by hand in the critical places, ok? so i don't have to > suffer so much down the road, ok?" > > (2) put the inferred annotations into the code as it goes along so i > can see what kind of crazy talk the inference engine is having with > itself? > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From robby at eecs.northwestern.edu Tue Aug 5 21:04:33 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Tue, 5 Aug 2014 20:04:33 -0500 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: Is TR's type checker organized in such a way that the decisions about what types are given to constants decided as a separate (first) phase? That is, no matter the context, is this constant: #(0 0) always going to be given the type (Vector Integer Integer), assuming there is no annotation? If so, then it seems like TR could communicate that series of decisions even when type checking fails and that that might be useful for this program? Robby On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen wrote: > > You guys came up with some wonderful ideas. > > I think this particular one is easy to implement when > the program type checks. But when it doesn't, what do > you show? > > -- Matthias > > > > > > On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: > >> >> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >> >>>>> add type declarations to variables and fields and function and method signatures. >>>> >>>> A good motto, which I shall endeavour to remember. >>> >>> what i do not get about TR and other languages (ocaml, haskell, etc.) >>> is: there are these rules of thumb that you must somehow learn to keep >>> yourself out of the weeds, but you only get to learn them the long and >>> hard way. why don't the runtimes/ides >>> >>> (1) have a switch that says "hey, force me, the user, to put in type >>> annotations by hand in the critical places, ok? so i don't have to >>> suffer so much down the road, ok?" >>> >>> (2) put the inferred annotations into the code as it goes along so i >>> can see what kind of crazy talk the inference engine is having with >>> itself? >> >> I?m just wondering, would it be possible for DrRacket to do something where you can right-click a variable or expression or something and one of the options is to see what the inferred type is? >> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From matthias at ccs.neu.edu Tue Aug 5 21:08:50 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Tue, 5 Aug 2014 21:08:50 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: <76461BDD-E640-4444-A691-70F61680D68B@ccs.neu.edu> True because it is local inference. That's a thought -- Matthias On Aug 5, 2014, at 9:04 PM, Robby Findler wrote: > Is TR's type checker organized in such a way that the decisions about > what types are given to constants decided as a separate (first) phase? > That is, no matter the context, is this constant: > > #(0 0) > > always going to be given the type (Vector Integer Integer), assuming > there is no annotation? > > If so, then it seems like TR could communicate that series of > decisions even when type checking fails and that that might be useful > for this program? > > Robby > > > On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen wrote: >> >> You guys came up with some wonderful ideas. >> >> I think this particular one is easy to implement when >> the program type checks. But when it doesn't, what do >> you show? >> >> -- Matthias >> >> >> >> >> >> On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: >> >>> >>> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >>> >>>>>> add type declarations to variables and fields and function and method signatures. >>>>> >>>>> A good motto, which I shall endeavour to remember. >>>> >>>> what i do not get about TR and other languages (ocaml, haskell, etc.) >>>> is: there are these rules of thumb that you must somehow learn to keep >>>> yourself out of the weeds, but you only get to learn them the long and >>>> hard way. why don't the runtimes/ides >>>> >>>> (1) have a switch that says "hey, force me, the user, to put in type >>>> annotations by hand in the critical places, ok? so i don't have to >>>> suffer so much down the road, ok?" >>>> >>>> (2) put the inferred annotations into the code as it goes along so i >>>> can see what kind of crazy talk the inference engine is having with >>>> itself? >>> >>> I?m just wondering, would it be possible for DrRacket to do something where you can right-click a variable or expression or something and one of the options is to see what the inferred type is? >>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users From robby at eecs.northwestern.edu Tue Aug 5 21:23:31 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Tue, 5 Aug 2014 20:23:31 -0500 Subject: [racket] Puzzled about type inference In-Reply-To: <76461BDD-E640-4444-A691-70F61680D68B@ccs.neu.edu> References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> <76461BDD-E640-4444-A691-70F61680D68B@ccs.neu.edu> Message-ID: Also because it is a decision that users a) have control over and b) may not guess TR's behavior correctly. Robby On Tue, Aug 5, 2014 at 8:08 PM, Matthias Felleisen wrote: > > True because it is local inference. That's a thought -- Matthias > > > > > On Aug 5, 2014, at 9:04 PM, Robby Findler wrote: > >> Is TR's type checker organized in such a way that the decisions about >> what types are given to constants decided as a separate (first) phase? >> That is, no matter the context, is this constant: >> >> #(0 0) >> >> always going to be given the type (Vector Integer Integer), assuming >> there is no annotation? >> >> If so, then it seems like TR could communicate that series of >> decisions even when type checking fails and that that might be useful >> for this program? >> >> Robby >> >> >> On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen wrote: >>> >>> You guys came up with some wonderful ideas. >>> >>> I think this particular one is easy to implement when >>> the program type checks. But when it doesn't, what do >>> you show? >>> >>> -- Matthias >>> >>> >>> >>> >>> >>> On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: >>> >>>> >>>> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >>>> >>>>>>> add type declarations to variables and fields and function and method signatures. >>>>>> >>>>>> A good motto, which I shall endeavour to remember. >>>>> >>>>> what i do not get about TR and other languages (ocaml, haskell, etc.) >>>>> is: there are these rules of thumb that you must somehow learn to keep >>>>> yourself out of the weeds, but you only get to learn them the long and >>>>> hard way. why don't the runtimes/ides >>>>> >>>>> (1) have a switch that says "hey, force me, the user, to put in type >>>>> annotations by hand in the critical places, ok? so i don't have to >>>>> suffer so much down the road, ok?" >>>>> >>>>> (2) put the inferred annotations into the code as it goes along so i >>>>> can see what kind of crazy talk the inference engine is having with >>>>> itself? >>>> >>>> I?m just wondering, would it be possible for DrRacket to do something where you can right-click a variable or expression or something and one of the options is to see what the inferred type is? >>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>> >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users > From robby at eecs.northwestern.edu Wed Aug 6 02:07:57 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Wed, 6 Aug 2014 01:07:57 -0500 Subject: [racket] lists vs strings In-Reply-To: <8F858B6F-9DCA-4E7C-A645-A7F359E5FB21@astro.gla.ac.uk> References: <20140727135114.260b811b@epsilon> <8F858B6F-9DCA-4E7C-A645-A7F359E5FB21@astro.gla.ac.uk> Message-ID: On Tue, Aug 5, 2014 at 6:10 PM, Norman Gray wrote: > (By the way, Racketeers, currently returns a 404) How did you come across this url? Thanks, Robby From norman at astro.gla.ac.uk Wed Aug 6 04:47:04 2014 From: norman at astro.gla.ac.uk (Norman Gray) Date: Wed, 6 Aug 2014 09:47:04 +0100 Subject: [racket] lists vs strings In-Reply-To: References: <20140727135114.260b811b@epsilon> <8F858B6F-9DCA-4E7C-A645-A7F359E5FB21@astro.gla.ac.uk> Message-ID: <080CF251-FEF4-46D6-B621-20787133ADA8@astro.gla.ac.uk> Robby, hello. On 2014 Aug 6, at 07:07, Robby Findler wrote: > On Tue, Aug 5, 2014 at 6:10 PM, Norman Gray wrote: >> (By the way, Racketeers, currently returns a 404) > > How did you come across this url? I searched for R5RS, found the page and it's the first link in Sec. 23.2.1. From it looks like the link should instead be . See you, Norman -- Norman Gray : http://nxg.me.uk SUPA School of Physics and Astronomy, University of Glasgow, UK From norman at astro.gla.ac.uk Wed Aug 6 05:18:21 2014 From: norman at astro.gla.ac.uk (Norman Gray) Date: Wed, 6 Aug 2014 10:18:21 +0100 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> <76461BDD-E640-4444-A691-70F61680D68B@ccs.neu.edu> Message-ID: Robby and Matthias, hello. On 2014 Aug 6, at 02:23, Robby Findler wrote: > Also because it is a decision that users a) have control over and b) > may not guess TR's behavior correctly. Very much (b). The consequences of TR's behaviour are reported later (at type-check time) and elsewhere (in an inappropriate domain for another function), relative to the place where the user is typing. There's also a little unpredictability which this would help with: '(1 2 3) is (Listof Positive-Byte), but #(1 2 3) is (Vector Integer Integer Integer). Further, the user may reason with the types they _mean_ an expression to have, and so may have difficulty tracking down the cause of a bad type. For example, because (in the example I mentioned) I intended a vector to be an index to indexes, incidentally with some missing values, I created (make-vector n #f) and _thought_ of it as (Vectorof Positive-Integer). That preconception meant it took slightly longer than it might have done to track down my error (of course, it was still faster than waiting for the program to fail a unit test). And finally -- a variant of Robby's point -- if a user puts in a type annotation and can see the effect ripple through the larger expression, that would surely very effectively build intuition about the behaviour of the type checker, and where it's best or necessary to help TC out. All the best, Norman -- Norman Gray : http://nxg.me.uk SUPA School of Physics and Astronomy, University of Glasgow, UK From hendrik at topoi.pooq.com Wed Aug 6 07:49:58 2014 From: hendrik at topoi.pooq.com (Hendrik Boom) Date: Wed, 6 Aug 2014 07:49:58 -0400 Subject: [racket] Historical note on type inference In-Reply-To: References: <3959075B-D796-4F24-A5C9-19B0EF706AFA@knauth.org> Message-ID: <20140806114957.GA31893@topoi.pooq.com> On Tue, Aug 05, 2014 at 11:00:47PM +0100, Norman Gray wrote: > > Alexander, hello. > > On 2014 Aug 5, at 14:11, "Alexander D. Knauth" wrote: > > > Well ann can?t add any detail, it can only make types less specific. > > Aha: I was thinking of this the wrong way round. > > If I type, say, #(1 2) into TR, it determines its type as > > > #(1 2) > - : (Vector Integer Integer) > '#(1 2) > > Compared to that, > > > (ann #(1 2) (Vectorof Positive-Integer)) > - : (Vectorof Positive-Integer) > '#(1 2) > > ...is more specific. But your explanation makes me realise that the most specific possible type is (Vector 1 2) (of limited utility), and that (Vector (U 1 2) (U 1 2), (Vector Integer Integer) and (Vectorof Positive-Integer) are just samples of the many possible less specific ones, and it happens that the less-specific one that TR guesses I want is not the one I actually want. Which is why I have to use `ann`. I first encountered this type-ambiguity with Algol 68, long long ago. But in that language, the type affected physical data representation, so it was necessary to deal with it quite explicitly. When, analogously, you have a choice of turning (1, 2.0) into either array of (union of integer and real) or array of real, it really matters which to choose. For Algol 68, the resolution of these kinds of quandary was actually specified in the (not context-free) grammar, and it practically never went wrong. The cases that seemed ambiguous to humans were mostly blocked syntactically and had to be resolved explicitly with casts. Indeed, much of the complexity of its language definition was involved with resolving the interactions between various degrees of contextual strength and operator everloading. The interaction between upward and downward moving type information was termed "coercion". -- hendrik From hendrik at topoi.pooq.com Wed Aug 6 07:56:50 2014 From: hendrik at topoi.pooq.com (Hendrik Boom) Date: Wed, 6 Aug 2014 07:56:50 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: <20140806115650.GB31893@topoi.pooq.com> On Tue, Aug 05, 2014 at 08:53:42PM -0400, Matthias Felleisen wrote: > > You guys came up with some wonderful ideas. > > I think this particular one is easy to implement when > the program type checks. But when it doesn't, what do > you show? When the program fails to type-check, does the type-checker just throw up its hands in despair because at the point where the contradiction becommes apparrent it no longer has any knowledge as to where in the source code it was working? Is the assignment of types to expressions not known at all until it is complete? Hindley-Milner analysis is of this kind. Or does it assign types in a mostly bottom-up fashion with possibly some top-down influence, until it finds one expression that has a type incompatible with context? In that case, there's still clear information to present to the programmer. -- hendrik From matthias at ccs.neu.edu Wed Aug 6 08:41:40 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Wed, 6 Aug 2014 08:41:40 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: <20140806115650.GB31893@topoi.pooq.com> References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> <20140806115650.GB31893@topoi.pooq.com> Message-ID: <6B466DA7-6DFB-4A3A-B9B1-A83D145E3F52@ccs.neu.edu> On Aug 6, 2014, at 7:56 AM, Hendrik Boom wrote: > On Tue, Aug 05, 2014 at 08:53:42PM -0400, Matthias Felleisen wrote: >> >> You guys came up with some wonderful ideas. >> >> I think this particular one is easy to implement when >> the program type checks. But when it doesn't, what do >> you show? > > When the program fails to type-check, does the type-checker just throw > up its hands in despair because at the point where the contradiction > becommes apparrent it no longer has any knowledge as to where in the > source code it was working? Is the assignment of types to expressions > not known at all until it is complete? Hindley-Milner analysis is of > this kind. Or does it assign types in a mostly bottom-up fashion with > possibly some top-down influence, until it finds one expression that > has a type incompatible with context? In that case, there's still > clear information to present to the programmer. Let's not wave hands for the sake of those who followed this thread up to this point. Conventional HM type inference (reconstruction) assigns type variables to all those places where programmers don't write down types, uses the algebraic structure of the type and expression language to set up equations among the types of expressions (including the type variables), and uses (symbolic) Gaussian elimination to solve those equations. If there are too few equations, you get solutions with free type variables, which yields HM's second-class parametric polymorphism. If you get contradictions, Example: f : __?__ = (lambda ({ x : __?__) 10) assign TF and TX to __?__ places use type of lambda is [TX -> Integer] because 10 is Integer equate TF = [TX -> Integer] one equation, two variables -> f is polymorphic like this: (forall (TX) [TX -> Integer]) If you apply this analysis to the entire module, you can (1) reduce a lot of the programmer's work and (2) smear the variables across a wide swath of space when you perform Gaussian elimination. Typed Racket performs local type inference. This means (1) we impose more work on the programmer and (2) smear type variables across a smaller space. BUT when type inference fails, you have already lost track of the original relations among variables and you have at least two contradictory equations. Worse, a solution may change almost all equations in your system. So no, you don't know all that much when a theorem prover (even a specialized one such as HM) fails on you. But yes, since we are doing local inference and these expressions tend to be small, one could investigate the idea and see how far users can follow. -- Matthias From hendrik at topoi.pooq.com Wed Aug 6 09:26:06 2014 From: hendrik at topoi.pooq.com (Hendrik Boom) Date: Wed, 6 Aug 2014 09:26:06 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: <6B466DA7-6DFB-4A3A-B9B1-A83D145E3F52@ccs.neu.edu> References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> <20140806115650.GB31893@topoi.pooq.com> <6B466DA7-6DFB-4A3A-B9B1-A83D145E3F52@ccs.neu.edu> Message-ID: <20140806132606.GC31893@topoi.pooq.com> On Wed, Aug 06, 2014 at 08:41:40AM -0400, Matthias Felleisen wrote: > > On Aug 6, 2014, at 7:56 AM, Hendrik Boom wrote: > > > On Tue, Aug 05, 2014 at 08:53:42PM -0400, Matthias Felleisen wrote: > >> > >> You guys came up with some wonderful ideas. > >> > >> I think this particular one is easy to implement when > >> the program type checks. But when it doesn't, what do > >> you show? > > > > When the program fails to type-check, does the type-checker just throw > > up its hands in despair because at the point where the contradiction > > becommes apparrent it no longer has any knowledge as to where in the > > source code it was working? Is the assignment of types to expressions > > not known at all until it is complete? Hindley-Milner analysis is of > > this kind. Or does it assign types in a mostly bottom-up fashion with > > possibly some top-down influence, until it finds one expression that > > has a type incompatible with context? In that case, there's still > > clear information to present to the programmer. > > > Let's not wave hands for the sake of those who followed this thread up to this point. > > Conventional HM type inference (reconstruction) assigns type variables to all those places where programmers don't write down types, uses the algebraic structure of the type and expression language to set up equations among the types of expressions (including the type variables), and uses (symbolic) Gaussian elimination to solve those equations. If there are too few equations, you get solutions with free type variables, which yields HM's second-class parametric polymorphism. If you get contradictions, > > Example: > f : __?__ = (lambda ({ x : __?__) 10) > assign TF and TX to __?__ places > use type of lambda is [TX -> Integer] because 10 is Integer > equate TF = [TX -> Integer] > one equation, two variables -> f is polymorphic like this: (forall (TX) [TX -> Integer]) > > If you apply this analysis to the entire module, you can (1) reduce a lot of the programmer's work and (2) smear the variables across a wide swath of space when you perform Gaussian elimination. > > Typed Racket performs local type inference. This means (1) we impose > more work on the programmer and (2) smear type variables across a > smaller space. I see. So you use something like HM inference, but on small pieces of the program. > BUT when type inference fails, you have already lost track of the > original relations among variables and you have at least two > contradictory equations. Worse, a solution may change almost all > equations in your system. So no, you don't know all that much when a > theorem prover (even a specialized one such as HM) fails on you. But > yes, since we are doing local inference and these expressions tend to > be small, one could investigate the idea and see how far users can > follow. Which leaves you in the same position conceptuallly, but as a practical matter, to a lesser degree. I' all for more work by the programmer if it means clearer error messages and less effort debugging. Often more means less. -- hendrik From jay.mccarthy at gmail.com Wed Aug 6 10:07:08 2014 From: jay.mccarthy at gmail.com (Jay McCarthy) Date: Wed, 6 Aug 2014 10:07:08 -0400 Subject: [racket] Racket VM in Racket In-Reply-To: References: Message-ID: This is awesome, Jens. I'd like to have more Racket VMs for experiments like JavaScript and LLVM (to get on to iOS better?). I wonder if you were able to use the Whalesong bytecode interpreter during the coding of this? Jay On Mon, Aug 4, 2014 at 4:23 PM, Jens Axel S?gaard wrote: > Hi All, > > To see how Racket's bytecodes work I have implemented an evaluator in Racket. > The best feature is the extensive amount of comments. > > https://github.com/soegaard/meta/blob/master/runtime/racket-eval.rkt > > Comments and patches are welcome, > Jens Axel S?gaard > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- Jay McCarthy http://jeapostrophe.github.io "Wherefore, be not weary in well-doing, for ye are laying the foundation of a great work. And out of small things proceedeth that which is great." - D&C 64:33 From robby at eecs.northwestern.edu Wed Aug 6 10:10:29 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Wed, 6 Aug 2014 09:10:29 -0500 Subject: [racket] Racket VM in Racket In-Reply-To: References: Message-ID: I think this is awesome too! Is there some way we can use this to help make Racket better, do you think? Would it be useful as a test oracle? Is there a way to maybe re-interpret the function definitions (say put them into a different "#lang") you've written to get some kind of a cool random bytecode generator maybe? Something else? Robby On Wed, Aug 6, 2014 at 9:07 AM, Jay McCarthy wrote: > This is awesome, Jens. > > I'd like to have more Racket VMs for experiments like JavaScript and > LLVM (to get on to iOS better?). I wonder if you were able to use the > Whalesong bytecode interpreter during the coding of this? > > Jay > > On Mon, Aug 4, 2014 at 4:23 PM, Jens Axel S?gaard wrote: >> Hi All, >> >> To see how Racket's bytecodes work I have implemented an evaluator in Racket. >> The best feature is the extensive amount of comments. >> >> https://github.com/soegaard/meta/blob/master/runtime/racket-eval.rkt >> >> Comments and patches are welcome, >> Jens Axel S?gaard >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > > -- > Jay McCarthy > http://jeapostrophe.github.io > > "Wherefore, be not weary in well-doing, > for ye are laying the foundation of a great work. > And out of small things proceedeth that which is great." > - D&C 64:33 > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From lysseus at gmail.com Wed Aug 6 13:10:55 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Wed, 6 Aug 2014 10:10:55 -0700 Subject: [racket] syntax-parse question In-Reply-To: References: Message-ID: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> On Aug 5, 2014, at 2:21 PM, Jens Axel S?gaard wrote: > Is this a step in the right direction? > > (define-syntax (x stx) > (syntax-parse stx > [(_ (y ... (z ...) w ...)) > #'(xf (yf y ... (zf z ...) w ...))])) > > The pattern (z ...) ... will match a sequence of lists such as (4 5 6) (7 8) > but it won't match (4 5 6) 7 8 from your example. > > /Jens Axel Closer. It doesn?t match something like ?( 1 2 3 (4 5 6) 7 (8 9) 10), for instance. I have tried: #lang racket (require (for-syntax syntax/parse)) (define-syntax (x stx) (define-syntax-class binding #:description "binding list" (pattern (z:id ...))) (define-syntax-class or-binding #:description "binding or" (pattern (~or zb:binding y:id) #:with (z ...) #'(zb.z ...))) (syntax-parse stx [(_ (ob:or-binding ...) ...) #''ok #;#'(xf (yf ob.y ...) ...) #;#'(xf (yf ob.y ... (zf ob.z ...) ...) ...)])) (define (xf . xs) xs) (define (yf . ys) ys) (define (zf . zs) zs) (x (a)) (x (a b (c))) (x (a b c (d e f) g h)) But while the pattern ?appears? to match, I can?t seem to construct a template that is acceptable to syntax-parse, which doesn?t like the #:with clause on my syntax-class or-binding. I must be missing something. -Kevin From alexander at knauth.org Wed Aug 6 13:47:47 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Wed, 6 Aug 2014 13:47:47 -0400 Subject: [racket] syntax-parse question In-Reply-To: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> Message-ID: <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> On Aug 6, 2014, at 1:10 PM, Kevin Forchione wrote: > > On Aug 5, 2014, at 2:21 PM, Jens Axel S?gaard wrote: > >> Is this a step in the right direction? >> >> (define-syntax (x stx) >> (syntax-parse stx >> [(_ (y ... (z ...) w ...)) >> #'(xf (yf y ... (zf z ...) w ...))])) >> >> The pattern (z ...) ... will match a sequence of lists such as (4 5 6) (7 8) >> but it won't match (4 5 6) 7 8 from your example. >> >> /Jens Axel > > Closer. It doesn?t match something like ?( 1 2 3 (4 5 6) 7 (8 9) 10), for instance. For that I think you want something like this: (syntax-parse stx [(_ (~or (z ...) y) ...) #'(xf (yf y ... (zf z ...)))]) Either that or you can use my version of syntax-parse with pattern-expanders and use ~seq-no-order: https://github.com/AlexKnauth/seq-no-order > > I have tried: > > #lang racket > > (require (for-syntax syntax/parse)) > > (define-syntax (x stx) > > (define-syntax-class binding > #:description "binding list" > (pattern (z:id ...))) > > (define-syntax-class or-binding > #:description "binding or" > (pattern (~or zb:binding y:id) > #:with (z ...) #'(zb.z ...))) This won?t work because if the y:id pattern matches instead of the zb:binding pattern, then the zb.z attribute won?t be there. Instead you probably wan?t this: (define-syntax-class or-binding #:description "binding or" (pattern zb:binding #:with (z ...) #'(zb.z ...)) (pattern y:id #:with (z ...) #'(y)) ; or whatever, depending on what you want to do here ) > > (syntax-parse stx > [(_ (ob:or-binding ...) ...) > #''ok > #;#'(xf (yf ob.y ...) ...) > #;#'(xf (yf ob.y ... (zf ob.z ...) ...) ...)])) > > (define (xf . xs) xs) > (define (yf . ys) ys) > (define (zf . zs) zs) > > (x (a)) > (x (a b (c))) > (x (a b c (d e f) g h)) > > But while the pattern ?appears? to match, I can?t seem to construct a template that is acceptable to syntax-parse, which doesn?t like the #:with clause on my syntax-class or-binding. I must be missing something. > > -Kevin > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Wed Aug 6 14:02:04 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Wed, 6 Aug 2014 14:02:04 -0400 Subject: [racket] syntax-parse question In-Reply-To: <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> Message-ID: On Aug 6, 2014, at 1:47 PM, Alexander D. Knauth wrote: > > > On Aug 6, 2014, at 1:10 PM, Kevin Forchione wrote: > >> >> On Aug 5, 2014, at 2:21 PM, Jens Axel S?gaard wrote: >> >>> Is this a step in the right direction? >>> >>> (define-syntax (x stx) >>> (syntax-parse stx >>> [(_ (y ... (z ...) w ...)) >>> #'(xf (yf y ... (zf z ...) w ...))])) >>> >>> The pattern (z ...) ... will match a sequence of lists such as (4 5 6) (7 8) >>> but it won't match (4 5 6) 7 8 from your example. >>> >>> /Jens Axel >> >> Closer. It doesn?t match something like ?( 1 2 3 (4 5 6) 7 (8 9) 10), for instance. > > For that I think you want something like this: > (syntax-parse stx > [(_ (~or (z ...) > y) > ...) > #'(xf (yf y ... (zf z ...)))]) Sorry I forgot an ellipsis. I meant this: (syntax-parse stx [(_ (~or (z ...) y) ...) #'(xf (yf y ... (zf z ...) ...))]) > > Either that or you can use my version of syntax-parse with pattern-expanders and use ~seq-no-order: > https://github.com/AlexKnauth/seq-no-order > >> >> I have tried: >> >> #lang racket >> >> (require (for-syntax syntax/parse)) >> >> (define-syntax (x stx) >> >> (define-syntax-class binding >> #:description "binding list" >> (pattern (z:id ...))) >> >> (define-syntax-class or-binding >> #:description "binding or" >> (pattern (~or zb:binding y:id) >> #:with (z ...) #'(zb.z ...))) > > This won?t work because if the y:id pattern matches instead of the zb:binding pattern, then the zb.z attribute won?t be there. > Instead you probably wan?t this: > (define-syntax-class or-binding > #:description "binding or" > (pattern zb:binding > #:with (z ...) #'(zb.z ...)) > (pattern y:id > #:with (z ...) #'(y)) ; or whatever, depending on what you want to do here > ) > >> >> (syntax-parse stx >> [(_ (ob:or-binding ...) ...) >> #''ok >> #;#'(xf (yf ob.y ...) ...) >> #;#'(xf (yf ob.y ... (zf ob.z ...) ...) ...)])) >> >> (define (xf . xs) xs) >> (define (yf . ys) ys) >> (define (zf . zs) zs) >> >> (x (a)) >> (x (a b (c))) >> (x (a b c (d e f) g h)) >> >> But while the pattern ?appears? to match, I can?t seem to construct a template that is acceptable to syntax-parse, which doesn?t like the #:with clause on my syntax-class or-binding. I must be missing something. >> >> -Kevin >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jensaxel at soegaard.net Wed Aug 6 16:03:17 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Wed, 6 Aug 2014 22:03:17 +0200 Subject: [racket] top-level-rename Message-ID: The program below produce bytecodes for the program that returns a syntax-object representing 42. The syntax-object looks like this: (#s((stx zo 0) #s((wrapped zo 0) 42 (#s((top-level-rename wrap 0 zo 0) #f) #s((top-level-rename wrap 0 zo 0) #f) #s((top-level-rename wrap 0 zo 0) #t) #s((phase-shift wrap 0 zo 0) 0 #f #f #f)) clean)))) Two questions: 1) Why three top-level-renames and not just one? 2) What is the meaning of the boolean flag? /Jens Axel #lang racket (require compiler/zo-structs compiler/zo-parse) (define (bytecode->zo bytecode) (zo-parse (open-input-bytes (with-output-to-bytes (? () (write bytecode)))))) (define (stx->zo x) (parameterize ([current-namespace (make-base-empty-namespace)]) (namespace-require 'racket/base) (bytecode->zo (compile x)))) (stx->zo '(syntax 42)) From jensaxel at soegaard.net Wed Aug 6 16:16:00 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Wed, 6 Aug 2014 22:16:00 +0200 Subject: [racket] Racket VM in Racket In-Reply-To: References: Message-ID: 2014-08-06 16:07 GMT+02:00 Jay McCarthy : > This is awesome, Jens. > > I'd like to have more Racket VMs for experiments like JavaScript and > LLVM (to get on to iOS better?). I wonder if you were able to use the > Whalesong bytecode interpreter during the coding of this? Whalesong do not interpret the bytecodes directly, so I didn't look for hints there. The main references were the documentation, but the paper "The Racket Virtual Machine and Randomized Testing" helped too. /Jens Axel From jensaxel at soegaard.net Wed Aug 6 16:33:04 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Wed, 6 Aug 2014 22:33:04 +0200 Subject: [racket] Racket VM in Racket In-Reply-To: References: Message-ID: 2014-08-06 16:10 GMT+02:00 Robby Findler : > I think this is awesome too! > > Is there some way we can use this to help make Racket better, do you think? That wasn't the motivation per se, but it might have some potential uses. A simple application would be to collect statistics of the bytecodes used. Another would be to add a tracer. > Would it be useful as a test oracle? Is there a way to maybe > re-interpret the function definitions (say put them into a different > "#lang") you've written to get some kind of a cool random bytecode > generator maybe? I am not sure what you mean here. /Jens Axel From dyoo at hashcollision.org Wed Aug 6 17:01:34 2014 From: dyoo at hashcollision.org (Danny Yoo) Date: Wed, 6 Aug 2014 14:01:34 -0700 Subject: [racket] Racket VM in Racket In-Reply-To: References: Message-ID: > Whalesong do not interpret the bytecodes directly, so I didn't > look for hints there. (Note: there was a preliminary simulator used for test cases in 2bc4b2a224fe7a485a1060c69ebde925cecdeb05) From mb at mbtype.com Wed Aug 6 18:50:41 2014 From: mb at mbtype.com (Matthew Butterick) Date: Wed, 6 Aug 2014 15:50:41 -0700 Subject: [racket] confusing error message: what is "lang:read.1"? Message-ID: Under certain circumstances, because of what I assume is a bug in my code, I get an error like this: > define-values: assignment disallowed; > cannot re-define a constant > constant: lang:read.1 > in module: "/Users/mb/git/racket/racket/collects/racket/main.rkt" > context...: > (submod /Users/mb/git/racket/racket/collects/racket/main.rkt reader): [running body] I understand how the "assignment disallowed" error arises. What I don't understand is the meaning of "lang:read.1" in this context. I'm guessing it has something to do with the #lang line (?) but ... the rest is hazy. Clarification welcome. From matthias at ccs.neu.edu Wed Aug 6 18:54:46 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Wed, 6 Aug 2014 18:54:46 -0400 Subject: [racket] Racket VM in Racket In-Reply-To: References: Message-ID: <2D42DA53-E34B-4E70-8E69-AF03F6E54EF7@ccs.neu.edu> On Aug 6, 2014, at 4:33 PM, Jens Axel S?gaard wrote: > 2014-08-06 16:10 GMT+02:00 Robby Findler : >> I think this is awesome too! >> >> Is there some way we can use this to help make Racket better, do you think? > > That wasn't the motivation per se, but it might have some potential uses. > A simple application would be to collect statistics of the bytecodes used. > Another would be to add a tracer. > >> Would it be useful as a test oracle? Is there a way to maybe >> re-interpret the function definitions (say put them into a different >> "#lang") you've written to get some kind of a cool random bytecode >> generator maybe? > > I am not sure what you mean here. I think you could do a #lang bc ; for byte code with it that comes with a traditional stepper. -- Matthias From florence at northwestern.edu Wed Aug 6 19:02:03 2014 From: florence at northwestern.edu (Spencer Florence) Date: Wed, 6 Aug 2014 18:02:03 -0500 Subject: [racket] confusing error message: what is "lang:read.1"? In-Reply-To: References: Message-ID: "lang:read.1" looks a some name generated by "syntax-local-lift-expression" or "generate-temporaries". IIRC the ".1" is how the printer handles showing identifiers that may have the same symbol, but different scope. so: #lang racket (define-syntax (example stx) (syntax-case stx () [(_) (with-syntax ([id (syntax-local-lift-expression #''anything)]) #'(displayln 'id))])) (example) (example) would display something like lifted.0 lifted.2 But I'm not sure what makes the name "lang:read". On Wed, Aug 6, 2014 at 5:50 PM, Matthew Butterick wrote: > Under certain circumstances, because of what I assume is a bug in my code, > I get an error like this: > > > define-values: assignment disallowed; > > cannot re-define a constant > > constant: lang:read.1 > > in module: "/Users/mb/git/racket/racket/collects/racket/main.rkt" > > context...: > > (submod /Users/mb/git/racket/racket/collects/racket/main.rkt reader): > [running body] > > I understand how the "assignment disallowed" error arises. What I don't > understand is the meaning of "lang:read.1" in this context. I'm guessing it > has something to do with the #lang line (?) but ... the rest is hazy. > > Clarification welcome. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mb at mbtype.com Wed Aug 6 20:39:40 2014 From: mb at mbtype.com (Matthew Butterick) Date: Wed, 6 Aug 2014 17:39:40 -0700 Subject: [racket] confusing error message: what is "lang:read.1"? In-Reply-To: References: Message-ID: <0BF391CD-CC3F-4B4C-A27D-C58DF77654ED@mbtype.com> I've now concocted a simple but strange test case using three files: ;;; three.rkt #lang racket ;;; two.rkt #lang datalog ;;; one.rkt #lang racket/base (require racket/rerequire) (dynamic-rerequire (string->path "two.rkt")) (eval '(require "three.rkt") (make-base-namespace)) Then from the command line: >racket one.rkt And you should get: define-values: assignment disallowed; cannot re-define a constant constant: lang:read.1 in module: "/Users/mb/git/racket/racket/collects/racket/main.rkt" context...: (submod /Users/mb/git/racket/racket/collects/racket/main.rkt reader): [running body] standard-module-name-resolver standard-module-name-resolver On Aug 6, 2014, at 4:02 PM, Spencer Florence wrote: > "lang:read.1" looks a some name generated by "syntax-local-lift-expression" or "generate-temporaries". IIRC the ".1" is how the printer handles showing identifiers that may have the same symbol, but different scope. > > so: > > #lang racket > (define-syntax (example stx) > (syntax-case stx () > [(_) > (with-syntax ([id (syntax-local-lift-expression #''anything)]) > #'(displayln 'id))])) > (example) > (example) > > > would display something like > > lifted.0 > lifted.2 > > But I'm not sure what makes the name "lang:read". > > > On Wed, Aug 6, 2014 at 5:50 PM, Matthew Butterick wrote: > Under certain circumstances, because of what I assume is a bug in my code, I get an error like this: > > > define-values: assignment disallowed; > > cannot re-define a constant > > constant: lang:read.1 > > in module: "/Users/mb/git/racket/racket/collects/racket/main.rkt" > > context...: > > (submod /Users/mb/git/racket/racket/collects/racket/main.rkt reader): [running body] > > I understand how the "assignment disallowed" error arises. What I don't understand is the meaning of "lang:read.1" in this context. I'm guessing it has something to do with the #lang line (?) but ... the rest is hazy. > > Clarification welcome. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lysseus at gmail.com Thu Aug 7 01:41:49 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Wed, 6 Aug 2014 22:41:49 -0700 Subject: [racket] syntax-parse question In-Reply-To: References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> Message-ID: <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> On Aug 6, 2014, at 11:02 AM, Alexander D. Knauth wrote: > > On Aug 6, 2014, at 1:47 PM, Alexander D. Knauth wrote: > >> >> >> On Aug 6, 2014, at 1:10 PM, Kevin Forchione wrote: >> >>> >>> On Aug 5, 2014, at 2:21 PM, Jens Axel S?gaard wrote: >>> >>>> Is this a step in the right direction? >>>> >>>> (define-syntax (x stx) >>>> (syntax-parse stx >>>> [(_ (y ... (z ...) w ...)) >>>> #'(xf (yf y ... (zf z ...) w ...))])) >>>> >>>> The pattern (z ...) ... will match a sequence of lists such as (4 5 6) (7 8) >>>> but it won't match (4 5 6) 7 8 from your example. >>>> >>>> /Jens Axel >>> >>> Closer. It doesn?t match something like ?( 1 2 3 (4 5 6) 7 (8 9) 10), for instance. >> >> For that I think you want something like this: >> (syntax-parse stx >> [(_ (~or (z ...) >> y) >> ...) >> #'(xf (yf y ... (zf z ...)))]) > > Sorry I forgot an ellipsis. I meant this: > (syntax-parse stx > [(_ (~or (z ...) > y) > ...) > #'(xf (yf y ... (zf z ...) ...))]) Remarkably difficult just to parse what amounts to nested lists! This doesn?t quite do what I want either. For instance: #lang racket (require (for-syntax syntax/parse)) #;(define-syntax (x stx) (define-syntax-class binding #:description "binding list" (pattern (z:number ...))) (syntax-parse stx [(_ b:binding ...) #'(list (list b.z ...) ...)])) #;(define-syntax (x stx) (define-syntax-class lbinding #:description "binding list" (pattern (z:number ...))) (define-syntax-class orbinding #:description "binding or" (pattern (y:number ...) #:with (z ...) #'(y ...)) (pattern (lb:lbinding) #:with (z ...) #'(lb.z ...))) (syntax-parse stx [(_ ob:orbinding ...) #'(list (list ob.z ...) ...)])) #;(define-syntax (x stx) (define-syntax-class lbinding #:description "binding list" (pattern (z:number ...))) (define-syntax-class orbinding #:description "binding or" (pattern (y:number ...) #:with (z ...) #'(y ...)) (pattern (lb:lbinding) #:with (z ...) #'(lb.z ...))) (syntax-parse stx [(_ ob:orbinding ...) #'(list (list ob.z ...) ...)])) (define-syntax (x stx) (syntax-parse stx [(_ (~or (z ...) y) ...) #'(list (list y ... (list z ...) ...))])) (x (1 2 3 4) (5 (6 7) 8)) expands to: (list (list (list 1 2 3 4) (list 5 (6 7) 8))))) instead of (list (list (list 1 2 3 4) (list 5 (list 6 7) 8))))). -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Thu Aug 7 09:39:49 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 7 Aug 2014 09:39:49 -0400 Subject: [racket] syntax-parse question In-Reply-To: <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> Message-ID: <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> On Aug 7, 2014, at 1:41 AM, Kevin Forchione wrote: > > On Aug 6, 2014, at 11:02 AM, Alexander D. Knauth wrote: > >> >> On Aug 6, 2014, at 1:47 PM, Alexander D. Knauth wrote: >> >>> >>> >>> On Aug 6, 2014, at 1:10 PM, Kevin Forchione wrote: >>> >>>> >>>> On Aug 5, 2014, at 2:21 PM, Jens Axel S?gaard wrote: >>>> >>>>> Is this a step in the right direction? >>>>> >>>>> (define-syntax (x stx) >>>>> (syntax-parse stx >>>>> [(_ (y ... (z ...) w ...)) >>>>> #'(xf (yf y ... (zf z ...) w ...))])) >>>>> >>>>> The pattern (z ...) ... will match a sequence of lists such as (4 5 6) (7 8) >>>>> but it won't match (4 5 6) 7 8 from your example. >>>>> >>>>> /Jens Axel >>>> >>>> Closer. It doesn?t match something like ?( 1 2 3 (4 5 6) 7 (8 9) 10), for instance. >>> >>> For that I think you want something like this: >>> (syntax-parse stx >>> [(_ (~or (z ...) >>> y) >>> ...) >>> #'(xf (yf y ... (zf z ...)))]) >> >> Sorry I forgot an ellipsis. I meant this: >> (syntax-parse stx >> [(_ (~or (z ...) >> y) >> ...) >> #'(xf (yf y ... (zf z ...) ...))]) > > > Remarkably difficult just to parse what amounts to nested lists! This doesn?t quite do what I want either. For instance: > > #lang racket > > (require (for-syntax syntax/parse)) > > #;(define-syntax (x stx) > > (define-syntax-class binding > #:description "binding list" > (pattern (z:number ...))) > > (syntax-parse stx > [(_ b:binding ...) > #'(list (list b.z ...) ...)])) > > #;(define-syntax (x stx) > > (define-syntax-class lbinding > #:description "binding list" > (pattern (z:number ...))) > > (define-syntax-class orbinding > #:description "binding or" > (pattern (y:number ...) > #:with (z ...) #'(y ...)) > (pattern (lb:lbinding) > #:with (z ...) #'(lb.z ...))) > > (syntax-parse stx > [(_ ob:orbinding ...) > #'(list (list ob.z ...) ...)])) > > #;(define-syntax (x stx) > > (define-syntax-class lbinding > #:description "binding list" > (pattern (z:number ...))) > > (define-syntax-class orbinding > #:description "binding or" > (pattern (y:number ...) > #:with (z ...) #'(y ...)) > (pattern (lb:lbinding) > #:with (z ...) #'(lb.z ...))) > > (syntax-parse stx > [(_ ob:orbinding ...) > #'(list (list ob.z ...) ...)])) > > (define-syntax (x stx) > (syntax-parse stx > [(_ (~or (z ...) > y) > ...) > #'(list (list y ... (list z ...) ...))])) > > (x (1 2 3 4) (5 (6 7) 8)) > > expands to: (list (list (list 1 2 3 4) (list 5 (6 7) 8))))) instead of (list (list (list 1 2 3 4) (list 5 (list 6 7) 8))))). > > -Kevin > Do you want something like this then: (syntax-parse stx [(_ (~or ((((e ...) ...) ...) ...) (((d ...) ...) ...) ((c ...) ...) (b ...) a) . . .) #?(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...) ...)]) Except going infinitely? For that I think you would need a recursive helper function. Or do you want to just replace all instances of (a ...) with (list a ...) ?: (define-syntax-class thing #:attributes (norm) [pattern (a:thing ...) #:with norm (list a.norm ...)] [pattern a #:with norm a]) Or what? -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Thu Aug 7 11:55:18 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 7 Aug 2014 11:55:18 -0400 Subject: [racket] syntax-parse question In-Reply-To: <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> Message-ID: <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> On Aug 7, 2014, at 9:39 AM, Alexander D. Knauth wrote: > > On Aug 7, 2014, at 1:41 AM, Kevin Forchione wrote: > >> >> On Aug 6, 2014, at 11:02 AM, Alexander D. Knauth wrote: >> >>> >>> On Aug 6, 2014, at 1:47 PM, Alexander D. Knauth wrote: >>> >>>> >>>> >>>> On Aug 6, 2014, at 1:10 PM, Kevin Forchione wrote: >>>> >>>>> >>>>> On Aug 5, 2014, at 2:21 PM, Jens Axel S?gaard wrote: >>>>> >>>>>> Is this a step in the right direction? >>>>>> >>>>>> (define-syntax (x stx) >>>>>> (syntax-parse stx >>>>>> [(_ (y ... (z ...) w ...)) >>>>>> #'(xf (yf y ... (zf z ...) w ...))])) >>>>>> >>>>>> The pattern (z ...) ... will match a sequence of lists such as (4 5 6) (7 8) >>>>>> but it won't match (4 5 6) 7 8 from your example. >>>>>> >>>>>> /Jens Axel >>>>> >>>>> Closer. It doesn?t match something like ?( 1 2 3 (4 5 6) 7 (8 9) 10), for instance. >>>> >>>> For that I think you want something like this: >>>> (syntax-parse stx >>>> [(_ (~or (z ...) >>>> y) >>>> ...) >>>> #'(xf (yf y ... (zf z ...)))]) >>> >>> Sorry I forgot an ellipsis. I meant this: >>> (syntax-parse stx >>> [(_ (~or (z ...) >>> y) >>> ...) >>> #'(xf (yf y ... (zf z ...) ...))]) >> >> >> Remarkably difficult just to parse what amounts to nested lists! This doesn?t quite do what I want either. For instance: >> >> #lang racket >> >> (require (for-syntax syntax/parse)) >> >> #;(define-syntax (x stx) >> >> (define-syntax-class binding >> #:description "binding list" >> (pattern (z:number ...))) >> >> (syntax-parse stx >> [(_ b:binding ...) >> #'(list (list b.z ...) ...)])) >> >> #;(define-syntax (x stx) >> >> (define-syntax-class lbinding >> #:description "binding list" >> (pattern (z:number ...))) >> >> (define-syntax-class orbinding >> #:description "binding or" >> (pattern (y:number ...) >> #:with (z ...) #'(y ...)) >> (pattern (lb:lbinding) >> #:with (z ...) #'(lb.z ...))) >> >> (syntax-parse stx >> [(_ ob:orbinding ...) >> #'(list (list ob.z ...) ...)])) >> >> #;(define-syntax (x stx) >> >> (define-syntax-class lbinding >> #:description "binding list" >> (pattern (z:number ...))) >> >> (define-syntax-class orbinding >> #:description "binding or" >> (pattern (y:number ...) >> #:with (z ...) #'(y ...)) >> (pattern (lb:lbinding) >> #:with (z ...) #'(lb.z ...))) >> >> (syntax-parse stx >> [(_ ob:orbinding ...) >> #'(list (list ob.z ...) ...)])) >> >> (define-syntax (x stx) >> (syntax-parse stx >> [(_ (~or (z ...) >> y) >> ...) >> #'(list (list y ... (list z ...) ...))])) >> >> (x (1 2 3 4) (5 (6 7) 8)) >> >> expands to: (list (list (list 1 2 3 4) (list 5 (6 7) 8))))) instead of (list (list (list 1 2 3 4) (list 5 (list 6 7) 8))))). >> >> -Kevin >> > > Do you want something like this then: > (syntax-parse stx > [(_ (~or ((((e ...) ...) ...) ...) > (((d ...) ...) ...) > ((c ...) ...) > (b ...) > a) > . . .) > #?(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...) ...)]) Sorry I meant this: (syntax-parse #'(x (1 2 3 4) (5 (6 7) 8)) [(_ (~or ((~or ((~or ((~or (e ...) d) ...) c) ...) b) ...) a) ...) #'(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...))]) > Except going infinitely? For that I think you would need a recursive helper function. > > Or do you want to just replace all instances of (a ...) with (list a ...) ?: > (define-syntax-class thing > #:attributes (norm) > [pattern (a:thing ...) > #:with norm (list a.norm ...)] > [pattern a > #:with norm a]) > > Or what? > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lysseus at gmail.com Thu Aug 7 12:50:18 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Thu, 7 Aug 2014 09:50:18 -0700 Subject: [racket] syntax-parse question In-Reply-To: <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> Message-ID: On Aug 7, 2014, at 8:55 AM, Alexander D. Knauth wrote: >> >> Do you want something like this then: >> (syntax-parse stx >> [(_ (~or ((((e ...) ...) ...) ...) >> (((d ...) ...) ...) >> ((c ...) ...) >> (b ...) >> a) >> . . .) >> #?(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...) ...)]) > > Sorry I meant this: > (syntax-parse #'(x (1 2 3 4) (5 (6 7) 8)) > [(_ (~or ((~or ((~or ((~or (e ...) d) ...) c) ...) b) ...) a) ...) > #'(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...))]) > >> Except going infinitely? For that I think you would need a recursive helper function. >> >> Or do you want to just replace all instances of (a ...) with (list a ...) ?: >> (define-syntax-class thing >> #:attributes (norm) >> [pattern (a:thing ...) >> #:with norm (list a.norm ...)] >> [pattern a >> #:with norm a]) >> >> Or what? Sorry, I should probably clarify the problem I?m attempting to solve. I?ve got an application that creates a composite image using classes of objects that draw themselves. Essentially the macro Compose-A (compose-A ( ?) ?) would produce something like: {compose-A (compose-B ?) ?) Compose-A can have an arbitrary number of compose-B clauses. compose-B clauses can have an arbitrarily number of elements in any order consisting of ing or clause-C. The clause-C consist of an arbitrary number of img. I?ve been wondering about having to go with a recursive macro. Is there any code in the current system that can be modeled from? -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From lysseus at gmail.com Thu Aug 7 13:28:23 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Thu, 7 Aug 2014 10:28:23 -0700 Subject: [racket] syntax-parse question In-Reply-To: References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> Message-ID: <6F4F02E2-7982-4F23-AA1D-BFD5FDCCD9E2@gmail.com> On Aug 7, 2014, at 9:50 AM, Kevin Forchione wrote: > > On Aug 7, 2014, at 8:55 AM, Alexander D. Knauth wrote: > >>> >>> Do you want something like this then: >>> (syntax-parse stx >>> [(_ (~or ((((e ...) ...) ...) ...) >>> (((d ...) ...) ...) >>> ((c ...) ...) >>> (b ...) >>> a) >>> . . .) >>> #?(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...) ...)]) >> >> Sorry I meant this: >> (syntax-parse #'(x (1 2 3 4) (5 (6 7) 8)) >> [(_ (~or ((~or ((~or ((~or (e ...) d) ...) c) ...) b) ...) a) ...) >> #'(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...))]) >> >>> Except going infinitely? For that I think you would need a recursive helper function. >>> >>> Or do you want to just replace all instances of (a ...) with (list a ...) ?: >>> (define-syntax-class thing >>> #:attributes (norm) >>> [pattern (a:thing ...) >>> #:with norm (list a.norm ...)] >>> [pattern a >>> #:with norm a]) >>> >>> Or what? > > Sorry, I should probably clarify the problem I?m attempting to solve. I?ve got an application that creates a composite image using classes of objects that draw themselves. Essentially the macro Compose-A > > (compose-A ( ?) ?) > > would produce something like: > > {compose-A (compose-B ?) ?) > > Compose-A can have an arbitrary number of compose-B clauses. > compose-B clauses can have an arbitrarily number of elements in any order consisting of ing or clause-C. > The clause-C consist of an arbitrary number of img. > > I?ve been wondering about having to go with a recursive macro. Is there any code in the current system that can be modeled from? > > -Kevin Actually, now that I think about it, the pattern can be generalized: (compose-macro [func ?) ?)> ?) producing something like: {func0 ?)> ?), etc. Essentially each clause consisting of an image or a sub-list, with succeeding levels of sub-list applying a new compose function to its arguments. I have to apologize, I don?t think I?ve captured the idea correctly with my notation. ?Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Thu Aug 7 15:43:10 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 7 Aug 2014 15:43:10 -0400 Subject: [racket] syntax-parse question In-Reply-To: <6F4F02E2-7982-4F23-AA1D-BFD5FDCCD9E2@gmail.com> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> <6F4F02E2-7982-4F23-AA1D-BFD5FDCCD9E2@gmail.com> Message-ID: <1588EAB6-B5FD-48E7-9A9C-FE1070BF3501@knauth.org> On Aug 7, 2014, at 1:28 PM, Kevin Forchione wrote: > On Aug 7, 2014, at 9:50 AM, Kevin Forchione wrote: > >> >> On Aug 7, 2014, at 8:55 AM, Alexander D. Knauth wrote: >> >>>> >>>> Do you want something like this then: >>>> (syntax-parse stx >>>> [(_ (~or ((((e ...) ...) ...) ...) >>>> (((d ...) ...) ...) >>>> ((c ...) ...) >>>> (b ...) >>>> a) >>>> . . .) >>>> #?(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...) ...)]) >>> >>> Sorry I meant this: >>> (syntax-parse #'(x (1 2 3 4) (5 (6 7) 8)) >>> [(_ (~or ((~or ((~or ((~or (e ...) d) ...) c) ...) b) ...) a) ...) >>> #'(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...))]) >>> >>>> Except going infinitely? For that I think you would need a recursive helper function. >>>> >>>> Or do you want to just replace all instances of (a ...) with (list a ...) ?: >>>> (define-syntax-class thing >>>> #:attributes (norm) >>>> [pattern (a:thing ...) >>>> #:with norm (list a.norm ...)] >>>> [pattern a >>>> #:with norm a]) >>>> >>>> Or what? >> >> Sorry, I should probably clarify the problem I?m attempting to solve. I?ve got an application that creates a composite image using classes of objects that draw themselves. Essentially the macro Compose-A >> >> (compose-A ( ?) ?) >> >> would produce something like: >> >> {compose-A (compose-B ?) ?) >> >> Compose-A can have an arbitrary number of compose-B clauses. >> compose-B clauses can have an arbitrarily number of elements in any order consisting of ing or clause-C. >> The clause-C consist of an arbitrary number of img. >> >> I?ve been wondering about having to go with a recursive macro. Is there any code in the current system that can be modeled from? >> >> -Kevin > > Actually, now that I think about it, the pattern can be generalized: > > (compose-macro [func ?) ?)> ?) > > producing something like: > > {func0 ?)> ?), etc. > > Essentially each clause consisting of an image or a sub-list, with succeeding levels of sub-list applying a new compose function to its arguments. I have to apologize, I don?t think I?ve captured the idea correctly with my notation. > > ?Kevin Ok then would this work for what you want? (define-syntax-class (thing fs) #:attributes (norm) [pattern x #:when (empty? fs) #:with norm #'x] [pattern (x ...) #:declare x (thing (rest fs)) #:with f (first fs) #:with norm #'(f x.norm ...)] [pattern x #:with norm #'x]) (syntax-parse #'(x [f1 f2 f3] (1 2 3 4) (5 (6 7) 8)) [(_ [f ...] . x) #:declare x (thing (syntax->list #'(f ...))) #'x.norm]) ; # -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Thu Aug 7 16:21:45 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 7 Aug 2014 16:21:45 -0400 Subject: [racket] syntax-parse question In-Reply-To: <1588EAB6-B5FD-48E7-9A9C-FE1070BF3501@knauth.org> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> <6F4F02E2-7982-4F23-AA1D-BFD5FDCCD9E2@gmail.com> <1588EAB6-B5FD-48E7-9A9C-FE1070BF3501@knauth.org> Message-ID: On Aug 7, 2014, at 3:43 PM, Alexander D. Knauth wrote: > > On Aug 7, 2014, at 1:28 PM, Kevin Forchione wrote: > >> On Aug 7, 2014, at 9:50 AM, Kevin Forchione wrote: >> >>> >>> On Aug 7, 2014, at 8:55 AM, Alexander D. Knauth wrote: >>> >>>>> >>>>> Do you want something like this then: >>>>> (syntax-parse stx >>>>> [(_ (~or ((((e ...) ...) ...) ...) >>>>> (((d ...) ...) ...) >>>>> ((c ...) ...) >>>>> (b ...) >>>>> a) >>>>> . . .) >>>>> #?(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...) ...)]) >>>> >>>> Sorry I meant this: >>>> (syntax-parse #'(x (1 2 3 4) (5 (6 7) 8)) >>>> [(_ (~or ((~or ((~or ((~or (e ...) d) ...) c) ...) b) ...) a) ...) >>>> #'(list (list a ... (list b ... (list c ... (list d ... (list e ...) ...) ...) ...) ...))]) >>>> >>>>> Except going infinitely? For that I think you would need a recursive helper function. >>>>> >>>>> Or do you want to just replace all instances of (a ...) with (list a ...) ?: >>>>> (define-syntax-class thing >>>>> #:attributes (norm) >>>>> [pattern (a:thing ...) >>>>> #:with norm (list a.norm ...)] >>>>> [pattern a >>>>> #:with norm a]) >>>>> >>>>> Or what? >>> >>> Sorry, I should probably clarify the problem I?m attempting to solve. I?ve got an application that creates a composite image using classes of objects that draw themselves. Essentially the macro Compose-A >>> >>> (compose-A ( ?) ?) >>> >>> would produce something like: >>> >>> {compose-A (compose-B ?) ?) >>> >>> Compose-A can have an arbitrary number of compose-B clauses. >>> compose-B clauses can have an arbitrarily number of elements in any order consisting of ing or clause-C. >>> The clause-C consist of an arbitrary number of img. >>> >>> I?ve been wondering about having to go with a recursive macro. Is there any code in the current system that can be modeled from? >>> >>> -Kevin >> >> Actually, now that I think about it, the pattern can be generalized: >> >> (compose-macro [func ?) ?)> ?) >> >> producing something like: >> >> {func0 ?)> ?), etc. >> >> Essentially each clause consisting of an image or a sub-list, with succeeding levels of sub-list applying a new compose function to its arguments. I have to apologize, I don?t think I?ve captured the idea correctly with my notation. >> >> ?Kevin > > Ok then would this work for what you want? > (define-syntax-class (thing fs) > #:attributes (norm) > [pattern x #:when (empty? fs) > #:with norm #'x] > [pattern (x ...) > #:declare x (thing (rest fs)) > #:with f (first fs) > #:with norm #'(f x.norm ...)] > [pattern x #:with norm #'x]) > (syntax-parse #'(x [f1 f2 f3] (1 2 3 4) (5 (6 7) 8)) > [(_ [f ...] . x) > #:declare x (thing (syntax->list #'(f ...))) > #'x.norm]) > ; # > > > By the way would this function version be helpful at all? (define (apply* fs lst*) (cond [(empty? fs) lst*] [(not (list? lst*)) lst*] [else (define f (first fs)) (define rst (rest fs)) (apply f (for/list ([lst (in-list lst*)]) (apply* rst lst)))])) (apply* (list list vector hash) '((1 2 3 4) (5 (6 7) 8))) ; '(#(1 2 3 4) #(5 #hash((6 . 7)) 8)) -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Thu Aug 7 17:58:29 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 7 Aug 2014 17:58:29 -0400 Subject: [racket] how does equal? determine with syntax objects? Message-ID: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> How does equal? determine whether two syntax objects are equal? Does it simply use eq?, or does it check the syntax-e, lexical context, srcloc and properties? From lysseus at gmail.com Thu Aug 7 18:48:57 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Thu, 7 Aug 2014 15:48:57 -0700 Subject: [racket] syntax-parse question In-Reply-To: <1588EAB6-B5FD-48E7-9A9C-FE1070BF3501@knauth.org> References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> <6F4F02E2-7982-4F23-AA1D-BFD5FDCCD9E2@gmail.com> <1588EAB6-B5FD-48E7-9A9C-FE1070BF3501@knauth.org> Message-ID: On Aug 7, 2014, at 12:43 PM, Alexander D. Knauth wrote: > (define-syntax-class (thing fs) > #:attributes (norm) > [pattern x #:when (empty? fs) > #:with norm #'x] > [pattern (x ...) > #:declare x (thing (rest fs)) > #:with f (first fs) > #:with norm #'(f x.norm ...)] > [pattern x #:with norm #'x]) > (syntax-parse #'(x [f1 f2 f3] (1 2 3 4) (5 (6 7) 8)) > [(_ [f ...] . x) > #:declare x (thing (syntax->list #'(f ...))) > #'x.norm]) > ; # Fantastic! I?ll have to study syntax-class more closely. Quite fabulous. Thanks so much! -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Thu Aug 7 20:53:46 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Thu, 7 Aug 2014 20:53:46 -0400 Subject: [racket] how does equal? determine with syntax objects? In-Reply-To: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> References: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> Message-ID: Here are some examples: > > (equal? #'(lambda (x) x) #'(lambda (x) x)) > #f > > (define so #'(lambda (x) x)) > > (equal? so so) > #t Are syntax objects mutable? If so, how would you define a function like eq? say syntax-eq? without using the built-in equality? Are syntax objects immutable? Why should they be immutable? How does equal? work on such structures normally? See HtDP on extensional and intensional equality. -- Matthias On Aug 7, 2014, at 5:58 PM, Alexander D. Knauth wrote: > How does equal? determine whether two syntax objects are equal? > > Does it simply use eq?, or does it check the syntax-e, lexical context, srcloc and properties? > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From alexander at knauth.org Thu Aug 7 21:44:30 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 7 Aug 2014 21:44:30 -0400 Subject: [racket] how does equal? determine with syntax objects? In-Reply-To: References: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> Message-ID: <789E84B0-0531-4C45-ABCE-93B660AC279C@knauth.org> On Aug 7, 2014, at 8:53 PM, Matthias Felleisen wrote: > > Here are some examples: > >>> (equal? #'(lambda (x) x) #'(lambda (x) x)) >> #f For these the source locations would still be different. >>> (define so #'(lambda (x) x)) >>> (equal? so so) >> #t For these they are eq?. Does equal? simply use eq? for syntax objects? This example says probably, or am I still missing something? (define stx #'(lambda (x) x)) (equal? stx (datum->syntax stx (syntax-e stx) stx stx stx)) > Are syntax objects mutable? If so, how would you define a function like eq? say syntax-eq? without using the built-in equality? > > Are syntax objects immutable? Why should they be immutable? How does equal? work on such structures normally? I was under the impression that syntax objects were immutable, but I don?t really know. And anyway, for mutable vectors, strings, byte-strings, and structs, equal? still checks each element. > See HtDP on extensional and intensional equality. ? Matthias Where? I have read a lot of HtDP, and looked at it again just now, but I don?t remember anything about this, and couldn?t find anything either. In the BSL docs for eq? and eqv? it mentions extensional and intensional, but doesn?t explain anything. In Realm of Racket there was a bit about that, but that doesn?t really tell me anything about syntax objects. > > On Aug 7, 2014, at 5:58 PM, Alexander D. Knauth wrote: > >> How does equal? determine whether two syntax objects are equal? >> >> Does it simply use eq?, or does it check the syntax-e, lexical context, srcloc and properties? >> >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From robby at eecs.northwestern.edu Thu Aug 7 21:49:10 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Thu, 7 Aug 2014 20:49:10 -0500 Subject: [racket] how does equal? determine with syntax objects? In-Reply-To: <789E84B0-0531-4C45-ABCE-93B660AC279C@knauth.org> References: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> <789E84B0-0531-4C45-ABCE-93B660AC279C@knauth.org> Message-ID: As a partial answer to your question, syntax objects internally have lots of caches that are most definitely mutable, but I don't think that there is any way you can observe the mutation without getting out a stopwatch. Robby On Thu, Aug 7, 2014 at 8:44 PM, Alexander D. Knauth wrote: > > On Aug 7, 2014, at 8:53 PM, Matthias Felleisen wrote: > > > Here are some examples: > > (equal? #'(lambda (x) x) #'(lambda (x) x)) > > #f > > > For these the source locations would still be different. > > (define so #'(lambda (x) x)) > (equal? so so) > > #t > > > For these they are eq?. > > > > Does equal? simply use eq? for syntax objects? > This example says probably, or am I still missing something? > (define stx #'(lambda (x) x)) > (equal? stx (datum->syntax stx (syntax-e stx) stx stx stx)) > > Are syntax objects mutable? If so, how would you define a function like eq? > say syntax-eq? without using the built-in equality? > > Are syntax objects immutable? Why should they be immutable? How does equal? > work on such structures normally? > > > I was under the impression that syntax objects were immutable, but I don?t > really know. > And anyway, for mutable vectors, strings, byte-strings, and structs, equal? > still checks each element. > > See HtDP on extensional and intensional equality. ? Matthias > > > Where? I have read a lot of HtDP, and looked at it again just now, but I > don?t remember anything about this, and couldn?t find anything either. > In the BSL docs for eq? and eqv? it mentions extensional and intensional, > but doesn?t explain anything. > In Realm of Racket there was a bit about that, but that doesn?t really tell > me anything about syntax objects. > > > On Aug 7, 2014, at 5:58 PM, Alexander D. Knauth wrote: > > How does equal? determine whether two syntax objects are equal? > > Does it simply use eq?, or does it check the syntax-e, lexical context, > srcloc and properties? > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From matthias at ccs.neu.edu Thu Aug 7 22:08:03 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Thu, 7 Aug 2014 22:08:03 -0400 Subject: [racket] how does equal? determine with syntax objects? In-Reply-To: <789E84B0-0531-4C45-ABCE-93B660AC279C@knauth.org> References: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> <789E84B0-0531-4C45-ABCE-93B660AC279C@knauth.org> Message-ID: http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-52.html#node_chap_42 (intensional ~ eq?, extensional ~ equal?) On Aug 7, 2014, at 9:44 PM, Alexander D. Knauth wrote: > > On Aug 7, 2014, at 8:53 PM, Matthias Felleisen wrote: > >> >> Here are some examples: >> >>>> (equal? #'(lambda (x) x) #'(lambda (x) x)) >>> #f > > For these the source locations would still be different. > >>>> (define so #'(lambda (x) x)) >>>> (equal? so so) >>> #t > > For these they are eq?. > > > > Does equal? simply use eq? for syntax objects? > This example says probably, or am I still missing something? > (define stx #'(lambda (x) x)) > (equal? stx (datum->syntax stx (syntax-e stx) stx stx stx)) > >> Are syntax objects mutable? If so, how would you define a function like eq? say syntax-eq? without using the built-in equality? >> >> Are syntax objects immutable? Why should they be immutable? How does equal? work on such structures normally? > > I was under the impression that syntax objects were immutable, but I don?t really know. > And anyway, for mutable vectors, strings, byte-strings, and structs, equal? still checks each element. > >> See HtDP on extensional and intensional equality. ? Matthias > > Where? I have read a lot of HtDP, and looked at it again just now, but I don?t remember anything about this, and couldn?t find anything either. > In the BSL docs for eq? and eqv? it mentions extensional and intensional, but doesn?t explain anything. > In Realm of Racket there was a bit about that, but that doesn?t really tell me anything about syntax objects. > >> >> On Aug 7, 2014, at 5:58 PM, Alexander D. Knauth wrote: >> >>> How does equal? determine whether two syntax objects are equal? >>> >>> Does it simply use eq?, or does it check the syntax-e, lexical context, srcloc and properties? >>> >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Thu Aug 7 22:19:30 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 7 Aug 2014 22:19:30 -0400 Subject: [racket] how does equal? determine with syntax objects? In-Reply-To: References: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> <789E84B0-0531-4C45-ABCE-93B660AC279C@knauth.org> Message-ID: On Aug 7, 2014, at 10:08 PM, Matthias Felleisen wrote: > http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-52.html#node_chap_42 Oh. I was reading the second edition. But that still doesn?t tell me anything about syntax objects. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lysseus at gmail.com Thu Aug 7 22:59:51 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Thu, 7 Aug 2014 19:59:51 -0700 Subject: [racket] syntax-parse question In-Reply-To: References: <2C662563-DBCE-4406-8989-7294F76CEC1C@gmail.com> <43810137-8C61-4787-A0A5-CC8CFA2B4697@knauth.org> <2468B23C-3443-4D1D-B681-D7695C74CFCD@gmail.com> <2AEDE8F1-B8D8-493D-A2D4-0CA3CFE6F166@knauth.org> <0BD3FD51-DB78-4532-9338-5FB172D83ACD@knauth.org> <6F4F02E2-7982-4F23-AA1D-BFD5FDCCD9E2@gmail.com> <1588EAB6-B5FD-48E7-9A9C-FE1070BF3501@knauth.org> Message-ID: <0783D07B-0315-4D52-8B1B-2F017E6C15A9@gmail.com> On Aug 7, 2014, at 1:21 PM, Alexander D. Knauth wrote: > By the way would this function version be helpful at all? > > (define (apply* fs lst*) > (cond [(empty? fs) lst*] > [(not (list? lst*)) lst*] > [else > (define f (first fs)) > (define rst (rest fs)) > (apply f > (for/list ([lst (in-list lst*)]) > (apply* rst lst)))])) > > (apply* (list list vector hash) > '((1 2 3 4) (5 (6 7) 8))) > ; '(#(1 2 3 4) #(5 #hash((6 . 7)) 8)) Yes! And extremely instructive. So much to learn! Thanks! -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Fri Aug 8 01:07:02 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 8 Aug 2014 06:07:02 +0100 Subject: [racket] top-level-rename In-Reply-To: References: Message-ID: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> At Wed, 6 Aug 2014 22:03:17 +0200, Jens Axel S?gaard wrote: > The program below produce bytecodes for the program that returns a > syntax-object representing 42. > > The syntax-object looks like this: > > (#s((stx zo 0) > #s((wrapped zo 0) > 42 > (#s((top-level-rename wrap 0 zo 0) #f) > #s((top-level-rename wrap 0 zo 0) #f) > #s((top-level-rename wrap 0 zo 0) #t) > #s((phase-shift wrap 0 zo 0) 0 #f #f #f)) > clean)))) > > Two questions: > 1) Why three top-level-renames and not just one? > > 2) What is the meaning of the boolean flag? The boolean apparently indicates whether the rename is for phase 0. It should instead be the phase of the rename, where using a boolean for the phase is probably a leftover from an original implementation where imports were either phase 0 or phase 1. The three renames are from phases 0, 1, and #f. I think this mismatch has gone unnoticed because we generally don't try to use non-module code in bytecode form --- especially non-module code that would involve syntax objects. > #lang racket > (require compiler/zo-structs compiler/zo-parse) > > (define (bytecode->zo bytecode) > (zo-parse > (open-input-bytes > (with-output-to-bytes > (? () (write bytecode)))))) > > (define (stx->zo x) > (parameterize ([current-namespace (make-base-empty-namespace)]) > (namespace-require 'racket/base) > (bytecode->zo (compile x)))) > > (stx->zo '(syntax 42)) > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Fri Aug 8 01:07:26 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 8 Aug 2014 06:07:26 +0100 Subject: [racket] how does equal? determine with syntax objects? In-Reply-To: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> References: <094153F6-47BC-482B-8139-B45ECE798C80@knauth.org> Message-ID: <20140808050728.A5B5C6501BF@mail-svr1.cs.utah.edu> At Thu, 7 Aug 2014 17:58:29 -0400, "Alexander D. Knauth" wrote: > How does equal? determine whether two syntax objects are equal? > > Does it simply use eq?, or does it check the syntax-e, lexical > context, srcloc and properties? It uses `eq?`. The general rule is that `equal?` uses `eq?` unless a data type is documented otherwise, but a clarification in the docs seems worthwhile in the case of syntax objects. From mflatt at cs.utah.edu Fri Aug 8 01:23:10 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 8 Aug 2014 06:23:10 +0100 Subject: [racket] confusing error message: what is "lang:read.1"? In-Reply-To: References: Message-ID: <20140808052313.A7EF86501C5@mail-svr1.cs.utah.edu> At Wed, 6 Aug 2014 15:50:41 -0700, Matthew Butterick wrote: > Under certain circumstances, because of what I assume is a bug in my code, I > get an error like this: > > > define-values: assignment disallowed; > > cannot re-define a constant > > constant: lang:read.1 > > in module: "/Users/mb/git/racket/racket/collects/racket/main.rkt" > > context...: > > (submod /Users/mb/git/racket/racket/collects/racket/main.rkt reader): > [running body] > > I understand how the "assignment disallowed" error arises. What I don't > understand is the meaning of "lang:read.1" in this context. I'm guessing it has > something to do with the #lang line (?) but ... the rest is hazy. The "lang:read" part is the name of a variable that appears in the macro expansion of the `racket` module's `reader` submodule. The ".1" part is because that variable is macro-introduced so that it is not directly accessible using the name `lang:read`. The way that `dynamic-rerequire` and submodules interact here is unsatisfying. I think it's a collision between the way that `dynamic-rerequire` pulls from source and the use of `namespace-module-attach` within `make-base-namspace`, and I think that `dynamic-rerequire` needs to do something different, but I haven't yet sorted it out. From dbastos at toledo.com Fri Aug 8 08:31:47 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Fri, 8 Aug 2014 09:31:47 -0300 Subject: [racket] on contract violation after adding 1471 strings to a BST In-Reply-To: <2551FF3D-E2F7-42D8-ABE7-75DF9E350CC5@ccs.neu.edu> References: <2551FF3D-E2F7-42D8-ABE7-75DF9E350CC5@ccs.neu.edu> Message-ID: On Tue, Aug 5, 2014 at 5:43 PM, Matthias Felleisen wrote: > Warning: you switched from a teaching language to full Racket. > The former would have caught this mistake, which is why we > designed them for HtDP. Racket is for grown-up parenthesis > eaters -- who want the behavior of cond that you just experienced, > or so I am told. -- Matthias > Is it possible to use the beginning-student-with-list-abbreviation language from a REPL inside the GNU EMACS? I copied the prelude that DrRacket adds when I save a beginning-student-language file with it and ran it with racket. I get %racket beginner.rkt cond: all question results were false context...: /home/dbastos/public_html/rkt/beginner.rkt: [running body] % (Very nice.) But I'm unable to run the prelude inside the REPL. That'd be this passage below. #reader(lib "htdp-beginner-reader.ss" "lang")((modname bst) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) After #reader, it seems to always expect more and more input. So my strategy didn't work for the REPL. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Fri Aug 8 08:34:09 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 8 Aug 2014 08:34:09 -0400 Subject: [racket] on contract violation after adding 1471 strings to a BST In-Reply-To: References: <2551FF3D-E2F7-42D8-ABE7-75DF9E350CC5@ccs.neu.edu> Message-ID: <9DB56A78-62CE-4294-BE28-D8BCEB3C3A7E@ccs.neu.edu> Why not turn on Emacs bindings inside of DrRacket? On Aug 8, 2014, at 8:31 AM, Daniel Bastos wrote: > On Tue, Aug 5, 2014 at 5:43 PM, Matthias Felleisen wrote: > Warning: you switched from a teaching language to full Racket. > The former would have caught this mistake, which is why we > designed them for HtDP. Racket is for grown-up parenthesis > eaters -- who want the behavior of cond that you just experienced, > or so I am told. -- Matthias > > Is it possible to use the beginning-student-with-list-abbreviation language from a REPL inside the GNU EMACS? > > I copied the prelude that DrRacket adds when I save a beginning-student-language file with it and ran it with racket. I get > > %racket beginner.rkt > cond: all question results were false > context...: > /home/dbastos/public_html/rkt/beginner.rkt: [running body] > % > > (Very nice.) But I'm unable to run the prelude inside the REPL. That'd be this passage below. > > #reader(lib "htdp-beginner-reader.ss" "lang")((modname bst) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) > > After #reader, it seems to always expect more and more input. So my strategy didn't work for the REPL. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbastos at toledo.com Fri Aug 8 09:28:08 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Fri, 8 Aug 2014 10:28:08 -0300 Subject: [racket] on emacs keybindings in dr racket (Was: Re: on contract violation after adding 1471 strings to a BST) Message-ID: On Fri, Aug 8, 2014 at 9:34 AM, Matthias Felleisen wrote: > Why not turn on Emacs bindings inside of DrRacket? I'll take the advice. BTW, some of my preferences windows don't show nicely because I use large fonts on my system. (See image attached.) Also, I think I only found the option being what I want by reading http://docs.racket-lang.org/drracket/Keyboard_Shortcuts.html With all my newbieness, I was looking for something like "enable EMACS keybindings". (But now I have the nice EMACS keybindings. Thank you.) -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: preferences.PNG Type: image/png Size: 25440 bytes Desc: not available URL: From dbastos at toledo.com Fri Aug 8 09:56:51 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Fri, 8 Aug 2014 10:56:51 -0300 Subject: [racket] missing solution 16.3.3 ex:file-du Message-ID: A candidate for a solution. ;; model 3 (define-struct file (name size content)) (define-struct dir (name dirs files)) ;; files: (define hang (make-file 'hang 8 empty)) (define draw (make-file 'draw 2 empty)) (define read (make-file 'read! 19 empty)) (define one (make-file 'part1 99 empty)) (define two (make-file 'part2 52 empty)) (define thre (make-file 'part3 17 empty)) (define rdme (make-file 'read 10 empty)) ;; directories: (define Code (make-dir 'Code '() (list hang draw))) (define Docs (make-dir 'Docs '() (list read))) (define Libs (make-dir 'Libs (list Code Docs) '())) (define Text (make-dir 'Text '() (list one two thre))) (define Top (make-dir 'TS (list Text Libs) (list rdme))) ;; dur-dir :: dir -> number ;; consumes a directory producing a sum of the list of files in each. ;; to the sum, it'll add 1 for each directory it finds. (we're assuming ;; each directory is of size 1). (define (du-dir d) (+ 1 (sum-files (dir-files d)) (du-dir-subdir (dir-dirs d)))) (define (du-dir-subdir ls) (cond [(empty? ls) 0] [(dir? (first ls)) (+ (du-dir (first ls)) (du-dir-subdir (rest ls)))])) ;; sum-files :: ls-of-files -> number ;; consumes a list of files producing the sum of their sizes (define (sum-files ls) (cond [(empty? ls) 0] [else (+ (file-size (first ls)) (sum-files (rest ls)))])) ;; tests (check-expect (sum-files (list hang draw)) 10) (check-expect (sum-files empty) 0) (check-expect (du-dir Libs) (+ 8 2 19 1 1 1)) Source: > http://www.htdp.org/2003-09-26/Solutions/file-du.html > No Solution Written, yetUnfortunately, the solution to this exercise has > not yet been written. To submit a solution you have written to this > problem, or to complain that the solution isn't available, please contact Robby > Findler > > . > > To see the list of solutions, visit the table of contents > . Each of the > hyperlinked exercise numbers has a solution. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mb at mbtype.com Fri Aug 8 10:05:04 2014 From: mb at mbtype.com (Matthew Butterick) Date: Fri, 8 Aug 2014 07:05:04 -0700 Subject: [racket] confusing error message: what is "lang:read.1"? In-Reply-To: <20140808052313.A7EF86501C5@mail-svr1.cs.utah.edu> References: <20140808052313.A7EF86501C5@mail-svr1.cs.utah.edu> Message-ID: FWIW this isn't a gratuitously perverse example. It's derived from the actual bug I've encountered. I use `eval` in my Pollen system to handle dynamic rendering of pages delivered through the web server (don't panic, everyone ? it's an approved use of `eval` [1]) I use the `dynamic-rerequire` to reload files that have changed since last render. In fact you added it at my request, as I was looking for a Racket function that approximated the Python `reload` function. [2] For now I've worked around the bug ? in test-case terms, I've changed this ;;; three.rkt #lang racket To this: ;;; three.rkt #lang racket/base But why that makes a difference, I'm not clear. [1] http://docs.racket-lang.org/web-server/faq.html [2] http://lists.racket-lang.org/users/archive/2013-April/057530.html On Aug 7, 2014, at 10:23 PM, Matthew Flatt wrote: > At Wed, 6 Aug 2014 15:50:41 -0700, Matthew Butterick wrote: >> Under certain circumstances, because of what I assume is a bug in my code, I >> get an error like this: >> >>> define-values: assignment disallowed; >>> cannot re-define a constant >>> constant: lang:read.1 >>> in module: "/Users/mb/git/racket/racket/collects/racket/main.rkt" >>> context...: >>> (submod /Users/mb/git/racket/racket/collects/racket/main.rkt reader): >> [running body] >> >> I understand how the "assignment disallowed" error arises. What I don't >> understand is the meaning of "lang:read.1" in this context. I'm guessing it has >> something to do with the #lang line (?) but ... the rest is hazy. > > The "lang:read" part is the name of a variable that appears in the > macro expansion of the `racket` module's `reader` submodule. The ".1" > part is because that variable is macro-introduced so that it is not > directly accessible using the name `lang:read`. > > The way that `dynamic-rerequire` and submodules interact here is > unsatisfying. I think it's a collision between the way that > `dynamic-rerequire` pulls from source and the use of > `namespace-module-attach` within `make-base-namspace`, and I think that > `dynamic-rerequire` needs to do something different, but I haven't yet > sorted it out. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ianj at ccs.neu.edu Fri Aug 8 10:05:24 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Fri, 8 Aug 2014 10:05:24 -0400 (EDT) Subject: [racket] splicing forms and for-body directives In-Reply-To: <16768995.674321407506698036.JavaMail.root@zimbra> Message-ID: <13633656.674341407506724871.JavaMail.root@zimbra> I'm working out a group of macros that use syntax parameters to coordinate implicit arguments. I use for/fold in one to have looping constructs that implicitly pass the arguments around. `split-for-body` can get the directives out for me to put in front of the splicing-syntax-parameterize, but that disallows using the correct implicit arguments in a #:break or #:final directive. What would it take to get these to work together? -Ian From matthias at ccs.neu.edu Fri Aug 8 11:12:20 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 8 Aug 2014 11:12:20 -0400 Subject: [racket] on emacs keybindings in dr racket (Was: Re: on contract violation after adding 1471 strings to a BST) In-Reply-To: References: Message-ID: <3AD584C6-BE70-4067-9EC5-A9A83452A56F@ccs.neu.edu> You're right. Enable Emacs bindings should probably be somewhat more prominent in DrRacket's menu set, at least on certain platforms. As it happens, I'll see Dr. Racket tomorrow and I'll bring it up with him. -- Matthias On Aug 8, 2014, at 9:28 AM, Daniel Bastos wrote: > On Fri, Aug 8, 2014 at 9:34 AM, Matthias Felleisen wrote: > Why not turn on Emacs bindings inside of DrRacket? > > I'll take the advice. > > BTW, some of my preferences windows don't show nicely because I use large fonts on my system. (See image attached.) Also, I think I only found the option being what I want by reading > > http://docs.racket-lang.org/drracket/Keyboard_Shortcuts.html > > With all my newbieness, I was looking for something like "enable EMACS keybindings". (But now I have the nice EMACS keybindings. Thank you.) > From matthias at ccs.neu.edu Fri Aug 8 11:43:58 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 8 Aug 2014 11:43:58 -0400 Subject: [racket] missing solution 16.3.3 ex:file-du In-Reply-To: References: Message-ID: <12E999D5-F692-420E-982D-AE9E5BC8C700@ccs.neu.edu> Robby, let's go with this one. -- Matthias ;; credit to Daniel Bastos ;; model 3 structure definitions [also available from teachpack] ;; (define-struct file (name size content)) ;; (define-struct dir (name dirs files)) ;; data definitions as in book (require htdp/dir) ;; data examples (define hang (make-file 'hang 8 empty)) (define draw (make-file 'draw 2 empty)) (define read (make-file 'read! 19 empty)) (define one (make-file 'part1 99 empty)) (define two (make-file 'part2 52 empty)) (define thre (make-file 'part3 17 empty)) (define rdme (make-file 'read 10 empty)) (define Code (make-dir 'Code '() (list hang draw))) (define Docs (make-dir 'Docs '() (list read))) (define Libs (make-dir 'Libs (list Code Docs) '())) (define Text (make-dir 'Text '() (list one two thre))) (define Top (make-dir 'TS (list Text Libs) (list rdme))) ;; dir -> number ;; determine the total size of the files in this directory ;; (we're assuming each directory is of size 1.) (define (du-dir d) (+ 1 (sum-files (dir-files d)) (du-dir-subdir (dir-dirs d)))) ;; list-of-directories -> number ;; determine the total size of the files in a list of directories (define (du-dir-subdir ls) (cond [(empty? ls) 0] [(dir? (first ls)) (+ (du-dir (first ls)) (du-dir-subdir (rest ls)))])) ;; sum-files :: list-of-files -> number ;; produces the sum of the file's sizes (define (sum-files ls) (cond [(empty? ls) 0] [else (+ (file-size (first ls)) (sum-files (rest ls)))])) ;; tests (check-expect (sum-files (list hang draw)) 10) (check-expect (sum-files empty) 0) (check-expect (du-dir Libs) (+ 8 2 19 1 1 1)) From jackhfirth at gmail.com Fri Aug 8 12:00:31 2014 From: jackhfirth at gmail.com (Jack Firth) Date: Fri, 8 Aug 2014 09:00:31 -0700 Subject: [racket] Question about tail recursion Message-ID: As far as I understand it, the vast majority of the benefit of tail recursion is less the stack-frame business and more the ability to discard values you're not using anymore at each step by combining partial results. To clarify what I mean, for a function sum with a recursive and tail-recursive version: (define (sum xs) (if (empty? xs) 0 (+ (first xs) (sum (rest xs))))) (define (sum-tailrec xs) (let loop ([xs xs] [s 0]) (if (empty? xs) s (loop (rest xs) (+ s (first xs)))))) > (sum '(1 2 3)) => (+ 1 (sum '(2 3))) => (+ 1 (+ 2 (sum '(3)))) => (+ 1 (+ 2 (+ 3 (sum '())))) => (+ 1 (+ 2 (+ 3 0))) => (+ 1 (+ 2 3)) => (+ 1 5) 6 > (sum-tailrec '(1 2 3)) => (loop '(1 2 3) 0) => (loop '(2 3) 1) => (loop '(3) 3) => (loop '() 6) 6 The tail recursive version is much better because you can perform the calculation on parts of the list and then ditch those parts and accumulate your results as you go. But for functions which don't really have any means of accumulating their results, is there any advantage to tail recursion? If so, how much? For clarity, consider these two implementations of filter: (define (my-filter p xs) (cond [(empty? xs) xs] [(p (first xs)) (cons (first xs) (my-filter p (rest xs)))] [else (my-filter (rest xs))])) (define (my-filter-tail-rec p xs) (let loop ([xs xs] [filtered '()]) (cond [(empty? xs) (reverse filtered)] [(p (first xs)) (loop (rest xs) (cons (first xs) filtered))] [else (loop (rest xs) filtered)]))) > (my-filter even? '(1 2 3 4)) => (my-filter even? '(2 3 4)) => (cons 2 (my-filter even? '(3 4))) => (cons 2 (my-filter even? '(4))) => (cons 2 (cons 4 (my-filter even? '()))) => (cons 2 (cons 4 '())) => (cons 2 '(4)) '(2 4) > (my-filter-tail-rec even? '(1 2 3)) => (loop '(1 2 3 4) '()) => (loop '(2 3 4) '()) => (loop '(3 4) '(2)) => (loop '(4) '(2)) => (loop '() '(4 2)) => (reverse '(4 2)) '(2 4) The tail recursion doesn't really help much in this problem, because the only real difference is that the tail recursive version holds the filtered values in a list instead of consing them on the stack. With the summing, you could take the values and combine them into something much more compact in terms of space by just summing them and passing the partial sum, but there is no logical "compacting" operation that can be done with filtering. So is there much of any performance or algorithmic difference between tail recursive and normal recursive functions when tail recursion is achieved simply by storing intermediate values in a list argument instead of consing them on the stack? And is that difference significant enough to justify the cost of reversing the list and the added complexity of writing the code in a tail recursive fashion? -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Fri Aug 8 12:17:37 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 8 Aug 2014 12:17:37 -0400 Subject: [racket] Question about tail recursion In-Reply-To: References: Message-ID: 1. Some calls are tail-calls [whether programmers care or not]. So this is really about the issue of how compilers deal with tail calls. 2. What people commonly call 'tail-call optimization' is not. It is a misnomer, and I am sure the people who dubbed it an 'optimization' regret this mistake. A lot. 3. It should be called Proper Implementation of Tail Calls (which I like to abbreviate to PITCH). 4. The point of PITCH is to save stack allocations and with it deallocation. Neither is very expensive (certainly cheaper than heap allocation) but if you don't have to do it, you save space. Period. 5. You are saving stack space in both cases: sum and filter. In both cases, you avoid pushing frames with return info and other data on to the stack. In one case, you have the additional benefit of computing the result on the fly -- because of the supposed commutativity of these operations. Try this with floating point numbers. Or try this for multiplication (say in factorial). Bottom lines: functions converted to TC shape may perform computations in a different order if you're not careful, they may get different results, and they may slow the program down, because they use to big-number multiplication immediately as opposed to small-number, built-in multiplication (and similar examples). On Aug 8, 2014, at 12:00 PM, Jack Firth wrote: > As far as I understand it, the vast majority of the benefit of tail recursion is less the stack-frame business and more the ability to discard values you're not using anymore at each step by combining partial results. To clarify what I mean, for a function sum with a recursive and tail-recursive version: > > (define (sum xs) > (if (empty? xs) 0 (+ (first xs) (sum (rest xs))))) > > (define (sum-tailrec xs) > (let loop ([xs xs] [s 0]) > (if (empty? xs) s (loop (rest xs) (+ s (first xs)))))) > > > (sum '(1 2 3)) > => (+ 1 (sum '(2 3))) > => (+ 1 (+ 2 (sum '(3)))) > => (+ 1 (+ 2 (+ 3 (sum '())))) > => (+ 1 (+ 2 (+ 3 0))) > => (+ 1 (+ 2 3)) > => (+ 1 5) > 6 > > > (sum-tailrec '(1 2 3)) > => (loop '(1 2 3) 0) > => (loop '(2 3) 1) > => (loop '(3) 3) > => (loop '() 6) > 6 > > The tail recursive version is much better because you can perform the calculation on parts of the list and then ditch those parts and accumulate your results as you go. But for functions which don't really have any means of accumulating their results, is there any advantage to tail recursion? If so, how much? For clarity, consider these two implementations of filter: > > (define (my-filter p xs) > (cond > [(empty? xs) xs] > [(p (first xs)) (cons (first xs) (my-filter p (rest xs)))] > [else (my-filter (rest xs))])) > > (define (my-filter-tail-rec p xs) > (let loop ([xs xs] [filtered '()]) > (cond > [(empty? xs) (reverse filtered)] > [(p (first xs)) (loop (rest xs) (cons (first xs) filtered))] > [else (loop (rest xs) filtered)]))) > > > (my-filter even? '(1 2 3 4)) > => (my-filter even? '(2 3 4)) > => (cons 2 (my-filter even? '(3 4))) > => (cons 2 (my-filter even? '(4))) > => (cons 2 (cons 4 (my-filter even? '()))) > => (cons 2 (cons 4 '())) > => (cons 2 '(4)) > '(2 4) > > > (my-filter-tail-rec even? '(1 2 3)) > => (loop '(1 2 3 4) '()) > => (loop '(2 3 4) '()) > => (loop '(3 4) '(2)) > => (loop '(4) '(2)) > => (loop '() '(4 2)) > => (reverse '(4 2)) > '(2 4) > > The tail recursion doesn't really help much in this problem, because the only real difference is that the tail recursive version holds the filtered values in a list instead of consing them on the stack. With the summing, you could take the values and combine them into something much more compact in terms of space by just summing them and passing the partial sum, but there is no logical "compacting" operation that can be done with filtering. So is there much of any performance or algorithmic difference between tail recursive and normal recursive functions when tail recursion is achieved simply by storing intermediate values in a list argument instead of consing them on the stack? And is that difference significant enough to justify the cost of reversing the list and the added complexity of writing the code in a tail recursive fashion? > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From zenspider at gmail.com Fri Aug 8 17:07:34 2014 From: zenspider at gmail.com (Ryan Davis) Date: Fri, 8 Aug 2014 14:07:34 -0700 Subject: [racket] help me speed up string split? In-Reply-To: <20140724152739.1BB2865018F@mail-svr1.cs.utah.edu> References: <39D378F7-3F27-4F7F-B794-A7A1261760BA@gmail.com> <20140724152739.1BB2865018F@mail-svr1.cs.utah.edu> Message-ID: <8D9BE81B-1929-4413-A1C7-1E6D4C510384@gmail.com> On Jul 24, 2014, at 8:27, Matthew Flatt wrote: > Sorry for the long delay, but I finally took a look at this. Awesome awesome awesome. Thank you. I assume that made it into the 6.1 release? From matthias at ccs.neu.edu Fri Aug 8 17:58:23 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 8 Aug 2014 17:58:23 -0400 Subject: [racket] Question about tail recursion In-Reply-To: References: Message-ID: <21BEF264-C460-4DA8-822D-04A3030A3FB8@ccs.neu.edu> I didn't use the word vastly. All I said was that __equivalent__ TC version of f run in constant stack space. The savings are exactly the depth of the recursion. Whether that's worth it, is the programmer's call. On Aug 8, 2014, at 4:18 PM, Jack Firth wrote: > So even for the cases where the tail recursive algorithm has the same space complexity as the non tail recursive algorithm, the savings of reusing the stack frame but building the results in reverse order are vastly greater than the cost of allocating a new stack frame for each result? > > > On Fri, Aug 8, 2014 at 9:17 AM, Matthias Felleisen wrote: > > 1. Some calls are tail-calls [whether programmers care or not]. So this is really about the issue of how compilers deal with tail calls. > > 2. What people commonly call 'tail-call optimization' is not. It is a misnomer, and I am sure the people who dubbed it an 'optimization' regret this mistake. A lot. > > 3. It should be called Proper Implementation of Tail Calls (which I like to abbreviate to PITCH). > > 4. The point of PITCH is to save stack allocations and with it deallocation. Neither is very expensive (certainly cheaper than heap allocation) but if you don't have to do it, you save space. Period. > > 5. You are saving stack space in both cases: sum and filter. In both cases, you avoid pushing frames with return info and other data on to the stack. In one case, you have the additional benefit of computing the result on the fly -- because of the supposed commutativity of these operations. Try this with floating point numbers. Or try this for multiplication (say in factorial). > > Bottom lines: functions converted to TC shape may perform computations in a different order if you're not careful, they may get different results, and they may slow the program down, because they use to big-number multiplication immediately as opposed to small-number, built-in multiplication (and similar examples). > > > > > > > > > > > > On Aug 8, 2014, at 12:00 PM, Jack Firth wrote: > > > As far as I understand it, the vast majority of the benefit of tail recursion is less the stack-frame business and more the ability to discard values you're not using anymore at each step by combining partial results. To clarify what I mean, for a function sum with a recursive and tail-recursive version: > > > > (define (sum xs) > > (if (empty? xs) 0 (+ (first xs) (sum (rest xs))))) > > > > (define (sum-tailrec xs) > > (let loop ([xs xs] [s 0]) > > (if (empty? xs) s (loop (rest xs) (+ s (first xs)))))) > > > > > (sum '(1 2 3)) > > => (+ 1 (sum '(2 3))) > > => (+ 1 (+ 2 (sum '(3)))) > > => (+ 1 (+ 2 (+ 3 (sum '())))) > > => (+ 1 (+ 2 (+ 3 0))) > > => (+ 1 (+ 2 3)) > > => (+ 1 5) > > 6 > > > > > (sum-tailrec '(1 2 3)) > > => (loop '(1 2 3) 0) > > => (loop '(2 3) 1) > > => (loop '(3) 3) > > => (loop '() 6) > > 6 > > > > The tail recursive version is much better because you can perform the calculation on parts of the list and then ditch those parts and accumulate your results as you go. But for functions which don't really have any means of accumulating their results, is there any advantage to tail recursion? If so, how much? For clarity, consider these two implementations of filter: > > > > (define (my-filter p xs) > > (cond > > [(empty? xs) xs] > > [(p (first xs)) (cons (first xs) (my-filter p (rest xs)))] > > [else (my-filter (rest xs))])) > > > > (define (my-filter-tail-rec p xs) > > (let loop ([xs xs] [filtered '()]) > > (cond > > [(empty? xs) (reverse filtered)] > > [(p (first xs)) (loop (rest xs) (cons (first xs) filtered))] > > [else (loop (rest xs) filtered)]))) > > > > > (my-filter even? '(1 2 3 4)) > > => (my-filter even? '(2 3 4)) > > => (cons 2 (my-filter even? '(3 4))) > > => (cons 2 (my-filter even? '(4))) > > => (cons 2 (cons 4 (my-filter even? '()))) > > => (cons 2 (cons 4 '())) > > => (cons 2 '(4)) > > '(2 4) > > > > > (my-filter-tail-rec even? '(1 2 3)) > > => (loop '(1 2 3 4) '()) > > => (loop '(2 3 4) '()) > > => (loop '(3 4) '(2)) > > => (loop '(4) '(2)) > > => (loop '() '(4 2)) > > => (reverse '(4 2)) > > '(2 4) > > > > The tail recursion doesn't really help much in this problem, because the only real difference is that the tail recursive version holds the filtered values in a list instead of consing them on the stack. With the summing, you could take the values and combine them into something much more compact in terms of space by just summing them and passing the partial sum, but there is no logical "compacting" operation that can be done with filtering. So is there much of any performance or algorithmic difference between tail recursive and normal recursive functions when tail recursion is achieved simply by storing intermediate values in a list argument instead of consing them on the stack? And is that difference significant enough to justify the cost of reversing the list and the added complexity of writing the code in a tail recursive fashion? > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > From alexander at knauth.org Fri Aug 8 18:33:31 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 8 Aug 2014 18:33:31 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <29806605.596031406933130307.JavaMail.root@zimbra> References: <29806605.596031406933130307.JavaMail.root@zimbra> Message-ID: <4A0EFAD7-F471-476A-A3AB-2EDF666043D2@knauth.org> On Aug 1, 2014, at 6:45 PM, J. Ian Johnson wrote: > Well one problem is expander application his its own mark to deal with, so you can't cancel the mark on x. > > https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157 > > Another problem is expecting the implementation of match-define to not have any inner macros that would change syntax-local-introduce to a less helpful extent. > What would be ideal is if racket/match could change some "parameter" so that syntax-local-introduce used the introducer defined in the above link, Well what if match-expander-transform did something like this: >From racket/require-syntax.rkt: (define-for-syntax current-require-introducer (make-parameter (lambda (x) (error "not expanding require form")))) (define-for-syntax (syntax-local-require-introduce x) (unless (syntax? x) (raise-argument-error 'syntax-local-introduce-require "syntax?" x)) ((current-require-introducer) x)) > since the generated temporary does not have x's mark that x has annihilated. Instead x's mark will be added to tmp after the transformer returns, and there's nothing you can do about it :( > > -Ian > ----- Original Message ----- > From: "Alexander D. Knauth" > To: "J. Ian Johnson" > Cc: "racket users list" > Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern > Subject: Re: [racket] getting one macro to tell another macro to define something > > Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? > > On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: > >> Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). >> The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. >> >> Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. >> -Ian >> ----- Original Message ----- >> From: "Alexander D. Knauth" >> To: "racket users list" >> Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern >> Subject: Re: [racket] getting one macro to tell another macro to define something >> >> >> >> >> >> On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >> >> >> It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. >> >> >> >> The reason I can?t do that is because in the real program, sender is actually a match-expander. >> >> >> You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... >> >> >> >> >> On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: >> >> >> Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. >> ... >> >> >> Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. >> >> I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? >> >> >> >> #lang racket >> (require racket/stxparam >> (for-syntax syntax/parse >> racket/syntax >> racket/set)) >> ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) >> (define-syntax-parameter current-defs #f) >> (define-match-expander sender >> (lambda (stx) >> (syntax-parse stx >> [(sender x) >> #:with tmp (generate-temporary #'x) >> (define defs (syntax-parameter-value #'current-defs)) >> (set-add! defs (syntax-local-introduce #'(define x tmp))) >> #'tmp]))) >> (define-syntax reciever >> (lambda (stx) >> (syntax-parse stx >> [(reciever) >> (define defs (syntax-parameter-value #'current-defs)) >> (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) >> #'(begin def ...))]))) >> >> >> (syntax-parameterize ([current-defs (mutable-set)]) >> (match-define (sender x) 1) >> (reciever) >> x) >> >> >> ;x3: unbound identifier; >> ; also, no #%top syntax transformer is bound in: x3 >> >> >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > From alexander at knauth.org Fri Aug 8 19:45:32 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 8 Aug 2014 19:45:32 -0400 Subject: [racket] getting one macro to tell another macro to define something In-Reply-To: <4A0EFAD7-F471-476A-A3AB-2EDF666043D2@knauth.org> References: <29806605.596031406933130307.JavaMail.root@zimbra> <4A0EFAD7-F471-476A-A3AB-2EDF666043D2@knauth.org> Message-ID: <07A53576-E124-41A1-88FC-49954DF52E7B@knauth.org> Ok I tried it, it worked, and I made a pull request. https://github.com/plt/racket/pull/749 On Aug 8, 2014, at 6:33 PM, Alexander D. Knauth wrote: > > On Aug 1, 2014, at 6:45 PM, J. Ian Johnson wrote: > >> Well one problem is expander application his its own mark to deal with, so you can't cancel the mark on x. >> >> https://github.com/plt/racket/blob/master/racket/collects/racket/match/parse-helper.rkt#L157 >> >> Another problem is expecting the implementation of match-define to not have any inner macros that would change syntax-local-introduce to a less helpful extent. >> What would be ideal is if racket/match could change some "parameter" so that syntax-local-introduce used the introducer defined in the above link, > > Well what if match-expander-transform did something like this: > From racket/require-syntax.rkt: > (define-for-syntax current-require-introducer > (make-parameter (lambda (x) (error "not expanding require form")))) > > (define-for-syntax (syntax-local-require-introduce x) > (unless (syntax? x) > (raise-argument-error 'syntax-local-introduce-require "syntax?" x)) > ((current-require-introducer) x)) > >> since the generated temporary does not have x's mark that x has annihilated. Instead x's mark will be added to tmp after the transformer returns, and there's nothing you can do about it :( >> >> -Ian >> ----- Original Message ----- >> From: "Alexander D. Knauth" >> To: "J. Ian Johnson" >> Cc: "racket users list" >> Sent: Friday, August 1, 2014 6:31:59 PM GMT -05:00 US/Canada Eastern >> Subject: Re: [racket] getting one macro to tell another macro to define something >> >> Well, if the match-expander is invoked in the ?dynamic extent? of the match-define form, then would syntax-local-introduce apply that syntax-mark? >> >> On Aug 1, 2014, at 6:20 PM, J. Ian Johnson wrote: >> >>> Well that's a pickle. I can tell you that (mac . args) gets expanded as (X[mac^m] . X[args^m])^m where m is a fresh mark and X expands a form. If m is applied to something with m already, they annihilate each other (see Syntactic Abstraction in Scheme for how this totally works). >>> The syntax-local-introduce form allows you to apply the macro application's mark to an arbitrary piece of syntax, so later on the application's mark will annihilate it and voila`, it's like it was textually given to the macro application itself. >>> >>> Here, however, a match expander is not treated as a macro invocation. There is no mark for that match-expander use to introduce. There is, however, the mark from match-define that you'll want to introduce to this temporary you've generated. I think. I haven't quite worked out how to make this work. >>> -Ian >>> ----- Original Message ----- >>> From: "Alexander D. Knauth" >>> To: "racket users list" >>> Sent: Friday, August 1, 2014 5:55:57 PM GMT -05:00 US/Canada Eastern >>> Subject: Re: [racket] getting one macro to tell another macro to define something >>> >>> >>> >>> >>> >>> On Aug 1, 2014, at 5:37 PM, J. Ian Johnson < ianj at ccs.neu.edu > wrote: >>> >>> >>> It's best to expand into a begin-for-syntax that does the desired mutation, rather than mutate within the transformer. You currently _cannot_ do this outside top level forms. >>> >>> >>> >>> The reason I can?t do that is because in the real program, sender is actually a match-expander. >>> >>> >>> You are also right about the marks. The call to receiver adds additional marks to the definitions that it pulls out, so you'll need to apply syntax-local-introduce. ... >>> >>> >>> >>> >>> On Aug 1, 2014, at 5:39 PM, Ryan Culpepper < ryanc at ccs.neu.edu > wrote: >>> >>> >>> Use syntax-local-introduce when putting syntax into a side-channel or getting it back out across macro calls. This only matters when the syntax represents a definition or more generally contains binders whose references are not all in the same syntax. >>> ... >>> >>> >>> Thanks, the syntax-local-introduce got it working for that example, but for some reason it?s not working when sender is a match-expander. >>> >>> I?m still not very clear on when to use syntax-local-introduce and when not to, or even what it does (other than get that example working), so could someone point me in the right direction? >>> >>> >>> >>> #lang racket >>> (require racket/stxparam >>> (for-syntax syntax/parse >>> racket/syntax >>> racket/set)) >>> ;; current-defs : (syntax-parameter-of (or/c set-mutable? #f)) >>> (define-syntax-parameter current-defs #f) >>> (define-match-expander sender >>> (lambda (stx) >>> (syntax-parse stx >>> [(sender x) >>> #:with tmp (generate-temporary #'x) >>> (define defs (syntax-parameter-value #'current-defs)) >>> (set-add! defs (syntax-local-introduce #'(define x tmp))) >>> #'tmp]))) >>> (define-syntax reciever >>> (lambda (stx) >>> (syntax-parse stx >>> [(reciever) >>> (define defs (syntax-parameter-value #'current-defs)) >>> (with-syntax ([(def ...) (map syntax-local-introduce (set->list defs))]) >>> #'(begin def ...))]))) >>> >>> >>> (syntax-parameterize ([current-defs (mutable-set)]) >>> (match-define (sender x) 1) >>> (reciever) >>> x) >>> >>> >>> ;x3: unbound identifier; >>> ; also, no #%top syntax transformer is bound in: x3 >>> >>> >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From stamourv at ccs.neu.edu Fri Aug 8 19:53:08 2014 From: stamourv at ccs.neu.edu (Vincent St-Amour) Date: Fri, 08 Aug 2014 19:53:08 -0400 Subject: [racket] Performance. Higher-order function In-Reply-To: <20140804054737.013CB65018A@mail-svr1.cs.utah.edu> References: <1407057319.566019875@f258.i.mail.ru> <1407123772.149158313@f121.i.mail.ru> <20140804054737.013CB65018A@mail-svr1.cs.utah.edu> Message-ID: <87sil6tu6z.wl%stamourv@ccs.neu.edu> FWIW, the optimization coach confirms both unrollings, and the fact that neither `build-string1` nor `test1` (you wrote `test2`, was that a mistake?) are ever inlined. Reaching out for the decompiler would not have been necessary. :) Vincent At Mon, 4 Aug 2014 06:47:34 +0100, Matthew Flatt wrote: > > Well... a function call is expensive relative to some things, such as > adding fixnums to produce a fixnum. > > > My read of your initial results is that calling an unknown function is > similar to the cost of one iteration in a loop that sets a character in > a string. > > More precisely, decompiling the program shows that the compiler unrolls > the loop in `test1` by 4 iterations, so one call to an unknown function > is the same cost as 4 generic `<`s on fixnums, 4 generic `+ 1`s on > fixnums, 4 `integer->char`s, 4 `string-set!s`, and one jump to a known > function (to recur). > > The `build-string1` loop is similarly unrolled 4 times, and the call to > `build-string1` is not inlined in `test3`, so we really can compare the > unknown function call in `test3` to the overall loop overhead plus > `string-set!`s of `test1`. And the fact that neither `build-string1` > nor `test2 is inlined is consistent with `test2` and `test3` having the > same performance. > > If I change the `for` body of `test1` with a constant, then the time is > cut in half. So, a `string-set!` takes up about half of the time. > > > Putting that all together, it looks like a call to an unknown function > takes about twice the time of a `string-set!` --- which (due to various > tag and bounds checks for the string assignment) costs the same as a > small pile of generic arithmetic on fixnums. That could be considered > expensive in a tight loop. > > I would hesitate to say that higher order functions are always slow, > because many uses do more work around the call than set one character > in a string. > > > At Mon, 04 Aug 2014 07:42:53 +0400, Roman Klochkov wrote: > > > unknown function call is expensive > > > > So, higher order function always slow. > > Thus, to improve performance, one should use for/fold, for/list, ... and never > > use map, foldl, build-string, ... with lambda. > > Is it correct? > > > > Sun, 3 Aug 2014 13:15:57 -0400 ?? Matthias Felleisen : > > > > > >Because build-string calls an unknown function 1000 x 100000 times, and an > > unknown function call is expensive.? > > > > > >Racket could possible collapse all modules and perform additional in-lining > > optimizations eventually, which may help here. But it doesn't yet.? > > > > > >-- Matthias > > > > > > > > > > > >On Aug 3, 2014, at 5:15 AM, Roman Klochkov wrote: > > >>Are higher order function always slow? > > >>... > > >>--- > > >> > > >>So I see, that build-string version is about two times slower, than > > set-in-the-loop. Why so much? I expected about 10-20% difference. > > >>-- > > >>Roman Klochkov ____________________ > > >>?Racket Users list: > > >>? http://lists.racket-lang.org/users > > > > > > > > > -- > > Roman Klochkov > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From morazanm at gmail.com Fri Aug 8 23:01:17 2014 From: morazanm at gmail.com (Marco Morazan) Date: Fri, 8 Aug 2014 23:01:17 -0400 Subject: [racket] Question about tail recursion In-Reply-To: References: Message-ID: On Fri, Aug 8, 2014 at 12:17 PM, Matthias Felleisen wrote: > > and they may slow the program down, because they use to big-number > multiplication immediately as opposed to small-number, built-in > multiplication (and similar examples). > This can also be true for assignment-based programs which is counter-intuitive to too many programmers. The idea is that you convert an "inefficient" recursive program to a more "efficient" tail-recursive program from which you can extract an even "more efficient" imperative program. It turns out that the imperative program can actually be slower, because of, as Matthias states, the operations used or simply because imperative programs require more operations--extra operations not required when you have referential transparency. It's fascinating stuff to explore if you choose to continue this line of thought. Marco > > > > > > > > > > > > On Aug 8, 2014, at 12:00 PM, Jack Firth wrote: > > > As far as I understand it, the vast majority of the benefit of tail > recursion is less the stack-frame business and more the ability to discard > values you're not using anymore at each step by combining partial results. > To clarify what I mean, for a function sum with a recursive and > tail-recursive version: > > > > (define (sum xs) > > (if (empty? xs) 0 (+ (first xs) (sum (rest xs))))) > > > > (define (sum-tailrec xs) > > (let loop ([xs xs] [s 0]) > > (if (empty? xs) s (loop (rest xs) (+ s (first xs)))))) > > > > > (sum '(1 2 3)) > > => (+ 1 (sum '(2 3))) > > => (+ 1 (+ 2 (sum '(3)))) > > => (+ 1 (+ 2 (+ 3 (sum '())))) > > => (+ 1 (+ 2 (+ 3 0))) > > => (+ 1 (+ 2 3)) > > => (+ 1 5) > > 6 > > > > > (sum-tailrec '(1 2 3)) > > => (loop '(1 2 3) 0) > > => (loop '(2 3) 1) > > => (loop '(3) 3) > > => (loop '() 6) > > 6 > > > > The tail recursive version is much better because you can perform the > calculation on parts of the list and then ditch those parts and accumulate > your results as you go. But for functions which don't really have any means > of accumulating their results, is there any advantage to tail recursion? If > so, how much? For clarity, consider these two implementations of filter: > > > > (define (my-filter p xs) > > (cond > > [(empty? xs) xs] > > [(p (first xs)) (cons (first xs) (my-filter p (rest xs)))] > > [else (my-filter (rest xs))])) > > > > (define (my-filter-tail-rec p xs) > > (let loop ([xs xs] [filtered '()]) > > (cond > > [(empty? xs) (reverse filtered)] > > [(p (first xs)) (loop (rest xs) (cons (first xs) filtered))] > > [else (loop (rest xs) filtered)]))) > > > > > (my-filter even? '(1 2 3 4)) > > => (my-filter even? '(2 3 4)) > > => (cons 2 (my-filter even? '(3 4))) > > => (cons 2 (my-filter even? '(4))) > > => (cons 2 (cons 4 (my-filter even? '()))) > > => (cons 2 (cons 4 '())) > > => (cons 2 '(4)) > > '(2 4) > > > > > (my-filter-tail-rec even? '(1 2 3)) > > => (loop '(1 2 3 4) '()) > > => (loop '(2 3 4) '()) > > => (loop '(3 4) '(2)) > > => (loop '(4) '(2)) > > => (loop '() '(4 2)) > > => (reverse '(4 2)) > > '(2 4) > > > > The tail recursion doesn't really help much in this problem, because the > only real difference is that the tail recursive version holds the filtered > values in a list instead of consing them on the stack. With the summing, > you could take the values and combine them into something much more compact > in terms of space by just summing them and passing the partial sum, but > there is no logical "compacting" operation that can be done with filtering. > So is there much of any performance or algorithmic difference between tail > recursive and normal recursive functions when tail recursion is achieved > simply by storing intermediate values in a list argument instead of consing > them on the stack? And is that difference significant enough to justify the > cost of reversing the list and the added complexity of writing the code in > a tail recursive fashion? > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -- Cheers, Marco Have a??) ?.???.?*??) ?.?*?) (?.?? (?.?? * wonderful day! :) -------------- next part -------------- An HTML attachment was scrubbed... URL: From eli at barzilay.org Sat Aug 9 07:31:03 2014 From: eli at barzilay.org (Eli Barzilay) Date: Sat, 9 Aug 2014 07:31:03 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53D55E34.4080306@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> Message-ID: I think that I ran into a nice way to discourage eval except when needed: the rule of thumb is to only use eval when you need to evaluate any arbitrary (Racket) expression. It sounds simplistic but it covers lots of cases that make newbies run to eval: * I just want to get the value of a variable whose name is held in x * More common: I have a symbol/string that names a function, I just need to call that function * I need to keep an update-able mapping from names to values, just like what the toplevel does * I want to let people write an arithmetic expression instead of a number In such cases questions like "do you need allow calling all functions", and "do you need to handle lambda expressions" have negative answers. On Sun, Jul 27, 2014 at 4:16 PM, Neil Van Dyke wrote: > Maybe there should be a periodic public service announcement about not using > "eval". This time I will communicate in FAQ format: > > Q: How do I use eval? > A: Don't use eval. > > Q: But don't so many academic books feature eval prominently, so doesn't > that mean I should use try to eval? > A: Those books use eval for pedagogic reasons, or because the author is > enamored of some theoretical appeal of eval, or because the author wants to > watch the world burn. Don't use eval. > > Q: But, but, but, I am just starting to learn, and eval seems to do what I > need. > A: Eval is almost certainly not what you want. Learn how to use the other > basics effectively. Don't use eval. > > Q: I now am very comfortable with the language, I am aware that I should > avoid eval in almost all cases, and I can tell you why eval is actually the > right thing in this highly unusual case. > A: Cool, that's why eval is there. > > Neil V. > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! From neil at neilvandyke.org Sat Aug 9 08:27:54 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Sat, 09 Aug 2014 08:27:54 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> Message-ID: <53E613CA.4070200@neilvandyke.org> Sounds like a good rule of thumb. Two suggestions to add: * Maybe there could also be a second rule of thumb, like, "If you need arbitrary Racket expressions, then consider whether you can do it with one of the following patterns: [list some patterns involving combinations of syntax extension, custom #lang, dynamic requires, considering whether config files can actually be compile-time #lang, etc.]" This is less important than the first rule of thumb. * When we list typical newbie cases that don't actually require "eval", we can expect that newbie will immediately want an example of the non-"eval" way to do that typical thing. At the very least, an example showing, say, good use of hashes in parameters, with a sensible thin abstraction layer over it, for that case. These examples would be tedious to work through and write up well, but someday some knowledgeable and benevolent person will do it. (I am not this person. Book royalties aren't enough to ease the pain. I'd rather that newbies just never heard of "eval" or were scared away from it, rather than having to talk them down off the ledge all the time.) Neil V. Eli Barzilay wrote at 08/09/2014 07:31 AM: > I think that I ran into a nice way to discourage eval except when > needed: the rule of thumb is to only use eval when you need to evaluate > any arbitrary (Racket) expression. It sounds simplistic but it covers > lots of cases that make newbies run to eval: > > * I just want to get the value of a variable whose name is held in x > > * More common: I have a symbol/string that names a function, I just need > to call that function > > * I need to keep an update-able mapping from names to values, just like > what the toplevel does > > * I want to let people write an arithmetic expression instead of a > number > > In such cases questions like "do you need allow calling all functions", > and "do you need to handle lambda expressions" have negative answers. > > > > On Sun, Jul 27, 2014 at 4:16 PM, Neil Van Dyke wrote: >> Maybe there should be a periodic public service announcement about not using >> "eval". This time I will communicate in FAQ format: >> >> Q: How do I use eval? >> A: Don't use eval. >> >> Q: But don't so many academic books feature eval prominently, so doesn't >> that mean I should use try to eval? >> A: Those books use eval for pedagogic reasons, or because the author is >> enamored of some theoretical appeal of eval, or because the author wants to >> watch the world burn. Don't use eval. >> >> Q: But, but, but, I am just starting to learn, and eval seems to do what I >> need. >> A: Eval is almost certainly not what you want. Learn how to use the other >> basics effectively. Don't use eval. >> >> Q: I now am very comfortable with the language, I am aware that I should >> avoid eval in almost all cases, and I can tell you why eval is actually the >> right thing in this highly unusual case. >> A: Cool, that's why eval is there. >> >> Neil V. >> >> From skanaley at gmail.com Sat Aug 9 10:10:08 2014 From: skanaley at gmail.com (Sean Kanaley) Date: Sat, 9 Aug 2014 10:10:08 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53E613CA.4070200@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> Message-ID: There's a simple enough example I think: apply with keyword parameters. Apply has that built-in..sort of...but the list is supposed to be provided inline to APPLY, seemingly requiring apply to be applied (e.g. (apply apply (cons *thefunctiontoapply* params))), except keywords can't be expressions anyway. I have a bunch of card definitions for Dominion with many defaults: (struct card (... actions buys ...)) (define (make-card ... #:actions actions #:buy buys ...) ...) The non-keyword-requiring way is (define CARDS (map (\ (lst) (apply make-card lst)) '([... 1 1 ...] [... 2 0 ...]))) The keyword way is ;ns is namespace (mapply (\ (lst) (eval `(apply make-card ',(car l) ,@(cdr l)) ns)) '([(...) #:actions 1 #:buys 1 ...])) Short of making a big macro to take some exact format and get it to work with keywords and all that, eval seems to be just what is needed. On Sat, Aug 9, 2014 at 8:27 AM, Neil Van Dyke wrote: > Sounds like a good rule of thumb. Two suggestions to add: > > * Maybe there could also be a second rule of thumb, like, "If you need > arbitrary Racket expressions, then consider whether you can do it with one > of the following patterns: [list some patterns involving combinations of > syntax extension, custom #lang, dynamic requires, considering whether > config files can actually be compile-time #lang, etc.]" This is less > important than the first rule of thumb. > > * When we list typical newbie cases that don't actually require "eval", we > can expect that newbie will immediately want an example of the non-"eval" > way to do that typical thing. At the very least, an example showing, say, > good use of hashes in parameters, with a sensible thin abstraction layer > over it, for that case. These examples would be tedious to work through > and write up well, but someday some knowledgeable and benevolent person > will do it. (I am not this person. Book royalties aren't enough to ease > the pain. I'd rather that newbies just never heard of "eval" or were scared > away from it, rather than having to talk them down off the ledge all the > time.) > > Neil V. > > > Eli Barzilay wrote at 08/09/2014 07:31 AM: > > I think that I ran into a nice way to discourage eval except when >> needed: the rule of thumb is to only use eval when you need to evaluate >> any arbitrary (Racket) expression. It sounds simplistic but it covers >> lots of cases that make newbies run to eval: >> >> * I just want to get the value of a variable whose name is held in x >> >> * More common: I have a symbol/string that names a function, I just need >> to call that function >> >> * I need to keep an update-able mapping from names to values, just like >> what the toplevel does >> >> * I want to let people write an arithmetic expression instead of a >> number >> >> In such cases questions like "do you need allow calling all functions", >> and "do you need to handle lambda expressions" have negative answers. >> >> >> >> On Sun, Jul 27, 2014 at 4:16 PM, Neil Van Dyke >> wrote: >> >>> Maybe there should be a periodic public service announcement about not >>> using >>> "eval". This time I will communicate in FAQ format: >>> >>> Q: How do I use eval? >>> A: Don't use eval. >>> >>> Q: But don't so many academic books feature eval prominently, so doesn't >>> that mean I should use try to eval? >>> A: Those books use eval for pedagogic reasons, or because the author is >>> enamored of some theoretical appeal of eval, or because the author wants >>> to >>> watch the world burn. Don't use eval. >>> >>> Q: But, but, but, I am just starting to learn, and eval seems to do what >>> I >>> need. >>> A: Eval is almost certainly not what you want. Learn how to use the >>> other >>> basics effectively. Don't use eval. >>> >>> Q: I now am very comfortable with the language, I am aware that I should >>> avoid eval in almost all cases, and I can tell you why eval is actually >>> the >>> right thing in this highly unusual case. >>> A: Cool, that's why eval is there. >>> >>> Neil V. >>> >>> >>> > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From skanaley at gmail.com Sat Aug 9 10:11:37 2014 From: skanaley at gmail.com (Sean Kanaley) Date: Sat, 9 Aug 2014 10:11:37 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> Message-ID: Sorry, couple typos: mapply = map and l = lst. On Sat, Aug 9, 2014 at 10:10 AM, Sean Kanaley wrote: > There's a simple enough example I think: apply with keyword parameters. > Apply has that built-in..sort of...but the list is supposed to be provided > inline to APPLY, seemingly requiring apply to be applied (e.g. (apply apply > (cons *thefunctiontoapply* params))), except keywords can't be expressions > anyway. I have a bunch of card definitions for Dominion with many defaults: > > (struct card (... actions buys ...)) > > (define (make-card ... #:actions actions #:buy buys ...) > ...) > > The non-keyword-requiring way is > > (define CARDS > (map (\ (lst) (apply make-card lst)) > '([... 1 1 ...] > [... 2 0 ...]))) > > The keyword way is > > ;ns is namespace > (mapply (\ (lst) (eval `(apply make-card ',(car l) ,@(cdr l)) ns)) > '([(...) #:actions 1 #:buys 1 ...])) > > Short of making a big macro to take some exact format and get it to work > with keywords and all that, eval seems to be just what is needed. > > > On Sat, Aug 9, 2014 at 8:27 AM, Neil Van Dyke > wrote: > >> Sounds like a good rule of thumb. Two suggestions to add: >> >> * Maybe there could also be a second rule of thumb, like, "If you need >> arbitrary Racket expressions, then consider whether you can do it with one >> of the following patterns: [list some patterns involving combinations of >> syntax extension, custom #lang, dynamic requires, considering whether >> config files can actually be compile-time #lang, etc.]" This is less >> important than the first rule of thumb. >> >> * When we list typical newbie cases that don't actually require "eval", >> we can expect that newbie will immediately want an example of the >> non-"eval" way to do that typical thing. At the very least, an example >> showing, say, good use of hashes in parameters, with a sensible thin >> abstraction layer over it, for that case. These examples would be tedious >> to work through and write up well, but someday some knowledgeable and >> benevolent person will do it. (I am not this person. Book royalties >> aren't enough to ease the pain. I'd rather that newbies just never heard of >> "eval" or were scared away from it, rather than having to talk them down >> off the ledge all the time.) >> >> Neil V. >> >> >> Eli Barzilay wrote at 08/09/2014 07:31 AM: >> >> I think that I ran into a nice way to discourage eval except when >>> needed: the rule of thumb is to only use eval when you need to evaluate >>> any arbitrary (Racket) expression. It sounds simplistic but it covers >>> lots of cases that make newbies run to eval: >>> >>> * I just want to get the value of a variable whose name is held in x >>> >>> * More common: I have a symbol/string that names a function, I just need >>> to call that function >>> >>> * I need to keep an update-able mapping from names to values, just like >>> what the toplevel does >>> >>> * I want to let people write an arithmetic expression instead of a >>> number >>> >>> In such cases questions like "do you need allow calling all functions", >>> and "do you need to handle lambda expressions" have negative answers. >>> >>> >>> >>> On Sun, Jul 27, 2014 at 4:16 PM, Neil Van Dyke >>> wrote: >>> >>>> Maybe there should be a periodic public service announcement about not >>>> using >>>> "eval". This time I will communicate in FAQ format: >>>> >>>> Q: How do I use eval? >>>> A: Don't use eval. >>>> >>>> Q: But don't so many academic books feature eval prominently, so doesn't >>>> that mean I should use try to eval? >>>> A: Those books use eval for pedagogic reasons, or because the author is >>>> enamored of some theoretical appeal of eval, or because the author >>>> wants to >>>> watch the world burn. Don't use eval. >>>> >>>> Q: But, but, but, I am just starting to learn, and eval seems to do >>>> what I >>>> need. >>>> A: Eval is almost certainly not what you want. Learn how to use the >>>> other >>>> basics effectively. Don't use eval. >>>> >>>> Q: I now am very comfortable with the language, I am aware that I should >>>> avoid eval in almost all cases, and I can tell you why eval is actually >>>> the >>>> right thing in this highly unusual case. >>>> A: Cool, that's why eval is there. >>>> >>>> Neil V. >>>> >>>> >>>> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Sat Aug 9 12:12:41 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sat, 9 Aug 2014 12:12:41 -0400 Subject: [racket] is there a check-match/values -like thing anywhere? Message-ID: <4EA2F991-FF5E-4620-96A9-9132C8DF60F3@knauth.org> Is there a check-match/values -like thing anywhere? From greghendershott at gmail.com Sat Aug 9 12:50:46 2014 From: greghendershott at gmail.com (Greg Hendershott) Date: Sat, 9 Aug 2014 12:50:46 -0400 Subject: [racket] Performance. Higher-order function In-Reply-To: <87sil6tu6z.wl%stamourv@ccs.neu.edu> References: <1407057319.566019875@f258.i.mail.ru> <1407123772.149158313@f121.i.mail.ru> <20140804054737.013CB65018A@mail-svr1.cs.utah.edu> <87sil6tu6z.wl%stamourv@ccs.neu.edu> Message-ID: Why isn't Optimization Coach one of the automatically-installed packages? From manfred.lotz at arcor.de Sat Aug 9 14:00:29 2014 From: manfred.lotz at arcor.de (Manfred Lotz) Date: Sat, 9 Aug 2014 20:00:29 +0200 Subject: [racket] DrRacket eats 100% cpu Message-ID: <20140809200029.1b19a2a5@arcor.com> Hi all, I'm not a DrRacket user so I have no idea what I did wrong. Out of curiosity I started DrRacket and looking around at the menu entries I chose: Insert/Insert Large Letters... just to see what happens. Nothing happened except that DrRacket took 100% cpu. When trying to stop DrRacket I got this user break context...: /home/manfred/racket/share/pkgs/draw-lib/racket/draw/private/dc.rkt:1248:4: core2823 get-w-size loop loop loop loop loop loop loop loop loop loop loop loop loop loop... Don't know what I did wrong? -- Manfred From alexander at knauth.org Sat Aug 9 16:25:51 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sat, 9 Aug 2014 16:25:51 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> Message-ID: <5894E7D1-76F1-44A3-BB7D-626BEF2791EF@knauth.org> Just for fun, I made a function to do this the ?non-eval? way, and it was more complicated than I would have thought, although maybe I was overcomplicating it a bit? https://github.com/AlexKnauth/hash-lambda/blob/master/keyword-lambda/kw-apply.rkt On Aug 9, 2014, at 10:10 AM, Sean Kanaley wrote: > There's a simple enough example I think: apply with keyword parameters. Apply has that built-in..sort of...but the list is supposed to be provided inline to APPLY, seemingly requiring apply to be applied (e.g. (apply apply (cons *thefunctiontoapply* params))), except keywords can't be expressions anyway. I have a bunch of card definitions for Dominion with many defaults: > > (struct card (... actions buys ...)) > > (define (make-card ... #:actions actions #:buy buys ...) > ...) > > The non-keyword-requiring way is > > (define CARDS > (map (\ (lst) (apply make-card lst)) > '([... 1 1 ...] > [... 2 0 ...]))) > > The keyword way is > > ;ns is namespace > (mapply (\ (lst) (eval `(apply make-card ',(car l) ,@(cdr l)) ns)) > '([(...) #:actions 1 #:buys 1 ...])) > > Short of making a big macro to take some exact format and get it to work with keywords and all that, eval seems to be just what is needed. > > > On Sat, Aug 9, 2014 at 8:27 AM, Neil Van Dyke wrote: > Sounds like a good rule of thumb. Two suggestions to add: > > * Maybe there could also be a second rule of thumb, like, "If you need arbitrary Racket expressions, then consider whether you can do it with one of the following patterns: [list some patterns involving combinations of syntax extension, custom #lang, dynamic requires, considering whether config files can actually be compile-time #lang, etc.]" This is less important than the first rule of thumb. > > * When we list typical newbie cases that don't actually require "eval", we can expect that newbie will immediately want an example of the non-"eval" way to do that typical thing. At the very least, an example showing, say, good use of hashes in parameters, with a sensible thin abstraction layer over it, for that case. These examples would be tedious to work through and write up well, but someday some knowledgeable and benevolent person will do it. (I am not this person. Book royalties aren't enough to ease the pain. I'd rather that newbies just never heard of "eval" or were scared away from it, rather than having to talk them down off the ledge all the time.) > > Neil V. > > > Eli Barzilay wrote at 08/09/2014 07:31 AM: > > I think that I ran into a nice way to discourage eval except when > needed: the rule of thumb is to only use eval when you need to evaluate > any arbitrary (Racket) expression. It sounds simplistic but it covers > lots of cases that make newbies run to eval: > > * I just want to get the value of a variable whose name is held in x > > * More common: I have a symbol/string that names a function, I just need > to call that function > > * I need to keep an update-able mapping from names to values, just like > what the toplevel does > > * I want to let people write an arithmetic expression instead of a > number > > In such cases questions like "do you need allow calling all functions", > and "do you need to handle lambda expressions" have negative answers. > > > > On Sun, Jul 27, 2014 at 4:16 PM, Neil Van Dyke wrote: > Maybe there should be a periodic public service announcement about not using > "eval". This time I will communicate in FAQ format: > > Q: How do I use eval? > A: Don't use eval. > > Q: But don't so many academic books feature eval prominently, so doesn't > that mean I should use try to eval? > A: Those books use eval for pedagogic reasons, or because the author is > enamored of some theoretical appeal of eval, or because the author wants to > watch the world burn. Don't use eval. > > Q: But, but, but, I am just starting to learn, and eval seems to do what I > need. > A: Eval is almost certainly not what you want. Learn how to use the other > basics effectively. Don't use eval. > > Q: I now am very comfortable with the language, I am aware that I should > avoid eval in almost all cases, and I can tell you why eval is actually the > right thing in this highly unusual case. > A: Cool, that's why eval is there. > > Neil V. > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From stamourv at ccs.neu.edu Sat Aug 9 17:36:20 2014 From: stamourv at ccs.neu.edu (Vincent St-Amour) Date: Sat, 09 Aug 2014 17:36:20 -0400 Subject: [racket] Performance. Higher-order function In-Reply-To: References: <1407057319.566019875@f258.i.mail.ru> <1407123772.149158313@f121.i.mail.ru> <20140804054737.013CB65018A@mail-svr1.cs.utah.edu> <87sil6tu6z.wl%stamourv@ccs.neu.edu> Message-ID: <87lhqxgxbf.wl%stamourv@ccs.neu.edu> It used to be. When we introduced the package system, it sounded like we were going to split the distribution into multiple repositories (and have the main distribution pulled from those multiple repositories). Optimization Coach is one of the few packages that did the switch. The rest never followed. It doesn't make sense to merge OC back to the main repo, assuming we still plan to split it up. In the meantime, that does mean that installing the coach has an additional barrier to entry, which is unfortunate. Vincent At Sat, 9 Aug 2014 12:50:46 -0400, Greg Hendershott wrote: > > Why isn't Optimization Coach one of the automatically-installed packages? > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From robby at eecs.northwestern.edu Sun Aug 10 00:17:37 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Sat, 9 Aug 2014 23:17:37 -0500 Subject: [racket] DrRacket eats 100% cpu In-Reply-To: <20140809200029.1b19a2a5@arcor.com> References: <20140809200029.1b19a2a5@arcor.com> Message-ID: Ah, thanks. I've fixed the performance bug. FWIW, I think it would have terminated eventually. It takes about 3 seconds to appear on my machine the first time the dialog is opened (before the push I just did). Robby On Sat, Aug 9, 2014 at 1:00 PM, Manfred Lotz wrote: > Hi all, > I'm not a DrRacket user so I have no idea what I did wrong. > > Out of curiosity I started DrRacket and looking around at the menu > entries I chose: > Insert/Insert Large Letters... > > just to see what happens. Nothing happened except that DrRacket took > 100% cpu. When trying to stop DrRacket I got this > > > user break > context...: > /home/manfred/racket/share/pkgs/draw-lib/racket/draw/private/dc.rkt:1248:4: > core2823 get-w-size > loop > loop > loop > loop > loop > loop > loop > loop > loop > loop > loop > loop > loop > loop... > > > Don't know what I did wrong? > > -- > Manfred > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From jackhfirth at gmail.com Sun Aug 10 02:26:25 2014 From: jackhfirth at gmail.com (Jack Firth) Date: Sat, 9 Aug 2014 23:26:25 -0700 Subject: [racket] About closing ports Message-ID: Is there any particular reason there's no general close-port function that works on both input ports and output ports? Would an implementation along the lines of ((if (input-port? p) close-input-port close-output-port) p) have problems that make this unreasonable? The only reason I ask is because I was writing a macro let-ports that works like let (but only for ports) that automatically closes the ports it defines. My naive implementations of these are: (define (close-port p) ((if (input-port? p) close-input-port close-output-port) p)) (define-syntax-rule (let-ports ([port port-expr] ...) body ...) (let ([port port-expr] ...) body ... (close-port port) ...)) -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Sun Aug 10 03:59:58 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Sun, 10 Aug 2014 08:59:58 +0100 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> Message-ID: <20140810075959.30B9B6501A5@mail-svr1.cs.utah.edu> I think you're looking for `keyword-apply`. It's true that `eval` works as way to get reflective operations in general, but it's better (again, for error checking and for efficiency) when a language construct is accompanied with specific reflective operations. In the case of keyword arguments, those operations include `make-keyword-procedure`, `keyword-apply`, and `procedure-reduce-keyword-arity`. It's not always obvious which operations to include, and `procedure-reduce-keyword-arity`, for one, wasn't included originally. I think I might also have trouble defining "reflective operation" precisely, as opposed to having constructs that support abstraction more directly (such as allowing the superclass position of a `class` form to be an expression). But if `keyword-apply` didn't exist, then this example would make me think that some form of abstraction was missing for keyword arguments, instead of seeming like a good use of `eval`. At Sat, 9 Aug 2014 10:10:08 -0400, Sean Kanaley wrote: > There's a simple enough example I think: apply with keyword parameters. > Apply has that built-in..sort of...but the list is supposed to be provided > inline to APPLY, seemingly requiring apply to be applied (e.g. (apply apply > (cons *thefunctiontoapply* params))), except keywords can't be expressions > anyway. I have a bunch of card definitions for Dominion with many defaults: > > (struct card (... actions buys ...)) > > (define (make-card ... #:actions actions #:buy buys ...) > ...) > > The non-keyword-requiring way is > > (define CARDS > (map (\ (lst) (apply make-card lst)) > '([... 1 1 ...] > [... 2 0 ...]))) > > The keyword way is > > ;ns is namespace > (mapply (\ (lst) (eval `(apply make-card ',(car l) ,@(cdr l)) ns)) > '([(...) #:actions 1 #:buys 1 ...])) > > Short of making a big macro to take some exact format and get it to work > with keywords and all that, eval seems to be just what is needed. > > > On Sat, Aug 9, 2014 at 8:27 AM, Neil Van Dyke wrote: > > > Sounds like a good rule of thumb. Two suggestions to add: > > > > * Maybe there could also be a second rule of thumb, like, "If you need > > arbitrary Racket expressions, then consider whether you can do it with one > > of the following patterns: [list some patterns involving combinations of > > syntax extension, custom #lang, dynamic requires, considering whether > > config files can actually be compile-time #lang, etc.]" This is less > > important than the first rule of thumb. > > > > * When we list typical newbie cases that don't actually require "eval", we > > can expect that newbie will immediately want an example of the non-"eval" > > way to do that typical thing. At the very least, an example showing, say, > > good use of hashes in parameters, with a sensible thin abstraction layer > > over it, for that case. These examples would be tedious to work through > > and write up well, but someday some knowledgeable and benevolent person > > will do it. (I am not this person. Book royalties aren't enough to ease > > the pain. I'd rather that newbies just never heard of "eval" or were scared > > away from it, rather than having to talk them down off the ledge all the > > time.) > > > > Neil V. > > > > > > Eli Barzilay wrote at 08/09/2014 07:31 AM: > > > > I think that I ran into a nice way to discourage eval except when > >> needed: the rule of thumb is to only use eval when you need to evaluate > >> any arbitrary (Racket) expression. It sounds simplistic but it covers > >> lots of cases that make newbies run to eval: > >> > >> * I just want to get the value of a variable whose name is held in x > >> > >> * More common: I have a symbol/string that names a function, I just need > >> to call that function > >> > >> * I need to keep an update-able mapping from names to values, just like > >> what the toplevel does > >> > >> * I want to let people write an arithmetic expression instead of a > >> number > >> > >> In such cases questions like "do you need allow calling all functions", > >> and "do you need to handle lambda expressions" have negative answers. > >> > >> > >> > >> On Sun, Jul 27, 2014 at 4:16 PM, Neil Van Dyke > >> wrote: > >> > >>> Maybe there should be a periodic public service announcement about not > >>> using > >>> "eval". This time I will communicate in FAQ format: > >>> > >>> Q: How do I use eval? > >>> A: Don't use eval. > >>> > >>> Q: But don't so many academic books feature eval prominently, so doesn't > >>> that mean I should use try to eval? > >>> A: Those books use eval for pedagogic reasons, or because the author is > >>> enamored of some theoretical appeal of eval, or because the author wants > >>> to > >>> watch the world burn. Don't use eval. > >>> > >>> Q: But, but, but, I am just starting to learn, and eval seems to do what > >>> I > >>> need. > >>> A: Eval is almost certainly not what you want. Learn how to use the > >>> other > >>> basics effectively. Don't use eval. > >>> > >>> Q: I now am very comfortable with the language, I am aware that I should > >>> avoid eval in almost all cases, and I can tell you why eval is actually > >>> the > >>> right thing in this highly unusual case. > >>> A: Cool, that's why eval is there. > >>> > >>> Neil V. > >>> > >>> > >>> > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From eli at barzilay.org Sun Aug 10 05:14:21 2014 From: eli at barzilay.org (Eli Barzilay) Date: Sun, 10 Aug 2014 05:14:21 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <53E613CA.4070200@neilvandyke.org> References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> Message-ID: On Sat, Aug 9, 2014 at 8:27 AM, Neil Van Dyke wrote: > Sounds like a good rule of thumb. Two suggestions to add: > > * Maybe there could also be a second rule of thumb, like, "If you need > arbitrary Racket expressions, then consider whether you can do it > with one of the following patterns: [list some patterns involving > combinations of syntax extension, custom #lang, dynamic requires, > considering whether config files can actually be compile-time #lang, > etc.]" This is less important than the first rule of thumb. That would be a good bottom addition -- after all the discouraging is done since (IIUC) your targeting valid eval cases in ways that are similar to it. > * When we list typical newbie cases that don't actually require > "eval", we can expect that newbie will immediately want an example > of the non-"eval" way to do that typical thing. At the very least, > an example showing, say, good use of hashes in parameters, with a > sensible thin abstraction layer over it, for that case. These > examples would be tedious to work through and write up well, but > someday some knowledgeable and benevolent person will do it. (I am > not this person. [...] +1, in general, but it sounds like a hard thing to do. IME, the big problem is that usually when people get to ask about how to do something with eval, that something is already an abstraction of their real motivation. The best example of that is the common case of trying to get from a symbol/string that names a binding to its value -- it could be that they need to use a hash table, or maybe they don't know that they can use functions (as in +) directly instead of names ('+), or they don't know how to use symbols and try to map them to integers in an attempt to implement some enum-like thing, etc. I've done a quick scan of eval-tagged questions on SO (crossed with `python', `javascript', and `lisp'), and I couldn't find questions that could be grouped. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! From eli at barzilay.org Sun Aug 10 05:22:11 2014 From: eli at barzilay.org (Eli Barzilay) Date: Sun, 10 Aug 2014 05:22:11 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <20140810075959.30B9B6501A5@mail-svr1.cs.utah.edu> References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> <20140810075959.30B9B6501A5@mail-svr1.cs.utah.edu> Message-ID: On Sun, Aug 10, 2014 at 3:59 AM, Matthew Flatt wrote: > > It's true that `eval` works as way to get reflective operations in > general, but it's better (again, for error checking and for > efficiency) when a language construct is accompanied with specific > reflective operations. [...] But if `keyword-apply` didn't exist, > then this example would make me think that some form of abstraction > was missing for keyword arguments, instead of seeming like a good use > of `eval`. +7 -- it's a nice demonstration of what I started with: use eval only when you need the ability to evaluate all expressions, is this what you need? -- No, I just want to apply functions with an unknown keyword... It's interesting to note that in Javascript there are many common uses of eval, which are indeed pointers at missing features of the language. (And only in rare cases the features get added -- as in the case of parsing JSON (which pointed to a missing `read' feature).) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! From skanaley at gmail.com Sun Aug 10 10:38:24 2014 From: skanaley at gmail.com (Sean Kanaley) Date: Sun, 10 Aug 2014 10:38:24 -0400 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> <20140810075959.30B9B6501A5@mail-svr1.cs.utah.edu> Message-ID: ***The ultimate (programming) concern is what will produce the highest average correct-and-useful-running-program-output per second over my lifespan.*** (philosophical extensions: provided it doesn't hurt other people, unless they are "bad", where bad = ...etc...) Or anyone else who programs. The average decreases when something new is learned, and increases later as a payoff from the new knowledge (ideally...). This is especially important to experts in other fields who want a quick solution instead of a theoretically maximally correct and beautiful and least upsetting to experts solution. So I didn't need keyword-apply. I had the following choices: 1. build literal expression, call eval (~1 min dev time) 2. search documentation or google for "apply keyword", reach page of documentation, *carefully* read all relevant-sounding functions on it, choose keyword apply, THEN implement it (~10+ min?) (in reality after trying apply for a bit since it seems like it would work, and for fear of just using eval and being branded a C programmer, eventually concluding it can't work = additional 5 min) 3. make a mistake with step 2, make post to user's list asking about this case, receive feedback that it wasn't necessary to use it, go back and fix code to be "correct" (unsure of time to type the first post, but the overall energy spent on this process exceeds #1 and #2 for sure) In my case, I'm glad I now know about keyword-apply because I will be using Racket until I die. Those 15 minutes will *hopefully* save over 15 minutes by the end of my life. They might not though, and time now > time later, but I'm still glad because I enjoy programming as a hobby and want to be good at it, but in terms of maximizing output I should have just used eval. Taken further, there is some optimal level of knowledge that allows for all tasks that need to be completed to be completed as quickly and accurately as possible, where further knowledge represents time spent wasted acquiring it. Professionals in fields other than programming itself will probably have a low level of optimal knowledge, and the attitude that some seem to have about "dumb newbies with their dumb evals" is incorrect. They should possibly do whatever is as fast as possible, regardless of how bad the code is. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jarcane at gmail.com Sun Aug 10 10:48:36 2014 From: jarcane at gmail.com (J Arcane) Date: Sun, 10 Aug 2014 17:48:36 +0300 Subject: [racket] Keyboard polling and user packages Message-ID: Hello, I've been working on a learning project, a simple 8-bit virtual stack machine, (code so far is here: https://github.com/jarcane/MicroMini/blob/master/main.rkt) and I've run into a bit of a snag when it comes to getting input. I'm trying to set up basic character terminal I/O. The spec I've written defines two instructions: TRMO, which pops the byte at the top of the stack to the terminal bus line (currently emulated in Racket with a simple (write-byte (pop))) TRMI, which polls the terminal bus line for a key press and pushes the resulting byte to the stack. I can't for the life of me figure out how to do this. I've been reading docs for hours, exhausting my google fu, and attempting any number of failed experiments involving the built-ins, and I've got nothing. The various incantations of (read-bytes) seem to produce finicky and unpredictable results, either spitting out random values or else taking input in the form of a \n terminated prompt. This is kind of unoptimal when all I need is a single-byte. I've looked at various libraries and bits of sample code, but all the command-line solutions are Unix specific (requiring stty), and everything else involves building a GUI (which wasn't really the intent, I was meaning to keep it as a simple CL app I could feed binary files to). I also ran into problems with installing libraries anyway, because unless I just called them from Planet, they install to user-scope by default, and I have no clue at all where user packages go on Windows or how to (require) them. Is there seriously no crossplatform, non-GUI means of polling a key event for Racket? Getting frustrated, John -------------- next part -------------- An HTML attachment was scrubbed... URL: From jensaxel at soegaard.net Sun Aug 10 11:01:01 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Sun, 10 Aug 2014 17:01:01 +0200 Subject: [racket] top-level-rename In-Reply-To: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> References: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> Message-ID: 2014-08-08 7:07 GMT+02:00 Matthew Flatt : > At Wed, 6 Aug 2014 22:03:17 +0200, Jens Axel S?gaard wrote: >> The program below produce bytecodes for the program that returns a >> syntax-object representing 42. >> >> The syntax-object looks like this: >> >> (#s((stx zo 0) >> #s((wrapped zo 0) >> 42 >> (#s((top-level-rename wrap 0 zo 0) #f) >> #s((top-level-rename wrap 0 zo 0) #f) >> #s((top-level-rename wrap 0 zo 0) #t) >> #s((phase-shift wrap 0 zo 0) 0 #f #f #f)) >> clean)))) >> >> Two questions: >> 1) Why three top-level-renames and not just one? >> >> 2) What is the meaning of the boolean flag? > > The boolean apparently indicates whether the rename is for phase 0. It > should instead be the phase of the rename, where using a boolean for > the phase is probably a leftover from an original implementation where > imports were either phase 0 or phase 1. > > The three renames are from phases 0, 1, and #f. Got it. The next part of the syntax object is: #s((phase-shift wrap 0 zo 0) 0 #f #f #f)) The form of a phase-shift is (phase-shift amt src dest cancel-id) where amt is #f or an integer, src and dest are module-path-index? cancel-id is #f or an integer The documentation on phase-shift is rather brief. 1) Is it correct that a shift of #f means that only bindings at phase level 0 are shifted to the label phase level? 2) Even though src and dest are documented to be module-path-indices the example show that #f is a valid value too. Is it safe to assume that the combination #f #f means toplevel and "self-module" ? Or do #f mean "use the same value as before" ? 3) The example shows a phase-shift of 0. At first I didn't get what the purpose of this. Then I found a comment in add_renames_unless_module : /* this "phase shift" just attaches the namespace's module registry: */ form = scheme_stx_phase_shift(form, NULL, NULL, NULL, genv->module_registry->exports, NULL, NULL); and this comment in scheme_stx_phase_shift : /* Shifts the phase on a syntax object in a module. A 0 shift might be used just to re-direct relative module paths. new_midx might be NULL to shift without redirection. And so on. */ Is this is the explanation behind the zero phase shift? 4) What is the cancel-id? used for ? /Jens Axel From neil at neilvandyke.org Sun Aug 10 11:09:46 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Sun, 10 Aug 2014 11:09:46 -0400 Subject: [racket] Keyboard polling and user packages In-Reply-To: References: Message-ID: <53E78B3A.6070909@neilvandyke.org> If you haven't already, you can try the following to disable any port buffering within Racket, but that doesn't help you if the OS (Windows and Posix-ish console stuff it's doing from the console window) isn't giving Racket raw, unbuffered access to keyboard input through stdin: (file-stream-buffer-mode my-port 'none) If you were using almost anything other than Windows, you could just use "http://www.neilvandyke.org/racket-charterm/". Other than that, you or someone could make a portable Racket text-terminal package that does stuff like uses the console API on Windows and tty on almost everything else. BTW, you mention getting random bytes with variations on "read-bytes". That simply shouldn't happen with "read-bytes", but, when using variations on "read-bytes-avail!", only the first N count bytes it says it read will be valid in the bytestring. Neil V. From alexander at knauth.org Sun Aug 10 17:19:37 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 10 Aug 2014 17:19:37 -0400 Subject: [racket] rename-transformer-target, prop:rename-transformer, and contracts Message-ID: <8E1A4EF3-A583-4C65-BAE9-E3E0426E4146@knauth.org> If I have this program: #lang racket/base (module foo racket/base (require racket/contract/base) (struct foo (id) #:transparent #:property prop:rename-transformer (struct-field-index id)) (provide (contract-out [struct foo ([id identifier?])]))) (require 'foo) (define id #'x) (rename-transformer-target (foo id)) Then it will return this: # Instead of returning id. Is this a bug? Why wouldn?t this work? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jarcane at gmail.com Sun Aug 10 18:46:49 2014 From: jarcane at gmail.com (J Arcane) Date: Mon, 11 Aug 2014 01:46:49 +0300 Subject: [racket] Keyboard polling and user packages In-Reply-To: <53E78B3A.6070909@neilvandyke.org> References: <53E78B3A.6070909@neilvandyke.org> Message-ID: Well, thanks to CharTerm, I have made it work. However, in adding some error handling routines for the runtime I've run into a weird bug. You can see the full code here: https://github.com/jarcane/MicroMini/blob/master/main.rkt The relevant bit, however, is the (crash-handler) function. For some reason that utterly escapes my notice or discovery, the (format "~X" ...) call there does not actually spit out a hexadecimal number at runtime. The weirdest part is: I can't repeat the bug anywhere but when actually running main.rkt. I've even tried hand-entering all the relevant bits into the commandline REPL and calling the crash-handler inside a (with-crashterm), and it doesn't do it there: It properly gives me a hexadecimal number. Other than that it works great so far. Now I need to write at least a basic assembler. On Sun, Aug 10, 2014 at 6:09 PM, Neil Van Dyke wrote: > If you haven't already, you can try the following to disable any port > buffering within Racket, but that doesn't help you if the OS (Windows and > Posix-ish console stuff it's doing from the console window) isn't giving > Racket raw, unbuffered access to keyboard input through stdin: > > (file-stream-buffer-mode my-port 'none) > > If you were using almost anything other than Windows, you could just use " > http://www.neilvandyke.org/racket-charterm/". > > Other than that, you or someone could make a portable Racket text-terminal > package that does stuff like uses the console API on Windows and tty on > almost everything else. > > BTW, you mention getting random bytes with variations on "read-bytes". > That simply shouldn't happen with "read-bytes", but, when using variations > on "read-bytes-avail!", only the first N count bytes it says it read will > be valid in the bytestring. > > Neil V. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Mon Aug 11 01:21:45 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 11 Aug 2014 06:21:45 +0100 Subject: [racket] rename-transformer-target, prop:rename-transformer, and contracts In-Reply-To: <8E1A4EF3-A583-4C65-BAE9-E3E0426E4146@knauth.org> References: <8E1A4EF3-A583-4C65-BAE9-E3E0426E4146@knauth.org> Message-ID: <20140811052148.56793650186@mail-svr1.cs.utah.edu> Yes, that's a bug, and I'll push a repair soon. Here's an even smaller program that demonstrates the same bug, which is that `rename-transformer-target` doesn't work right on a chaperone of a structure when the structure type's `prop:rename-transformer` value is an integer. #lang racket/base (struct foo (id) #:property prop:rename-transformer 0) (rename-transformer-target (chaperone-struct (foo #'x) foo-id (lambda (f x) x))) At Sun, 10 Aug 2014 17:19:37 -0400, "Alexander D. Knauth" wrote: > If I have this program: > #lang racket/base > > (module foo racket/base > (require racket/contract/base) > (struct foo (id) #:transparent > #:property prop:rename-transformer (struct-field-index id)) > (provide (contract-out > [struct foo ([id identifier?])]))) > (require 'foo) > > (define id #'x) > (rename-transformer-target (foo id)) > > Then it will return this: > # > Instead of returning id. > > Is this a bug? > > Why wouldn?t this work? > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Mon Aug 11 01:44:16 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 11 Aug 2014 06:44:16 +0100 Subject: [racket] top-level-rename In-Reply-To: References: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> Message-ID: <20140811054418.D2D74650186@mail-svr1.cs.utah.edu> At Sun, 10 Aug 2014 17:01:01 +0200, Jens Axel S?gaard wrote: > 2014-08-08 7:07 GMT+02:00 Matthew Flatt : > > At Wed, 6 Aug 2014 22:03:17 +0200, Jens Axel S?gaard wrote: > >> The program below produce bytecodes for the program that returns a > >> syntax-object representing 42. > >> > >> The syntax-object looks like this: > >> > >> (#s((stx zo 0) > >> #s((wrapped zo 0) > >> 42 > >> (#s((top-level-rename wrap 0 zo 0) #f) > >> #s((top-level-rename wrap 0 zo 0) #f) > >> #s((top-level-rename wrap 0 zo 0) #t) > >> #s((phase-shift wrap 0 zo 0) 0 #f #f #f)) > >> clean)))) > >> > >> Two questions: > >> 1) Why three top-level-renames and not just one? > >> > >> 2) What is the meaning of the boolean flag? > > > > The boolean apparently indicates whether the rename is for phase 0. It > > should instead be the phase of the rename, where using a boolean for > > the phase is probably a leftover from an original implementation where > > imports were either phase 0 or phase 1. > > > > The three renames are from phases 0, 1, and #f. > > Got it. > > The next part of the syntax object is: Answers below, but first a big caution: While these details have been the same for a while, I hope and expect the representation of syntax objects to change in the coming months. I have been threatening to rewrite the macro expander (yes, in Racket) for a while, but things are lining up so that I can actually start trying soon. > #s((phase-shift wrap 0 zo 0) 0 #f #f #f)) > > The form of a phase-shift is > (phase-shift amt src dest cancel-id) > where > amt is #f or an integer, > src and dest are module-path-index? > cancel-id is #f or an integer > > The documentation on phase-shift is rather brief. > > 1) Is it correct that a shift of #f means that only bindings at phase level 0 > are shifted to the label phase level? I'm afraid I could only look for the answer in the same place in the implementation where you must have found the "phase shift to #f shifts only phase-0 bindings" comment. So, yes. > 2) Even though src and dest are documented to be module-path-indices > the example show that #f is a valid value too. > Is it safe to assume that the combination #f #f means toplevel and > "self-module" ? > Or do #f mean "use the same value as before" ? I believe it means "use the same value as before". > 3) The example shows a phase-shift of 0. At first I didn't get what > the purpose of this. > Then I found a comment in add_renames_unless_module : > > /* this "phase shift" just attaches the namespace's module registry: */ > form = scheme_stx_phase_shift(form, NULL, NULL, NULL, > > genv->module_registry->exports, NULL, NULL); > > and this comment in scheme_stx_phase_shift : > > /* Shifts the phase on a syntax object in a module. A 0 shift might be > used just to re-direct relative module paths. new_midx might be > NULL to shift without redirection. And so on. */ > > Is this is the explanation behind the zero phase shift? Yes, that sounds right. > 4) What is the cancel-id? used for ? It's for yet another job of "phase shift" entries: to indicate the boundaries between information for a submodule context and information for the enclosing module's context. Roughly, a cancel ID causes a later module context to be ignored for the purposes of determining an identifier's context. The value of the cancel-ID field is matched against an identity field of each module-rename record. You could see get_old_module_env() for more, but I have trouble understanding and trusting this piece myself. I think it's a hack that has worked just well enough... except for Typed Racket, where submodule expansion doesn't work right, probably due to this part. From mflatt at cs.utah.edu Mon Aug 11 02:07:42 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 11 Aug 2014 07:07:42 +0100 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> <20140810075959.30B9B6501A5@mail-svr1.cs.utah.edu> Message-ID: <20140811060744.AADBE650185@mail-svr1.cs.utah.edu> +1 In the grand scheme of things, using `eval` to solve a problem (because you want to get something done now) is nowhere near as bad as, say, using/building an interpreter that is implemented in C (because I want to get something done "now", circa 1995). :) At Sun, 10 Aug 2014 10:38:24 -0400, Sean Kanaley wrote: > ***The ultimate (programming) concern is what will produce the highest > average correct-and-useful-running-program-output per second over my > lifespan.*** > > (philosophical extensions: provided it doesn't hurt other people, unless > they are "bad", where bad = ...etc...) > > Or anyone else who programs. The average decreases when something new is > learned, and increases later as a payoff from the new knowledge > (ideally...). This is especially important to experts in other fields who > want a quick solution instead of a theoretically maximally correct and > beautiful and least upsetting to experts solution. > > So I didn't need keyword-apply. I had the following choices: > > 1. build literal expression, call eval (~1 min dev time) > > 2. search documentation or google for "apply keyword", reach page of > documentation, *carefully* read all relevant-sounding functions on it, > choose keyword apply, THEN implement it (~10+ min?) (in reality after > trying apply for a bit since it seems like it would work, and for fear of > just using eval and being branded a C programmer, eventually concluding it > can't work = additional 5 min) > > 3. make a mistake with step 2, make post to user's list asking about this > case, receive feedback that it wasn't necessary to use it, go back and fix > code to be "correct" (unsure of time to type the first post, but the > overall energy spent on this process exceeds #1 and #2 for sure) > > In my case, I'm glad I now know about keyword-apply because I will be using > Racket until I die. Those 15 minutes will *hopefully* save over 15 minutes > by the end of my life. They might not though, and time now > time later, > but I'm still glad because I enjoy programming as a hobby and want to be > good at it, but in terms of maximizing output I should have just used eval. > > Taken further, there is some optimal level of knowledge that allows for all > tasks that need to be completed to be completed as quickly and accurately > as possible, where further knowledge represents time spent wasted acquiring > it. Professionals in fields other than programming itself will probably > have a low level of optimal knowledge, and the attitude that some seem to > have about "dumb newbies with their dumb evals" is incorrect. They should > possibly do whatever is as fast as possible, regardless of how bad the code > is. From olopierpa at gmail.com Mon Aug 11 03:15:02 2014 From: olopierpa at gmail.com (Pierpaolo Bernardi) Date: Mon, 11 Aug 2014 09:15:02 +0200 Subject: [racket] Use of map and eval to evaluate symbol in namespace In-Reply-To: <20140811060744.AADBE650185@mail-svr1.cs.utah.edu> References: <53D55E34.4080306@neilvandyke.org> <53E613CA.4070200@neilvandyke.org> <20140810075959.30B9B6501A5@mail-svr1.cs.utah.edu> <20140811060744.AADBE650185@mail-svr1.cs.utah.edu> Message-ID: On Mon, Aug 11, 2014 at 8:07 AM, Matthew Flatt wrote: > +1 > > In the grand scheme of things, using `eval` to solve a problem (because > you want to get something done now) is nowhere near as bad as, say, but, to come back to the original question, in order to not confuse further the OP: in this case eval was NOT getting anything done. On the contrary, it was creating a nightmare out of a trivial task. From manfred.lotz at arcor.de Mon Aug 11 03:03:46 2014 From: manfred.lotz at arcor.de (Manfred Lotz) Date: Mon, 11 Aug 2014 09:03:46 +0200 Subject: [racket] DrRacket eats 100% cpu References: <20140809200029.1b19a2a5@arcor.com> Message-ID: <20140811090346.3d2ad57b@arcor.com> On Sat, 9 Aug 2014 23:17:37 -0500 Robby Findler wrote: > Ah, thanks. I've fixed the performance bug. > > FWIW, I think it would have terminated eventually. It takes about 3 > seconds to appear on my machine the first time the dialog is opened > (before the push I just did). > Yes you are right. It terminates eventually. On my laptop it takes much longer, 35 seconds or so. -- Manfred > Robby > > > On Sat, Aug 9, 2014 at 1:00 PM, Manfred Lotz > wrote: > > Hi all, > > I'm not a DrRacket user so I have no idea what I did wrong. > > > > Out of curiosity I started DrRacket and looking around at the menu > > entries I chose: > > Insert/Insert Large Letters... > > > > just to see what happens. Nothing happened except that DrRacket took > > 100% cpu. When trying to stop DrRacket I got this > > > > > > user break > > context...: > > /home/manfred/racket/share/pkgs/draw-lib/racket/draw/private/dc.rkt:1248:4: > > core2823 get-w-size > > loop > > loop > > loop > > loop > > loop > > loop > > loop > > loop > > loop > > loop > > loop > > loop > > loop > > loop... > > > > > > Don't know what I did wrong? > > > > -- > > Manfred > > > > > > > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From robby at eecs.northwestern.edu Mon Aug 11 04:13:46 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Mon, 11 Aug 2014 03:13:46 -0500 Subject: [racket] DrRacket eats 100% cpu In-Reply-To: <20140811090346.3d2ad57b@arcor.com> References: <20140809200029.1b19a2a5@arcor.com> <20140811090346.3d2ad57b@arcor.com> Message-ID: Yuck! Sorry. The nightly build should have my change by now. If you want to try it out, I'd be curious to know if it helped you: http://plt.eecs.northwestern.edu/snapshots/ Robby On Mon, Aug 11, 2014 at 2:03 AM, Manfred Lotz wrote: > On Sat, 9 Aug 2014 23:17:37 -0500 > Robby Findler > wrote: > >> Ah, thanks. I've fixed the performance bug. >> >> FWIW, I think it would have terminated eventually. It takes about 3 >> seconds to appear on my machine the first time the dialog is opened >> (before the push I just did). >> > > Yes you are right. It terminates eventually. On my laptop it takes much > longer, 35 seconds or so. > > > -- > Manfred > > > >> Robby >> >> >> On Sat, Aug 9, 2014 at 1:00 PM, Manfred Lotz >> wrote: >> > Hi all, >> > I'm not a DrRacket user so I have no idea what I did wrong. >> > >> > Out of curiosity I started DrRacket and looking around at the menu >> > entries I chose: >> > Insert/Insert Large Letters... >> > >> > just to see what happens. Nothing happened except that DrRacket took >> > 100% cpu. When trying to stop DrRacket I got this >> > >> > >> > user break >> > context...: >> > /home/manfred/racket/share/pkgs/draw-lib/racket/draw/private/dc.rkt:1248:4: >> > core2823 get-w-size >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop >> > loop... >> > >> > >> > Don't know what I did wrong? >> > >> > -- >> > Manfred >> > >> > >> > >> > ____________________ >> > Racket Users list: >> > http://lists.racket-lang.org/users >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From manfred.lotz at arcor.de Mon Aug 11 05:17:06 2014 From: manfred.lotz at arcor.de (Manfred Lotz) Date: Mon, 11 Aug 2014 11:17:06 +0200 Subject: [racket] DrRacket eats 100% cpu References: <20140809200029.1b19a2a5@arcor.com> <20140811090346.3d2ad57b@arcor.com> Message-ID: <20140811111706.084729c5@arcor.com> On Mon, 11 Aug 2014 03:13:46 -0500 Robby Findler wrote: > Yuck! Sorry. > > The nightly build should have my change by now. If you want to try it > out, I'd be curious to know if it helped you: > http://plt.eecs.northwestern.edu/snapshots/ > Yep, it did help. Now, I wait for 1-2 seconds and the windows pops up. There is no loop any longer. Thanks, Manfred > > > On Mon, Aug 11, 2014 at 2:03 AM, Manfred Lotz > wrote: > > On Sat, 9 Aug 2014 23:17:37 -0500 > > Robby Findler > > wrote: > > > >> Ah, thanks. I've fixed the performance bug. > >> > >> FWIW, I think it would have terminated eventually. It takes about 3 > >> seconds to appear on my machine the first time the dialog is opened > >> (before the push I just did). > >> > > > > Yes you are right. It terminates eventually. On my laptop it takes > > much longer, 35 seconds or so. > > > > > > -- > > Manfred > > > > > > > >> Robby > >> > >> > >> On Sat, Aug 9, 2014 at 1:00 PM, Manfred Lotz > >> wrote: > >> > Hi all, > >> > I'm not a DrRacket user so I have no idea what I did wrong. > >> > > >> > Out of curiosity I started DrRacket and looking around at the > >> > menu entries I chose: > >> > Insert/Insert Large Letters... > >> > > >> > just to see what happens. Nothing happened except that DrRacket > >> > took 100% cpu. When trying to stop DrRacket I got this > >> > > >> > > >> > user break > >> > context...: > >> > /home/manfred/racket/share/pkgs/draw-lib/racket/draw/private/dc.rkt:1248:4: > >> > core2823 get-w-size > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop > >> > loop... > >> > > >> > > >> > Don't know what I did wrong? > >> > > >> > -- > >> > Manfred > >> > > >> > > >> > > >> > ____________________ > >> > Racket Users list: > >> > http://lists.racket-lang.org/users > >> ____________________ > >> Racket Users list: > >> http://lists.racket-lang.org/users > >> > > > > > > > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From mflatt at cs.utah.edu Mon Aug 11 06:28:34 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 11 Aug 2014 11:28:34 +0100 Subject: [racket] confusing error message: what is "lang:read.1"? In-Reply-To: References: <20140808052313.A7EF86501C5@mail-svr1.cs.utah.edu> Message-ID: <20140811102837.5A845650181@mail-svr1.cs.utah.edu> I've finally tracked down the problem and pushed a repair (commit c4508ad0d9). At Fri, 8 Aug 2014 07:05:04 -0700, Matthew Butterick wrote: > FWIW this isn't a gratuitously perverse example. It's derived from the actual > bug I've encountered. I use `eval` in my Pollen system to handle dynamic > rendering of pages delivered through the web server (don't panic, everyone ? > it's an approved use of `eval` [1]) > > I use the `dynamic-rerequire` to reload files that have changed since last > render. In fact you added it at my request, as I was looking for a Racket > function that approximated the Python `reload` function. [2] > > For now I've worked around the bug ? in test-case terms, I've changed this > > ;;; three.rkt > #lang racket > > To this: > > ;;; three.rkt > #lang racket/base > > But why that makes a difference, I'm not clear. > > [1] http://docs.racket-lang.org/web-server/faq.html > [2] http://lists.racket-lang.org/users/archive/2013-April/057530.html > > > On Aug 7, 2014, at 10:23 PM, Matthew Flatt wrote: > > > At Wed, 6 Aug 2014 15:50:41 -0700, Matthew Butterick wrote: > >> Under certain circumstances, because of what I assume is a bug in my code, I > >> get an error like this: > >> > >>> define-values: assignment disallowed; > >>> cannot re-define a constant > >>> constant: lang:read.1 > >>> in module: "/Users/mb/git/racket/racket/collects/racket/main.rkt" > >>> context...: > >>> (submod /Users/mb/git/racket/racket/collects/racket/main.rkt reader): > >> [running body] > >> > >> I understand how the "assignment disallowed" error arises. What I don't > >> understand is the meaning of "lang:read.1" in this context. I'm guessing it > has > >> something to do with the #lang line (?) but ... the rest is hazy. > > > > The "lang:read" part is the name of a variable that appears in the > > macro expansion of the `racket` module's `reader` submodule. The ".1" > > part is because that variable is macro-introduced so that it is not > > directly accessible using the name `lang:read`. > > > > The way that `dynamic-rerequire` and submodules interact here is > > unsatisfying. I think it's a collision between the way that > > `dynamic-rerequire` pulls from source and the use of > > `namespace-module-attach` within `make-base-namspace`, and I think that > > `dynamic-rerequire` needs to do something different, but I haven't yet > > sorted it out. > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From lysseus at gmail.com Mon Aug 11 12:05:20 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Mon, 11 Aug 2014 09:05:20 -0700 Subject: [racket] ] Converting symbols to procedures? Message-ID: <48657EA8-7131-417C-91A1-6FA7C687A18D@gmail.com> If I use apply on a list of procedures, the quoting of the list converts the procedures into symbols, which is not what I want to pass to the function supplied to apply (or to map for that matter). What?s the best way to handle this situation? -Kevin From ianj at ccs.neu.edu Mon Aug 11 12:20:20 2014 From: ianj at ccs.neu.edu (J. Ian Johnson) Date: Mon, 11 Aug 2014 12:20:20 -0400 (EDT) Subject: [racket] ] Converting symbols to procedures? In-Reply-To: <48657EA8-7131-417C-91A1-6FA7C687A18D@gmail.com> Message-ID: <21549290.697001407774020293.JavaMail.root@zimbra> Quoting is not a synonym for creating lists. For example: (define foo (lambda (x y z) (printf "~a ~a~%" x z) y)) foo => # 'foo => 'foo If you want to write, say, (list (foo 'arg0 1 #f) (bar 'arg0 1 #f) (baz 'arg0 1 #f)) as (apply* (list foo bar baz) '(arg0 1 #f)) where (define (apply* ps vs) (if (pair? ps) (cons (apply (car ps) vs) (apply* (cdr ps) vs)) '())) then you have to use list and refer to the /bindings/ of the /identifiers/ foo, bar and baz. Symbols can be mucked around with as identifiers using eval, but that is almost always not the right thing to do. -Ian ----- Original Message ----- From: "Kevin Forchione" To: "Racket Users" Sent: Monday, August 11, 2014 12:05:20 PM GMT -05:00 US/Canada Eastern Subject: [racket] ] Converting symbols to procedures? If I use apply on a list of procedures, the quoting of the list converts the procedures into symbols, which is not what I want to pass to the function supplied to apply (or to map for that matter). What?s the best way to handle this situation? -Kevin ____________________ Racket Users list: http://lists.racket-lang.org/users From deren.dohoda at gmail.com Mon Aug 11 12:38:19 2014 From: deren.dohoda at gmail.com (Deren Dohoda) Date: Mon, 11 Aug 2014 12:38:19 -0400 Subject: [racket] ] Converting symbols to procedures? In-Reply-To: <48657EA8-7131-417C-91A1-6FA7C687A18D@gmail.com> References: <48657EA8-7131-417C-91A1-6FA7C687A18D@gmail.com> Message-ID: Is it not as simple as "don't quote the list, use the procedure 'list'?" Procedures are first class. Welcome to DrRacket, version 6.0.1 [3m]. Language: racket [custom]; memory limit: 4096 MB. > (define (filter* procs lst) (define (fil ps l) (if (empty? (rest ps)) (filter (first ps) l) (fil (rest ps) (filter (first ps) l)))) (if (empty? procs) (error 'filter* "Expected at least one procedure for filtering.") (fil procs lst))) > (define test-list (append (build-list 20 values) (build-list 20 (?(x) 'derp)))) > (define proc-list (list number? even? (?(x) (zero? (modulo x 3))))) > (displayln proc-list) (# # #) > (filter* proc-list test-list) '(0 6 12 18) > On Mon, Aug 11, 2014 at 12:05 PM, Kevin Forchione wrote: > If I use apply on a list of procedures, the quoting of the list converts > the procedures into symbols, which is not what I want to pass to the > function supplied to apply (or to map for that matter). What?s the best way > to handle this situation? > > -Kevin > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lysseus at gmail.com Mon Aug 11 12:57:29 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Mon, 11 Aug 2014 09:57:29 -0700 Subject: [racket] ] Converting symbols to procedures? In-Reply-To: <21549290.697001407774020293.JavaMail.root@zimbra> References: <21549290.697001407774020293.JavaMail.root@zimbra> Message-ID: <98002E4A-6DD6-4FF3-8E90-4CC112FF41AB@gmail.com> Here?s another example of my problem: #lang racket (define foo% (class object% (super-new) (field [x 0]))) (define bar% (class object% (super-new) (field [x 0]))) ?(apply make-object '(foo% bar%)) This doesn?t work because the make-object is being passed symbols instead of classes. If I wrap make-object in a function that does an eval on the symbol I run into another problem dealing with namespaces. -Kevin From lysseus at gmail.com Mon Aug 11 13:04:11 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Mon, 11 Aug 2014 10:04:11 -0700 Subject: [racket] ] Converting symbols to procedures? In-Reply-To: <98002E4A-6DD6-4FF3-8E90-4CC112FF41AB@gmail.com> References: <21549290.697001407774020293.JavaMail.root@zimbra> <98002E4A-6DD6-4FF3-8E90-4CC112FF41AB@gmail.com> Message-ID: <9B587375-39EF-4E79-A904-F34CFD88DC71@gmail.com> On Aug 11, 2014, at 9:57 AM, Kevin Forchione wrote: > > Here?s another example of my problem: > > #lang racket > > (define foo% > (class object% > (super-new) > (field [x 0]))) > (define bar% > (class object% > (super-new) > (field [x 0]))) > > ?(apply make-object '(foo% bar%)) > > This doesn?t work because the make-object is being passed symbols instead of classes. If I wrap make-object in a function that does an eval on the symbol I run into another problem dealing with namespaces. Oops. That should be (map make-object ?(foo% bar%)) -Kevin From deren.dohoda at gmail.com Mon Aug 11 13:04:43 2014 From: deren.dohoda at gmail.com (Deren Dohoda) Date: Mon, 11 Aug 2014 13:04:43 -0400 Subject: [racket] ] Converting symbols to procedures? In-Reply-To: <98002E4A-6DD6-4FF3-8E90-4CC112FF41AB@gmail.com> References: <21549290.697001407774020293.JavaMail.root@zimbra> <98002E4A-6DD6-4FF3-8E90-4CC112FF41AB@gmail.com> Message-ID: Don't quote. You want to pass the class in a list, pass the class in a list. #lang racket (define foo% (class object% (super-new) (field [x 0]))) (define bar% (class object% (super-new) (field [x 0]))) (define-values (f b) (apply values (map make-object (list foo% bar%)))) f b On Mon, Aug 11, 2014 at 12:57 PM, Kevin Forchione wrote: > > Here?s another example of my problem: > > #lang racket > > (define foo% > (class object% > (super-new) > (field [x 0]))) > (define bar% > (class object% > (super-new) > (field [x 0]))) > > ?(apply make-object '(foo% bar%)) > > This doesn?t work because the make-object is being passed symbols instead > of classes. If I wrap make-object in a function that does an eval on the > symbol I run into another problem dealing with namespaces. > > -Kevin > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From plragde at uwaterloo.ca Mon Aug 11 13:16:20 2014 From: plragde at uwaterloo.ca (Prabhakar Ragde) Date: Mon, 11 Aug 2014 10:16:20 -0700 Subject: [racket] ] Converting symbols to procedures? In-Reply-To: Message-ID: <53E8FA64.1090400@uwaterloo.ca> Deren wrote: > Don't quote. You want to pass the class in a list, pass the class in a list. You can also quasiquote and unquote. (list + *) can be written `(,+ ,*). This is overkill for such a small example, but is useful if you want to mix literal quotation and expressions while maintaining the readability of quote. --PR From lysseus at gmail.com Mon Aug 11 13:23:51 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Mon, 11 Aug 2014 10:23:51 -0700 Subject: [racket] ] Converting symbols to procedures? In-Reply-To: <53E8FA64.1090400@uwaterloo.ca> References: <53E8FA64.1090400@uwaterloo.ca> Message-ID: <523B1272-DE8B-41EA-AB0E-E01B286BD0C2@gmail.com> On Aug 11, 2014, at 10:16 AM, Prabhakar Ragde wrote: > Deren wrote: > >> Don't quote. You want to pass the class in a list, pass the class in a list. > > You can also quasiquote and unquote. (list + *) can be written `(,+ ,*). This is overkill for such a small example, but is useful if you want to mix literal quotation and expressions while maintaining the readability of quote. --PR Thanks! -Kevin From alexander at knauth.org Mon Aug 11 15:22:18 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Mon, 11 Aug 2014 15:22:18 -0400 Subject: [racket] top-level-rename In-Reply-To: <20140811054418.D2D74650186@mail-svr1.cs.utah.edu> References: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> <20140811054418.D2D74650186@mail-svr1.cs.utah.edu> Message-ID: On Aug 11, 2014, at 1:44 AM, Matthew Flatt wrote: > Answers below, but first a big caution: While these details have been > the same for a while, I hope and expect the representation of syntax > objects to change in the coming months. I have been threatening to > rewrite the macro expander (yes, in Racket) for a while, but things are > lining up so that I can actually start trying soon. This is off topic, but if your planning on rewriting the macro expander in Racket, would it be possible to make it so that syntax-local-introduce uses a parameter? That way for match expanders (etc.) it could set that parameter to a new syntax-introducer so that syntax-local-introduce could be used within match-expanders (etc.)? From gustavo at oma.org.ar Tue Aug 12 09:47:47 2014 From: gustavo at oma.org.ar (Gustavo Massaccesi) Date: Tue, 12 Aug 2014 10:47:47 -0300 Subject: [racket] top-level-rename In-Reply-To: References: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> <20140811054418.D2D74650186@mail-svr1.cs.utah.edu> Message-ID: +1 . Last year I was experimenting with require-tranformers and provide-transformers. They are very weird macros, because they have to be executed in the "wrong order" (from inside to outside, like functions). They use a newly created syntax-mark, and to break hygiene you must use syntax-local-require-introduce or syntax-local-provide-introduce (under the hood, the marker is stored in a parameter, but the parameter is not exported, so you can't change/parameterize it). I think that all of them can be merged in a generalized syntax-local-introduce with a public parameter. The parameter should be used only in a parameterize form. Overwriting the parameter doesn't look like a good idea. I think it will break the current macro and create a syntax error, but it will not be useful to break the security. Gustavo On Mon, Aug 11, 2014 at 4:22 PM, Alexander D. Knauth wrote: > > On Aug 11, 2014, at 1:44 AM, Matthew Flatt wrote: > >> Answers below, but first a big caution: While these details have been >> the same for a while, I hope and expect the representation of syntax >> objects to change in the coming months. I have been threatening to >> rewrite the macro expander (yes, in Racket) for a while, but things are >> lining up so that I can actually start trying soon. > > > This is off topic, but if your planning on rewriting the macro expander in Racket, would it be possible to make it so that syntax-local-introduce uses a parameter? > That way for match expanders (etc.) it could set that parameter to a new syntax-introducer so that syntax-local-introduce could be used within match-expanders (etc.)? > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From samth at cs.indiana.edu Tue Aug 12 09:55:20 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Tue, 12 Aug 2014 09:55:20 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: [rather late] Typed Racket knows quite a bit about the types of expressions, not just constants, even when type checking fails. I think we could use a logging mechanism similar to the one that allows check syntax to work even when type checking fails to communicate types of sub-expressions to DrRacket. There are some cases where expressions are typechecked twice that might cause problems, but in general this should be pretty easy. Sam On Tue, Aug 5, 2014 at 9:04 PM, Robby Findler wrote: > Is TR's type checker organized in such a way that the decisions about > what types are given to constants decided as a separate (first) phase? > That is, no matter the context, is this constant: > > #(0 0) > > always going to be given the type (Vector Integer Integer), assuming > there is no annotation? > > If so, then it seems like TR could communicate that series of > decisions even when type checking fails and that that might be useful > for this program? > > Robby > > > On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen wrote: >> >> You guys came up with some wonderful ideas. >> >> I think this particular one is easy to implement when >> the program type checks. But when it doesn't, what do >> you show? >> >> -- Matthias >> >> >> >> >> >> On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: >> >>> >>> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >>> >>>>>> add type declarations to variables and fields and function and method signatures. >>>>> >>>>> A good motto, which I shall endeavour to remember. >>>> >>>> what i do not get about TR and other languages (ocaml, haskell, etc.) >>>> is: there are these rules of thumb that you must somehow learn to keep >>>> yourself out of the weeds, but you only get to learn them the long and >>>> hard way. why don't the runtimes/ides >>>> >>>> (1) have a switch that says "hey, force me, the user, to put in type >>>> annotations by hand in the critical places, ok? so i don't have to >>>> suffer so much down the road, ok?" >>>> >>>> (2) put the inferred annotations into the code as it goes along so i >>>> can see what kind of crazy talk the inference engine is having with >>>> itself? >>> >>> I?m just wondering, would it be possible for DrRacket to do something where you can right-click a variable or expression or something and one of the options is to see what the inferred type is? >>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From robby at eecs.northwestern.edu Tue Aug 12 12:15:27 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Tue, 12 Aug 2014 11:15:27 -0500 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: That would be great. I think you'd just want to tell check syntax "at this position, here is a string to show the user". Is that ok? (And you'd put newlines in the string to format it, I guess?) Robby On Tue, Aug 12, 2014 at 8:55 AM, Sam Tobin-Hochstadt wrote: > [rather late] > > Typed Racket knows quite a bit about the types of expressions, not > just constants, even when type checking fails. I think we could use a > logging mechanism similar to the one that allows check syntax to work > even when type checking fails to communicate types of sub-expressions > to DrRacket. > > There are some cases where expressions are typechecked twice that > might cause problems, but in general this should be pretty easy. > > Sam > > On Tue, Aug 5, 2014 at 9:04 PM, Robby Findler > wrote: >> Is TR's type checker organized in such a way that the decisions about >> what types are given to constants decided as a separate (first) phase? >> That is, no matter the context, is this constant: >> >> #(0 0) >> >> always going to be given the type (Vector Integer Integer), assuming >> there is no annotation? >> >> If so, then it seems like TR could communicate that series of >> decisions even when type checking fails and that that might be useful >> for this program? >> >> Robby >> >> >> On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen wrote: >>> >>> You guys came up with some wonderful ideas. >>> >>> I think this particular one is easy to implement when >>> the program type checks. But when it doesn't, what do >>> you show? >>> >>> -- Matthias >>> >>> >>> >>> >>> >>> On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: >>> >>>> >>>> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >>>> >>>>>>> add type declarations to variables and fields and function and method signatures. >>>>>> >>>>>> A good motto, which I shall endeavour to remember. >>>>> >>>>> what i do not get about TR and other languages (ocaml, haskell, etc.) >>>>> is: there are these rules of thumb that you must somehow learn to keep >>>>> yourself out of the weeds, but you only get to learn them the long and >>>>> hard way. why don't the runtimes/ides >>>>> >>>>> (1) have a switch that says "hey, force me, the user, to put in type >>>>> annotations by hand in the critical places, ok? so i don't have to >>>>> suffer so much down the road, ok?" >>>>> >>>>> (2) put the inferred annotations into the code as it goes along so i >>>>> can see what kind of crazy talk the inference engine is having with >>>>> itself? >>>> >>>> I?m just wondering, would it be possible for DrRacket to do something where you can right-click a variable or expression or something and one of the options is to see what the inferred type is? >>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>> >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users From alexander at knauth.org Tue Aug 12 13:28:28 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Tue, 12 Aug 2014 13:28:28 -0400 Subject: [racket] top-level-rename In-Reply-To: References: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> <20140811054418.D2D74650186@mail-svr1.cs.utah.edu> Message-ID: Maybe something like this, to make sure it is only changed by a parameterize form? (provide syntax-local-introduce call-with-syntax-introducer) (define current-syntax-introducer (make-parameter #f)) (define (syntax-local-introduce stx) ((current-syntax-introducer) stx)) (define (call-with-syntax-introducer intro thunk) (parameterize ([current-syntax-introducer intro]) (thunk))) On Aug 12, 2014, at 9:47 AM, Gustavo Massaccesi wrote: > +1 . Last year I was experimenting with require-tranformers and > provide-transformers. They are very weird macros, because they have to > be executed in the "wrong order" (from inside to outside, like > functions). They use a newly created syntax-mark, and to break hygiene > you must use syntax-local-require-introduce or > syntax-local-provide-introduce (under the hood, the marker is stored > in a parameter, but the parameter is not exported, so you can't > change/parameterize it). > > I think that all of them can be merged in a generalized > syntax-local-introduce with a public parameter. The parameter should > be used only in a parameterize form. Overwriting the parameter doesn't > look like a good idea. I think it will break the current macro and > create a syntax error, but it will not be useful to break the > security. > > > Gustavo > > > On Mon, Aug 11, 2014 at 4:22 PM, Alexander D. Knauth > wrote: >> >> On Aug 11, 2014, at 1:44 AM, Matthew Flatt wrote: >> >>> Answers below, but first a big caution: While these details have been >>> the same for a while, I hope and expect the representation of syntax >>> objects to change in the coming months. I have been threatening to >>> rewrite the macro expander (yes, in Racket) for a while, but things are >>> lining up so that I can actually start trying soon. >> >> >> This is off topic, but if your planning on rewriting the macro expander in Racket, would it be possible to make it so that syntax-local-introduce uses a parameter? >> That way for match expanders (etc.) it could set that parameter to a new syntax-introducer so that syntax-local-introduce could be used within match-expanders (etc.)? >> >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From samth at cs.indiana.edu Tue Aug 12 13:36:04 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Tue, 12 Aug 2014 13:36:04 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: I think that it would work better to: a. Associate the information with a syntax object rather than a location. b. Provide an sexp rather than a string, so that it can be formatted appropriately by DrRacket. Sam On Aug 12, 2014 12:15 PM, "Robby Findler" wrote: > That would be great. I think you'd just want to tell check syntax "at > this position, here is a string to show the user". Is that ok? (And > you'd put newlines in the string to format it, I guess?) > > Robby > > On Tue, Aug 12, 2014 at 8:55 AM, Sam Tobin-Hochstadt > wrote: > > [rather late] > > > > Typed Racket knows quite a bit about the types of expressions, not > > just constants, even when type checking fails. I think we could use a > > logging mechanism similar to the one that allows check syntax to work > > even when type checking fails to communicate types of sub-expressions > > to DrRacket. > > > > There are some cases where expressions are typechecked twice that > > might cause problems, but in general this should be pretty easy. > > > > Sam > > > > On Tue, Aug 5, 2014 at 9:04 PM, Robby Findler > > wrote: > >> Is TR's type checker organized in such a way that the decisions about > >> what types are given to constants decided as a separate (first) phase? > >> That is, no matter the context, is this constant: > >> > >> #(0 0) > >> > >> always going to be given the type (Vector Integer Integer), assuming > >> there is no annotation? > >> > >> If so, then it seems like TR could communicate that series of > >> decisions even when type checking fails and that that might be useful > >> for this program? > >> > >> Robby > >> > >> > >> On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen < > matthias at ccs.neu.edu> wrote: > >>> > >>> You guys came up with some wonderful ideas. > >>> > >>> I think this particular one is easy to implement when > >>> the program type checks. But when it doesn't, what do > >>> you show? > >>> > >>> -- Matthias > >>> > >>> > >>> > >>> > >>> > >>> On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: > >>> > >>>> > >>>> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: > >>>> > >>>>>>> add type declarations to variables and fields and function and > method signatures. > >>>>>> > >>>>>> A good motto, which I shall endeavour to remember. > >>>>> > >>>>> what i do not get about TR and other languages (ocaml, haskell, etc.) > >>>>> is: there are these rules of thumb that you must somehow learn to > keep > >>>>> yourself out of the weeds, but you only get to learn them the long > and > >>>>> hard way. why don't the runtimes/ides > >>>>> > >>>>> (1) have a switch that says "hey, force me, the user, to put in type > >>>>> annotations by hand in the critical places, ok? so i don't have to > >>>>> suffer so much down the road, ok?" > >>>>> > >>>>> (2) put the inferred annotations into the code as it goes along so i > >>>>> can see what kind of crazy talk the inference engine is having with > >>>>> itself? > >>>> > >>>> I?m just wondering, would it be possible for DrRacket to do something > where you can right-click a variable or expression or something and one of > the options is to see what the inferred type is? > >>>> > >>>>> ____________________ > >>>>> Racket Users list: > >>>>> http://lists.racket-lang.org/users > >>>> > >>>> > >>>> ____________________ > >>>> Racket Users list: > >>>> http://lists.racket-lang.org/users > >>> > >>> > >>> ____________________ > >>> Racket Users list: > >>> http://lists.racket-lang.org/users > >> > >> ____________________ > >> Racket Users list: > >> http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From robby at eecs.northwestern.edu Tue Aug 12 13:39:57 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Tue, 12 Aug 2014 12:39:57 -0500 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: A. won't work; the communication has to be things that can be transmitted on place channels. Currently, all of this communication is already position-based. Of course, it's easy to make position based information from a syntax object. B.: I don't see what you mean. Why does DrRacket know better than TR how to format TR types? On Tue, Aug 12, 2014 at 12:36 PM, Sam Tobin-Hochstadt wrote: > I think that it would work better to: > > a. Associate the information with a syntax object rather than a location. > b. Provide an sexp rather than a string, so that it can be formatted > appropriately by DrRacket. > > Sam > > On Aug 12, 2014 12:15 PM, "Robby Findler" > wrote: >> >> That would be great. I think you'd just want to tell check syntax "at >> this position, here is a string to show the user". Is that ok? (And >> you'd put newlines in the string to format it, I guess?) >> >> Robby >> >> On Tue, Aug 12, 2014 at 8:55 AM, Sam Tobin-Hochstadt >> wrote: >> > [rather late] >> > >> > Typed Racket knows quite a bit about the types of expressions, not >> > just constants, even when type checking fails. I think we could use a >> > logging mechanism similar to the one that allows check syntax to work >> > even when type checking fails to communicate types of sub-expressions >> > to DrRacket. >> > >> > There are some cases where expressions are typechecked twice that >> > might cause problems, but in general this should be pretty easy. >> > >> > Sam >> > >> > On Tue, Aug 5, 2014 at 9:04 PM, Robby Findler >> > wrote: >> >> Is TR's type checker organized in such a way that the decisions about >> >> what types are given to constants decided as a separate (first) phase? >> >> That is, no matter the context, is this constant: >> >> >> >> #(0 0) >> >> >> >> always going to be given the type (Vector Integer Integer), assuming >> >> there is no annotation? >> >> >> >> If so, then it seems like TR could communicate that series of >> >> decisions even when type checking fails and that that might be useful >> >> for this program? >> >> >> >> Robby >> >> >> >> >> >> On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen >> >> wrote: >> >>> >> >>> You guys came up with some wonderful ideas. >> >>> >> >>> I think this particular one is easy to implement when >> >>> the program type checks. But when it doesn't, what do >> >>> you show? >> >>> >> >>> -- Matthias >> >>> >> >>> >> >>> >> >>> >> >>> >> >>> On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: >> >>> >> >>>> >> >>>> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >> >>>> >> >>>>>>> add type declarations to variables and fields and function and >> >>>>>>> method signatures. >> >>>>>> >> >>>>>> A good motto, which I shall endeavour to remember. >> >>>>> >> >>>>> what i do not get about TR and other languages (ocaml, haskell, >> >>>>> etc.) >> >>>>> is: there are these rules of thumb that you must somehow learn to >> >>>>> keep >> >>>>> yourself out of the weeds, but you only get to learn them the long >> >>>>> and >> >>>>> hard way. why don't the runtimes/ides >> >>>>> >> >>>>> (1) have a switch that says "hey, force me, the user, to put in type >> >>>>> annotations by hand in the critical places, ok? so i don't have to >> >>>>> suffer so much down the road, ok?" >> >>>>> >> >>>>> (2) put the inferred annotations into the code as it goes along so i >> >>>>> can see what kind of crazy talk the inference engine is having with >> >>>>> itself? >> >>>> >> >>>> I?m just wondering, would it be possible for DrRacket to do something >> >>>> where you can right-click a variable or expression or something and one of >> >>>> the options is to see what the inferred type is? >> >>>> >> >>>>> ____________________ >> >>>>> Racket Users list: >> >>>>> http://lists.racket-lang.org/users >> >>>> >> >>>> >> >>>> ____________________ >> >>>> Racket Users list: >> >>>> http://lists.racket-lang.org/users >> >>> >> >>> >> >>> ____________________ >> >>> Racket Users list: >> >>> http://lists.racket-lang.org/users >> >> >> >> ____________________ >> >> Racket Users list: >> >> http://lists.racket-lang.org/users From samth at cs.indiana.edu Tue Aug 12 15:46:53 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Tue, 12 Aug 2014 15:46:53 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: On Tue, Aug 12, 2014 at 1:39 PM, Robby Findler wrote: > A. won't work; the communication has to be things that can be > transmitted on place channels. Currently, all of this communication is > already position-based. Of course, it's easy to make position based > information from a syntax object. Sure, I can do that. It might make sense for the logging to handle syntax objects, though, and do its own internal serialization that could be improved as needed. > B.: I don't see what you mean. Why does DrRacket know better than TR > how to format TR types? I was thinking that DrRacket might want to line-break things differently, or otherwise render things more interestingly. Sam > On Tue, Aug 12, 2014 at 12:36 PM, Sam Tobin-Hochstadt > wrote: >> I think that it would work better to: >> >> a. Associate the information with a syntax object rather than a location. >> b. Provide an sexp rather than a string, so that it can be formatted >> appropriately by DrRacket. >> >> Sam >> >> On Aug 12, 2014 12:15 PM, "Robby Findler" >> wrote: >>> >>> That would be great. I think you'd just want to tell check syntax "at >>> this position, here is a string to show the user". Is that ok? (And >>> you'd put newlines in the string to format it, I guess?) >>> >>> Robby >>> >>> On Tue, Aug 12, 2014 at 8:55 AM, Sam Tobin-Hochstadt >>> wrote: >>> > [rather late] >>> > >>> > Typed Racket knows quite a bit about the types of expressions, not >>> > just constants, even when type checking fails. I think we could use a >>> > logging mechanism similar to the one that allows check syntax to work >>> > even when type checking fails to communicate types of sub-expressions >>> > to DrRacket. >>> > >>> > There are some cases where expressions are typechecked twice that >>> > might cause problems, but in general this should be pretty easy. >>> > >>> > Sam >>> > >>> > On Tue, Aug 5, 2014 at 9:04 PM, Robby Findler >>> > wrote: >>> >> Is TR's type checker organized in such a way that the decisions about >>> >> what types are given to constants decided as a separate (first) phase? >>> >> That is, no matter the context, is this constant: >>> >> >>> >> #(0 0) >>> >> >>> >> always going to be given the type (Vector Integer Integer), assuming >>> >> there is no annotation? >>> >> >>> >> If so, then it seems like TR could communicate that series of >>> >> decisions even when type checking fails and that that might be useful >>> >> for this program? >>> >> >>> >> Robby >>> >> >>> >> >>> >> On Tue, Aug 5, 2014 at 7:53 PM, Matthias Felleisen >>> >> wrote: >>> >>> >>> >>> You guys came up with some wonderful ideas. >>> >>> >>> >>> I think this particular one is easy to implement when >>> >>> the program type checks. But when it doesn't, what do >>> >>> you show? >>> >>> >>> >>> -- Matthias >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> On Aug 5, 2014, at 6:13 PM, Alexander D. Knauth wrote: >>> >>> >>> >>>> >>> >>>> On Aug 5, 2014, at 6:06 PM, Raoul Duke wrote: >>> >>>> >>> >>>>>>> add type declarations to variables and fields and function and >>> >>>>>>> method signatures. >>> >>>>>> >>> >>>>>> A good motto, which I shall endeavour to remember. >>> >>>>> >>> >>>>> what i do not get about TR and other languages (ocaml, haskell, >>> >>>>> etc.) >>> >>>>> is: there are these rules of thumb that you must somehow learn to >>> >>>>> keep >>> >>>>> yourself out of the weeds, but you only get to learn them the long >>> >>>>> and >>> >>>>> hard way. why don't the runtimes/ides >>> >>>>> >>> >>>>> (1) have a switch that says "hey, force me, the user, to put in type >>> >>>>> annotations by hand in the critical places, ok? so i don't have to >>> >>>>> suffer so much down the road, ok?" >>> >>>>> >>> >>>>> (2) put the inferred annotations into the code as it goes along so i >>> >>>>> can see what kind of crazy talk the inference engine is having with >>> >>>>> itself? >>> >>>> >>> >>>> I?m just wondering, would it be possible for DrRacket to do something >>> >>>> where you can right-click a variable or expression or something and one of >>> >>>> the options is to see what the inferred type is? >>> >>>> >>> >>>>> ____________________ >>> >>>>> Racket Users list: >>> >>>>> http://lists.racket-lang.org/users >>> >>>> >>> >>>> >>> >>>> ____________________ >>> >>>> Racket Users list: >>> >>>> http://lists.racket-lang.org/users >>> >>> >>> >>> >>> >>> ____________________ >>> >>> Racket Users list: >>> >>> http://lists.racket-lang.org/users >>> >> >>> >> ____________________ >>> >> Racket Users list: >>> >> http://lists.racket-lang.org/users From asumu at ccs.neu.edu Tue Aug 12 17:45:48 2014 From: asumu at ccs.neu.edu (Asumu Takikawa) Date: Tue, 12 Aug 2014 17:45:48 -0400 Subject: [racket] Puzzled about type inference In-Reply-To: References: <4956245C-D28C-4249-A5FC-864AB892DA0E@ccs.neu.edu> Message-ID: <20140812214548.GT20640@localhost> On 2014-08-12 12:39:57 -0500, Robby Findler wrote: > B.: I don't see what you mean. Why does DrRacket know better than TR > how to format TR types? FWIW, if there are width limitations in the widget that DrRacket shows the type information, DrRacket may be able to pretty-print s-expressions better to fit than strings. Also, as far as TR is concerned it doesn't matter that much if it outputs s-exps or strings since internally we just pretty-print types as s-exps in a mostly standard way anyway (aside from indentation rules). Cheers, Asumu From jensaxel at soegaard.net Wed Aug 13 02:47:54 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Wed, 13 Aug 2014 08:47:54 +0200 Subject: [racket] top-level-rename In-Reply-To: <20140811054418.D2D74650186@mail-svr1.cs.utah.edu> References: <20140808050706.D3EFC6501BF@mail-svr1.cs.utah.edu> <20140811054418.D2D74650186@mail-svr1.cs.utah.edu> Message-ID: 2014-08-11 7:44 GMT+02:00 Matthew Flatt : > At Sun, 10 Aug 2014 17:01:01 +0200, Jens Axel S?gaard wrote: ... >> The next part of the syntax object is: > > Answers below, but first a big caution: While these details have been > the same for a while, I hope and expect the representation of syntax > objects to change in the coming months. I have been threatening to > rewrite the macro expander (yes, in Racket) for a while, but things are > lining up so that I can actually start trying soon. That is great news. That will make it easier make a version of Whalesong that can run in the browser. >> #s((phase-shift wrap 0 zo 0) 0 #f #f #f)) >> >> The form of a phase-shift is >> (phase-shift amt src dest cancel-id) >> where >> amt is #f or an integer, >> src and dest are module-path-index? >> cancel-id is #f or an integer >> >> The documentation on phase-shift is rather brief. >> >> 1) Is it correct that a shift of #f means that only bindings at phase level 0 >> are shifted to the label phase level? > > I'm afraid I could only look for the answer in the same place in the > implementation where you must have found the "phase shift to #f shifts > only phase-0 bindings" comment. So, yes. > > >> 2) Even though src and dest are documented to be module-path-indices >> the example show that #f is a valid value too. >> Is it safe to assume that the combination #f #f means toplevel and >> "self-module" ? >> Or do #f mean "use the same value as before" ? > > I believe it means "use the same value as before". > > >> 3) The example shows a phase-shift of 0. At first I didn't get what >> the purpose of this. >> Then I found a comment in add_renames_unless_module : >> >> /* this "phase shift" just attaches the namespace's module registry: */ >> form = scheme_stx_phase_shift(form, NULL, NULL, NULL, >> >> genv->module_registry->exports, NULL, NULL); >> >> and this comment in scheme_stx_phase_shift : >> >> /* Shifts the phase on a syntax object in a module. A 0 shift might be >> used just to re-direct relative module paths. new_midx might be >> NULL to shift without redirection. And so on. */ >> >> Is this is the explanation behind the zero phase shift? > > Yes, that sounds right. >> 4) What is the cancel-id? used for ? > > It's for yet another job of "phase shift" entries: to indicate the > boundaries between information for a submodule context and information > for the enclosing module's context. I better begin reading "phase shift" as "context shift" ;-) > Roughly, a cancel ID causes a later module context to be ignored for > the purposes of determining an identifier's context. The value of the > cancel-ID field is matched against an identity field of each > module-rename record. > > You could see get_old_module_env() for more, but I have trouble > understanding and trusting this piece myself. I think it's a hack that > has worked just well enough... except for Typed Racket, where submodule > expansion doesn't work right, probably due to this part. Thanks for the explanation. It makes more sense now. /Jens Axel From greghendershott at gmail.com Wed Aug 13 11:09:11 2014 From: greghendershott at gmail.com (Greg Hendershott) Date: Wed, 13 Aug 2014 11:09:11 -0400 Subject: [racket] Review request: Partially expanding to make "blue boxes" Message-ID: I was hoping someone more-experienced might have time to review something. For possible use in racket-mode, I've been experimenting with extracting "blue boxes" and "blue lines" from arbitrary Racket sources (not just functions with installed documentation): https://github.com/greghendershott/bluebox More background explanation is in the README.md. An early version analyzed fully-unexpanded syntax. But of course that misses things created by definer macros. On the other hand, trying to extract contracts from fully-expanded syntax is... ugly; I started down that road and realized it was insane. Instead I'm trying to work with the warm bowl of porridge: Wrap each module-level form in a macro that uses `local-expand` to partially expand stopping at forms like define, provide, define/contract, provide/contract, and so on. Then walk the form looking for function definitions, contracts, and renamings, storing this in a "database" consisting of a bunch of hash tables. On the source files I've tried so far, "it works". However: 1. This is my first ever need to use `local-expand`. 2. I'm not sure if my `munge-module` function is the best way to go about this? 3. In a couple cases I have to match on datums not literals. Usually that would be a red flag. I'm not sure in this case? If you search for "QUESTION" in main.rkt you'll see what I mean wrt 2 and 3. I'd welcome any feedback, either posted here or as GitHub comments (whichever you prefer). Thanks in advance! From mflatt at cs.utah.edu Wed Aug 13 15:44:47 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Wed, 13 Aug 2014 20:44:47 +0100 Subject: [racket] Cognicast on Racket & RacketCon Message-ID: <20140813194451.BE1F265018F@mail-svr1.cs.utah.edu> I enjoyed chatting with Craig Andera about Racket and RacketCon on the Cognicast: http://blog.cognitect.com/cognicast/061-matthew-flatt The idea is to to get out the word on RacketCon, so please share with anyone who might be interested. And if you haven't heard of the Cognicast before, you'll see that the above link is episode 61, so there's lots more to listen to. From kalimehtar at mail.ru Thu Aug 14 00:50:52 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Thu, 14 Aug 2014 08:50:52 +0400 Subject: [racket] =?utf-8?q?Type_information_in_macros?= Message-ID: <1407991852.672490660@f314.i.mail.ru> Is there a way to get type information in macro? Either from cintracts or from Typed Raacket. Or only way is to make up own type declaration syntax : something like (define-syntax-rule declare (VAR TYPE) ???(begin-for-syntax (hash-set! types 'VAR TYPE))) ? -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Thu Aug 14 08:47:37 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Thu, 14 Aug 2014 08:47:37 -0400 Subject: [racket] Type information in macros In-Reply-To: <1407991852.672490660@f314.i.mail.ru> References: <1407991852.672490660@f314.i.mail.ru> Message-ID: <3D483837-9B14-46A4-B677-9D4F586BC9B0@knauth.org> Do you mean like in this thread? http://lists.racket-lang.org/users/archive/2014-June/062943.html On Aug 14, 2014, at 12:50 AM, Roman Klochkov wrote: > Is there a way to get type information in macro? Either from cintracts or from Typed Raacket. > > Or only way is to make up own type declaration syntax : something like > > (define-syntax-rule declare (VAR TYPE) > (begin-for-syntax (hash-set! types 'VAR TYPE))) > > ? > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From kalimehtar at mail.ru Thu Aug 14 22:04:24 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Fri, 15 Aug 2014 06:04:24 +0400 Subject: [racket] =?utf-8?q?Type_information_in_macros?= In-Reply-To: <3D483837-9B14-46A4-B677-9D4F586BC9B0@knauth.org> References: <1407991852.672490660@f314.i.mail.ru> <3D483837-9B14-46A4-B677-9D4F586BC9B0@knauth.org> Message-ID: <1408068264.534337944@f168.i.mail.ru> Yes. Thank you! Thu, 14 Aug 2014 08:47:37 -0400 ?? "Alexander D. Knauth" : >Do you mean like in this thread? >http://lists.racket-lang.org/users/archive/2014-June/062943.html > >On Aug 14, 2014, at 12:50 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: > >> Is there a way to get type information in macro? Either from cintracts or from Typed Raacket. >> >> Or only way is to make up own type declaration syntax : something like >> >> (define-syntax-rule declare (VAR TYPE) >> (begin-for-syntax (hash-set! types 'VAR TYPE))) >> >> ? >> >> -- >> Roman Klochkov >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From kalimehtar at mail.ru Fri Aug 15 01:55:11 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Fri, 15 Aug 2014 09:55:11 +0400 Subject: [racket] =?utf-8?q?syntax-e_vs_syntax-=3Elist?= Message-ID: <1408082111.136640157@f320.i.mail.ru> What is the difference? > (let ([stx #'(1 (+ 3 4) 5 6)]) (equal? (syntax->list stx) (syntax-e stx))) #t Or syntax->list == (lambda (x) (let ([res (syntax-e x)]) (if (list? x) x #f))) ? -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Fri Aug 15 02:13:39 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 15 Aug 2014 07:13:39 +0100 Subject: [racket] syntax-e vs syntax->list In-Reply-To: <1408082111.136640157@f320.i.mail.ru> References: <1408082111.136640157@f320.i.mail.ru> Message-ID: <20140815061342.19C8F6501A4@mail-svr1.cs.utah.edu> At Fri, 15 Aug 2014 09:55:11 +0400, Roman Klochkov wrote: > What is the difference? > > > (let ([stx #'(1 (+ 3 4) 5 6)]) (equal? (syntax->list stx) (syntax-e stx))) > #t Or syntax->list == (lambda (x) (let ([res (syntax-e x)]) (if (list? x) x > #f))) ? You need a `.` to expose the difference: > (syntax-e #'(1 . (2))) '(# . #) > (syntax->list #'(1 . (2))) '(# #) From kalimehtar at mail.ru Fri Aug 15 05:03:27 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Fri, 15 Aug 2014 13:03:27 +0400 Subject: [racket] =?utf-8?q?syntax-e_vs_syntax-=3Elist?= In-Reply-To: <20140815061342.19C8F6501A4@mail-svr1.cs.utah.edu> References: <1408082111.136640157@f320.i.mail.ru> <20140815061342.19C8F6501A4@mail-svr1.cs.utah.edu> Message-ID: <1408093407.673207648@f295.i.mail.ru> Thank you! I thought, that #'(1 . (2)) == #'(1 2) as '(1 . (2)) == '(1 2) And Racket printer thinks same: > #'(1 . (2)) # Fri, 15 Aug 2014 07:13:39 +0100 ?? Matthew Flatt : >At Fri, 15 Aug 2014 09:55:11 +0400, Roman Klochkov wrote: >> What is the difference? >> >> > (let ([stx #'(1 (+ 3 4) 5 6)]) (equal? (syntax->list stx) (syntax-e stx))) >> #t Or syntax->list == (lambda (x) (let ([res (syntax-e x)]) (if (list? x) x >> #f))) ? > >You need a `.` to expose the difference: > >?> (syntax-e #'(1 . (2))) >?'(# . #) > >?> (syntax->list #'(1 . (2))) >?'(# #) > -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Fri Aug 15 05:33:01 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 15 Aug 2014 10:33:01 +0100 Subject: [racket] syntax-e vs syntax->list In-Reply-To: <1408093407.673207648@f295.i.mail.ru> References: <1408082111.136640157@f320.i.mail.ru> <20140815061342.19C8F6501A4@mail-svr1.cs.utah.edu> <1408093407.673207648@f295.i.mail.ru> Message-ID: <20140815093304.669486501B4@mail-svr1.cs.utah.edu> Yes, the printer oversimplifies in that sense. It simplifies in the obvious way of not printing lexical context, but it turns out that it also simplifies by neglecting the difference between a plain list and a sequence of pairs that ends in a syntax-object list. At Fri, 15 Aug 2014 13:03:27 +0400, Roman Klochkov wrote: > I thought, that #'(1 . (2)) == #'(1 2) as '(1 . (2)) == '(1 2) > > And Racket printer thinks same: > > > #'(1 . (2)) > # > Fri, 15 Aug 2014 07:13:39 +0100 ?? Matthew Flatt : > >At Fri, 15 Aug 2014 09:55:11 +0400, Roman Klochkov wrote: > >> What is the difference? > >> > >> > (let ([stx #'(1 (+ 3 4) 5 6)]) (equal? (syntax->list stx) (syntax-e stx))) > >> #t Or syntax->list == (lambda (x) (let ([res (syntax-e x)]) (if (list? x) x > >> #f))) ? > > > >You need a `.` to expose the difference: > > > >?> (syntax-e #'(1 . (2))) > >?'(# . #) > > > >?> (syntax->list #'(1 . (2))) > >?'(# #) > > > > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From kalimehtar at mail.ru Fri Aug 15 06:42:09 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Fri, 15 Aug 2014 14:42:09 +0400 Subject: [racket] =?utf-8?q?Can_impersonator_be_a_cache=3F?= Message-ID: <1408099329.948080869@f287.i.mail.ru> I have (struct object (a b c)) (struct reference (id data)) Let `ref' -- an instance of `reference'. I want, that (object-a ref) call my own (ref-get object-a ref) (define (ref-get accessor ref) ? (unless (weak-box-value (ref-data ref)) ? ? ?(set-ref-data! ref (make-weak-box (load-data (ref-id ref))))) ? (accessor?(weak-box-value (ref-data ref)))) Is it possible? I found `impersonate-struct', but it is not struct itself (no `id' field). I can add `prop:impersonator-of',. but how to redirect accessors? -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Fri Aug 15 08:45:59 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 15 Aug 2014 08:45:59 -0400 Subject: [racket] Can impersonator be a cache? In-Reply-To: <1408099329.948080869@f287.i.mail.ru> References: <1408099329.948080869@f287.i.mail.ru> Message-ID: Why not just define a new version of object-a that does that? You probably have a good reason, but what is it? Is it to change the result of struct->vector, allow (object a b c) as a match pattern to match ref, or what? On Aug 15, 2014, at 6:42 AM, Roman Klochkov wrote: > I have > (struct object (a b c)) > (struct reference (id data)) > > Let `ref' -- an instance of `reference'. > > I want, that (object-a ref) call my own (ref-get object-a ref) > > (define (ref-get accessor ref) > (unless (weak-box-value (ref-data ref)) > (set-ref-data! ref (make-weak-box (load-data (ref-id ref))))) > (accessor (weak-box-value (ref-data ref)))) > > Is it possible? > I found `impersonate-struct', but it is not struct itself (no `id' field). > I can add `prop:impersonator-of',. but how to redirect accessors? > > -- > Roman Klochkov > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From kalimehtar at mail.ru Fri Aug 15 14:16:55 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Fri, 15 Aug 2014 22:16:55 +0400 Subject: [racket] =?utf-8?q?Can_impersonator_be_a_cache=3F?= In-Reply-To: References: <1408099329.948080869@f287.i.mail.ru> Message-ID: <1408126615.623444307@f349.i.mail.ru> I want to have lazy-load struct. In C++ it is called proxy reference (when dereferencing return new (or cached) object loaded on demand) Ideally, it would be like (lazy-struct obj (a b c) #:loader load-data) then (define my-obj (make-ref obj "unique-id")) (displayln (obj-a my-obj)) ;; here content of my-obj should be loaded via load-data. And match pattern would also work. Now I made API with (get-field my-obj 'a), but is not Racketish. Fri, 15 Aug 2014 08:45:59 -0400 ?? "Alexander D. Knauth" : > >Why not just define a new version of object-a that does that? >You probably have a good reason, but what is it? >Is it to change the result of struct->vector, allow (object a b c) as a match pattern to match ref, or what? > >On Aug 15, 2014, at 6:42 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: > >> I have >> (struct object (a b c)) >> (struct reference (id data)) >> >> Let `ref' -- an instance of `reference'. >> >> I want, that (object-a ref) call my own (ref-get object-a ref) >> >> (define (ref-get accessor ref) >> (unless (weak-box-value (ref-data ref)) >> (set-ref-data! ref (make-weak-box (load-data (ref-id ref))))) >> (accessor (weak-box-value (ref-data ref)))) >> >> Is it possible? >> I found `impersonate-struct', but it is not struct itself (no `id' field). >> I can add `prop:impersonator-of',. but how to redirect accessors? >> >> -- >> Roman Klochkov >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From kalimehtar at mail.ru Fri Aug 15 14:21:58 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Fri, 15 Aug 2014 22:21:58 +0400 Subject: [racket] =?utf-8?q?Can_impersonator_be_a_cache=3F?= In-Reply-To: References: <1408099329.948080869@f287.i.mail.ru> Message-ID: <1408126918.959845849@f349.i.mail.ru> > Why not just define a new version of object-a that does that? (set! object-a ? ? (let ([old object-a]) ? ? ? ?(lambda (x) ? ? ? ? ? (if (reference? x) ? ? ? ? ? ? ? (ref-get old x) ? ? ? ? ? ? ? (old x))))) Like that for every accessor? + prop:impersonator-of... Maybe shall work. Fri, 15 Aug 2014 08:45:59 -0400 ?? "Alexander D. Knauth" : > >Why not just define a new version of object-a that does that? >You probably have a good reason, but what is it? >Is it to change the result of struct->vector, allow (object a b c) as a match pattern to match ref, or what? > >On Aug 15, 2014, at 6:42 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: > >> I have >> (struct object (a b c)) >> (struct reference (id data)) >> >> Let `ref' -- an instance of `reference'. >> >> I want, that (object-a ref) call my own (ref-get object-a ref) >> >> (define (ref-get accessor ref) >> (unless (weak-box-value (ref-data ref)) >> (set-ref-data! ref (make-weak-box (load-data (ref-id ref))))) >> (accessor (weak-box-value (ref-data ref)))) >> >> Is it possible? >> I found `impersonate-struct', but it is not struct itself (no `id' field). >> I can add `prop:impersonator-of',. but how to redirect accessors? >> >> -- >> Roman Klochkov >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From jackhfirth at gmail.com Fri Aug 15 16:11:55 2014 From: jackhfirth at gmail.com (Jack Firth) Date: Fri, 15 Aug 2014 13:11:55 -0700 Subject: [racket] Scribble srcdoc and macros Message-ID: Is there a form similar to proc-doc/names but for providing syntactic forms instead? Something where it expands to using @defform instead of @defproc. It looks like thing-doc might work, but that's meant for arbitrary values and I'm really looking for something specifically meant for exporting syntactic forms. If no such thing exists, how would an implementation based on thing-doc look exactly? -------------- next part -------------- An HTML attachment was scrubbed... URL: From antoine.brand at sfr.fr Fri Aug 15 16:41:35 2014 From: antoine.brand at sfr.fr (antoine) Date: Fri, 15 Aug 2014 22:41:35 +0200 Subject: [racket] Review request: Partially expanding to make "blue boxes" In-Reply-To: References: Message-ID: <20140815204100.GA3696@debian> Hello, The other approch i see for munge-module. Is to use: (dynamic-require target-module 0) (parameterize ([current-namespace (module->namespace target-module)]) (expand-once a-module-level-stx)) Where a-module-level-stx is a form inside #%module-begin. From alexander at knauth.org Fri Aug 15 21:26:55 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Fri, 15 Aug 2014 21:26:55 -0400 Subject: [racket] Can impersonator be a cache? In-Reply-To: <1408126615.623444307@f349.i.mail.ru> References: <1408099329.948080869@f287.i.mail.ru> <1408126615.623444307@f349.i.mail.ru> Message-ID: <604B9E71-44A5-4130-A95D-0F66804DB2F0@knauth.org> If what you want is lazy struct, would something like this work? #lang racket/base (require racket/splicing racket/promise (for-syntax racket/base racket/struct-info syntax/parse racket/syntax)) (module+ test (require rackunit) (lazy-struct object (a b c)) (define obj (object #:loader (? (field) (printf "calculating ~a\n" field) field))) (let ([out (open-output-string)]) (parameterize ([current-output-port out]) (check-equal? (get-output-string out) "") (check-equal? (object-a obj) 'a) (check-equal? (get-output-string out) "calculating a\n") (check-equal? (object-a obj) 'a) (check-equal? (get-output-string out) "calculating a\n") (check-match obj (object 'a 'b 'c)) (check-equal? (get-output-string out) "calculating a\ncalculating b\ncalculating c\n") (close-output-port out) )) ) (define-syntax lazy-struct (lambda (stx) (syntax-parse stx [(lazy-struct name:id (field:id ...) . options) #:with (~var struct:name) (format-id #'name "struct:~a" #'name #:source #'name) #:with name? (format-id #'name "~a?" #'name #:source #'name) #:with (name-field ...) (for/list ([field-id (in-list (syntax->list #'(field ...)))]) (format-id #'name "~a-~a" #'name field-id #:source #'name)) #:with (old-name-field ...) (generate-temporaries #'(name-field ...)) #'(splicing-local [(splicing-local [(struct name (field ...) . options)] (define old-name name) (define old-struct:name struct:name) (define old-name? name?) (define old-name-field name-field) ... (define (make-name #:loader loader) (old-name (delay (loader 'field)) ...)))] (define name? old-name?) (define struct:name old-struct:name) (define (name-field name) (force (old-name-field name))) ... (define-syntax name (make-struct-desc #:descriptor #'struct:name #:constructor #'make-name #:predicate #'name? #:accessors (reverse (list #'name-field ...)) #:mutators (list (begin 'name-field #f) ...) #:super #t)))]))) (begin-for-syntax (define (make-struct-desc #:descriptor [descriptor-id #f] #:constructor constructor-id #:predicate [predicate-id #f] #:accessors [accessors '(#f)] #:mutators [mutators (map (? (x) #f) accessors)] #:super [super #f]) (with-syntax ([constructor constructor-id]) (proc+struct-info (lambda (stx) (syntax-parse stx [(name . stuff) (quasisyntax/loc stx (#,(syntax/loc #'name constructor) . stuff))] [name (syntax/loc stx constructor)])) (list descriptor-id constructor-id predicate-id accessors mutators super)))) (struct proc+struct-info (proc struct-info) #:transparent #:property prop:procedure (struct-field-index proc) #:property prop:struct-info (? (this) (proc+struct-info-struct-info this))) ) On Aug 15, 2014, at 2:16 PM, Roman Klochkov wrote: > I want to have lazy-load struct. In C++ it is called proxy reference (when dereferencing return new (or cached) object loaded on demand) > > Ideally, it would be like > (lazy-struct obj (a b c) #:loader load-data) > > then > > (define my-obj (make-ref obj "unique-id")) > > (displayln (obj-a my-obj)) ;; here content of my-obj should be loaded via load-data. > > And match pattern would also work. > > Now I made API with (get-field my-obj 'a), but is not Racketish. > > Fri, 15 Aug 2014 08:45:59 -0400 ?? "Alexander D. Knauth" : > > Why not just define a new version of object-a that does that? > You probably have a good reason, but what is it? > Is it to change the result of struct->vector, allow (object a b c) as a match pattern to match ref, or what? > > On Aug 15, 2014, at 6:42 AM, Roman Klochkov wrote: > > > I have > > (struct object (a b c)) > > (struct reference (id data)) > > > > Let `ref' -- an instance of `reference'. > > > > I want, that (object-a ref) call my own (ref-get object-a ref) > > > > (define (ref-get accessor ref) > > (unless (weak-box-value (ref-data ref)) > > (set-ref-data! ref (make-weak-box (load-data (ref-id ref))))) > > (accessor (weak-box-value (ref-data ref)))) > > > > Is it possible? > > I found `impersonate-struct', but it is not struct itself (no `id' field). > > I can add `prop:impersonator-of',. but how to redirect accessors? > > > > -- > > Roman Klochkov > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > > -- > Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From greghendershott at gmail.com Fri Aug 15 21:49:47 2014 From: greghendershott at gmail.com (Greg Hendershott) Date: Fri, 15 Aug 2014 21:49:47 -0400 Subject: [racket] Review request: Partially expanding to make "blue boxes" In-Reply-To: <20140815204100.GA3696@debian> References: <20140815204100.GA3696@debian> Message-ID: > (dynamic-require target-module 0) > (parameterize ([current-namespace (module->namespace target-module)]) > (expand-once a-module-level-stx)) > > Where a-module-level-stx is a form inside #%module-begin. Thanks for the idea! Unfortunately: 1. (expand-once #'(provide foo)) will fail with e.g. "(provide foo): not at module level". I don't think I can use expand-once on individual #%module-begin expressions. 2. Besides, I don't think expand-once will necessarily expand "definer" macros sufficiently to produce the forms I want to see (define, provide, define/contract, provide/contract). I think I really do need to use local-expand; it seems like the tool for this job. Now, local-expand complains if it's not used in an expander/transformer[^1]. It complains if I call it from phase 0 code on a syntax object. That stumped me. Then I had the idea to insert a macro definition at the start of the module, so that I do call local-expand in the context it wants. Whether that's OK-clever or horrible-clever, is I guess part of the feedback I'm looking for. :) [^1]: The local-expand docs actually say: "This procedure must be called during the dynamic extent of a syntax transformer application by the expander or while a module is visited". The latter possibility sounds promising, but I don't understand how I would insinuate myself into the process of visiting a module. Would this be via overriding current-compile then chaining to the original? From greghendershott at gmail.com Fri Aug 15 22:04:19 2014 From: greghendershott at gmail.com (Greg Hendershott) Date: Fri, 15 Aug 2014 22:04:19 -0400 Subject: [racket] Review request: Partially expanding to make "blue boxes" In-Reply-To: References: <20140815204100.GA3696@debian> Message-ID: > [^1]: The local-expand docs actually say: "This procedure must be > called during the dynamic extent of a syntax transformer application > by the expander or while a module is visited". The latter possibility > sounds promising, but I don't understand how I would insinuate myself > into the process of visiting a module. Would this be via overriding > current-compile then chaining to the original? To answer my own question: >From experimentation, no. The time when `current-compile` is called doesn't qualify as "while a module is visited" -- `local-expand` gives the usual error: "local-expand: not currently transforming". From kalimehtar at mail.ru Sat Aug 16 05:40:06 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sat, 16 Aug 2014 13:40:06 +0400 Subject: [racket] =?utf-8?q?Can_impersonator_be_a_cache=3F?= In-Reply-To: <604B9E71-44A5-4130-A95D-0F66804DB2F0@knauth.org> References: <1408099329.948080869@f287.i.mail.ru> <1408126615.623444307@f349.i.mail.ru> <604B9E71-44A5-4130-A95D-0F66804DB2F0@knauth.org> Message-ID: <1408182006.520992607@f310.i.mail.ru> I think, yes. Thank you! Fri, 15 Aug 2014 21:26:55 -0400 ?? "Alexander D. Knauth" : >If what you want is lazy struct, would something like this work? > >#lang racket/base > >(require racket/splicing >? ? ? ? ?racket/promise >? ? ? ? ?(for-syntax racket/base >? ? ? ? ? ? ? ? ? ? ?racket/struct-info >? ? ? ? ? ? ? ? ? ? ?syntax/parse >? ? ? ? ? ? ? ? ? ? ?racket/syntax)) > >(module+ test >? (require rackunit) >? (lazy-struct object (a b c)) >? (define obj (object #:loader (? (field) >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(printf "calculating ~a\n" field) >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?field))) >? (let ([out (open-output-string)]) >? ? (parameterize ([current-output-port out]) >? ? ? (check-equal? (get-output-string out) "") >? ? ? (check-equal? (object-a obj) 'a) >? ? ? (check-equal? (get-output-string out) "calculating a\n") >? ? ? (check-equal? (object-a obj) 'a) >? ? ? (check-equal? (get-output-string out) "calculating a\n") >? ? ? (check-match obj (object 'a 'b 'c)) >? ? ? (check-equal? (get-output-string out) "calculating a\ncalculating b\ncalculating c\n") >? ? ? (close-output-port out) >? ? ? )) >? ) > >(define-syntax lazy-struct >? (lambda (stx) >? ? (syntax-parse stx >? ? ? [(lazy-struct name:id (field:id ...) . options) >? ? ? ?#:with (~var struct:name) (format-id #'name "struct:~a" #'name #:source #'name) >? ? ? ?#:with name? (format-id #'name "~a?" #'name #:source #'name) >? ? ? ?#:with (name-field ...) (for/list ([field-id (in-list (syntax->list #'(field ...)))]) >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(format-id #'name "~a-~a" #'name field-id #:source #'name)) >? ? ? ?#:with (old-name-field ...) (generate-temporaries #'(name-field ...)) >? ? ? ?#'(splicing-local [(splicing-local [(struct name (field ...) . options)] >? ? ? ? ? ? ? ? ? ? ? ? ? ? (define old-name name) >? ? ? ? ? ? ? ? ? ? ? ? ? ? (define old-struct:name struct:name) >? ? ? ? ? ? ? ? ? ? ? ? ? ? (define old-name? name?) >? ? ? ? ? ? ? ? ? ? ? ? ? ? (define old-name-field name-field) >? ? ? ? ? ? ? ? ? ? ? ? ? ? ... >? ? ? ? ? ? ? ? ? ? ? ? ? ? (define (make-name #:loader loader) >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (old-name (delay (loader 'field)) ...)))] >? ? ? ? ? ?(define name? old-name?) >? ? ? ? ? ?(define struct:name old-struct:name) >? ? ? ? ? ?(define (name-field name) >? ? ? ? ? ? ?(force (old-name-field name))) >? ? ? ? ? ?... >? ? ? ? ? ?(define-syntax name >? ? ? ? ? ? ?(make-struct-desc #:descriptor #'struct:name >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#:constructor #'make-name >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#:predicate #'name? >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#:accessors (reverse (list #'name-field ...)) >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#:mutators (list (begin 'name-field #f) ...) >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#:super #t)))]))) > >(begin-for-syntax >? (define (make-struct-desc #:descriptor [descriptor-id #f] >? ? ? ? ? ? ? ? ? ? ? ? ? ? #:constructor constructor-id >? ? ? ? ? ? ? ? ? ? ? ? ? ? #:predicate [predicate-id #f] >? ? ? ? ? ? ? ? ? ? ? ? ? ? #:accessors [accessors '(#f)] >? ? ? ? ? ? ? ? ? ? ? ? ? ? #:mutators [mutators (map (? (x) #f) accessors)] >? ? ? ? ? ? ? ? ? ? ? ? ? ? #:super [super #f]) >? ? (with-syntax ([constructor constructor-id]) >? ? ? (proc+struct-info >? ? ? ?(lambda (stx) >? ? ? ? ?(syntax-parse stx >? ? ? ? ? ?[(name . stuff) >? ? ? ? ? ? (quasisyntax/loc stx >? ? ? ? ? ? ? (#,(syntax/loc #'name constructor) . stuff))] >? ? ? ? ? ?[name (syntax/loc stx constructor)])) >? ? ? ?(list descriptor-id constructor-id predicate-id accessors mutators super)))) >? (struct proc+struct-info (proc struct-info) #:transparent >? ? #:property prop:procedure (struct-field-index proc) >? ? #:property prop:struct-info (? (this) (proc+struct-info-struct-info this))) >? ) > > >On Aug 15, 2014, at 2:16 PM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>I want to have lazy-load struct. In C++ it is called proxy reference (when dereferencing return new (or cached) object loaded on demand) >> >>Ideally, it would be like >>(lazy-struct obj (a b c) #:loader load-data) >> >>then >> >>(define my-obj (make-ref obj "unique-id")) >> >>(displayln (obj-a my-obj)) ;; here content of my-obj should be loaded via load-data. >> >>And match pattern would also work. >> >>Now I made API with (get-field my-obj 'a), but is not Racketish. >> >>Fri, 15 Aug 2014 08:45:59 -0400 ?? "Alexander D. Knauth" < alexander at knauth.org >: >>> >>>Why not just define a new version of object-a that does that? >>>You probably have a good reason, but what is it? ? >>>Is it to change the result of struct->vector, allow (object a b c) as a match pattern to match ref, or what? ? >>> >>>On Aug 15, 2014, at 6:42 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>> >>>> I have >>>> (struct object (a b c)) >>>> (struct reference (id data)) >>>> ? >>>> Let `ref' -- an instance of `reference'. >>>> ? >>>> I want, that (object-a ref) call my own (ref-get object-a ref) >>>> ? >>>> (define (ref-get accessor ref) >>>> (unless (weak-box-value (ref-data ref)) >>>> (set-ref-data! ref (make-weak-box (load-data (ref-id ref))))) >>>> (accessor (weak-box-value (ref-data ref)))) >>>> ? >>>> Is it possible? ? >>>> I found `impersonate-struct', but it is not struct itself (no `id' field). ? >>>> I can add `prop:impersonator-of',. but how to redirect accessors? >>>> ? >>>> -- ? >>>> Roman Klochkov >>>> ____________________ >>>> Racket Users list: >>>> ? http://lists.racket-lang.org/users >>> >> >> >>-- ? >>Roman Klochkov -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Sat Aug 16 23:32:10 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sat, 16 Aug 2014 23:32:10 -0400 Subject: [racket] is there any way to check whether two syntax objects have the same ... ? Message-ID: <72FBCEC1-8A4C-46BA-80BD-8E1A32824868@knauth.org> Is there any way to check whether two syntax objects have the same lexical information, syntax-e (recursively), source location, properties, and whatever else they have, even if they aren?t eq? For the syntax-e and source-location this is straightforward, but if there?s no accessor for the lexical information then how do I check if the lexical information is the same if the syntax objects aren?t eq? And for the properties, can you only check the properties with keys that are interned symbols? From lotabout at gmail.com Sun Aug 17 05:03:53 2014 From: lotabout at gmail.com (Mark Wallace) Date: Sun, 17 Aug 2014 17:03:53 +0800 Subject: [racket] reference #:when clause in for/list? Message-ID: <53F06FF9.5090807@gmail.com> Consider the following pseudocode: (for/list ([i ...] #:when ) ) Can I bind that expression E and reference in the body of "for/list"? If expression E takes lots of time to finish, we would not want to compute it again :). I understand that there are workarounds like first collect all items of expression E and then use 'filter' to get interested items. However it would be a waste of memory if the number of interested items is small. So, any ideas? -- Best Regards, Mark Wallace. From daniel.a.prager at gmail.com Sun Aug 17 07:17:38 2014 From: daniel.a.prager at gmail.com (Daniel Prager) Date: Sun, 17 Aug 2014 21:17:38 +1000 Subject: [racket] reference #:when clause in for/list? In-Reply-To: <53F06FF9.5090807@gmail.com> References: <53F06FF9.5090807@gmail.com> Message-ID: Hi Mark Two ideas: 1. add a bit of state with for/list to save a reference to the expensive computation 2. filter-map keeps the reference more localised E.g. #lang racket (require math/number-theory) (define (mersenne-primes n) (let ([c 'dummy]) (for/list ([i n] #:when (begin (set! c (sub1 (expt 2 i))) (prime? c))) (list i c)))) (define (mersenne-primes-2 n) (filter-map (? (i) (let ([c (sub1 (expt 2 i))]) (and (prime? c) (list i c)))) (range n))) (mersenne-primes 128) (mersenne-primes-2 128) Dan On Sun, Aug 17, 2014 at 7:03 PM, Mark Wallace wrote: > Consider the following pseudocode: > > (for/list ([i ...] > #:when ) > ) > > Can I bind that expression E and reference in the body of "for/list"? > > If expression E takes lots of time to finish, we would not want to compute > it again :). > > I understand that there are workarounds like first collect all items of > expression E and then use 'filter' to get interested items. However it > would be a waste of memory if the number of interested items is small. > > So, any ideas? > > -- > Best Regards, > Mark Wallace. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From samth at cs.indiana.edu Sun Aug 17 07:59:13 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Sun, 17 Aug 2014 07:59:13 -0400 Subject: [racket] reference #:when clause in for/list? In-Reply-To: <53F06FF9.5090807@gmail.com> References: <53F06FF9.5090807@gmail.com> Message-ID: This is what 'in-value' is for. Sam On Aug 17, 2014 5:07 AM, "Mark Wallace" wrote: > Consider the following pseudocode: > > (for/list ([i ...] > #:when ) > ) > > Can I bind that expression E and reference in the body of "for/list"? > > If expression E takes lots of time to finish, we would not want to compute > it again :). > > I understand that there are workarounds like first collect all items of > expression E and then use 'filter' to get interested items. However it > would be a waste of memory if the number of interested items is small. > > So, any ideas? > > -- > Best Regards, > Mark Wallace. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lotabout at gmail.com Sun Aug 17 08:14:14 2014 From: lotabout at gmail.com (Mark Wallace) Date: Sun, 17 Aug 2014 20:14:14 +0800 Subject: [racket] reference #:when clause in for/list? In-Reply-To: References: <53F06FF9.5090807@gmail.com> Message-ID: <53F09C96.2040003@gmail.com> Thank Daniel and Sam! Below is a little conclusion: 1. When it comes to "for*/list", "in-values" can be used to introduce bindings just like "let". 2. "filter-map" can be a great alternative when "for/list" is considered. On 08/17/2014 07:59 PM, Sam Tobin-Hochstadt wrote: > This is what 'in-value' is for. > > Sam > > On Aug 17, 2014 5:07 AM, "Mark Wallace" > wrote: > > Consider the following pseudocode: > > (for/list ([i ...] > #:when ) > ) > > Can I bind that expression E and reference in the body of "for/list"? > > If expression E takes lots of time to finish, we would not want to > compute it again :). > > I understand that there are workarounds like first collect all items > of expression E and then use 'filter' to get interested items. > However it would be a waste of memory if the number of interested > items is small. > > So, any ideas? > > -- > Best Regards, > Mark Wallace. > ____________________ > Racket Users list: > http://lists.racket-lang.org/__users > > -- Best Regards, Mark Wallace. From daniel.a.prager at gmail.com Sun Aug 17 08:27:46 2014 From: daniel.a.prager at gmail.com (Daniel Prager) Date: Sun, 17 Aug 2014 22:27:46 +1000 Subject: [racket] reference #:when clause in for/list? In-Reply-To: <53F09C96.2040003@gmail.com> References: <53F06FF9.5090807@gmail.com> <53F09C96.2040003@gmail.com> Message-ID: Hi Mark 'in-value' -- which is new to me - thanks Sam! -- is cleaner than using a 'let' (or 'define') outside the for/list, hence preferable. Re-factoring my earlier example: (define (mersenne-primes-3 n) (for*/list ([i n] [c (in-value (sub1 (expt 2 i)))] #:when (prime? c)) (list i c))) Core Racketeers: Maybe add an 'in-values' example to the docs? Dan -------------- next part -------------- An HTML attachment was scrubbed... URL: From kalimehtar at mail.ru Sun Aug 17 13:31:23 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Sun, 17 Aug 2014 21:31:23 +0400 Subject: [racket] =?utf-8?q?is_there_any_way_to_check_whether_two_syntax_o?= =?utf-8?q?bjects_have_the_same_=2E=2E=2E_=3F?= In-Reply-To: <72FBCEC1-8A4C-46BA-80BD-8E1A32824868@knauth.org> References: <72FBCEC1-8A4C-46BA-80BD-8E1A32824868@knauth.org> Message-ID: <1408296682.420932664@f381.i.mail.ru> Maybe something of http://docs.racket-lang.org/reference/stxcmp.html ? Sat, 16 Aug 2014 23:32:10 -0400 ?? "Alexander D. Knauth" : >Is there any way to check whether two syntax objects have the same lexical information, syntax-e (recursively), source location, properties, and whatever else they have, even if they aren?t eq? > >For the syntax-e and source-location this is straightforward, but if there?s no accessor for the lexical information then how do I check if the lexical information is the same if the syntax objects aren?t eq? > >And for the properties, can you only check the properties with keys that are interned symbols? > > > >____________________ >??Racket Users list: >?? http://lists.racket-lang.org/users -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Sun Aug 17 14:02:09 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 17 Aug 2014 14:02:09 -0400 Subject: [racket] is there any way to check whether two syntax objects have the same ... ? In-Reply-To: <1408296682.420932664@f381.i.mail.ru> References: <72FBCEC1-8A4C-46BA-80BD-8E1A32824868@knauth.org> <1408296682.420932664@f381.i.mail.ru> Message-ID: But those only work on identifiers, right? But would something like this work? (define (lexical-context=? s1 s2) (bound-identifier=? (datum->syntax s1 ?x) (datum->syntax s2 ?x))) Or would that miss something? On Aug 17, 2014, at 1:31 PM, Roman Klochkov wrote: > Maybe something of > > http://docs.racket-lang.org/reference/stxcmp.html > > ? > > > Sat, 16 Aug 2014 23:32:10 -0400 ?? "Alexander D. Knauth" : > Is there any way to check whether two syntax objects have the same lexical information, syntax-e (recursively), source location, properties, and whatever else they have, even if they aren?t eq? > > For the syntax-e and source-location this is straightforward, but if there?s no accessor for the lexical information then how do I check if the lexical information is the same if the syntax objects aren?t eq? > > And for the properties, can you only check the properties with keys that are interned symbols? > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > -- > Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From carl.eastlund at gmail.com Sun Aug 17 14:29:18 2014 From: carl.eastlund at gmail.com (Carl Eastlund) Date: Sun, 17 Aug 2014 14:29:18 -0400 Subject: [racket] is there any way to check whether two syntax objects have the same ... ? In-Reply-To: References: <72FBCEC1-8A4C-46BA-80BD-8E1A32824868@knauth.org> <1408296682.420932664@f381.i.mail.ru> Message-ID: Comparing lexical context is a very involved process. Remember that every syntax object potentially carries context for an unbounded number of symbol names at an unbounded number of phases, since context information can be transferred freely. Comparing all of them for equivalence would be quite expensive. You probably want to either decide what subset of that context is relevant to you, or reformulate your solution in a way that does not involve comparing syntax at all. It's a problematic technique to employ, to say the very least. On Aug 17, 2014 12:02 PM, "Alexander D. Knauth" wrote: > But those only work on identifiers, right? > > But would something like this work? > > (define (lexical-context=? s1 s2) > (bound-identifier=? (datum->syntax s1 ?x) (datum->syntax s2 ?x))) > > Or would that miss something? > > > > On Aug 17, 2014, at 1:31 PM, Roman Klochkov wrote: > > Maybe something of > > http://docs.racket-lang.org/reference/stxcmp.html > > > ? > > > Sat, 16 Aug 2014 23:32:10 -0400 ?? "Alexander D. Knauth" < > alexander at knauth.org>: > > Is there any way to check whether two syntax objects have the same lexical > information, syntax-e (recursively), source location, properties, and > whatever else they have, even if they aren?t eq? > > For the syntax-e and source-location this is straightforward, but if > there?s no accessor for the lexical information then how do I check if the > lexical information is the same if the syntax objects aren?t eq? > > And for the properties, can you only check the properties with keys that > are interned symbols? > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > > -- > Roman Klochkov > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Sun Aug 17 15:58:08 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 17 Aug 2014 15:58:08 -0400 Subject: [racket] is there any way to check whether two syntax objects have the same ... ? In-Reply-To: References: <72FBCEC1-8A4C-46BA-80BD-8E1A32824868@knauth.org> <1408296682.420932664@f381.i.mail.ru> Message-ID: <7D58AD28-4E35-47DD-BB04-1367D9D29FFF@knauth.org> On Aug 17, 2014, at 2:29 PM, Carl Eastlund wrote: > Comparing lexical context is a very involved process. Remember that every syntax object potentially carries context for an unbounded number of symbol names at an unbounded number of phases, since context information can be transferred freely. Comparing all of them for equivalence would be quite expensive. You probably want to either decide what subset of that context is relevant to you, or reformulate your solution in a way that does not involve comparing syntax at all. It's a problematic technique to employ, to say the very least. > Well, if what I want to do is a sort of syntax-object memoizing, where I do something like this: #lang racket/base (require (for-syntax racket/base)) (module+ test (require rackunit)) (begin-for-syntax (define (syntax=? s1 s2) ....) (define (make-stx-dict) (stx-dict '())) (struct stx-dict ([alist #:mutable]) #:transparent) (define (stx-dict-ref! stx-dict key to-set) (define alist (stx-dict-alist stx-dict)) (define maybe-pair (assoc key alist syntax=?)) (if maybe-pair (cdr maybe-pair) (let ([new-val (to-set)]) (set-stx-dict-alist! stx-dict (cons (cons key new-val) alist)) new-val))) ) (define-syntax m (let ([stx-dict (make-stx-dict)]) (lambda (stx) (define sym (stx-dict-ref! stx-dict (syntax-local-introduce stx) gensym)) (with-syntax ([sym (datum->syntax stx sym)]) (syntax 'sym))))) (module+ test (define-syntax chk (lambda (stx) (with-syntax ([expr #'(m)]) #`(begin (check-not-equal? (m) (m)) (check-equal? expr expr) (check-equal? #,(syntax-local-introduce #'expr) #,(syntax-local-introduce #'expr)) (check-not-equal? expr #,(syntax-local-introduce #'expr)))))) (chk) ) > On Aug 17, 2014 12:02 PM, "Alexander D. Knauth" wrote: > But those only work on identifiers, right? > > But would something like this work? > > (define (lexical-context=? s1 s2) > (bound-identifier=? (datum->syntax s1 ?x) (datum->syntax s2 ?x))) > > Or would that miss something? > > > > On Aug 17, 2014, at 1:31 PM, Roman Klochkov wrote: > >> Maybe something of >> >> http://docs.racket-lang.org/reference/stxcmp.html >> >> ? >> >> >> Sat, 16 Aug 2014 23:32:10 -0400 ?? "Alexander D. Knauth" : >> Is there any way to check whether two syntax objects have the same lexical information, syntax-e (recursively), source location, properties, and whatever else they have, even if they aren?t eq? >> >> For the syntax-e and source-location this is straightforward, but if there?s no accessor for the lexical information then how do I check if the lexical information is the same if the syntax objects aren?t eq? >> >> And for the properties, can you only check the properties with keys that are interned symbols? >> >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users >> >> >> -- >> Roman Klochkov > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From zeppieri at gmail.com Mon Aug 18 23:44:11 2014 From: zeppieri at gmail.com (Jon Zeppieri) Date: Mon, 18 Aug 2014 23:44:11 -0400 Subject: [racket] struct generics and mutual dependencies Message-ID: Say I want to do basically the following, except with larger, more complicated generic interfaces: ```racket #lang racket/base (require racket/generic) (define-generics ->foo-provider (->foo ->foo-provider)) (define-generics ->bar-provider (->bar ->bar-provider)) (struct foo (x) #:methods gen:->foo-provider [(define (->foo f) f)] #:methods gen:->bar-provider [(define (->bar f) (bar (foo-x f)))]) (struct bar (x) #:methods gen:->foo-provider [(define (->foo b) (foo (bar-x b)))] #:methods gen:->bar-provider [(define (->bar b) b)]) ``` That is, I want to have struct types that can use generic methods to construct instances of one another. Since the actual struct types are rather more complicated than this example, I'd really like to split up their implementations into separate modules. If I weren't using generics, this would be straightforward; I'd put the struct type definitions themselves in a module, or set of modules, and I'd put the operations in modules specific to their respective struct types. The modules containing the operations would be able to require all of the struct type definitions, so they could freely construct instances of one another. In the present case, however, the method implementations need to be defined along with the struct type definition. I can't do something like: ``` [(define ->foo bar->foo)] ``` ... where bar->foo comes from a bar-specific module, because that would lead to a circular dependency (bar->foo needs the foo constructor, which is defined in this module, while this module needs bar->foo). I could work around this with mutable bindings (either at the module level or, better, in method dispatch), but I'm not fond of either approach. With the right structure inspector maybe (?) it would be possible to modify whatever dispatch table is actually used, but that sounds hairy. I guess I'm wondering if some other trick is possible here. -Jon From zeppieri at gmail.com Tue Aug 19 01:29:39 2014 From: zeppieri at gmail.com (Jon Zeppieri) Date: Tue, 19 Aug 2014 01:29:39 -0400 Subject: [racket] struct generics and mutual dependencies In-Reply-To: References: Message-ID: I do see another option. I could use either the #:defaults or #fast-defaults options to define-generics to separate the struct type definitions from the methods. I'm not sure if this is a legitimate use of the feature or an abuse. -J On Mon, Aug 18, 2014 at 11:44 PM, Jon Zeppieri wrote: > Say I want to do basically the following, except with larger, more > complicated generic interfaces: > > ```racket > #lang racket/base > > (require racket/generic) > > (define-generics ->foo-provider > (->foo ->foo-provider)) > > (define-generics ->bar-provider > (->bar ->bar-provider)) > > (struct foo (x) > #:methods gen:->foo-provider > [(define (->foo f) f)] > > #:methods gen:->bar-provider > [(define (->bar f) (bar (foo-x f)))]) > > (struct bar (x) > #:methods gen:->foo-provider > [(define (->foo b) (foo (bar-x b)))] > > #:methods gen:->bar-provider > [(define (->bar b) b)]) > ``` > > That is, I want to have struct types that can use generic methods to > construct instances of one another. Since the actual struct types are > rather more complicated than this example, I'd really like to split up > their implementations into separate modules. If I weren't using > generics, this would be straightforward; I'd put the struct type > definitions themselves in a module, or set of modules, and I'd put the > operations in modules specific to their respective struct types. The > modules containing the operations would be able to require all of the > struct type definitions, so they could freely construct instances of > one another. > > In the present case, however, the method implementations need to be > defined along with the struct type definition. I can't do something > like: > > ``` > [(define ->foo bar->foo)] > ``` > ... where bar->foo comes from a bar-specific module, because that > would lead to a circular dependency (bar->foo needs the foo > constructor, which is defined in this module, while this module needs > bar->foo). > > I could work around this with mutable bindings (either at the module > level or, better, in method dispatch), but I'm not fond of either > approach. With the right structure inspector maybe (?) it would be > possible to modify whatever dispatch table is actually used, but that > sounds hairy. I guess I'm wondering if some other trick is possible > here. > > -Jon From neil at neilvandyke.org Tue Aug 19 05:03:03 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Tue, 19 Aug 2014 05:03:03 -0400 Subject: [racket] base64 decoding Message-ID: <53F312C7.4020601@neilvandyke.org> Has anyone written a faster Base64 decode than in the "net/base64" module? ("base64-decode-stream" is suffering when tens of MB are run through it. Perhaps due in part to whatever overhead the input port has. The code looks pretty good. I'd probably have to try using block reads to reduce calls for the port abstractions, and also make a variant that works directly on byte strings without ports. Just checking whether someone has already done this.) Neil V. From kalimehtar at mail.ru Tue Aug 19 08:32:33 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Tue, 19 Aug 2014 16:32:33 +0400 Subject: [racket] =?utf-8?q?Struct_=26_match_magick?= Message-ID: <1408451553.140735391@f376.i.mail.ru> #lang racket (require (for-syntax racket racket/struct-info)) (struct foo (a b)) (set! foo-a (let ([old foo-a]) ? ? ? ? ? ? ? ? ? ? ? ? ? (? (x) (displayln x) (old x)))) (define t (foo 1 2)) (displayln "Before change") (match t [(foo a b) a]) (let-syntax ([foo (extract-struct-info (syntax-local-value #'foo))]) ? ?(displayln "After change") ? ?(match t [(foo a b) a])) Gives: Before change 1 After change # 1 So, resetting foo to the same struct-info enable calling modified foo-a. But why? Besides, if it is inevitable, how to redefine (like set!) the syntax? -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From kalimehtar at mail.ru Tue Aug 19 08:40:01 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Tue, 19 Aug 2014 16:40:01 +0400 Subject: [racket] =?utf-8?q?struct_generics_and_mutual_dependencies?= In-Reply-To: References: Message-ID: <1408452001.194475786@f376.i.mail.ru> Recommended way for mutual dependencies is to use units: http://docs.racket-lang.org/guide/units.html You may define struct accessors as unit exports/imports and then link them Mon, 18 Aug 2014 23:44:11 -0400 ?? Jon Zeppieri : >Say I want to do basically the following, except with larger, more >complicated generic interfaces: > >```racket >#lang racket/base > >(require racket/generic) > >(define-generics ->foo-provider >??(->foo ->foo-provider)) > >(define-generics ->bar-provider >??(->bar ->bar-provider)) > >(struct foo (x) >??#:methods gen:->foo-provider >??[(define (->foo f) f)] > >??#:methods gen:->bar-provider >??[(define (->bar f) (bar (foo-x f)))]) > >(struct bar (x) >??#:methods gen:->foo-provider >??[(define (->foo b) (foo (bar-x b)))] > >??#:methods gen:->bar-provider >??[(define (->bar b) b)]) >``` > >That is, I want to have struct types that can use generic methods to >construct instances of one another. Since the actual struct types are >rather more complicated than this example, I'd really like to split up >their implementations into separate modules. If I weren't using >generics, this would be straightforward; I'd put the struct type >definitions themselves in a module, or set of modules, and I'd put the >operations in modules specific to their respective struct types. The >modules containing the operations would be able to require all of the >struct type definitions, so they could freely construct instances of >one another. > >In the present case, however, the method implementations need to be >defined along with the struct type definition. I can't do something >like: > >``` >[(define ->foo bar->foo)] >``` >... where bar->foo comes from a bar-specific module, because that >would lead to a circular dependency (bar->foo needs the foo >constructor, which is defined in this module, while this module needs >bar->foo). > >I could work around this with mutable bindings (either at the module >level or, better, in method dispatch), but I'm not fond of either >approach. With the right structure inspector maybe (?) it would be >possible to modify whatever dispatch table is actually used, but that >sounds hairy. I guess I'm wondering if some other trick is possible >here. > >-Jon >____________________ >??Racket Users list: >?? http://lists.racket-lang.org/users -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From samth at cs.indiana.edu Tue Aug 19 09:35:48 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Tue, 19 Aug 2014 09:35:48 -0400 Subject: [racket] Struct & match magick In-Reply-To: <1408451553.140735391@f376.i.mail.ru> References: <1408451553.140735391@f376.i.mail.ru> Message-ID: On Tue, Aug 19, 2014 at 8:32 AM, Roman Klochkov wrote: > #lang racket > (require (for-syntax racket racket/struct-info)) > (struct foo (a b)) > (set! foo-a (let ([old foo-a]) > (? (x) (displayln x) (old x)))) > (define t (foo 1 2)) > > (displayln "Before change") > (match t [(foo a b) a]) In this code, `match` looks at `foo`, and sees that it's definitely a struct descriptor created by `struct`, and so that it knows that `t` will really be an instance of `foo`. Then it generates code that uses `unsafe-struct-ref` to extract the fields. That's why it never uses the modified `foo-a`. To check this, it uses the `checked-struct-info?` predicate. > > (let-syntax ([foo (extract-struct-info (syntax-local-value #'foo))]) > (displayln "After change") > (match t [(foo a b) a])) In this code, `match` can't be sure that `foo` refers to a real struct, so it just treats the struct info as describing some procedures and a predicate, and it generates the "obvious" code, which calls `foo-a`, which you've modified. I could change `match` so that it also uses `variable-reference-mutated?` for all of the identifiers where it uses checked struct info, and so behaves the same in both cases. However, I'd prefer to reject the first program instead, by hiding `foo-a` behind a macro that rejects assignment. Sam From gustavo at oma.org.ar Tue Aug 19 09:38:08 2014 From: gustavo at oma.org.ar (Gustavo Massaccesi) Date: Tue, 19 Aug 2014 10:38:08 -0300 Subject: [racket] base64 decoding In-Reply-To: <53F312C7.4020601@neilvandyke.org> References: <53F312C7.4020601@neilvandyke.org> Message-ID: I used base64 a few years ago, but only for short string, so I didn't do anything fancy. My problem was that there are millions of base64 variants, and I just needed one that is different from the standard. Standard: AZaz09+/ Filename compatible: AZaz09-_ for crypt/bcrypt: ./AZaz09 for regular expressions: AZaz!- ... It would be useful that the base64 functions have a optional named argument that specifies the encoding. I think that the better format is a string of 64 characters, because there are just too many variants out there. The most common variants should be included in the library. (And there are still the differences with the padding and line length options ... ) Gustavo On Tue, Aug 19, 2014 at 6:03 AM, Neil Van Dyke wrote: > Has anyone written a faster Base64 decode than in the "net/base64" module? > > ("base64-decode-stream" is suffering when tens of MB are run through it. > Perhaps due in part to whatever overhead the input port has. The code looks > pretty good. I'd probably have to try using block reads to reduce calls for > the port abstractions, and also make a variant that works directly on byte > strings without ports. Just checking whether someone has already done > this.) > > Neil V. > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From matthias at ccs.neu.edu Tue Aug 19 10:37:59 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Tue, 19 Aug 2014 10:37:59 -0400 Subject: [racket] big-bang bug when creating racket distribution executable? In-Reply-To: <17C36348-F17D-4164-8EF1-04BB52D7883F@ccs.neu.edu> References: <58ADFB0A-93F3-4ABD-BE97-5433A54ABEEE@gmail.com> <17C36348-F17D-4164-8EF1-04BB52D7883F@ccs.neu.edu> Message-ID: I have fixed the bug, thanks to a thorough code review with Robby. The next release of DrRacket will create executables for big-bang (and universe) programs whose window remains open after stop-when (or equivalent action) halt the execution. If you are eager to test this, you may wish to try it in one of the nightly builds from NWU or Utah tomorrow. Thanks for reporting -- Matthias On Aug 4, 2014, at 12:31 PM, Matthias Felleisen wrote: > > I can confirm the behavior, which is visible under both *SL and Racket and all methods for creating executable. > > For a workaround, use this for now: > > #lang racket/gui > > (require 2htdp/universe 2htdp/image) > > (define (render ws) ws) > > (define (halt ws) #t) > > (big-bang (rectangle 600 400 'solid 'gold) > (to-draw render) > (stop-when halt render)) > > (yield (make-semaphore)) > > -- Matthias > > > > > On Aug 4, 2014, at 11:39 AM, Kevin Forchione wrote: > >> When you run big-bang in Dr Racket and the stop-when evaluates true the window remains open to display the final image (when specified) and must be manually closed by the user. However, running the racket executable created for distribution closes the window and returns you to terminal as soon as stop-when is returns true, thus bringing the execution to a jarring halt without adequately displaying the final image (it?s hard to tell whether it displays because the action is so quick). This appears to be the case for both Windows and Mac installers. Is this a bug or how the process is designed to work? >> >> Below is a link to some very basic racket code and a mac installer to demonstrate the effect: >> >> https://dl.dropboxusercontent.com/u/4859392/test5.rkt >> >> https://dl.dropboxusercontent.com/u/4859392/test5.dmg >> >> If this is how it?s designed to work, then stop-when, for executable distribution is probably not a desired handler for what I?m intending, as I seldom want the window to close automatically when big-bang terminates, but would prefer the user to close the window manually. I can probably achieve this with some finagling of the world state, but the two different behaviors between Dr Racket and distribution was surprising. >> >> ?Kevin >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > From zeppieri at gmail.com Tue Aug 19 10:34:30 2014 From: zeppieri at gmail.com (Jon Zeppieri) Date: Tue, 19 Aug 2014 10:34:30 -0400 Subject: [racket] struct generics and mutual dependencies In-Reply-To: <1408452001.194475786@f376.i.mail.ru> References: <1408452001.194475786@f376.i.mail.ru> Message-ID: Could you elaborate, maybe provide an example? I'm not sure what you have in mind. -Jon On Tue, Aug 19, 2014 at 8:40 AM, Roman Klochkov wrote: > Recommended way for mutual dependencies is to use units: > > http://docs.racket-lang.org/guide/units.html > > You may define struct accessors as unit exports/imports and then link them > > > Mon, 18 Aug 2014 23:44:11 -0400 ?? Jon Zeppieri : > > Say I want to do basically the following, except with larger, more > complicated generic interfaces: > > ```racket > #lang racket/base > > (require racket/generic) > > (define-generics ->foo-provider > (->foo ->foo-provider)) > > (define-generics ->bar-provider > (->bar ->bar-provider)) > > (struct foo (x) > #:methods gen:->foo-provider > [(define (->foo f) f)] > > #:methods gen:->bar-provider > [(define (->bar f) (bar (foo-x f)))]) > > (struct bar (x) > #:methods gen:->foo-provider > [(define (->foo b) (foo (bar-x b)))] > > #:methods gen:->bar-provider > [(define (->bar b) b)]) > ``` > > That is, I want to have struct types that can use generic methods to > construct instances of one another. Since the actual struct types are > rather more complicated than this example, I'd really like to split up > their implementations into separate modules. If I weren't using > generics, this would be straightforward; I'd put the struct type > definitions themselves in a module, or set of modules, and I'd put the > operations in modules specific to their respective struct types. The > modules containing the operations would be able to require all of the > struct type definitions, so they could freely construct instances of > one another. > > In the present case, however, the method implementations need to be > defined along with the struct type definition. I can't do something > like: > > ``` > [(define ->foo bar->foo)] > ``` > ... where bar->foo comes from a bar-specific module, because that > would lead to a circular dependency (bar->foo needs the foo > constructor, which is defined in this module, while this module needs > bar->foo). > > I could work around this with mutable bindings (either at the module > level or, better, in method dispatch), but I'm not fond of either > approach. With the right structure inspector maybe (?) it would be > possible to modify whatever dispatch table is actually used, but that > sounds hairy. I guess I'm wondering if some other trick is possible > here. > > -Jon > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > > -- > Roman Klochkov From kalimehtar at mail.ru Tue Aug 19 10:45:38 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Tue, 19 Aug 2014 18:45:38 +0400 Subject: [racket] =?utf-8?q?Persistent_struct_API?= In-Reply-To: References: <1408451553.140735391@f376.i.mail.ru> Message-ID: <1408459538.894111552@f70.i.mail.ru> So you mean, that struct should be only struct, not like Common Lisp CLOS or C++ classes, that are "anything with fields". Then I need an advice. I want to make persistent structs. There are several options: 1) Build "`struct?' with #:reader and #:writer options". Then I have to make a struct, redefine accessors and mutators and somehow tell (match ...) that it is not genuine struct (I don't know, how to redefine syntax). 2) Build my own persistent-struct, that is not `struct?'. Then it cannont be used where strut? may be used and I have to write own match-expander. 3) Don't mimic struct. Maybe classes. What would you advice? What is more correct? Tue, 19 Aug 2014 09:35:48 -0400 ?? Sam Tobin-Hochstadt : >On Tue, Aug 19, 2014 at 8:32 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >> #lang racket >> (require (for-syntax racket racket/struct-info)) >> (struct foo (a b)) >> (set! foo-a (let ([old foo-a]) >> (? (x) (displayln x) (old x)))) >> (define t (foo 1 2)) >> >> (displayln "Before change") >> (match t [(foo a b) a]) > >In this code, `match` looks at `foo`, and sees that it's definitely a >struct descriptor created by `struct`, and so that it knows that `t` >will really be an instance of `foo`. Then it generates code that uses >`unsafe-struct-ref` to extract the fields. That's why it never uses >the modified `foo-a`. To check this, it uses the >`checked-struct-info?` predicate. > >> >> (let-syntax ([foo (extract-struct-info (syntax-local-value #'foo))]) >> (displayln "After change") >> (match t [(foo a b) a])) > >In this code, `match` can't be sure that `foo` refers to a real >struct, so it just treats the struct info as describing some >procedures and a predicate, and it generates the "obvious" code, which >calls `foo-a`, which you've modified. > >I could change `match` so that it also uses >`variable-reference-mutated?` for all of the identifiers where it uses >checked struct info, and so behaves the same in both cases. However, >I'd prefer to reject the first program instead, by hiding `foo-a` >behind a macro that rejects assignment. > >Sam -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From samth at cs.indiana.edu Tue Aug 19 10:52:23 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Tue, 19 Aug 2014 10:52:23 -0400 Subject: [racket] Persistent struct API In-Reply-To: <1408459538.894111552@f70.i.mail.ru> References: <1408451553.140735391@f376.i.mail.ru> <1408459538.894111552@f70.i.mail.ru> Message-ID: First, for persistence, can you use either prefab structs or the serialize library? If you can't, what I'd do is implement a generic called `persist` using `racket/generic`, and then have all the structs you wanted to be persistent implement that generic. Sam On Tue, Aug 19, 2014 at 10:45 AM, Roman Klochkov wrote: > So you mean, that struct should be only struct, not like Common Lisp CLOS or > C++ classes, that are "anything with fields". > > Then I need an advice. I want to make persistent structs. There are several > options: > > 1) Build "`struct?' with #:reader and #:writer options". Then I have to make > a struct, redefine accessors and mutators and somehow tell (match ...) that > it is not genuine struct (I don't know, how to redefine syntax). > > 2) Build my own persistent-struct, that is not `struct?'. Then it cannont be > used where strut? may be used and I have to write own match-expander. > > 3) Don't mimic struct. Maybe classes. > > What would you advice? What is more correct? > > > Tue, 19 Aug 2014 09:35:48 -0400 ?? Sam Tobin-Hochstadt > : > > On Tue, Aug 19, 2014 at 8:32 AM, Roman Klochkov wrote: >> #lang racket >> (require (for-syntax racket racket/struct-info)) >> (struct foo (a b)) >> (set! foo-a (let ([old foo-a]) >> (? (x) (displayln x) (old x)))) >> (define t (foo 1 2)) >> >> (displayln "Before change") >> (match t [(foo a b) a]) > > In this code, `match` looks at `foo`, and sees that it's definitely a > struct descriptor created by `struct`, and so that it knows that `t` > will really be an instance of `foo`. Then it generates code that uses > `unsafe-struct-ref` to extract the fields. That's why it never uses > the modified `foo-a`. To check this, it uses the > `checked-struct-info?` predicate. > >> >> (let-syntax ([foo (extract-struct-info (syntax-local-value #'foo))]) >> (displayln "After change") >> (match t [(foo a b) a])) > > In this code, `match` can't be sure that `foo` refers to a real > struct, so it just treats the struct info as describing some > procedures and a predicate, and it generates the "obvious" code, which > calls `foo-a`, which you've modified. > > I could change `match` so that it also uses > `variable-reference-mutated?` for all of the identifiers where it uses > checked struct info, and so behaves the same in both cases. However, > I'd prefer to reject the first program instead, by hiding `foo-a` > behind a macro that rejects assignment. > > Sam > > > > -- > Roman Klochkov From kalimehtar at mail.ru Tue Aug 19 11:10:25 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Tue, 19 Aug 2014 19:10:25 +0400 Subject: [racket] =?utf-8?q?Persistent_struct_API?= In-Reply-To: References: <1408451553.140735391@f376.i.mail.ru> <1408459538.894111552@f70.i.mail.ru> Message-ID: <1408461025.998529353@f70.i.mail.ru> Serialize is good for one-shot import/export. By persistence I mean possibility to get objects from persistent storage by reference on-demand. For example I have facebook-like site: (persistent-struct user (login password photo ...)) (persistent-struct message (user text seen-by)) If i read concrete message for its text, I don't want to pull all user information for its author and list of users, that have seen the message. Then I need to make load only references to these users. But when I write (user-login (message-user the-message)), the library must make in field user real struct from reference (and memoize it). I tried to use impersonator, but it doesn't allow to have own fields in impersonator (and prop:impersonator-of doesn't replace accessors). generic doesn't add accessors to fields. It only gives common function for different structs. Tue, 19 Aug 2014 10:52:23 -0400 ?? Sam Tobin-Hochstadt : >First, for persistence, can you use either prefab structs or the >serialize library? > >If you can't, what I'd do is implement a generic called `persist` >using `racket/generic`, and then have all the structs you wanted to be >persistent implement that generic. > >Sam > >On Tue, Aug 19, 2014 at 10:45 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >> So you mean, that struct should be only struct, not like Common Lisp CLOS or >> C++ classes, that are "anything with fields". >> >> Then I need an advice. I want to make persistent structs. There are several >> options: >> >> 1) Build "`struct?' with #:reader and #:writer options". Then I have to make >> a struct, redefine accessors and mutators and somehow tell (match ...) that >> it is not genuine struct (I don't know, how to redefine syntax). >> >> 2) Build my own persistent-struct, that is not `struct?'. Then it cannont be >> used where strut? may be used and I have to write own match-expander. >> >> 3) Don't mimic struct. Maybe classes. >> >> What would you advice? What is more correct? >> >> >> Tue, 19 Aug 2014 09:35:48 -0400 ?? Sam Tobin-Hochstadt >> < samth at cs.indiana.edu >: >> >> On Tue, Aug 19, 2014 at 8:32 AM, Roman Klochkov < kalimehtar at mail.ru > wrote: >>> #lang racket >>> (require (for-syntax racket racket/struct-info)) >>> (struct foo (a b)) >>> (set! foo-a (let ([old foo-a]) >>> (? (x) (displayln x) (old x)))) >>> (define t (foo 1 2)) >>> >>> (displayln "Before change") >>> (match t [(foo a b) a]) >> >> In this code, `match` looks at `foo`, and sees that it's definitely a >> struct descriptor created by `struct`, and so that it knows that `t` >> will really be an instance of `foo`. Then it generates code that uses >> `unsafe-struct-ref` to extract the fields. That's why it never uses >> the modified `foo-a`. To check this, it uses the >> `checked-struct-info?` predicate. >> >>> >>> (let-syntax ([foo (extract-struct-info (syntax-local-value #'foo))]) >>> (displayln "After change") >>> (match t [(foo a b) a])) >> >> In this code, `match` can't be sure that `foo` refers to a real >> struct, so it just treats the struct info as describing some >> procedures and a predicate, and it generates the "obvious" code, which >> calls `foo-a`, which you've modified. >> >> I could change `match` so that it also uses >> `variable-reference-mutated?` for all of the identifiers where it uses >> checked struct info, and so behaves the same in both cases. However, >> I'd prefer to reject the first program instead, by hiding `foo-a` >> behind a macro that rejects assignment. >> >> Sam >> >> >> >> -- >> Roman Klochkov -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From neil.toronto at gmail.com Tue Aug 19 13:32:55 2014 From: neil.toronto at gmail.com (Neil Toronto) Date: Tue, 19 Aug 2014 13:32:55 -0400 Subject: [racket] Typed classes: how to send to a value with union type Message-ID: <53F38A47.6020200@gmail.com> I'm making a snip in Typed Racket. I have essentially this: (define admin (send this get-admin)) (define editor (and admin (send admin get-editor))) (when editor (send editor set-caret-owner #f)) I get this error: Type Checker: send: type mismatch expected: an object given: (U (Instance Text%) (Instance Pasteboard%)) in: (send editor set-caret-owner #f) It's unexpected in the first place because text% and pasteboard% both implement editor<%>. Guarding with (is-a? editor text%) doesn't work. Casting doesn't work because TR can't generate a contract. How do I do this? Neil ? From alexander at knauth.org Tue Aug 19 14:48:22 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Tue, 19 Aug 2014 14:48:22 -0400 Subject: [racket] Typed classes: how to send to a value with union type In-Reply-To: <53F38A47.6020200@gmail.com> References: <53F38A47.6020200@gmail.com> Message-ID: <687E7FDA-74AF-4D7F-9F5E-C1D54B3C5226@knauth.org> This works fine for me in version 6.1.0.5: #lang typed/racket (require typed/racket/snip) (define snip (new snip%)) (define admin (send snip get-admin)) (define editor (and admin (send admin get-editor))) (when editor (send editor set-caret-owner #f)) On Aug 19, 2014, at 1:32 PM, Neil Toronto wrote: > I'm making a snip in Typed Racket. I have essentially this: > > (define admin (send this get-admin)) > (define editor (and admin (send admin get-editor))) > (when editor > (send editor set-caret-owner #f)) > > I get this error: > > Type Checker: send: type mismatch > expected: an object > given: (U (Instance Text%) (Instance Pasteboard%)) in: > (send editor set-caret-owner #f) > > It's unexpected in the first place because text% and pasteboard% both implement editor<%>. Guarding with (is-a? editor text%) doesn't work. Casting doesn't work because TR can't generate a contract. How do I do this? > > Neil ? > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From asumu at ccs.neu.edu Tue Aug 19 15:39:45 2014 From: asumu at ccs.neu.edu (Asumu Takikawa) Date: Tue, 19 Aug 2014 15:39:45 -0400 Subject: [racket] Typed classes: how to send to a value with union type In-Reply-To: <687E7FDA-74AF-4D7F-9F5E-C1D54B3C5226@knauth.org> References: <53F38A47.6020200@gmail.com> <687E7FDA-74AF-4D7F-9F5E-C1D54B3C5226@knauth.org> Message-ID: <20140819193945.GJ20640@localhost> On 2014-08-19 14:48:22 -0400, Alexander D. Knauth wrote: > This works fine for me in version 6.1.0.5: > #lang typed/racket > (require typed/racket/snip) > (define snip (new snip%)) > (define admin (send snip get-admin)) > (define editor (and admin (send admin get-editor))) > (when editor > (send editor set-caret-owner #f)) Yes, I think this was fixed in commit 7743386eec4f5d752f5f87dab52e2da43bd11926. Cheers, Asumu From lotabout at gmail.com Tue Aug 19 21:50:06 2014 From: lotabout at gmail.com (Mark Wallace) Date: Wed, 20 Aug 2014 09:50:06 +0800 Subject: [racket] bug? bit-vector equal problem Message-ID: <53F3FECE.4050501@gmail.com> It seems that "equal?" misbehave on bit-vectors when the size is less then 9. Below is a small test case that show this bug? maybe. Can you guys help to test whether it's only happening on my machine? #lang racket (require data/bit-vector) (define bv1 (make-bit-vector 8 #t)) (define bv2 (make-bit-vector 8 #f)) (equal? bv1 bv2) ; => #t (bit-vector-set! bv1 5 #f) (equal? bv1 bv2) ; => #t (define bv3 (make-bit-vector 9 #t)) (define bv4 (make-bit-vector 9 #f)) (equal? bv3 bv4) ; => #f (bit-vector-set! bv3 5 #f) (equal? bv3 bv4) ; => #f Racket version: $ racket --version Welcome to Racket v6.0. $ uname -a Linux darkstar 3.10.30 #2 SMP Fri Feb 14 19:46:22 CST 2014 x86_64 Intel(R) Core(TM) i3-2120 CPU @ 3.30GHz GenuineIntel GNU/Linux From greghendershott at gmail.com Tue Aug 19 22:44:33 2014 From: greghendershott at gmail.com (Greg Hendershott) Date: Tue, 19 Aug 2014 22:44:33 -0400 Subject: [racket] bug? bit-vector equal problem In-Reply-To: <53F3FECE.4050501@gmail.com> References: <53F3FECE.4050501@gmail.com> Message-ID: I can repro it on 6.1.0.3. Looking at bit-vector.rkt, it seems the problem might be the "TODO" comment here: (serializable-struct bit-vector (words size) .... #:methods gen:equal+hash [(define (equal-proc x y recursive-equal?) (let ([vx (bit-vector-words x)] [vy (bit-vector-words y)] [nx (bit-vector-size x)] [ny (bit-vector-size y)]) (and (= nx ny) (for/and ([index (in-range (- (bytes-length vx) 1))]) (eq? (bytes-ref vx index) (bytes-ref vy index))) ; TODO: check last word ))) .... But, you say, you're using equal? Although I'm not familiar with gen:equal+hash, it must be that equal? checks for and uses that. (I say "must" because I know that equal? always returns #f for a non #:transparent struct. Since you're getting #t, at all, it can't be plain equal?.) From samth at cs.indiana.edu Tue Aug 19 22:58:54 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Tue, 19 Aug 2014 22:58:54 -0400 Subject: [racket] bug? bit-vector equal problem In-Reply-To: References: <53F3FECE.4050501@gmail.com> Message-ID: On Tue, Aug 19, 2014 at 10:44 PM, Greg Hendershott wrote: > > But, you say, you're using equal? Although I'm not familiar with > gen:equal+hash, it must be that equal? checks for and uses that. Yep: http://docs.racket-lang.org/reference/booleans.html?q=equal%3F#%28def._%28%28quote._~23~25kernel%29._equal~3f%29%29 Sam From greghendershott at gmail.com Tue Aug 19 23:11:12 2014 From: greghendershott at gmail.com (Greg Hendershott) Date: Tue, 19 Aug 2014 23:11:12 -0400 Subject: [racket] bug? bit-vector equal problem In-Reply-To: References: <53F3FECE.4050501@gmail.com> Message-ID: I submitted a PR with a suggested fix: https://github.com/plt/racket/pull/756 > Looking at bit-vector.rkt, it seems the problem might be the "TODO" > comment here: > > (serializable-struct bit-vector (words size) > .... > #:methods gen:equal+hash > [(define (equal-proc x y recursive-equal?) > (let ([vx (bit-vector-words x)] > [vy (bit-vector-words y)] > [nx (bit-vector-size x)] > [ny (bit-vector-size y)]) > (and (= nx ny) > (for/and ([index (in-range (- (bytes-length vx) 1))]) > (eq? (bytes-ref vx index) > (bytes-ref vy index))) > ; TODO: check last word > ))) > .... From lysseus at gmail.com Wed Aug 20 01:44:57 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Tue, 19 Aug 2014 22:44:57 -0700 Subject: [racket] contracts questions Message-ID: Hi guys, In an attempt to tighten up my code I started using the raise-xxxx-error feature and then began looking at contracts. I like the concept and think it would lead to cleaner looking code But I have two questions: Why does list? allow a vector in the following contract? Also, how do I indicate an optional (in this case keyword) argument? (I?m assuming I?d have to define a contract to handle the valid exact-nonnegative-integer/range for the index, unless there is one already defined. I?ll have a go at that later. ) #lang racket (provide (contract-out (insert-at (list? exact-nonnegative-integer? any/c . -> . any)))) (define (insert-at lst index val #:splice (splice #f)) #;(unless (list? lst) (raise-argument-error 'insert-at "list?" lst)) #;(uqnless (exact-nonnegative-integer? index) (raise-argument-error 'insert-at "exact-nonnegative-integer?" index)) #;(unless (<= index (length lst)) (raise-range-error 'insert-at "list" "" index lst 0 (length lst))) #;(unless (boolean? splice) (raise-argument-error 'insert-at "boolean?" splice)) (define-values (head tail) (split-at lst index)) (append head (cond [(and splice (cons? val)) val] [else (list val)]) tail)) >(insert-at #(a b) 0 ?c) '(c . #(a b)) Thanks! -Kevin From kalimehtar at mail.ru Wed Aug 20 03:02:24 2014 From: kalimehtar at mail.ru (=?UTF-8?B?Um9tYW4gS2xvY2hrb3Y=?=) Date: Wed, 20 Aug 2014 11:02:24 +0400 Subject: [racket] =?utf-8?q?contracts_questions?= In-Reply-To: References: Message-ID: <1408518144.940845442@f257.i.mail.ru> > Why does list? allow a vector in the following contract?? Contract in `provide' is used only when you `require' your module from other. If you want always test it, use define/contract > Also, how do I indicate an optional (in this case keyword) argument? http://docs.racket-lang.org/reference/function-contracts.html#%28form._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._-~3e%2A%29%29 (->* (list??exact-nonnegative-integer?) (#:splice boolean?) any) Tue, 19 Aug 2014 22:44:57 -0700 ?? Kevin Forchione : >Hi guys, >In an attempt to tighten up my code I started using the raise-xxxx-error feature and then began looking at contracts. I like the concept and think it would lead to cleaner looking code But I have two questions: > >Why does list? allow a vector in the following contract? Also, how do I indicate an optional (in this case keyword) argument? > >(I?m assuming I?d have to define a contract to handle the valid exact-nonnegative-integer/range for the index, unless there is one already defined. I?ll have a go at that later. ) > >#lang racket > >(provide (contract-out >??????????(insert-at (list? exact-nonnegative-integer? any/c . -> . any)))) > >(define (insert-at lst index val #:splice (splice #f)) >??#;(unless (list? lst) >????(raise-argument-error 'insert-at "list?" lst)) >??#;(uqnless (exact-nonnegative-integer? index) >????(raise-argument-error 'insert-at "exact-nonnegative-integer?" index)) >??#;(unless (<= index (length lst)) >????(raise-range-error 'insert-at "list" "" index lst 0 (length lst))) >??#;(unless (boolean? splice) >????(raise-argument-error 'insert-at "boolean?" splice)) >?? >??(define-values (head tail) (split-at lst index)) >??(append head >??????????(cond >????????????[(and splice (cons? val)) val] >????????????[else (list val)]) >??????????tail)) > >>(insert-at #(a b) 0 ?c) >'(c . #(a b)) > >Thanks! > >-Kevin > > >____________________ >??Racket Users list: >?? http://lists.racket-lang.org/users -- Roman Klochkov -------------- next part -------------- An HTML attachment was scrubbed... URL: From sperber at deinprogramm.de Wed Aug 20 08:17:15 2014 From: sperber at deinprogramm.de (Michael Sperber) Date: Wed, 20 Aug 2014 14:17:15 +0200 Subject: [racket] Commercial Users of Functional Programming at ICFP 2014, Gothenburg, Sep 4-6 Message-ID: ****************************************************************** CALL FOR PARTICIPATION Commercial Users of Functional Programming (CUFP) 2014 at ICFP 2014; Gothenburg, Sweden, Sep 4-6. ****************************************************************** Overview ======== Functional programming has been at the forefront of a new generation of programming technologies: Companies employing functional programming use it to enable more effective, robust, and flexible software development. The annual CUFP workshop is designed to serve the growing community of commercial users of functional programming: Practitioners meet and collaborate; language designers and users can share ideas about the future of their languages; experts share their expertise on practical functional programming. CUFP 2014 begins with two days of tutorials by top-notch language experts including advanced tutorials on special topics, followed by a day of talks about industrial applications of functional programming. More information about CUFP 2014 is available on the CUFP web site at http://cufp.org/2014/ Registration is available at: https://regmaster4.com/2014conf/ICFP14/register.php TUTORIALS, SEPTEMBER 4 ====================== T1: Programming with Dependent Types Ulf Norell T2: Haskell in the Real World Stefan Wehr T3: Intro to Elm: a field guide for functional front-end programming (Part 1) Evan Czaplicki & Spiros Eliopoulos T4: Elm-d3: Front-end Development without Frameworks (Part 2) Spiros Eliopoulos T5: Idris: Practical Software Verification with Dependent Types Edwin Brady T6: Lens Edward Kmett TUTORIALS, SEPTEMBER 5 ====================== T7: Introduction to OCaml Leo White & Jeremy Yallop T8: Programming in Rust Felix Klock & Lars Bergstrom T9: Tinkering with the Raspberry Pi using Erlang Torben Hoffmann T10: Hands-on Functional Web Development in F# with WebSharper Adam Granicz T11: Batteries Included: Generative Programming with Scala and LMS Tiark Rompf & Nada Amin T12: Introduction to testing with QuickCheck John Hughes TALKS, SEPTEMBER 6 ================== Keynote: Making Money From FP Joe Armstrong, Ericsson and Royal Institute of Technology in Stockholm Functional Programming at Verizon OnCue Timothy Perrett, Verizon Adopting Functional Programming with OCaml at Bloomberg LP Maxime Ransan, Bloomberg LP MBrace: large-scale programming in F# Eirik Tsarpalis, Nessos Probabilistic Synchronization of State Between Independent Nodes Erlend Hamberg Towards "annex", a Fact Based Dependency System Mark Hibberd Building data and time-series analytics tools for F# Tomas Petricek & Howard Mansell Haskell in the Misson Control Domain Michael Oswald Haskell tools for satellite operations Bj??rn Buckwalter F# For Fun and Games Anthony Brown Some usages of functional programming for FO and quants Renaud Bechade Reactive I/O with Scala, Akka, and Play Kenneth Owens, Comcast If your server is a function, is your company a library? Andrew Cowie From mansour.alqattan at gmail.com Wed Aug 20 08:54:24 2014 From: mansour.alqattan at gmail.com (Mansour Alqattan) Date: Wed, 20 Aug 2014 13:54:24 +0100 Subject: [racket] Assembly X86 Self Contained Code Message-ID: Hello, Is there a software can fix the bugs and security vulnerabilities on assembly X86 ?? if yes, what kind of assembly can fix? is it libc-functions code or fully self contained same as the attachment file "fakt.asm code". I have heard that if we want to get a self contained code, we need to compile it static, then look at the assembly dump.I think the flag is -static to gcc. Then gcc will bring the wanted code out from libc into your code. And if I want 16-bit code I think I need to be on a 32-bit OS, like Windows 98. Then run gcc and tell it to output 16-bit code. I am not sure of the flag, maybe -m16. As I actually need the Assembly X86 - 16 bit and 32 bit fully self contained to analyse source code and binaries, identifying programming bugs that can result in system crashes, memory corruption, leaks, data races, and security vulnerabilities. *My questions are:* Do you know how to get Assembly X86 - 16 bit and 32 bit fully self contained same as the attachment.? if yes can you tell me how. Do you have examples on Assembly X86 - 16 bit and 32 bit fully self contained which have bugs and security vulnerabilities? If yes code you provide me some examples. Do you know a software can convert the Assembly X86 libc-functions code to Assembly X86 - 16 bit and 32 bit fully self contained? Is there a way to convert the Assembly X86 libc-functions code to Assembly X86 - 16 bit and 32 bit fully self contained? Do you know a software can fix the bugs and security vulnerabilities on assembly X86 - 16 bit and 32 bit fully self contained?? Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: fakt.asm Type: application/octet-stream Size: 586 bytes Desc: not available URL: From lysseus at gmail.com Wed Aug 20 11:18:11 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Wed, 20 Aug 2014 08:18:11 -0700 Subject: [racket] big-bang bug when creating racket distribution executable? In-Reply-To: References: <58ADFB0A-93F3-4ABD-BE97-5433A54ABEEE@gmail.com> <17C36348-F17D-4164-8EF1-04BB52D7883F@ccs.neu.edu> Message-ID: <9A0599B6-5FB0-4597-A6B9-4F353F33710F@gmail.com> On Aug 19, 2014, at 7:37 AM, Matthias Felleisen wrote: > > I have fixed the bug, thanks to a thorough code review with Robby. The next release of DrRacket will create executables for big-bang (and universe) programs whose window remains open after stop-when (or equivalent action) halt the execution. > > If you are eager to test this, you may wish to try it in one of the nightly builds from NWU or Utah tomorrow. > > Thanks for reporting -- Matthias Wonderful! I?ll download the fix and test it out! Thanks! -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From spdegabrielle at gmail.com Wed Aug 20 12:14:56 2014 From: spdegabrielle at gmail.com (Stephen De Gabrielle) Date: Wed, 20 Aug 2014 17:14:56 +0100 Subject: [racket] Cognicast on Racket & RacketCon In-Reply-To: <20140813194451.BE1F265018F@mail-svr1.cs.utah.edu> References: <20140813194451.BE1F265018F@mail-svr1.cs.utah.edu> Message-ID: Great interview. Did I hear right? Are you currently a visiting scholar with MS research in the uk? I'd love to know if you are doing any talks while here in the UK as I won't be able to go to racketcon. Kind regards, Stephen On Wednesday, 13 August 2014, Matthew Flatt wrote: > I enjoyed chatting with Craig Andera about Racket and RacketCon on the > Cognicast: > > http://blog.cognitect.com/cognicast/061-matthew-flatt > > The idea is to to get out the word on RacketCon, so please share with > anyone who might be interested. > > And if you haven't heard of the Cognicast before, you'll see that the > above link is episode 61, so there's lots more to listen to. > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -- Sent from Gmail Mobile -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander at knauth.org Wed Aug 20 13:27:52 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Wed, 20 Aug 2014 13:27:52 -0400 Subject: [racket] struct generics and mutual dependencies In-Reply-To: References: Message-ID: <1C0A4248-A309-454B-A433-F66C1D0BD1A5@knauth.org> I think you can also do it with lazy-require: #lang racket/base (module generics racket/base (provide (all-defined-out)) (require racket/generic) (define-generics ->foo-provider (->foo ->foo-provider)) (define-generics ->bar-provider (->bar ->bar-provider))) (module foo racket/base (provide (struct-out foo)) (require racket/lazy-require (submod ".." generics)) (lazy-require [(submod ".." bar) (bar)]) (struct foo (x) #:methods gen:->foo-provider [(define (->foo f) f)] #:methods gen:->bar-provider [(define (->bar f) (bar (foo-x f)))])) (module bar racket/base (provide (struct-out bar)) (require (submod ".." generics) (submod ".." foo)) (struct bar (x) #:methods gen:->foo-provider [(define (->foo b) (foo (bar-x b)))] #:methods gen:->bar-provider [(define (->bar b) b)])) (module+ test (require rackunit) (require (submod ".." generics) (submod ".." foo) (submod ".." bar)) (check-equal? (foo-x (->foo (bar 1))) 1) (check-equal? (bar-x (->bar (foo 1))) 1)) On Aug 18, 2014, at 11:44 PM, Jon Zeppieri wrote: > Say I want to do basically the following, except with larger, more > complicated generic interfaces: > > ```racket > #lang racket/base > > (require racket/generic) > > (define-generics ->foo-provider > (->foo ->foo-provider)) > > (define-generics ->bar-provider > (->bar ->bar-provider)) > > (struct foo (x) > #:methods gen:->foo-provider > [(define (->foo f) f)] > > #:methods gen:->bar-provider > [(define (->bar f) (bar (foo-x f)))]) > > (struct bar (x) > #:methods gen:->foo-provider > [(define (->foo b) (foo (bar-x b)))] > > #:methods gen:->bar-provider > [(define (->bar b) b)]) > ``` > > That is, I want to have struct types that can use generic methods to > construct instances of one another. Since the actual struct types are > rather more complicated than this example, I'd really like to split up > their implementations into separate modules. If I weren't using > generics, this would be straightforward; I'd put the struct type > definitions themselves in a module, or set of modules, and I'd put the > operations in modules specific to their respective struct types. The > modules containing the operations would be able to require all of the > struct type definitions, so they could freely construct instances of > one another. > > In the present case, however, the method implementations need to be > defined along with the struct type definition. I can't do something > like: > > ``` > [(define ->foo bar->foo)] > ``` > ... where bar->foo comes from a bar-specific module, because that > would lead to a circular dependency (bar->foo needs the foo > constructor, which is defined in this module, while this module needs > bar->foo). > > I could work around this with mutable bindings (either at the module > level or, better, in method dispatch), but I'm not fond of either > approach. With the right structure inspector maybe (?) it would be > possible to modify whatever dispatch table is actually used, but that > sounds hairy. I guess I'm wondering if some other trick is possible > here. > > -Jon > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From iamfakemail at yandex.ru Wed Aug 20 14:16:07 2014 From: iamfakemail at yandex.ru (seryojka) Date: Wed, 20 Aug 2014 23:16:07 +0500 Subject: [racket] strange behaviour of class inspector Message-ID: <53F4E5E7.7090100@yandex.ru> Hello, I can't understand why does my program produce an error. The code should be readable enough to get the crux of the issue. #lang racket/base (require racket/class) (define some<%> (interface () ;; method ; ok [method (->m any)] ; fails for contracted method )) (define some-mixin (mixin () (some<%>) (super-new) (inspect #f) (define/public (method) 'value))) (define cls% (class (some-mixin object%) (super-new) (inspect #f) (define/public (info) (class-info this%)))) (send (new cls%) info) => class-info: current inspector cannot inspect class class: # context...: From stamourv at ccs.neu.edu Wed Aug 20 15:00:33 2014 From: stamourv at ccs.neu.edu (Vincent St-Amour) Date: Wed, 20 Aug 2014 15:00:33 -0400 Subject: [racket] struct generics and mutual dependencies In-Reply-To: References: Message-ID: <87lhqjdm0e.wl%stamourv@ccs.neu.edu> We added these options to allow retrofitting methods on already defined types. We've used it to break cyclic dependencies inside the standard library, so I'd say it's the right way to do what you're trying to do. Vincent At Tue, 19 Aug 2014 01:29:39 -0400, Jon Zeppieri wrote: > > I do see another option. I could use either the #:defaults or > #fast-defaults options to define-generics to separate the struct type > definitions from the methods. I'm not sure if this is a legitimate use > of the feature or an abuse. -J > > > On Mon, Aug 18, 2014 at 11:44 PM, Jon Zeppieri wrote: > > Say I want to do basically the following, except with larger, more > > complicated generic interfaces: > > > > ```racket > > #lang racket/base > > > > (require racket/generic) > > > > (define-generics ->foo-provider > > (->foo ->foo-provider)) > > > > (define-generics ->bar-provider > > (->bar ->bar-provider)) > > > > (struct foo (x) > > #:methods gen:->foo-provider > > [(define (->foo f) f)] > > > > #:methods gen:->bar-provider > > [(define (->bar f) (bar (foo-x f)))]) > > > > (struct bar (x) > > #:methods gen:->foo-provider > > [(define (->foo b) (foo (bar-x b)))] > > > > #:methods gen:->bar-provider > > [(define (->bar b) b)]) > > ``` > > > > That is, I want to have struct types that can use generic methods to > > construct instances of one another. Since the actual struct types are > > rather more complicated than this example, I'd really like to split up > > their implementations into separate modules. If I weren't using > > generics, this would be straightforward; I'd put the struct type > > definitions themselves in a module, or set of modules, and I'd put the > > operations in modules specific to their respective struct types. The > > modules containing the operations would be able to require all of the > > struct type definitions, so they could freely construct instances of > > one another. > > > > In the present case, however, the method implementations need to be > > defined along with the struct type definition. I can't do something > > like: > > > > ``` > > [(define ->foo bar->foo)] > > ``` > > ... where bar->foo comes from a bar-specific module, because that > > would lead to a circular dependency (bar->foo needs the foo > > constructor, which is defined in this module, while this module needs > > bar->foo). > > > > I could work around this with mutable bindings (either at the module > > level or, better, in method dispatch), but I'm not fond of either > > approach. With the right structure inspector maybe (?) it would be > > possible to modify whatever dispatch table is actually used, but that > > sounds hairy. I guess I'm wondering if some other trick is possible > > here. > > > > -Jon > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From zeppieri at gmail.com Wed Aug 20 15:19:39 2014 From: zeppieri at gmail.com (Jon Zeppieri) Date: Wed, 20 Aug 2014 15:19:39 -0400 Subject: [racket] struct generics and mutual dependencies In-Reply-To: <87lhqjdm0e.wl%stamourv@ccs.neu.edu> References: <87lhqjdm0e.wl%stamourv@ccs.neu.edu> Message-ID: Thanks, Vincent. I'll go with that. -J On Wed, Aug 20, 2014 at 3:00 PM, Vincent St-Amour wrote: > We added these options to allow retrofitting methods on already defined > types. We've used it to break cyclic dependencies inside the standard > library, so I'd say it's the right way to do what you're trying to do. > > Vincent > > > At Tue, 19 Aug 2014 01:29:39 -0400, > Jon Zeppieri wrote: >> >> I do see another option. I could use either the #:defaults or >> #fast-defaults options to define-generics to separate the struct type >> definitions from the methods. I'm not sure if this is a legitimate use >> of the feature or an abuse. -J >> >> >> On Mon, Aug 18, 2014 at 11:44 PM, Jon Zeppieri wrote: >> > Say I want to do basically the following, except with larger, more >> > complicated generic interfaces: >> > >> > ```racket >> > #lang racket/base >> > >> > (require racket/generic) >> > >> > (define-generics ->foo-provider >> > (->foo ->foo-provider)) >> > >> > (define-generics ->bar-provider >> > (->bar ->bar-provider)) >> > >> > (struct foo (x) >> > #:methods gen:->foo-provider >> > [(define (->foo f) f)] >> > >> > #:methods gen:->bar-provider >> > [(define (->bar f) (bar (foo-x f)))]) >> > >> > (struct bar (x) >> > #:methods gen:->foo-provider >> > [(define (->foo b) (foo (bar-x b)))] >> > >> > #:methods gen:->bar-provider >> > [(define (->bar b) b)]) >> > ``` >> > >> > That is, I want to have struct types that can use generic methods to >> > construct instances of one another. Since the actual struct types are >> > rather more complicated than this example, I'd really like to split up >> > their implementations into separate modules. If I weren't using >> > generics, this would be straightforward; I'd put the struct type >> > definitions themselves in a module, or set of modules, and I'd put the >> > operations in modules specific to their respective struct types. The >> > modules containing the operations would be able to require all of the >> > struct type definitions, so they could freely construct instances of >> > one another. >> > >> > In the present case, however, the method implementations need to be >> > defined along with the struct type definition. I can't do something >> > like: >> > >> > ``` >> > [(define ->foo bar->foo)] >> > ``` >> > ... where bar->foo comes from a bar-specific module, because that >> > would lead to a circular dependency (bar->foo needs the foo >> > constructor, which is defined in this module, while this module needs >> > bar->foo). >> > >> > I could work around this with mutable bindings (either at the module >> > level or, better, in method dispatch), but I'm not fond of either >> > approach. With the right structure inspector maybe (?) it would be >> > possible to modify whatever dispatch table is actually used, but that >> > sounds hairy. I guess I'm wondering if some other trick is possible >> > here. >> > >> > -Jon >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users From lysseus at gmail.com Wed Aug 20 15:47:00 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Wed, 20 Aug 2014 12:47:00 -0700 Subject: [racket] contracts questions In-Reply-To: <1408518144.940845442@f257.i.mail.ru> References: <1408518144.940845442@f257.i.mail.ru> Message-ID: <4A2C1FFE-8B59-44ED-B7CB-8B976329BB4C@gmail.com> On Aug 20, 2014, at 12:02 AM, Roman Klochkov wrote: > > Why does list? allow a vector in the following contract? > > Contract in `provide' is used only when you `require' your module from other. If you want always test it, use define/contract > > > Also, how do I indicate an optional (in this case keyword) argument? > > http://docs.racket-lang.org/reference/function-contracts.html#%28form._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._-~3e%2A%29%29 > > (->* (list? exact-nonnegative-integer?) (#:splice boolean?) any) Thanks! That got me started. This looks much better than what the raise-xxxx-error approach: ;; subseq: list number number -> list ;; returns the list of length len starting from pos elements of lst. ;; ;; Examples: ;; ;; > (subseq '(a b c d e f g) 3 2) ;; '(d e) (define/contract (subseq lst pos (len (- (length lst) pos))) ; Contract (man ...) (opt ...) (result) (->i ([lst list?] [pos (lst) (integer-in 0 (length lst))]) ([len (lst pos) (integer-in 0 (- (length lst) pos))]) (result list?)) (take (drop lst pos) len)) -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Wed Aug 20 16:34:38 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Wed, 20 Aug 2014 14:34:38 -0600 Subject: [racket] Cognicast on Racket & RacketCon In-Reply-To: References: <20140813194451.BE1F265018F@mail-svr1.cs.utah.edu> Message-ID: <20140820203440.2845E65018D@mail-svr1.cs.utah.edu> I was in Cambridge for a few months, but I've just now returned to Utah. You didn't miss any talks from me. :) At Wed, 20 Aug 2014 17:14:56 +0100, Stephen De Gabrielle wrote: > Great interview. > > Did I hear right? Are you currently a visiting scholar with MS research in > the uk? > > I'd love to know if you are doing any talks while here in the UK as I won't > be able to go to racketcon. > > Kind regards, > > Stephen > > On Wednesday, 13 August 2014, Matthew Flatt wrote: > > > I enjoyed chatting with Craig Andera about Racket and RacketCon on the > > Cognicast: > > > > http://blog.cognitect.com/cognicast/061-matthew-flatt > > > > The idea is to to get out the word on RacketCon, so please share with > > anyone who might be interested. > > > > And if you haven't heard of the Cognicast before, you'll see that the > > above link is episode 61, so there's lots more to listen to. > > > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > > > -- > Sent from Gmail Mobile From robby at eecs.northwestern.edu Wed Aug 20 22:31:58 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Wed, 20 Aug 2014 21:31:58 -0500 Subject: [racket] contracts questions In-Reply-To: <4A2C1FFE-8B59-44ED-B7CB-8B976329BB4C@gmail.com> References: <1408518144.940845442@f257.i.mail.ru> <4A2C1FFE-8B59-44ED-B7CB-8B976329BB4C@gmail.com> Message-ID: Kevin: one thing to keep in mind when working with contracts is that they come with a notion of a boundary -- this is critical for proper blame assignment; without being able to divide up your program into different pieces, blame assignment cannot point to a specific piece. When you use define/contract, the boundary is drawn around that single definition, excluding the rest of the file. When you use 'contract-out' in a provide, the boundary is drawn around the entire module. Usually, but not always, the module is a more natural division, especially if you keep your modules relatively small. This is why you didn't see any contract checking at the REPL with the code from your earlier message; the REPL counts as "inside" the module. hth, Robby On Wed, Aug 20, 2014 at 2:47 PM, Kevin Forchione wrote: > > On Aug 20, 2014, at 12:02 AM, Roman Klochkov wrote: > >> Why does list? allow a vector in the following contract? > > Contract in `provide' is used only when you `require' your module from > other. If you want always test it, use define/contract > >> Also, how do I indicate an optional (in this case keyword) argument? > > http://docs.racket-lang.org/reference/function-contracts.html#%28form._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._-~3e%2A%29%29 > > (->* (list? exact-nonnegative-integer?) (#:splice boolean?) any) > > > Thanks! That got me started. This looks much better than what the > raise-xxxx-error approach: > > ;; subseq: list number number -> list > ;; returns the list of length len starting from pos elements of lst. > ;; > ;; Examples: > ;; > ;; > (subseq '(a b c d e f g) 3 2) > ;; '(d e) > (define/contract (subseq lst pos (len (- (length lst) pos))) > ; Contract (man ...) (opt ...) (result) > (->i ([lst list?] [pos (lst) (integer-in 0 (length lst))]) > ([len (lst pos) (integer-in 0 (- (length lst) pos))]) > (result list?)) > (take (drop lst pos) len)) > > -Kevin > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From hirotaka.niitsuma at gmail.com Wed Aug 20 22:58:41 2014 From: hirotaka.niitsuma at gmail.com (Niitsuma Hirotaka) Date: Thu, 21 Aug 2014 11:58:41 +0900 Subject: [racket] using Python from Racket Message-ID: I wrote interface for python https://github.com/niitsuma/pyjsonrpcembd example usage https://github.com/niitsuma/pyjsonrpcembd/blob/master/example/example-racket.rkt ========= (pyinit) (pystr "str(3*4)") (pystrexec "print(3*4)") (pystrexec "import nltk") (pystrexec "import numpy") (pystrexec "print(numpy.array([3,4]))") (pystr "3*4") (string->jsexpr (pyjson "{\"method\": \"min\", \"params\": [[9, 3 , 7]]}")) ;;=> 3 (string->jsexpr (pyjson "{\"method\": \"range\", \"params\": [2,6]}")) ;; =>'(2 3 4 5) (string->jsexpr (pyjson (jsexpr->string (make-hash ' ((method . "range") ( params . (2 6))))))) ;;=> '(2 3 4 5) (pystr "_") ;"[2, 3, 4, 5]" (pystrexec "x=[3,4]") (string->jsexpr (pystr "x*2")) From marco at neniu.org Thu Aug 21 12:22:29 2014 From: marco at neniu.org (Marco Monteiro) Date: Thu, 21 Aug 2014 17:22:29 +0100 Subject: [racket] Understanding error in use of submodule in my language Message-ID: Hello! I'm using Racket 6.1 I'm trying to understand this error. I'm using submodules in a language I defined. The language file is here: http://pastebin.com/7RiHHRmi Notice the commented out line 28. I use that language in the following code http://pastebin.com/Qa6RD9wF raco expanding this last file fails with module: duplicate submodule definition at: configure-runtime in: module context...: /usr/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:29:11: loop /usr/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt: [running body] /usr/share/racket/collects/raco/raco.rkt: [running body] /usr/share/racket/collects/raco/main.rkt: [running body] If I uncomment line 28 it no longer fails. If I use (module ...) instead of (module* ...) it no longer fails independently of line 28 being commented out or not. Trying to macro expand that in drracket gives me "Internal error: car: contract violation ." error. What is happending here? Thanks, Marco -------------- next part -------------- An HTML attachment was scrubbed... URL: From spencerflorence at gmail.com Thu Aug 21 14:33:20 2014 From: spencerflorence at gmail.com (Spencer florence) Date: Thu, 21 Aug 2014 11:33:20 -0700 (PDT) Subject: [racket] Macro Stepper with custom languages Message-ID: <1408645999204.0c5ced38@Nodemailer> Hi all, I?m currently making a custom language in racket. For some reason DrRacket does not give me a macro stepper button with my language, although it does for other custom languages like ?#lang honu? or ?#lang datalog? do get the macro stepper. What do I need to do to convince DrRacket to give me the stepper? ?Spencer -------------- next part -------------- An HTML attachment was scrubbed... URL: From robby at eecs.northwestern.edu Thu Aug 21 21:55:49 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Thu, 21 Aug 2014 20:55:49 -0500 Subject: [racket] Macro Stepper with custom languages In-Reply-To: <1408645999204.0c5ced38@Nodemailer> References: <1408645999204.0c5ced38@Nodemailer> Message-ID: What does this expression return, where you replace #lang racket with #lang spenlang (or pop-pl I suppose): > ((read-language (open-input-string "#lang racket")) 'drracket:opt-out-toolbar-buttons '()) If it raises an error, that would explain what's going on. Robby On Thu, Aug 21, 2014 at 1:33 PM, Spencer florence wrote: > Hi all, > > I?m currently making a custom language in racket. For some reason DrRacket > does not give me a macro stepper button with my language, although it does > for other custom languages like ?#lang honu? or ?#lang datalog? do get the > macro stepper. > > What do I need to do to convince DrRacket to give me the stepper? > > ?Spencer > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From lysseus at gmail.com Fri Aug 22 00:44:36 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Thu, 21 Aug 2014 21:44:36 -0700 Subject: [racket] contracts questions In-Reply-To: References: <1408518144.940845442@f257.i.mail.ru> <4A2C1FFE-8B59-44ED-B7CB-8B976329BB4C@gmail.com> Message-ID: On Aug 20, 2014, at 7:31 PM, Robby Findler wrote: > Kevin: one thing to keep in mind when working with contracts is that > they come with a notion of a boundary -- this is critical for proper > blame assignment; without being able to divide up your program into > different pieces, blame assignment cannot point to a specific piece. > > When you use define/contract, the boundary is drawn around that single > definition, excluding the rest of the file. When you use > 'contract-out' in a provide, the boundary is drawn around the entire > module. Usually, but not always, the module is a more natural > division, especially if you keep your modules relatively small. > > This is why you didn't see any contract checking at the REPL with the > code from your earlier message; the REPL counts as "inside? the > module. Thanks for pointing that out. After further reading and some experimenting with both contract-out and define/contract I see what is meant about the boundaries and the ?blame? and have moved my contracts into the provide as it would provide the level of feedback I desire. Fantastic! -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From dcherkassov at gmail.com Fri Aug 22 06:58:51 2014 From: dcherkassov at gmail.com (Dmitry Cherkassov) Date: Fri, 22 Aug 2014 14:58:51 +0400 Subject: [racket] Setting exception handler for GUI message loop Message-ID: Hi! Is it possible to set an exception handler to GUI message loop, so that any exception thrown in GUI thread can be handled? -- With best regards, Dmitry From mflatt at cs.utah.edu Fri Aug 22 08:53:47 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 06:53:47 -0600 Subject: [racket] package builds, updated daily Message-ID: <20140822125349.2E5B165019A@mail-svr1.cs.utah.edu> The site http://pkg-build.racket-lang.org/ reports the result of a daily build of all packages that are listed at "pkgs.racket-lang.org". The builds use the current release of Racket (version 6.1), and the site includes documentation for packages that build successfully. We expect to get these results --- especially links to the built documentation --- added to "pkgs.racket-lang.org" in the near future. One caveat: A package fails to install if it depends on a PLaneT package, even if it references the compatibility variant from "planet-compats.racket-lang.org". That limitation could be removed with more work, but I haven't done that work because I think it's better to get all packages that we care about onto "pkgs.racket-lang.org". The packages are not built from scratch each day. Instead, each package that has changed is rebuilt, along with any package that declares a dependency on a changed package. The build service relies on virtual-machine instances to sandbox package builds. The implementation of the build service is `meta/pkg-build/main` in the Racket repo's "plt-services" package, and I'm happy to provide more details if anyone is interested. From samth at cs.indiana.edu Fri Aug 22 09:13:52 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Fri, 22 Aug 2014 09:13:52 -0400 Subject: [racket] package builds, updated daily In-Reply-To: <20140822125349.2E5B165019A@mail-svr1.cs.utah.edu> References: <20140822125349.2E5B165019A@mail-svr1.cs.utah.edu> Message-ID: On Fri, Aug 22, 2014 at 8:53 AM, Matthew Flatt wrote: > The site > > http://pkg-build.racket-lang.org/ > > reports the result of a daily build of all packages that are listed at > "pkgs.racket-lang.org". The builds use the current release of Racket > (version 6.1), and the site includes documentation for packages that > build successfully. What should happen for packages that require an unreleased version of Racket (such as "misc1" and its dependencies)? Right now they fail to build, but it would be nice to have documentation for them. Sam From laurent.orseau at gmail.com Fri Aug 22 09:20:39 2014 From: laurent.orseau at gmail.com (Laurent) Date: Fri, 22 Aug 2014 15:20:39 +0200 Subject: [racket] package builds, updated daily In-Reply-To: <20140822125349.2E5B165019A@mail-svr1.cs.utah.edu> References: <20140822125349.2E5B165019A@mail-svr1.cs.utah.edu> Message-ID: That's awesome! Thank you Matthew and those who made this possible, this no doubt improves a lot the usability of packages. Laurent On Fri, Aug 22, 2014 at 2:53 PM, Matthew Flatt wrote: > The site > > http://pkg-build.racket-lang.org/ > > reports the result of a daily build of all packages that are listed at > "pkgs.racket-lang.org". The builds use the current release of Racket > (version 6.1), and the site includes documentation for packages that > build successfully. > > We expect to get these results --- especially links to the built > documentation --- added to "pkgs.racket-lang.org" in the near future. > > > One caveat: A package fails to install if it depends on a PLaneT > package, even if it references the compatibility variant from > "planet-compats.racket-lang.org". That limitation could be removed with > more work, but I haven't done that work because I think it's better to > get all packages that we care about onto "pkgs.racket-lang.org". > > > The packages are not built from scratch each day. Instead, each package > that has changed is rebuilt, along with any package that declares a > dependency on a changed package. The build service relies on > virtual-machine instances to sandbox package builds. The implementation > of the build service is `meta/pkg-build/main` in the Racket repo's > "plt-services" package, and I'm happy to provide more details if anyone > is interested. > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Fri Aug 22 10:29:16 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 08:29:16 -0600 Subject: [racket] package builds, updated daily In-Reply-To: References: <20140822125349.2E5B165019A@mail-svr1.cs.utah.edu> Message-ID: <20140822142918.E3B4C65019A@mail-svr1.cs.utah.edu> At Fri, 22 Aug 2014 09:13:52 -0400, Sam Tobin-Hochstadt wrote: > On Fri, Aug 22, 2014 at 8:53 AM, Matthew Flatt wrote: > > The site > > > > http://pkg-build.racket-lang.org/ > > > > reports the result of a daily build of all packages that are listed at > > "pkgs.racket-lang.org". The builds use the current release of Racket > > (version 6.1), and the site includes documentation for packages that > > build successfully. > > What should happen for packages that require an unreleased version of > Racket (such as "misc1" and its dependencies)? Right now they fail to > build, but it would be nice to have documentation for them. If there's a branch or commit of a package that works with v6.1, and if the author of the package registers that branch/commit as source of the package when requested for version "6.1", then the package-build service will pick up that branch/commit and the build can succeed. The package author can register a core-version-specific source at "pkgs.racket-lang.org" through the package-configuration dialog's "version exception" field. ---------------------------------------- Stepping back, there are different possible modes for working with Racket and packages: working with the very latest of everything, working with the most recent release of the Racket core but the latest versions of packages, working with a snapshot of packages taken at the most recent release, and so on. In general, the way to select a different mode is to use a particular package catalog. Different catalogs can implement different modes and policies. (A Racket distribution selects a mode through its default package-catalog configuration. For example, a distribution from "download.racket-lang.org" consults a catalog that supplies a snapshot of some packages and defers to "pkgs.racket-lang.org" for others. The subset of packages in the release snapshot is currently the packages that are in the main Racket repo, but that's evolving.) The "pkgs.racket-lang.org" catalog is mainly set up for "the very latest of everything", but it tries to provide "the latest that works for a particular Racket core version". The latter currently requires more work from package authors in the case that "latest for a core version" is not the same as "latest". The package-build service could similarly always build against the latest of everything. That would work well enough with the number of packages that we have now, but when there are 20 times as many packages, then I think it will be difficult for the build service to keep up when a widely-used package changes (e.g., when "base" changes). The current combination tries to hit a workable compromise between "the latest of everything" and "the latest that works for the current release". My guess is that the latest of a package will usually work with the latest release, mainly because package developers will be like other users and use the latest release. If so, things will generally work out. (In other words, I think that "misc1" is an exception in the way that it depends on a pre-release addition to "base", and I bet the author is willing to register a v6.1-compatible source.) If not, then we'll end up changing the policy at either "pkgs.racket-lang.org" or "pkg-build.racket-lang.org", or we may end up with multiple catalogs and multiple build services to support different modes. From matthias at ccs.neu.edu Fri Aug 22 10:37:35 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 22 Aug 2014 10:37:35 -0400 Subject: [racket] Setting exception handler for GUI message loop In-Reply-To: References: Message-ID: Your question is somewhat generic. You will need to equip each callback/event handler with an exn handler that puts the exception into a channel so that another thread can pick it up. -- Matthias On Aug 22, 2014, at 6:58 AM, Dmitry Cherkassov wrote: > Hi! > > Is it possible to set an exception handler to GUI message loop, so > that any exception thrown in GUI thread can be handled? > > -- > With best regards, > Dmitry > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Fri Aug 22 10:37:54 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 08:37:54 -0600 Subject: [racket] Setting exception handler for GUI message loop In-Reply-To: References: Message-ID: <20140822143755.8868265019A@mail-svr1.cs.utah.edu> Another possibility is to set the `uncaught-exception-handler` parameter (in the eventspace's main thread). At Fri, 22 Aug 2014 10:37:35 -0400, Matthias Felleisen wrote: > > Your question is somewhat generic. You will need to equip each callback/event > handler with an exn handler that puts the exception into a channel so that > another thread can pick it up. -- Matthias > > > > > > On Aug 22, 2014, at 6:58 AM, Dmitry Cherkassov wrote: > > > Hi! > > > > Is it possible to set an exception handler to GUI message loop, so > > that any exception thrown in GUI thread can be handled? > > > > -- > > With best regards, > > Dmitry > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From dcherkassov at gmail.com Fri Aug 22 10:51:26 2014 From: dcherkassov at gmail.com (Dmitry Cherkassov) Date: Fri, 22 Aug 2014 18:51:26 +0400 Subject: [racket] Setting exception handler for GUI message loop In-Reply-To: <20140822143755.8868265019A@mail-svr1.cs.utah.edu> References: <20140822143755.8868265019A@mail-svr1.cs.utah.edu> Message-ID: > Another possibility is to set the `uncaught-exception-handler` parameter (in the eventspace's main thread). set as dynamic parameter via `parameterize'? how do i get to GUI thread to accomplish that? On Fri, Aug 22, 2014 at 6:37 PM, Matthew Flatt wrote: > Another possibility is to set the `uncaught-exception-handler` > parameter (in the eventspace's main thread). > > At Fri, 22 Aug 2014 10:37:35 -0400, Matthias Felleisen wrote: >> >> Your question is somewhat generic. You will need to equip each callback/event >> handler with an exn handler that puts the exception into a channel so that >> another thread can pick it up. -- Matthias >> >> >> >> >> >> On Aug 22, 2014, at 6:58 AM, Dmitry Cherkassov wrote: >> >> > Hi! >> > >> > Is it possible to set an exception handler to GUI message loop, so >> > that any exception thrown in GUI thread can be handled? >> > >> > -- >> > With best regards, >> > Dmitry >> > ____________________ >> > Racket Users list: >> > http://lists.racket-lang.org/users >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users -- With best regards, Dmitry From mflatt at cs.utah.edu Fri Aug 22 10:57:46 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 08:57:46 -0600 Subject: [racket] Setting exception handler for GUI message loop In-Reply-To: References: <20140822143755.8868265019A@mail-svr1.cs.utah.edu> Message-ID: <20140822145747.90C1165019A@mail-svr1.cs.utah.edu> If you're not already in the handler thread (which is the same as the initial thread for the initial eventspace), then you can use `queue-callback` to run a thunk in the current eventspace's handler thread. At Fri, 22 Aug 2014 18:51:26 +0400, Dmitry Cherkassov wrote: > > Another possibility is to set the `uncaught-exception-handler` parameter (in > the eventspace's main thread). > set as dynamic parameter via `parameterize'? > > how do i get to GUI thread to accomplish that? > > > > On Fri, Aug 22, 2014 at 6:37 PM, Matthew Flatt wrote: > > Another possibility is to set the `uncaught-exception-handler` > > parameter (in the eventspace's main thread). > > > > At Fri, 22 Aug 2014 10:37:35 -0400, Matthias Felleisen wrote: > >> > >> Your question is somewhat generic. You will need to equip each callback/event > >> handler with an exn handler that puts the exception into a channel so that > >> another thread can pick it up. -- Matthias > >> > >> > >> > >> > >> > >> On Aug 22, 2014, at 6:58 AM, Dmitry Cherkassov wrote: > >> > >> > Hi! > >> > > >> > Is it possible to set an exception handler to GUI message loop, so > >> > that any exception thrown in GUI thread can be handled? > >> > > >> > -- > >> > With best regards, > >> > Dmitry > >> > ____________________ > >> > Racket Users list: > >> > http://lists.racket-lang.org/users > >> > >> > >> ____________________ > >> Racket Users list: > >> http://lists.racket-lang.org/users > > > > -- > With best regards, > Dmitry From dcherkassov at gmail.com Fri Aug 22 11:18:40 2014 From: dcherkassov at gmail.com (Dmitry Cherkassov) Date: Fri, 22 Aug 2014 19:18:40 +0400 Subject: [racket] Setting exception handler for GUI message loop In-Reply-To: <20140822145747.90C1165019A@mail-svr1.cs.utah.edu> References: <20140822143755.8868265019A@mail-svr1.cs.utah.edu> <20140822145747.90C1165019A@mail-svr1.cs.utah.edu> Message-ID: WIll that install my exception handler only for calls under `(parameterize uncaught-exception-hamdler () ... )` or for all the stuff in GUI thread? On Fri, Aug 22, 2014 at 6:57 PM, Matthew Flatt wrote: > If you're not already in the handler thread (which is the same as the > initial thread for the initial eventspace), then you can use > `queue-callback` to run a thunk in the current eventspace's handler > thread. > > At Fri, 22 Aug 2014 18:51:26 +0400, Dmitry Cherkassov wrote: >> > Another possibility is to set the `uncaught-exception-handler` parameter (in >> the eventspace's main thread). >> set as dynamic parameter via `parameterize'? >> >> how do i get to GUI thread to accomplish that? >> >> >> >> On Fri, Aug 22, 2014 at 6:37 PM, Matthew Flatt wrote: >> > Another possibility is to set the `uncaught-exception-handler` >> > parameter (in the eventspace's main thread). >> > >> > At Fri, 22 Aug 2014 10:37:35 -0400, Matthias Felleisen wrote: >> >> >> >> Your question is somewhat generic. You will need to equip each callback/event >> >> handler with an exn handler that puts the exception into a channel so that >> >> another thread can pick it up. -- Matthias >> >> >> >> >> >> >> >> >> >> >> >> On Aug 22, 2014, at 6:58 AM, Dmitry Cherkassov wrote: >> >> >> >> > Hi! >> >> > >> >> > Is it possible to set an exception handler to GUI message loop, so >> >> > that any exception thrown in GUI thread can be handled? >> >> > >> >> > -- >> >> > With best regards, >> >> > Dmitry >> >> > ____________________ >> >> > Racket Users list: >> >> > http://lists.racket-lang.org/users >> >> >> >> >> >> ____________________ >> >> Racket Users list: >> >> http://lists.racket-lang.org/users >> >> >> >> -- >> With best regards, >> Dmitry -- With best regards, Dmitry From matthias at ccs.neu.edu Fri Aug 22 11:21:23 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 22 Aug 2014 11:21:23 -0400 Subject: [racket] Setting exception handler for GUI message loop In-Reply-To: References: <20140822143755.8868265019A@mail-svr1.cs.utah.edu> <20140822145747.90C1165019A@mail-svr1.cs.utah.edu> Message-ID: Think along this minimal example: #lang racket/gui (define frame (new frame% [label "x"][width 200][height 200])) (define button (new button% [label "hello world"] [parent frame] [callback (lambda (b e) (/ 1 0))])) (queue-callback (lambda () (uncaught-exception-handler (lambda (xn) (displayln `(qb ,(exn-message xn))))))) (send frame show #t) On Aug 22, 2014, at 11:18 AM, Dmitry Cherkassov wrote: > WIll that install my exception handler only for calls under > `(parameterize uncaught-exception-hamdler () ... )` or for all the > stuff in GUI thread? > > On Fri, Aug 22, 2014 at 6:57 PM, Matthew Flatt wrote: >> If you're not already in the handler thread (which is the same as the >> initial thread for the initial eventspace), then you can use >> `queue-callback` to run a thunk in the current eventspace's handler >> thread. >> >> At Fri, 22 Aug 2014 18:51:26 +0400, Dmitry Cherkassov wrote: >>>> Another possibility is to set the `uncaught-exception-handler` parameter (in >>> the eventspace's main thread). >>> set as dynamic parameter via `parameterize'? >>> >>> how do i get to GUI thread to accomplish that? >>> >>> >>> >>> On Fri, Aug 22, 2014 at 6:37 PM, Matthew Flatt wrote: >>>> Another possibility is to set the `uncaught-exception-handler` >>>> parameter (in the eventspace's main thread). >>>> >>>> At Fri, 22 Aug 2014 10:37:35 -0400, Matthias Felleisen wrote: >>>>> >>>>> Your question is somewhat generic. You will need to equip each callback/event >>>>> handler with an exn handler that puts the exception into a channel so that >>>>> another thread can pick it up. -- Matthias >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Aug 22, 2014, at 6:58 AM, Dmitry Cherkassov wrote: >>>>> >>>>>> Hi! >>>>>> >>>>>> Is it possible to set an exception handler to GUI message loop, so >>>>>> that any exception thrown in GUI thread can be handled? >>>>>> >>>>>> -- >>>>>> With best regards, >>>>>> Dmitry >>>>>> ____________________ >>>>>> Racket Users list: >>>>>> http://lists.racket-lang.org/users >>>>> >>>>> >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>> >>> >>> >>> -- >>> With best regards, >>> Dmitry > > > > -- > With best regards, > Dmitry From mflatt at cs.utah.edu Fri Aug 22 11:38:49 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 09:38:49 -0600 Subject: [racket] Understanding error in use of submodule in my language In-Reply-To: References: Message-ID: <20140822153851.1C28965018F@mail-svr1.cs.utah.edu> I think this may be a problem in macro expansion with submodules. The `#%module-begin` from `racket/base` adds a submodule declaration for `configure-runtime` when it doesn't see an existing submodule declaration for `configure-runtime` --- but it looks for an existing declaration as an immediate one, before macro-expanding the module body. In your code, the `mute` wrapper hides the declaration of `configure-runtime`, so a conflicting one gets added. The tricky part is that this happens the second time that the `test` submodule is expanded: * The overall module's body is forced via `local-expand`. * As a part of that local expansion, the `test` submodule is expanded' its expansion includes a declaration of a `configure-runtime` submodule. * The overall module's expanded body is wrapped back in `#%module-begin`, which will re-expand all of the content, including the `test` submodule. * The `test` submodule this second time around has a `#%module-begin` that is supposed to be bound to `#%plain-module-begin`, but it ends up being captured[*] by `#%module-begin` from "bootstrap-lang.rkt", so that the submodule's body is again local-expanded and again send to `#%module-begin` from `racket/base` with a `mute` wrapper around the `configure-runtime` sub-submodule. The [*] step seems wrong to me. I think this may be an example of a problem deep in the macro expander, and solving that is my next project. Since the repair (assuming that I have correctly diagnosed the cause) may be a while, do you have a workaround already? The macro name `mute` suggests that you may want to suppress the printing of expression results at the top-level of a module, and that might be as easy as expanding `#%module-begin` to `#%plain-module-begin`. Or maybe `syntax/wrap-modbeg` can help, or maybe the strategy used by `syntax/wrap-modbeg` would work better for your macro. At Thu, 21 Aug 2014 17:22:29 +0100, Marco Monteiro wrote: > Hello! > > I'm using Racket 6.1 > > I'm trying to understand this error. I'm using submodules in a language I > defined. The language file is here: > > http://pastebin.com/7RiHHRmi > > Notice the commented out line 28. > > I use that language in the following code > > http://pastebin.com/Qa6RD9wF > > raco expanding this last file fails with > > module: duplicate submodule definition > at: configure-runtime > in: module > context...: > /usr/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:29:11: > loop > /usr/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt: > [running body] > /usr/share/racket/collects/raco/raco.rkt: [running body] > /usr/share/racket/collects/raco/main.rkt: [running body] > > If I uncomment line 28 it no longer fails. If I use (module ...) instead of > (module* ...) it no longer fails independently of line 28 being commented > out or not. > > Trying to macro expand that in drracket gives me "Internal error: car: > contract violation ." error. > > What is happending here? > > Thanks, > Marco > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From dcherkassov at gmail.com Fri Aug 22 11:44:37 2014 From: dcherkassov at gmail.com (Dmitry Cherkassov) Date: Fri, 22 Aug 2014 19:44:37 +0400 Subject: [racket] Setting exception handler for GUI message loop In-Reply-To: References: <20140822143755.8868265019A@mail-svr1.cs.utah.edu> <20140822145747.90C1165019A@mail-svr1.cs.utah.edu> Message-ID: Thank you for help. On Fri, Aug 22, 2014 at 7:21 PM, Matthias Felleisen wrote: > > Think along this minimal example: > > #lang racket/gui > > (define frame (new frame% [label "x"][width 200][height 200])) > > (define button > (new button% > [label "hello world"] > [parent frame] > [callback > (lambda (b e) > (/ 1 0))])) > > (queue-callback > (lambda () > (uncaught-exception-handler > (lambda (xn) > (displayln `(qb ,(exn-message xn))))))) > > (send frame show #t) > > > > > On Aug 22, 2014, at 11:18 AM, Dmitry Cherkassov wrote: > >> WIll that install my exception handler only for calls under >> `(parameterize uncaught-exception-hamdler () ... )` or for all the >> stuff in GUI thread? >> >> On Fri, Aug 22, 2014 at 6:57 PM, Matthew Flatt wrote: >>> If you're not already in the handler thread (which is the same as the >>> initial thread for the initial eventspace), then you can use >>> `queue-callback` to run a thunk in the current eventspace's handler >>> thread. >>> >>> At Fri, 22 Aug 2014 18:51:26 +0400, Dmitry Cherkassov wrote: >>>>> Another possibility is to set the `uncaught-exception-handler` parameter (in >>>> the eventspace's main thread). >>>> set as dynamic parameter via `parameterize'? >>>> >>>> how do i get to GUI thread to accomplish that? >>>> >>>> >>>> >>>> On Fri, Aug 22, 2014 at 6:37 PM, Matthew Flatt wrote: >>>>> Another possibility is to set the `uncaught-exception-handler` >>>>> parameter (in the eventspace's main thread). >>>>> >>>>> At Fri, 22 Aug 2014 10:37:35 -0400, Matthias Felleisen wrote: >>>>>> >>>>>> Your question is somewhat generic. You will need to equip each callback/event >>>>>> handler with an exn handler that puts the exception into a channel so that >>>>>> another thread can pick it up. -- Matthias >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Aug 22, 2014, at 6:58 AM, Dmitry Cherkassov wrote: >>>>>> >>>>>>> Hi! >>>>>>> >>>>>>> Is it possible to set an exception handler to GUI message loop, so >>>>>>> that any exception thrown in GUI thread can be handled? >>>>>>> >>>>>>> -- >>>>>>> With best regards, >>>>>>> Dmitry >>>>>>> ____________________ >>>>>>> Racket Users list: >>>>>>> http://lists.racket-lang.org/users >>>>>> >>>>>> >>>>>> ____________________ >>>>>> Racket Users list: >>>>>> http://lists.racket-lang.org/users >>>> >>>> >>>> >>>> -- >>>> With best regards, >>>> Dmitry >> >> >> >> -- >> With best regards, >> Dmitry > -- With best regards, Dmitry From mflatt at cs.utah.edu Fri Aug 22 15:33:11 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 13:33:11 -0600 Subject: [racket] About closing ports In-Reply-To: References: Message-ID: <20140822193312.7EE3B650181@mail-svr1.cs.utah.edu> Sorry for the long delay here. There's no particular reason for the absence of `close-port`, as far as I know --- just that `close-input-port` and `close-output-port` were always there. It's possible for a value to represent both an input port and an output port, so if that matters at all, you might want (define (close-port p) (when (input-port? p) (close-input-port p)) (when (output-port? p) (close-output-port p))) At Sat, 9 Aug 2014 23:26:25 -0700, Jack Firth wrote: > Is there any particular reason there's no general close-port function that > works on both input ports and output ports? Would an implementation along > the lines of ((if (input-port? p) close-input-port close-output-port) p) > have problems that make this unreasonable? The only reason I ask is because > I was writing a macro let-ports that works like let (but only for ports) > that automatically closes the ports it defines. My naive implementations of > these are: > > (define (close-port p) > ((if (input-port? p) close-input-port close-output-port) p)) > > (define-syntax-rule (let-ports ([port port-expr] ...) body ...) > (let ([port port-expr] ...) > body ... > (close-port port) ...)) > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Fri Aug 22 15:36:18 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 13:36:18 -0600 Subject: [racket] racket/gui: changing the background color In-Reply-To: References: Message-ID: <20140822193619.DF7BA650181@mail-svr1.cs.utah.edu> There's currently no way to set the background color for `message%` objects, and I'd still use a `canvas%`. At Tue, 5 Aug 2014 10:47:37 -0500, David Nelson wrote: > I am working on a manufacturing system to asynchronously program and test > 16 USB devices. The main display is a grid of "slot" displays. Each slot > display currently is a group box with the slot number in big digits, a > status message in normal sized text, and a guage to display the progress. > I'd like to change the background color of the group box for each slot > depending on the status. E.g. red for a problem, green for success, yellow > - in progress, etc.. > > The problem is that setting a background color only seems to be possible > with a canvas%. I seem to have two options: > 1) Use a canvas for the slot and draw all of the contents. > 2) Create a subclass of panel% that can position a canvas behind the rest > of the children. > > In the previous implementation option #1 was used because I needed to work > around another issue. We used a collection of BeagleBones with small LCD > displays to drive the slots, one computer per slot. I had to roll my own > classes to deal with the display physically rotated 90 degrees from normal. > (The X server did not support rotating the display.) I used a canvas > filling the top-level frame, and then my rotated-text% and progress-bar% > classes used absolute positioning and sizing. The draw operation on the > canvas filled the background, applied a rotation transformation to the dc > and then for each child it applied the appropriate translation to the > position of the child and told the child object to draw with the rotated & > translated device context. > > Comments or suggestions? > > -- David > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Fri Aug 22 15:40:47 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 13:40:47 -0600 Subject: [racket] help me speed up string split? In-Reply-To: <8D9BE81B-1929-4413-A1C7-1E6D4C510384@gmail.com> References: <39D378F7-3F27-4F7F-B794-A7A1261760BA@gmail.com> <20140724152739.1BB2865018F@mail-svr1.cs.utah.edu> <8D9BE81B-1929-4413-A1C7-1E6D4C510384@gmail.com> Message-ID: <20140822194048.A689E650181@mail-svr1.cs.utah.edu> At Fri, 8 Aug 2014 14:07:34 -0700, Ryan Davis wrote: > I assume that made it into the 6.1 release? Sorry, no. The repair came relatively late in the v6.1 release process. From mflatt at cs.utah.edu Fri Aug 22 15:49:00 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 22 Aug 2014 13:49:00 -0600 Subject: [racket] Scribble srcdoc and macros In-Reply-To: References: Message-ID: <20140822194901.CFBEE650188@mail-svr1.cs.utah.edu> I've added `form-doc` to `scribble/srcdoc`. Otherwise, I don't think there's a good way to use `thing-doc` to document syntactic forms. At Fri, 15 Aug 2014 13:11:55 -0700, Jack Firth wrote: > Is there a form similar to proc-doc/names but for providing syntactic forms > instead? Something where it expands to using @defform instead of @defproc. > It looks like thing-doc might work, but that's meant for arbitrary values > and I'm really looking for something specifically meant for exporting > syntactic forms. If no such thing exists, how would an implementation based > on thing-doc look exactly? > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From jackhfirth at gmail.com Fri Aug 22 15:54:46 2014 From: jackhfirth at gmail.com (Jack Firth) Date: Fri, 22 Aug 2014 12:54:46 -0700 Subject: [racket] Scribble srcdoc and macros In-Reply-To: <20140822194901.CFBEE650188@mail-svr1.cs.utah.edu> References: <20140822194901.CFBEE650188@mail-svr1.cs.utah.edu> Message-ID: Excellent! Thank you for the addition. On Fri, Aug 22, 2014 at 12:49 PM, Matthew Flatt wrote: > I've added `form-doc` to `scribble/srcdoc`. > > Otherwise, I don't think there's a good way to use `thing-doc` to > document syntactic forms. > > At Fri, 15 Aug 2014 13:11:55 -0700, Jack Firth wrote: > > Is there a form similar to proc-doc/names but for providing syntactic > forms > > instead? Something where it expands to using @defform instead of > @defproc. > > It looks like thing-doc might work, but that's meant for arbitrary values > > and I'm really looking for something specifically meant for exporting > > syntactic forms. If no such thing exists, how would an implementation > based > > on thing-doc look exactly? > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From davidcnelson at gmail.com Fri Aug 22 17:28:50 2014 From: davidcnelson at gmail.com (David Nelson) Date: Fri, 22 Aug 2014 16:28:50 -0500 Subject: [racket] racket/gui: changing the background color In-Reply-To: <20140822193619.DF7BA650181@mail-svr1.cs.utah.edu> References: <20140822193619.DF7BA650181@mail-svr1.cs.utah.edu> Message-ID: I ended up going the canvas% route. To reduce the amount of screen space that had to be redrawn when updating the progress bar or changing the status text, I created my own message% and gauge% classes based on canvas%. The final arrangement was a custom panel% that stretched its children out to the full width/height as the parent. Its children were a canvas% to fill the background, and a vertical-pane% to layout the custom message and gauge classes. To change the background color, I had to tell each part to change the background color, but that could be automated with a method to walk the children to find my custom classes. Why don't pane% and panel% honor the stretchable-width and stretchable-height properties of their children. Every other pane/panel class does. It seems like this would be a reasonable thing to do. I have two specific use cases: 1) A tab-less tabbed panel where I want to display different content pages, but size the whole area is based on the largest width and height from the children. All but one of the children was told (send child show #f). In my case, this is a page with the controls to prepare and start an operation. Once the operation is started, it flips to a status page. There is a button to stop the operation and return back to the first page. 2) I want to arrange a canvas as a background behind other objects. After playing with this, the only other things that seem to reliably work in the foreground are other canvases so I understand this would not be a typical use. Setting the minimum width and height the same for all children is OK as a starting point, but if the window grows and you want that space to grow too, the children are not currently stretched out. I ended up creating a custom pane% that overrides place-children, but it seems the default implementation could do this. -- David On Fri, Aug 22, 2014 at 2:36 PM, Matthew Flatt wrote: > There's currently no way to set the background color for `message%` > objects, and I'd still use a `canvas%`. > > At Tue, 5 Aug 2014 10:47:37 -0500, David Nelson wrote: > > I am working on a manufacturing system to asynchronously program and test > > 16 USB devices. The main display is a grid of "slot" displays. Each slot > > display currently is a group box with the slot number in big digits, a > > status message in normal sized text, and a guage to display the progress. > > I'd like to change the background color of the group box for each slot > > depending on the status. E.g. red for a problem, green for success, > yellow > > - in progress, etc.. > > > > The problem is that setting a background color only seems to be possible > > with a canvas%. I seem to have two options: > > 1) Use a canvas for the slot and draw all of the contents. > > 2) Create a subclass of panel% that can position a canvas behind the rest > > of the children. > > > > In the previous implementation option #1 was used because I needed to > work > > around another issue. We used a collection of BeagleBones with small LCD > > displays to drive the slots, one computer per slot. I had to roll my own > > classes to deal with the display physically rotated 90 degrees from > normal. > > (The X server did not support rotating the display.) I used a canvas > > filling the top-level frame, and then my rotated-text% and progress-bar% > > classes used absolute positioning and sizing. The draw operation on the > > canvas filled the background, applied a rotation transformation to the dc > > and then for each child it applied the appropriate translation to the > > position of the child and told the child object to draw with the rotated > & > > translated device context. > > > > Comments or suggestions? > > > > -- David > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From planpublicity at gmail.com Thu Aug 14 15:53:03 2014 From: planpublicity at gmail.com (planpublicity at gmail.com) Date: Thu, 14 Aug 2014 12:53:03 -0700 (PDT) Subject: [racket] Second call for papers IFL 2014 Message-ID: <53ed139f.630bc20a.1524.50a7@mx.google.com> Hello, Please, find below the second call for papers for IFL 2014. The submission page is now open. Please forward these to anyone you think may be interested. Apologies for any duplicates you may receive. best regards, Jurriaan Hage Publicity Chair of IFL --- CALL FOR PAPERS 26th SYMPOSIUM ON IMPLEMENTATION AND APPLICATION OF FUNCTIONAL LANGUAGES - IFL 2014 NORTHEASTERN UNIVERSITY/BOSTON, USA OCTOBER 1-3, 2014 http://ifl2014.github.io We are pleased to announce that the 26th edition of the IFL series will be held at Northeastern University in Boston, USA. The symposium will be held from 1st to 3rd of October 2014. Scope ----- The goal of the IFL symposia is to bring together researchers actively engaged in the implementation and application of functional and function-based programming languages. IFL 2014 will be a venue for researchers to present and discuss new ideas and concepts, work in progress, and publication-ripe results related to the implementation and application of functional languages and function-based programming. Following the IFL tradition, IFL 2014 will use a post-symposium review process to produce the formal proceedings. All participants of IFL 2014 are invited to submit either a draft paper or an extended abstract describing work to be presented at the symposium. At no time may work submitted to IFL be simultaneously submitted to other venues; submissions must adhere to ACM SIGPLAN's republication policy: http://www.sigplan.org/Resources/Policies/Republication The submissions will be screened by the program committee chair to make sure they are within the scope of IFL, and will appear in the draft proceedings distributed at the symposium. Submissions appearing in the draft proceedings are not peer-reviewed publications. Hence, publications that appear only in the draft proceedings do not count as publication for the ACM SIGPLAN republication policy. After the symposium, authors will be given the opportunity to incorporate the feedback from discussions at the symposium and will be invited to submit a revised full article for the formal review process. From the revised submissions, the program committee will select papers for the formal proceedings considering their correctness, novelty, originality, relevance, significance, and clarity. Submission Details ------------------ Submission deadline draft papers: September 1 Notification of acceptance for presentation: September 5 Early registration deadline: September 10 Late registration deadline: September 17 Submission deadline for pre-symposium proceedings: September 24 26th IFL Symposium: October 1-3 Submission deadline for post-symposium proceedings: December 15 Notification of acceptance for post-symposium proceedings: January 31 2015 Camera-ready version for post-symposium proceedings: March 15 2015 Prospective authors are encouraged to submit papers or extended abstracts to be published in the draft proceedings and to present them at the symposium. All contributions must be written in English. Papers must adhere to the standard ACM two columns conference format. For the pre-symposium proceedings we adopt a 'weak' page limit of 12 pages. For the post-symposium proceedings the page limit of 12 pages is firm. A suitable document template for LaTeX can be found at: http://www.acm.org/sigs/sigplan/authorInformation.htm Papers should be submitted online at https://easychair.org/conferences/?conf=ifl2014 Topics ------ IFL welcomes submissions describing practical and theoretical work as well as submissions describing applications and tools in the context of functional programming. If you are not sure whether your work is appropriate for IFL 2014, please contact the PC chair at samth at cs.indiana.edu. Topics of interest include, but are not limited to: ??? language concepts ??? type systems, type checking, type inferencing ??? compilation techniques ??? staged compilation ??? run-time function specialization ??? run-time code generation ??? partial evaluation ??? (abstract) interpretation ??? metaprogramming ??? generic programming ??? automatic program generation ??? array processing ??? concurrent/parallel programming ??? concurrent/parallel program execution ??? embedded systems ??? web applications ??? (embedded) domain specific languages ??? security ??? novel memory management techniques ??? run-time profiling performance measurements ??? debugging and tracing ??? virtual/abstract machine architectures ??? validation, verification of functional programs ??? tools and programming techniques ??? (industrial) applications Peter Landin Prize ------------------ The Peter Landin Prize is awarded to the best paper presented at the symposium every year. The honoured article is selected by the program committee based on the submissions received for the formal review process. The prize carries a cash award equivalent to 150 Euros. Programme committee ------------------- Sam Tobin-Hochstadt, Indiana University (Chair) Rinus Plasmeijer, Radboud University Nijmegen (Co-Chair) Atze Dijkstra, Utrecht University Colin Runciman, University of York Graham Hutton, University of Nottingham Mary Sheeran, Chalmers University of Technology Patricia Johann, Appalachian State University Matthew Fluet, Rochester Institute of Technology Josef Svenningsson, Chalmers University of Technology Ma??gorzata Biernacka, University of Wroclaw Peter Achten, Radboud Univerity Nijmegen Laura Castro, University of A Coru??a Hai Paul Liu, Intel Labs Kathryn Gray, Cambridge University Lars Bergstrom, Mozilla Research Lindsey Kuper, Indiana University Nicolas Wu, Oxford T. Stephen Strickland, University of Maryland Xavier Clerc, INRIA Venue ----- The 26th IFL will be held in association with the College of Computer and Information Science at Northeastern University. It can be reached quickly and easily by public transport. From planpublicity at gmail.com Thu Aug 14 15:53:19 2014 From: planpublicity at gmail.com (planpublicity at gmail.com) Date: Thu, 14 Aug 2014 12:53:19 -0700 (PDT) Subject: [racket] Second call for papers IFL 2014 Message-ID: <53ed13af.630bc20a.1524.50c0@mx.google.com> Hello, Please, find below the second call for papers for IFL 2014. The submission page is now open. Please forward these to anyone you think may be interested. Apologies for any duplicates you may receive. best regards, Jurriaan Hage Publicity Chair of IFL --- CALL FOR PAPERS 26th SYMPOSIUM ON IMPLEMENTATION AND APPLICATION OF FUNCTIONAL LANGUAGES - IFL 2014 NORTHEASTERN UNIVERSITY/BOSTON, USA OCTOBER 1-3, 2014 http://ifl2014.github.io We are pleased to announce that the 26th edition of the IFL series will be held at Northeastern University in Boston, USA. The symposium will be held from 1st to 3rd of October 2014. Scope ----- The goal of the IFL symposia is to bring together researchers actively engaged in the implementation and application of functional and function-based programming languages. IFL 2014 will be a venue for researchers to present and discuss new ideas and concepts, work in progress, and publication-ripe results related to the implementation and application of functional languages and function-based programming. Following the IFL tradition, IFL 2014 will use a post-symposium review process to produce the formal proceedings. All participants of IFL 2014 are invited to submit either a draft paper or an extended abstract describing work to be presented at the symposium. At no time may work submitted to IFL be simultaneously submitted to other venues; submissions must adhere to ACM SIGPLAN's republication policy: http://www.sigplan.org/Resources/Policies/Republication The submissions will be screened by the program committee chair to make sure they are within the scope of IFL, and will appear in the draft proceedings distributed at the symposium. Submissions appearing in the draft proceedings are not peer-reviewed publications. Hence, publications that appear only in the draft proceedings do not count as publication for the ACM SIGPLAN republication policy. After the symposium, authors will be given the opportunity to incorporate the feedback from discussions at the symposium and will be invited to submit a revised full article for the formal review process. From the revised submissions, the program committee will select papers for the formal proceedings considering their correctness, novelty, originality, relevance, significance, and clarity. Submission Details ------------------ Submission deadline draft papers: September 1 Notification of acceptance for presentation: September 5 Early registration deadline: September 10 Late registration deadline: September 17 Submission deadline for pre-symposium proceedings: September 24 26th IFL Symposium: October 1-3 Submission deadline for post-symposium proceedings: December 15 Notification of acceptance for post-symposium proceedings: January 31 2015 Camera-ready version for post-symposium proceedings: March 15 2015 Prospective authors are encouraged to submit papers or extended abstracts to be published in the draft proceedings and to present them at the symposium. All contributions must be written in English. Papers must adhere to the standard ACM two columns conference format. For the pre-symposium proceedings we adopt a 'weak' page limit of 12 pages. For the post-symposium proceedings the page limit of 12 pages is firm. A suitable document template for LaTeX can be found at: http://www.acm.org/sigs/sigplan/authorInformation.htm Papers should be submitted online at https://easychair.org/conferences/?conf=ifl2014 Topics ------ IFL welcomes submissions describing practical and theoretical work as well as submissions describing applications and tools in the context of functional programming. If you are not sure whether your work is appropriate for IFL 2014, please contact the PC chair at samth at cs.indiana.edu. Topics of interest include, but are not limited to: ??? language concepts ??? type systems, type checking, type inferencing ??? compilation techniques ??? staged compilation ??? run-time function specialization ??? run-time code generation ??? partial evaluation ??? (abstract) interpretation ??? metaprogramming ??? generic programming ??? automatic program generation ??? array processing ??? concurrent/parallel programming ??? concurrent/parallel program execution ??? embedded systems ??? web applications ??? (embedded) domain specific languages ??? security ??? novel memory management techniques ??? run-time profiling performance measurements ??? debugging and tracing ??? virtual/abstract machine architectures ??? validation, verification of functional programs ??? tools and programming techniques ??? (industrial) applications Peter Landin Prize ------------------ The Peter Landin Prize is awarded to the best paper presented at the symposium every year. The honoured article is selected by the program committee based on the submissions received for the formal review process. The prize carries a cash award equivalent to 150 Euros. Programme committee ------------------- Sam Tobin-Hochstadt, Indiana University (Chair) Rinus Plasmeijer, Radboud University Nijmegen (Co-Chair) Atze Dijkstra, Utrecht University Colin Runciman, University of York Graham Hutton, University of Nottingham Mary Sheeran, Chalmers University of Technology Patricia Johann, Appalachian State University Matthew Fluet, Rochester Institute of Technology Josef Svenningsson, Chalmers University of Technology Ma??gorzata Biernacka, University of Wroclaw Peter Achten, Radboud Univerity Nijmegen Laura Castro, University of A Coru??a Hai Paul Liu, Intel Labs Kathryn Gray, Cambridge University Lars Bergstrom, Mozilla Research Lindsey Kuper, Indiana University Nicolas Wu, Oxford T. Stephen Strickland, University of Maryland Xavier Clerc, INRIA Venue ----- The 26th IFL will be held in association with the College of Computer and Information Science at Northeastern University. It can be reached quickly and easily by public transport. From 280145668 at qq.com Thu Aug 14 21:42:09 2014 From: 280145668 at qq.com (=?utf-8?B?5qWg5a2X5pWw6KGl5LiB5Lmf?=) Date: Fri, 15 Aug 2014 09:42:09 +0800 Subject: [racket] How to forbid Racket console to display lists? Message-ID: Version Win 8.1 64bit Hello, I use "racket.exe [file name]" to execute .rkt file. But sometimes when in this situation (just an example easy to explain): #lang racket (range 100000) The console will automatically display a list of 100000 elements even if I don't want to display it. Some times I just want to know how much time it will take for a function to work out a very large list, for example: (define f ) (time (f args)) Now in this case, Racket will still try to display the list for you, and you will never see the result you want. So, how to forbid Racket console to display lists? ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From archambault.v at gmail.com Tue Aug 19 11:41:49 2014 From: archambault.v at gmail.com (Vincent Archambault-Bouffard) Date: Tue, 19 Aug 2014 11:41:49 -0400 Subject: [racket] Macro : Reify a function body definition Message-ID: <76CBEBF4-D7DC-410D-A1C9-03950DAACF10@gmail.com> Hello, I am new to Racket. I have used another Scheme implementation before (Gambit) so I know a bit about Scheme in general. I?m looking for a way to reify a function definition from a macro. The function is defined at phase 0 because it is used at runtime. Simple example, suppose we want to differentiate a function : (define (foo x) (+ x (sin x))) (define fooPrime (derivative foo)) where ?derivative" would be a macro that reify foo (looks-up the definition of and returns a syntax object) and generates its derivative. I understand why macros cannot access phase 0 variable instances. (Composable and Compilable Macros: You Want it When?, Matthew Flatt, 2002) and that (syntax-local-value ) can do something similar with transformer binding. But the body definition is available at compile time. I know the definition could be changed using a set! but for now I?m willing to ignore this corner case. Thank you Vincent Archambault-B From kernel at matikai.com Tue Aug 19 19:34:28 2014 From: kernel at matikai.com (E Comer) Date: Tue, 19 Aug 2014 16:34:28 -0700 Subject: [racket] How to display math formulas using LaTeX in Scribble? Message-ID: <1408491268.26078.YahooMailNeo@web163003.mail.bf1.yahoo.com> Hi dear friends: What is the recommended way to display math formulas using LaTeX in Scribble? After installing the racket-poppler package under Windows, I try: #lang slideshow (require racket-poppler/render-tex) (latex-path "C:/Program Files/MiKTeX 2.9 ? ? ? ? ? ? /miktex/bin/pdflatex") (define p (latex->pict "$\\sqrt{x^2+y^2}$")) (pict->bitmap p) but I receive the following error: ffi-lib: couldn't open "libpoppler-glib.dll.8" (No se puede encontrar el m?dulo especificado.; errno=126) Thank you very much in advance for any suggestion or example to help me to solve this problem. Sincerely, Enrique P.S. Congratulations for all your great work related to Racket, especially with the beautiful Scribble tool. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Sat Aug 23 09:01:27 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sat, 23 Aug 2014 09:01:27 -0400 Subject: [racket] How to forbid Racket console to display lists? In-Reply-To: References: Message-ID: <6A733394-F00C-4AD1-9FAA-98BF244053A3@ccs.neu.edu> FILE tst.rkt #lang racket (define x (range 100000)) $ racket tst.rkt On Aug 14, 2014, at 9:42 PM, ?????? wrote: > Version Win 8.1 64bit > > Hello, I use "racket.exe [file name]" to execute .rkt file. But sometimes when in this situation (just an example easy to explain): > > #lang racket > (range 100000) > > The console will automatically display a list of 100000 elements even if I don't want to display it. > > Some times I just want to know how much time it will take for a function to work out a very large list, for example: > > (define f ) > (time (f args)) > > Now in this case, Racket will still try to display the list for you, and you will never see the result you want. So, how to forbid Racket console to display lists? > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From gustavo at oma.org.ar Sat Aug 23 09:56:56 2014 From: gustavo at oma.org.ar (Gustavo Massaccesi) Date: Sat, 23 Aug 2014 10:56:56 -0300 Subject: [racket] How to forbid Racket console to display lists? In-Reply-To: References: Message-ID: You can use void, because by default it's not printed. Another possibility is to use a "bounded" version of display, that use ... when the output is too long. #lang racket (void (range 1000)) (void (time (range 1000))) (define (displayln/... x) (printf "~.a" x)) (displayln/... (range 1000)) ;--- Output: cpu time: 0 real time: 1 gc time: 0 (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 8... Gustavo On Thu, Aug 14, 2014 at 10:42 PM, ?????? <280145668 at qq.com> wrote: > Version Win 8.1 64bit > > Hello, I use "racket.exe [file name]" to execute .rkt file. But sometimes > when in this situation (just an example easy to explain): > > #lang racket > (range 100000) > > The console will automatically display a list of 100000 elements even if I > don't want to display it. > > Some times I just want to know how much time it will take for a function to > work out a very large list, for example: > > (define f ) > (time (f args)) > > Now in this case, Racket will still try to display the list for you, and you > will never see the result you want. So, how to forbid Racket console to > display lists? ? > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From jensaxel at soegaard.net Sat Aug 23 10:09:48 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Sat, 23 Aug 2014 16:09:48 +0200 Subject: [racket] How to display math formulas using LaTeX in Scribble? In-Reply-To: <1408491268.26078.YahooMailNeo@web163003.mail.bf1.yahoo.com> References: <1408491268.26078.YahooMailNeo@web163003.mail.bf1.yahoo.com> Message-ID: 2014-08-20 1:34 GMT+02:00 E Comer : After installing the racket-poppler package under Windows, I try: > ffi-lib: couldn't open "libpoppler-glib.dll.8" (No se puede encontrar el > m?dulo especificado.; errno=126) The intention was that the file libpoppler-glib.dll.8 should to be installed automatically, but I might have something done something wrong in the configuration file. I have updated the racket-poppler package. Try installing it again. I am testing on OS X, so you if you run into any problems, I'd like to know. Note that the libpoppler-glib included was built to work with Racket (thanks Matthew), and using another version will almost certainly not work. https://github.com/soegaard/racket-poppler/tree/master/poppler-libs/poppler-win32-x86_64/racket-poppler If you are not subscribed to the list, then reply to both me and the list. -- Jens Axel S?gaard From jensaxel at soegaard.net Sat Aug 23 12:21:26 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Sat, 23 Aug 2014 18:21:26 +0200 Subject: [racket] copy-shared-files and different platforms Message-ID: Hi All, How exactly are copy-shared-files to be used? I have a set of shared libraries for different platforms in: racket-poppler/poppler-libs/poppler-i386-macosx racket-poppler/poppler-libs/poppler-win32-i386 etc. My info file is here: https://github.com/soegaard/racket-poppler/blob/master/info.rkt I tried listing the folder poppler-libs, but it seems not to work. /Jens Axel From antoine.brand at sfr.fr Sat Aug 23 13:28:02 2014 From: antoine.brand at sfr.fr (antoine) Date: Sat, 23 Aug 2014 19:28:02 +0200 Subject: [racket] Macro : Reify a function body definition In-Reply-To: <76CBEBF4-D7DC-410D-A1C9-03950DAACF10@gmail.com> References: <76CBEBF4-D7DC-410D-A1C9-03950DAACF10@gmail.com> Message-ID: <20140823172802.GA6312@debian> Hello, If i understand well, you want to have access to the source code of foo. Here is a program that give you the source code: #lang racket (define-syntax (define-equation stx) (syntax-case stx () [(_ (name . params) value ...) (begin (when (not (symbol? (syntax-e #'name))) (raise "not a symbol")) #`(begin (define #,(cons #'name #'params) value ...) (define-for-syntax name (list (quote params) (quote value ...)))))])) (define-equation (foo x) (+ x (sin x))) ;; => (define (foo x) (+ x (sin x))) ;; (define-for-syntax foo '((x) (+ x (sin x)))) (define-syntax (derivate stx) (define sym (syntax-e (cadr (syntax-e stx)))) (print (eval sym)) ;;do the stuff you want here with the code #'1) (derivate foo) Two things to mentions: - The source code data is given as a list of symbols instead of a syntax objects so you can't do free-identifier=?. You should rewrite define-equation with syntax-parse instead of syntax-case. But know just for the beginning i think you can live with that. - I use eval inside derivate to fetch the data of foo at phase 1 i suspect it is not the right way to do it. Hope it helps. From mflatt at cs.utah.edu Sat Aug 23 14:12:02 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Sat, 23 Aug 2014 12:12:02 -0600 Subject: [racket] copy-shared-files and different platforms In-Reply-To: References: Message-ID: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> The `copy-shared-files` declaration is for collection "info.rkt" files, not for package "info.rkt" files. So, the one in the top-level "info.rkt" of https://github.com/soegaard/racket-poppler has no effect, since that's a multi-collection package (i.e., the top-level "info.rkt" is a package "info.rkt" and not a collection "info.rkt"). In a collection "info.rkt", whatever you list for `copy-shared-files` is copied to the "lib" directory. So, (define copy-shared-files (list "poppler-libs")) would mean that the "poppler-libs" directory will be copied there, instead of individual ".dll" or ".dylib" files within that directory. Since `ffi-lib` doesn't look in subdirectories of the library directory, that won't be useful. The "info.rkt" files within specific library directories look right, such as this one: https://github.com/soegaard/racket-poppler/blob/master/poppler-libs/poppler-win32-i386/racket-poppler/info.rkt And those "info.rkt" files are also collection directories, so they cause the listed libraries to be installed --- at least for the five platforms represented in "poppler-libs". The `install-platform` definitions in those "info.rkt" files mean that only libraries for the current platform will be installed. It's probably better for each directory within "poppler-libs" to be its own package, so that an installation gets only the libraries for the installation's platform, but the current way should work. (For Unix variants, so far, we have been assuming that programmers will install foreign libraries through the OS's package system.) At Sat, 23 Aug 2014 18:21:26 +0200, Jens Axel S?gaard wrote: > Hi All, > > How exactly are copy-shared-files to be used? > > I have a set of shared libraries for different platforms in: > > racket-poppler/poppler-libs/poppler-i386-macosx > racket-poppler/poppler-libs/poppler-win32-i386 > etc. > > My info file is here: > > https://github.com/soegaard/racket-poppler/blob/master/info.rkt > > I tried listing the folder poppler-libs, but it seems not to work. > > /Jens Axel > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From lysseus at gmail.com Sun Aug 24 01:03:58 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Sat, 23 Aug 2014 22:03:58 -0700 Subject: [racket] contracts ->i optional keyword syntax Message-ID: <9F4C17FC-FBB8-485A-8061-D98E45F7F90C@gmail.com> I?ve been trying to figure out the syntax for optional keywords in the ->i contract form. For example: (->i ([lst list?]) ([#:foo ?.]) ; what does this look like? (result list?)) The mandatory domain syntax seems straightforward, but I?ve tried various combinations for the optional keyword that don?t appear to be correct. (->i ([lst list?]) ([#:foo (lst) (?.etc))) (result list?)) doesn?t work for me, neither does sticking an id before or after ? (lat) ? Does anyone have an example of an optional keyword ->i contract? This would seem to be an extremely useful form, but the examples in the documentation do not appear to cover it. They do cover the ->* form, but not the ->i for that combination. Thanks! -Kevin From dfeltey at ccs.neu.edu Sun Aug 24 01:24:15 2014 From: dfeltey at ccs.neu.edu (dfeltey at ccs.neu.edu) Date: Sun, 24 Aug 2014 01:24:15 -0400 (EDT) Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <11137808.851961408857687363.JavaMail.root@zimbra> Message-ID: <4448938.852001408857855972.JavaMail.root@zimbra> Keywords should be followed by an id+ctc as described in the documentation, so something like the following should work (->i ([lst list?]) (#:foo [foo (lst) foo?]) (result list?)) Hope this helps Dan ----- Original Message ----- From: "Kevin Forchione" To: "Racket Users" Sent: Sunday, August 24, 2014 1:03:58 AM GMT -05:00 US/Canada Eastern Subject: [racket] contracts ->i optional keyword syntax I?ve been trying to figure out the syntax for optional keywords in the ->i contract form. For example: (->i ([lst list?]) ([#:foo ?.]) ; what does this look like? (result list?)) The mandatory domain syntax seems straightforward, but I?ve tried various combinations for the optional keyword that don?t appear to be correct. (->i ([lst list?]) ([#:foo (lst) (?.etc))) (result list?)) doesn?t work for me, neither does sticking an id before or after ? (lat) ? Does anyone have an example of an optional keyword ->i contract? This would seem to be an extremely useful form, but the examples in the documentation do not appear to cover it. They do cover the ->* form, but not the ->i for that combination. Thanks! -Kevin ____________________ Racket Users list: http://lists.racket-lang.org/users From lysseus at gmail.com Sun Aug 24 03:17:15 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Sun, 24 Aug 2014 00:17:15 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <9F4C17FC-FBB8-485A-8061-D98E45F7F90C@gmail.com> References: <9F4C17FC-FBB8-485A-8061-D98E45F7F90C@gmail.com> Message-ID: <7FAA0CA0-38DF-4128-BEC4-EBF96D7FA810@gmail.com> On Aug 23, 2014, at 10:03 PM, Kevin Forchione wrote: > I?ve been trying to figure out the syntax for optional keywords in the ->i contract form. For example: > > (->i ([lst list?]) > ([#:foo ?.]) ; what does this look like? > (result list?)) > > The mandatory domain syntax seems straightforward, but I?ve tried various combinations for the optional keyword that don?t appear to be correct. > > (->i ([lst list?]) > ([#:foo (lst) (?.etc))) > (result list?)) > > doesn?t work for me, neither does sticking an id before or after ? (lat) ? > > Does anyone have an example of an optional keyword ->i contract? This would seem to be an extremely useful form, but the examples in the documentation do not appear to cover it. They do cover the ->* form, but not the ->i for that combination. Well, I seem to have sussed it. But I find it odd that the contract doesn?t appear to apply to the optional value as supplied. For example, the below shows a sample of ->*, and an ->i version that shows points up the issue: #lang racket (define/contract (foo x #:y y #:z (z 42)) (->* (integer? #:y integer?) (#:z integer?) list?) (list x y z)) (foo 3 #:y 1) (define/contract (bar x #:y y #:z (z 42)) (->i ([x integer?] #:y (y integer?)) (#:z (z (x y) (integer-in x y))) (result list?)) (list x y z)) (bar 3 #:y 5) (bar 3 #:y 5 #:z 4) -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From robby at eecs.northwestern.edu Sun Aug 24 03:35:29 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Sun, 24 Aug 2014 02:35:29 -0500 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <7FAA0CA0-38DF-4128-BEC4-EBF96D7FA810@gmail.com> References: <9F4C17FC-FBB8-485A-8061-D98E45F7F90C@gmail.com> <7FAA0CA0-38DF-4128-BEC4-EBF96D7FA810@gmail.com> Message-ID: The default value is considered "inside" the contract boundary, not outside. Robby On Sun, Aug 24, 2014 at 2:17 AM, Kevin Forchione wrote: > > On Aug 23, 2014, at 10:03 PM, Kevin Forchione wrote: > > I?ve been trying to figure out the syntax for optional keywords in the ->i > contract form. For example: > > (->i ([lst list?]) > ([#:foo ?.]) ; what does this look like? > (result list?)) > > The mandatory domain syntax seems straightforward, but I?ve tried various > combinations for the optional keyword that don?t appear to be correct. > > (->i ([lst list?]) > ([#:foo (lst) (?.etc))) > (result list?)) > > doesn?t work for me, neither does sticking an id before or after ? (lat) ? > > Does anyone have an example of an optional keyword ->i contract? This would > seem to be an extremely useful form, but the examples in the documentation > do not appear to cover it. They do cover the ->* form, but not the ->i for > that combination. > > > Well, I seem to have sussed it. But I find it odd that the contract doesn?t > appear to apply to the optional value as supplied. For example, the below > shows a sample of ->*, and an ->i version that shows points up the issue: > > #lang racket > > (define/contract (foo x #:y y #:z (z 42)) > (->* (integer? > #:y integer?) > (#:z integer?) > list?) > (list x y z)) > > (foo 3 #:y 1) > > (define/contract (bar x #:y y #:z (z 42)) > (->i ([x integer?] > #:y (y integer?)) > (#:z (z (x y) (integer-in x y))) > (result list?)) > (list x y z)) > > (bar 3 #:y 5) > (bar 3 #:y 5 #:z 4) > > -Kevin > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From mflatt at cs.utah.edu Sun Aug 24 09:49:40 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Sun, 24 Aug 2014 07:49:40 -0600 Subject: [racket] racket/gui: changing the background color In-Reply-To: References: <20140822193619.DF7BA650181@mail-svr1.cs.utah.edu> Message-ID: <20140824134941.E429465018E@mail-svr1.cs.utah.edu> At Fri, 22 Aug 2014 16:28:50 -0500, David Nelson wrote: > Why don't pane% and panel% honor the stretchable-width and > stretchable-height properties of their children. The `pane%` and `panel%` classes weren't meant to be instantiated directly, but as base classes to be extended with a useful placement strategy... > Setting the minimum width and height the same for all children is OK as a > starting point, but if the window grows and you want that space to grow > too, the children are not currently stretched out. I ended up creating a > custom pane% that overrides place-children, but it seems the default > implementation could do this. I didn't think of this as useful, because it would leave children overlapping, and overlapping children generally don't display well. In the case that you'll show only one child at a time, though, I agree that the default you suggest seems sensible and useful. I've pushed that change. > 2) I want to arrange a canvas as a background behind other objects. After > playing with this, the only other things that seem to reliably work in the > foreground are other canvases so I understand this would not be a typical > use. Right. I've tried before and not succeeded in providing better support for drawing the background behind controls. I forget exactly why it doesn't work out, but it has to do with the way platform-specific toolkits draw controls. I think that putting a canvas with 'transparent over another canvas should work, but there may be Z-order issues, still. From lysseus at gmail.com Sun Aug 24 14:05:50 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Sun, 24 Aug 2014 11:05:50 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: References: <9F4C17FC-FBB8-485A-8061-D98E45F7F90C@gmail.com> <7FAA0CA0-38DF-4128-BEC4-EBF96D7FA810@gmail.com> Message-ID: <8A08369A-A012-423D-A9A1-EAE521FD0E17@gmail.com> On Aug 24, 2014, at 12:35 AM, Robby Findler wrote: > The default value is considered "inside" the contract boundary, not outside. Oh, that makes perfect sense. I?ll have to keep boundaries in mind. -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From lysseus at gmail.com Sun Aug 24 16:59:45 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Sun, 24 Aug 2014 13:59:45 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <4448938.852001408857855972.JavaMail.root@zimbra> References: <4448938.852001408857855972.JavaMail.root@zimbra> Message-ID: On Aug 23, 2014, at 10:24 PM, dfeltey at ccs.neu.edu wrote: > Keywords should be followed by an id+ctc as described in the documentation, so something like the following should work > > (->i ([lst list?]) > (#:foo [foo (lst) foo?]) > (result list?)) > > > Hope this helps > Dan Yes, neither reference nor guide provided an example for this case, and it seems I need to get more familiar with the BNF notation of the reference! Even after more than 30 years in computer programming I find the journey continues to be one of simultaneously pulling oneself up by one?s bootstraps while shrinking the wholes in the swiss cheese of my knowledge, with the haunting suspicion that I?ve somehow failed to grasp some vital concepts that elude me like Monty Python?s Holy Grail. So in that quest every little helps. :) -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From dcherkassov at gmail.com Sun Aug 24 17:00:55 2014 From: dcherkassov at gmail.com (Dmitry Cherkassov) Date: Mon, 25 Aug 2014 01:00:55 +0400 Subject: [racket] Asynchronously inserting text to editor% Message-ID: Hi. I am asyncrhonously insert text strings to editor% (from another thread) The problem is that i sometimes get this exception from object of editor% class: sequence-contract-violation: negative: method insert cannot be called, except in states (unlocked) I've tried to loop while editor is locked calling these functions http://docs.racket-lang.org/gui/editor___.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._editor~3c~25~3e%29._locked-for-flow~3f%29%29 But it seems they do not work for me (do not return if editor is locked) and still that exception in caused. I've fallen back to ugly loop then. (define retry (call/cc (lambda (k) k))) (with-handlers ([exn:fail? (lambda (ex) (sleep 1) (retry retry))]) (send editor insert message)) Is there a better way? P.S Full source code for that stuff is available there: ------------------------------------------------------------------------------- https://github.com/lehitoskin/blight/blob/master/msg-history.rkt#L143 `add-recv-message' is called by `on-friend-message': https://github.com/lehitoskin/blight/blob/master/blight.rkt#L956 which is called back by `callback-friend-message' C function: https://github.com/lehitoskin/libtoxcore-racket/blob/master/functions.rkt#L489 ---------------------------------------------------------------------------------- Thank you. -- With best regards, Dmitry From matthias at ccs.neu.edu Sun Aug 24 17:09:18 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 24 Aug 2014 17:09:18 -0400 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: References: <4448938.852001408857855972.JavaMail.root@zimbra> Message-ID: <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> On Aug 24, 2014, at 4:59 PM, Kevin Forchione wrote: > > On Aug 23, 2014, at 10:24 PM, dfeltey at ccs.neu.edu wrote: > >> Keywords should be followed by an id+ctc as described in the documentation, so something like the following should work >> >> (->i ([lst list?]) >> (#:foo [foo (lst) foo?]) >> (result list?)) >> >> >> Hope this helps >> Dan > > Yes, neither reference nor guide provided an example for this case, and it seems I need to get more familiar with the BNF notation of the reference! > > Even after more than 30 years in computer programming I find the journey continues to be one of simultaneously pulling oneself up by one?s bootstraps while shrinking the wholes in the swiss cheese of my knowledge, with the haunting suspicion that I?ve somehow failed to grasp some vital concepts that elude me like Monty Python?s Holy Grail. So in that quest every little helps. :) Before you make fondue, ask. As you can see, people answer and answer quickly. Indeed, Robby added an example to the Guide as he responded and pushed it out into the repo. The next release will have an example due to your posts. Thanks! Having said that, Racket is created by people who focus on systematic design of software. The contract system is an example of this; -- it serves the purpose of creating software systematically (continuing the so-called Design by Contract line of work) -- it itself is developed systematically with inquires into the semantics of contracts because we took contracts way beyond the primitive notion from the 1980s and 1990s. But, the existence of ->i and ->d should give you a hint that we occasionally make mistakes and we try to correct them without modifying existing code. ->d is mostly okay, but ->i is better. When Robby created ->i, he also used his experience with ->d to force programmers to list dependency variables explicitly. That's why you have to say "(lst)", for example. In addition, the language grows and with it, we have to grow the contract system. Keyword arguments is an example of that kind. As for the philosophy behind our contract system, I think the guide's opening section on boundaries brings across the idea that separates our contracts from old-style stuff. It may not become immediately clear, but when you program with contracts for a while, you will appreciate it. -- Matthias -------------- next part -------------- An HTML attachment was scrubbed... URL: From mkjxocai at gmail.com Sun Aug 24 19:03:56 2014 From: mkjxocai at gmail.com (Maria Jenkins) Date: Sun, 24 Aug 2014 17:03:56 -0600 Subject: [racket] Latex Symbols Message-ID: Hello all, I am writing a paper and the implementation was done in redex. My question is when I render the semantics and state space is there a way to get a wide hat symbol to print out over some of the characters like in latex? Thank you! Maria From alexander at knauth.org Sun Aug 24 20:11:37 2014 From: alexander at knauth.org (Alexander D. Knauth) Date: Sun, 24 Aug 2014 20:11:37 -0400 Subject: [racket] =?utf-8?b?aW50ZXJwcmV0aW5nIGDOuycgYXMgYMOOJyA/?= Message-ID: <7BA36888-1AD0-4C9D-9A22-21B761283D2F@knauth.org> On pkg-build.racket-lang.org/server/built/fail/afl.txt, my afl package is failing with it saying read: bad syntax `#??? But in the place that it?s pointing to, I have #? So is there anything wrong with either how the file is written or how pkg-build.racket-lang.org is interpreting it? And is there anything I can do to either right the file properly or tell pkg-build.racket-lang.org how to interpret it? From mflatt at cs.utah.edu Sun Aug 24 20:29:32 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Sun, 24 Aug 2014 18:29:32 -0600 Subject: [racket] =?utf-8?b?aW50ZXJwcmV0aW5nIGDOuycgYXMgYMOOJyA/?= In-Reply-To: <7BA36888-1AD0-4C9D-9A22-21B761283D2F@knauth.org> References: <7BA36888-1AD0-4C9D-9A22-21B761283D2F@knauth.org> Message-ID: <20140825002933.8C7AC65018E@mail-svr1.cs.utah.edu> I think there's no encoding problem with the install, but there's a problem in the way that "fail/afl.txt" is served to browsers. The server should tell browsers to use UTF-8 (as opposed to Latin-1) to show the failure log; I'll work on that. Meanwhile, the install fails for with v6.1 but not the current development version. As I recall, we had to adjust the at-exp reader to compose nicely with afl. Maybe drop "test-afl-at-exp-racket.rkt" for a v6.1-compatible variant of the package? At Sun, 24 Aug 2014 20:11:37 -0400, "Alexander D. Knauth" wrote: > On pkg-build.racket-lang.org/server/built/fail/afl.txt, my afl package is > failing with it saying read: bad syntax `#??? > But in the place that it?s pointing to, I have #? > > So is there anything wrong with either how the file is written or how > pkg-build.racket-lang.org is interpreting it? > > And is there anything I can do to either right the file properly or tell > pkg-build.racket-lang.org how to interpret it? > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Sun Aug 24 22:02:05 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Sun, 24 Aug 2014 20:02:05 -0600 Subject: [racket] Latex Symbols In-Reply-To: References: Message-ID: <20140825020206.82A4065018E@mail-svr1.cs.utah.edu> At Sun, 24 Aug 2014 17:03:56 -0600, Maria Jenkins wrote: > I am writing a paper and the implementation was done in redex. > > My question is when I render the semantics and state space is there a way to > get a wide hat symbol to print out over some of the characters like in latex? Someone else may have a better answer, but the enclosed example shows one approach. It implements a rewriter for `in-hat`, which causes the term (in-hat apple) to render as "apple" with a hat. The "hat.scrbl" file just uses the pict in a demo document. The rewriter for `in-hat` works by first rendering the argument to a pict. Then, it uses the `dc` pict constructor to generate a hat, where the function passed to `dc` uses the `racket/draw` library. The hat is placed on the argument with `pin-over`, which is also from the `pict` library. Finally, the `refit` helper function makes the generated representation have the same line and column span as the original so that it will work right in a larger context. (None of that is easy; if this is on the right track, then clearly it belongs in a library.) -------------- next part -------------- A non-text attachment was scrubbed... Name: hat.rkt Type: application/octet-stream Size: 2476 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: hat.scrbl Type: application/octet-stream Size: 58 bytes Desc: not available URL: From robby at eecs.northwestern.edu Sun Aug 24 22:02:24 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Sun, 24 Aug 2014 21:02:24 -0500 Subject: [racket] Latex Symbols In-Reply-To: References: Message-ID: There isn't built-in support for that, I'm sorry to say. You can use unicode characters that have hats on them, which should be straightforward, or you can implement a function that accepts and returns picts and then draws a hat on top of the given pict to produce the result pict. Below is a start on such a function. You'll need to use the redex pict adjustment combinators to actually use this function, tho, and how you do that depends on how your model is set up. hth, Robby #lang racket (require pict) (define (wide-hat p) (define hat-h (* (pict-height p) .2)) (define hat-w (pict-width p)) (define (draw-hat dc dx y) (send dc draw-line dx (+ dy hat-h) (+ dx (/ hat-w 2)) dy) (send dc draw-line (+ dx (/ hat-w 2)) dy (+ dx hat-w) (+ dy hat-h))) (inset (refocus (vl-append (dc draw-hat hat-w hat-h) p) p) 0 hat-h 0 0)) (wide-hat (text "a")) (wide-hat (text "a+b+c+d")) On Sun, Aug 24, 2014 at 6:03 PM, Maria Jenkins wrote: > > Hello all, > > I am writing a paper and the implementation was done in redex. > > My question is when I render the semantics and state space is there a way to get a wide hat symbol to print out over some of the characters like in latex? > > Thank you! > > Maria > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From matthias at ccs.neu.edu Sun Aug 24 23:10:22 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Sun, 24 Aug 2014 23:10:22 -0400 Subject: [racket] Latex Symbols In-Reply-To: References: Message-ID: I tend to cheat in such situations and use @latex{\hat{x}}. -- Matthias On Aug 24, 2014, at 7:03 PM, Maria Jenkins wrote: > > Hello all, > > I am writing a paper and the implementation was done in redex. > > My question is when I render the semantics and state space is there a way to get a wide hat symbol to print out over some of the characters like in latex? > > Thank you! > > Maria > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From hirotaka.niitsuma at gmail.com Mon Aug 25 06:10:50 2014 From: hirotaka.niitsuma at gmail.com (Niitsuma Hirotaka) Date: Mon, 25 Aug 2014 19:10:50 +0900 Subject: [racket] copy-shared-files and different platforms In-Reply-To: References: Message-ID: cmake can detect platform dependant lib path. For example cmake can find libpoppler as the following mkdir -p cmake/Modules wget https://raw.githubusercontent.com/Eyescale/CMake/master/FindPoppler.cmake mv FindPoppler.cmake cmake/Modules/ cat CMakeLists.txt --------- set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/ Modules/") find_package(Poppler REQUIRED) message("Libs of poppler: " ${POPPLER_LIBRARIES} ) file(WRITE poppler.txt ${POPPLER_LIBRARIES} ) --------- cmake . then poppler.txt contain libpoppler path platform dependant install dest also can be auto custimzed by cmake. install(TARGETS yourtargetname DESTINATION lib ) 2014-08-24 1:21 GMT+09:00 Jens Axel S?gaard : > Hi All, > > How exactly are copy-shared-files to be used? > > I have a set of shared libraries for different platforms in: > > racket-poppler/poppler-libs/poppler-i386-macosx > racket-poppler/poppler-libs/poppler-win32-i386 > etc. > > My info file is here: > > https://github.com/soegaard/racket-poppler/blob/master/info.rkt > > I tried listing the folder poppler-libs, but it seems not to work. > > /Jens Axel > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From jensaxel at soegaard.net Mon Aug 25 10:06:15 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Mon, 25 Aug 2014 16:06:15 +0200 Subject: [racket] copy-shared-files and different platforms In-Reply-To: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> Message-ID: 2014-08-23 20:12 GMT+02:00 Matthew Flatt : > The `install-platform` definitions in those "info.rkt" files mean that > only libraries for the current platform will be installed. It's > probably better for each directory within "poppler-libs" to be its own > package, so that an installation gets only the libraries for the > installation's platform, but the current way should work. Got it. Each platform gets its own package. This leads to the question: How can I have multiple packages in the same GitHub repository? This package is for i386-macosx: http://pkgs.racket-lang.org/#[poppler-i386-macosx] At Github the package is at: https://github.com/soegaard/poppler-libs/tree/master/poppler-i386-macosx So I entered: Source: github://github.com/soegaard/poppler-libs/tree/master/poppler-i386-macosx Alas, pgk.racket-lang.org produces an error: Checksum:Error: =: contract violation expected: number? given: # argument position: 1st other arguments...: 31 From mflatt at cs.utah.edu Mon Aug 25 10:11:56 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 25 Aug 2014 08:11:56 -0600 Subject: [racket] copy-shared-files and different platforms In-Reply-To: References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> Message-ID: <20140825141158.88847650190@mail-svr1.cs.utah.edu> At Mon, 25 Aug 2014 16:06:15 +0200, Jens Axel S?gaard wrote: > 2014-08-23 20:12 GMT+02:00 Matthew Flatt : > > > The `install-platform` definitions in those "info.rkt" files mean that > > only libraries for the current platform will be installed. It's > > probably better for each directory within "poppler-libs" to be its own > > package, so that an installation gets only the libraries for the > > installation's platform, but the current way should work. > > Got it. Each platform gets its own package. > > This leads to the question: How can I have multiple packages in the > same GitHub repository? > > This package is for i386-macosx: > http://pkgs.racket-lang.org/#[poppler-i386-macosx] > > At Github the package is at: > https://github.com/soegaard/poppler-libs/tree/master/poppler-i386-macosx > > So I entered: > Source: > github://github.com/soegaard/poppler-libs/tree/master/poppler-i386-macosx To specify a path within a repo, use a "path=..." query with the "git:" package-source format: git://github.com/soegaard/poppler-libs?path=poppler-i386-macosx From svenpanne at gmail.com Mon Aug 25 11:16:53 2014 From: svenpanne at gmail.com (Sven Panne) Date: Mon, 25 Aug 2014 17:16:53 +0200 Subject: [racket] sllgen:make-rep-loop in Racket 6.1 Message-ID: I've just updated my Racket installation to 6.1 (Windows 64bit), and something seems to be strange with sllgen:make-rep-loop: Although the auto-completion finds it (and other sllgen stuff), it seems to be unbound. Tiny repro: ----------------------------------------------------------------------------------------- #lang eopl (display sllgen:make-rep-loop) ----------------------------------------------------------------------------------------- The output (in German, but I think you get the point): ----------------------------------------------------------------------------------------- Willkommen bei DrRacket, Version 6.1 [3m]. Sprache: eopl [angepasst]; memory limit: 128 MB. sllgen:make-rep-loop: unbound identifier in module in: sllgen:make-rep-loop ----------------------------------------------------------------------------------------- If I run the same program in Racket 5.3 (Linux x64), I get: ----------------------------------------------------------------------------------------- Welcome to DrRacket, version 5.3 [3m]. Language: eopl; memory limit: 128 MB. # ----------------------------------------------------------------------------------------- Is this a bug in 6.1 or am I doing something wrong? I've discovered that while trying out my old EOPL exercise, which don't work anymore... :-/ Cheers, S. From jensaxel at soegaard.net Mon Aug 25 11:52:03 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Mon, 25 Aug 2014 17:52:03 +0200 Subject: [racket] copy-shared-files and different platforms In-Reply-To: <20140825141158.88847650190@mail-svr1.cs.utah.edu> References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> <20140825141158.88847650190@mail-svr1.cs.utah.edu> Message-ID: 2014-08-25 16:11 GMT+02:00 Matthew Flatt : > At Mon, 25 Aug 2014 16:06:15 +0200, Jens Axel S?gaard wrote: >> 2014-08-23 20:12 GMT+02:00 Matthew Flatt : > package-source format: > > git://github.com/soegaard/poppler-libs?path=poppler-i386-macosx Thanks! Getting closer... The libraries are now copied in to /Users/soegaard/Library/Racket/6.1/lib/ But for some reason ffi-lib can't find them? The following is from newly installed Racket 6.1. downloaded from the racket-lang.org after installing the package poppler-i386-macosx via the package manager. Running: #lang racket (require ffi/unsafe setup/dirs) (directory-list (find-user-lib-dir)) (ffi-lib "libpoppler-glib" '("8")) The output: Welcome to DrRacket, version 6.1 [3m]. Language: racket [custom]; memory limit: 512 MB. '(# # #) . ffi-lib: couldn't open "libpoppler-glib.8.dylib" (dlopen(libpoppler-glib.8.dylib, 6): image not found) Am I missing something? /Jens Axel -- -- Jens Axel S?gaard From mflatt at cs.utah.edu Mon Aug 25 12:07:36 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 25 Aug 2014 10:07:36 -0600 Subject: [racket] copy-shared-files and different platforms In-Reply-To: References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> <20140825141158.88847650190@mail-svr1.cs.utah.edu> Message-ID: <20140825160738.0FA21650195@mail-svr1.cs.utah.edu> At Mon, 25 Aug 2014 17:52:03 +0200, Jens Axel S?gaard wrote: > 2014-08-25 16:11 GMT+02:00 Matthew Flatt : > > At Mon, 25 Aug 2014 16:06:15 +0200, Jens Axel S?gaard wrote: > >> 2014-08-23 20:12 GMT+02:00 Matthew Flatt : > > > package-source format: > > > > git://github.com/soegaard/poppler-libs?path=poppler-i386-macosx > > Thanks! Getting closer... > > The libraries are now copied in to /Users/soegaard/Library/Racket/6.1/lib/ > > But for some reason ffi-lib can't find them? > > The following is from newly installed Racket 6.1. downloaded > from the racket-lang.org after installing the package poppler-i386-macosx > via the package manager. > > Running: > > #lang racket > (require ffi/unsafe setup/dirs) > (directory-list (find-user-lib-dir)) > (ffi-lib "libpoppler-glib" '("8")) > > The output: > > Welcome to DrRacket, version 6.1 [3m]. > Language: racket [custom]; memory limit: 512 MB. > '(# # > #) > . ffi-lib: couldn't open "libpoppler-glib.8.dylib" > (dlopen(libpoppler-glib.8.dylib, 6): image not found) > > Am I missing something? Does it work if you install the package in installation scope, instead of user scope? I think the problem is "@loader_path/libgio-2.0.0.dylib" and similar references in the ".dylib" files. That is, the "libpoppler-glib.8.dylib" library is found by `ffil-lib`, but the load fails because libraries referenced by "libpoppler-glib.8.dylib" are not found in the expected location. The "@loader_path" references mean that the shared libraries as currently compiled work only when installed in the same scope as the `racket/draw` libraries. Offhand, I don't have a good idea for solving this problem. (FWIW, Windows installations won't have this problem.) From davidcnelson at gmail.com Mon Aug 25 12:34:47 2014 From: davidcnelson at gmail.com (David Nelson) Date: Mon, 25 Aug 2014 11:34:47 -0500 Subject: [racket] racket/gui: changing the background color In-Reply-To: <20140824134941.E429465018E@mail-svr1.cs.utah.edu> References: <20140822193619.DF7BA650181@mail-svr1.cs.utah.edu> <20140824134941.E429465018E@mail-svr1.cs.utah.edu> Message-ID: On Sun, Aug 24, 2014 at 8:49 AM, Matthew Flatt wrote: > At Fri, 22 Aug 2014 16:28:50 -0500, David Nelson wrote: > > Why don't pane% and panel% honor the stretchable-width and > > stretchable-height properties of their children. > > In the case that you'll show only one child at a time, though, I agree > that the default you suggest seems sensible and useful. I've pushed > that change. > Thank you. The consistency with the rest of the classes makes it a bit friendlier. > 2) I want to arrange a canvas as a background behind other objects. After > > playing with this, the only other things that seem to reliably work in > the > > foreground are other canvases so I understand this would not be a typical > > use. > > Right. I've tried before and not succeeded in providing better support > for drawing the background behind controls. I forget exactly why it > doesn't work out, but it has to do with the way platform-specific > toolkits draw controls. I think that putting a canvas with 'transparent > over another canvas should work, but there may be Z-order issues, still. > Trying to create a cross platform framework that uses native controls is quite a challenge. I was surprised how well placing controls over a canvas worked on OS X. On the other hand the results on Linux showed just how challenging this is. For example, transparent canvas backgrounds worked fine on OS X, but on Linux (in a VM), it filled the background with white. Thanks to all who were involved for a useful GUI framework. When I started work on our first generation program and test system several years ago, I dreaded the thought of having to write an X program for the UI. A friend directed me to Racket. My previous job was programming in Common Lisp, so picking up Racket was rather easy. Having the gui framework made it rather easy to throw together the UI so I could concentrate on creating the main programming state machine and the other threads to handle the various parts of the system. -- David -------------- next part -------------- An HTML attachment was scrubbed... URL: From jensaxel at soegaard.net Mon Aug 25 12:50:24 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Mon, 25 Aug 2014 18:50:24 +0200 Subject: [racket] copy-shared-files and different platforms In-Reply-To: <20140825160738.0FA21650195@mail-svr1.cs.utah.edu> References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> <20140825141158.88847650190@mail-svr1.cs.utah.edu> <20140825160738.0FA21650195@mail-svr1.cs.utah.edu> Message-ID: >> Am I missing something? > > Does it work if you install the package in installation scope, instead > of user scope? Yes! Using ./raco pkg install --scope installation poppler-i386-macosx from the command line worked. And later I saw that the GUI also allows one to choose installation scope in settings. > I think the problem is "@loader_path/libgio-2.0.0.dylib" and similar > references in the ".dylib" files. That is, the > "libpoppler-glib.8.dylib" library is found by `ffil-lib`, but the load > fails because libraries referenced by "libpoppler-glib.8.dylib" are not > found in the expected location. This problem is luckily restricted to a fairly small set of libraries. > The "@loader_path" references mean that the shared libraries as > currently compiled work only when installed in the same scope as the > `racket/draw` libraries. Offhand, I don't have a good idea for solving > this problem. (FWIW, Windows installations won't have this problem.) I have yet to test on Windows. Thanks for the help, Jens Axel From mflatt at cs.utah.edu Mon Aug 25 19:46:00 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Mon, 25 Aug 2014 17:46:00 -0600 Subject: [racket] copy-shared-files and different platforms In-Reply-To: References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> <20140825141158.88847650190@mail-svr1.cs.utah.edu> <20140825160738.0FA21650195@mail-svr1.cs.utah.edu> Message-ID: <20140825234602.37E26650199@mail-svr1.cs.utah.edu> At Mon, 25 Aug 2014 18:50:24 +0200, Jens Axel S?gaard wrote: > > The "@loader_path" references mean that the shared libraries as > > currently compiled work only when installed in the same scope as the > > `racket/draw` libraries. Offhand, I don't have a good idea for solving > > this problem. (FWIW, Windows installations won't have this problem.) I've changed `raco setup` to replace "@loader_path" in installed Mach-O files with an absolute path as needed. From eli at barzilay.org Mon Aug 25 23:09:35 2014 From: eli at barzilay.org (Eli Barzilay) Date: Mon, 25 Aug 2014 23:09:35 -0400 Subject: [racket] Asynchronously inserting text to editor% In-Reply-To: References: Message-ID: You generally can't do that kind of stuff from a different thread... After fighting with this for a while I eventually realized that it's not too hard to avoid the extra thread: instead of doing the work there, just stick it in a closure that is handed to `queue-callback'. (This is based on lessons learned the hard way in an application that does a lot of this kind of stuff...) On Sun, Aug 24, 2014 at 5:00 PM, Dmitry Cherkassov wrote: > Hi. I am asyncrhonously insert text strings to editor% (from another thread) > > The problem is that i sometimes get this exception from object of editor% class: > > sequence-contract-violation: negative: method insert cannot be called, > except in states (unlocked) > > I've tried to loop while editor is locked calling these functions > http://docs.racket-lang.org/gui/editor___.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._editor~3c~25~3e%29._locked-for-flow~3f%29%29 > > But it seems they do not work for me (do not return if editor is > locked) and still that exception in caused. > > I've fallen back to ugly loop then. > > (define retry (call/cc (lambda (k) k))) > > (with-handlers ([exn:fail? > (lambda (ex) > (sleep 1) > (retry retry))]) > (send editor insert message)) > > > Is there a better way? > > P.S Full source code for that stuff is available there: > ------------------------------------------------------------------------------- > > https://github.com/lehitoskin/blight/blob/master/msg-history.rkt#L143 > > `add-recv-message' is called by `on-friend-message': > https://github.com/lehitoskin/blight/blob/master/blight.rkt#L956 > > which is called back by `callback-friend-message' C function: > https://github.com/lehitoskin/libtoxcore-racket/blob/master/functions.rkt#L489 > ---------------------------------------------------------------------------------- > > Thank you. > > -- > With best regards, > Dmitry > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! From dcherkassov at gmail.com Tue Aug 26 06:46:42 2014 From: dcherkassov at gmail.com (Dmitry Cherkassov) Date: Tue, 26 Aug 2014 14:46:42 +0400 Subject: [racket] Asynchronously inserting text to editor% In-Reply-To: References: Message-ID: Thanks for your reply. I've found that `disable`-ing canvas of text editor when inserting works too. But with downside that you cant select anything or move the cursor when bulk of text strings are inserted. 26 ???. 2014 ?. 7:09 ???????????? "Eli Barzilay" ???????: > You generally can't do that kind of stuff from a different thread... > After fighting with this for a while I eventually realized that it's > not too hard to avoid the extra thread: instead of doing the work > there, just stick it in a closure that is handed to `queue-callback'. > (This is based on lessons learned the hard way in an application that > does a lot of this kind of stuff...) > > > On Sun, Aug 24, 2014 at 5:00 PM, Dmitry Cherkassov > wrote: > > Hi. I am asyncrhonously insert text strings to editor% (from another > thread) > > > > The problem is that i sometimes get this exception from object of > editor% class: > > > > sequence-contract-violation: negative: method insert cannot be called, > > except in states (unlocked) > > > > I've tried to loop while editor is locked calling these functions > > > http://docs.racket-lang.org/gui/editor___.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._editor~3c~25~3e%29._locked-for-flow~3f%29%29 > > > > But it seems they do not work for me (do not return if editor is > > locked) and still that exception in caused. > > > > I've fallen back to ugly loop then. > > > > (define retry (call/cc (lambda (k) k))) > > > > (with-handlers ([exn:fail? > > (lambda (ex) > > (sleep 1) > > (retry retry))]) > > (send editor insert message)) > > > > > > Is there a better way? > > > > P.S Full source code for that stuff is available there: > > > ------------------------------------------------------------------------------- > > > > https://github.com/lehitoskin/blight/blob/master/msg-history.rkt#L143 > > > > `add-recv-message' is called by `on-friend-message': > > https://github.com/lehitoskin/blight/blob/master/blight.rkt#L956 > > > > which is called back by `callback-friend-message' C function: > > > https://github.com/lehitoskin/libtoxcore-racket/blob/master/functions.rkt#L489 > > > ---------------------------------------------------------------------------------- > > > > Thank you. > > > > -- > > With best regards, > > Dmitry > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > > -- > ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: > http://barzilay.org/ Maze is Life! > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eli at barzilay.org Tue Aug 26 07:11:17 2014 From: eli at barzilay.org (Eli Barzilay) Date: Tue, 26 Aug 2014 07:11:17 -0400 Subject: [racket] Asynchronously inserting text to editor% In-Reply-To: References: Message-ID: On Tue, Aug 26, 2014 at 6:46 AM, Dmitry Cherkassov wrote: > Thanks for your reply. I've found that `disable`-ing canvas of text editor > when inserting works too. But with downside that you cant select anything or > move the cursor when bulk of text strings are inserted. Well, that's why I said that you're much better off just doing the callback -- even if you disable things, you're likely to get the same problem later on. OTOH, doing a callback is easy, and can be done from a different thread with no issues, since the actual addition happens when the GUI is prepared to do so. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! From svenpanne at gmail.com Tue Aug 26 07:45:31 2014 From: svenpanne at gmail.com (Sven Panne) Date: Tue, 26 Aug 2014 13:45:31 +0200 Subject: [racket] sllgen:make-rep-loop in Racket 6.1 In-Reply-To: References: Message-ID: 2014-08-25 17:16 GMT+02:00 Sven Panne : > I've just updated my Racket installation to 6.1 (Windows 64bit), and > something seems to be strange with sllgen:make-rep-loop: Although the > auto-completion finds it (and other sllgen stuff), it seems to be > unbound. [...] I've just found this problem in the bug tracker, but the issue is over a year old, and there has been no reply so far: :-( http://bugs.racket-lang.org/query/?debug=&database=default&cmd=view+audit-trail&cmd=view&pr=13831 The commit which broke things is http://git.racket-lang.org/plt/commit/b265e260b259d36d38239cbeeb6dc191a5a542ef. The fix is easy, I think: Add sllgen:make-rep-loop to a provide in share/pkgs/eopl/private/sllgen.rkt again. I can build from source on Linux, but I need a fixed version on Windows, too. Can I just grab share/racket/pkgs/eopl/private/compiled/sllgen_rkt.zo from the compiled Linux version and put that into the corresponding folder on Windows? I've got no clue if the *.zo files are portable or not, but at least the "shared" in the path indicate that they might be. From robby at eecs.northwestern.edu Tue Aug 26 08:25:37 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Tue, 26 Aug 2014 07:25:37 -0500 Subject: [racket] Asynchronously inserting text to editor% In-Reply-To: References: Message-ID: The real issue here is that the implementation of text% is not thread-safe (nor are the GUI controls generally speaking). So when you modify them from two threads, strange things can happen. Robby On Tue, Aug 26, 2014 at 6:11 AM, Eli Barzilay wrote: > On Tue, Aug 26, 2014 at 6:46 AM, Dmitry Cherkassov > wrote: >> Thanks for your reply. I've found that `disable`-ing canvas of text editor >> when inserting works too. But with downside that you cant select anything or >> move the cursor when bulk of text strings are inserted. > > Well, that's why I said that you're much better off just doing the > callback -- even if you disable things, you're likely to get the same > problem later on. OTOH, doing a callback is easy, and can be done from > a different thread with no issues, since the actual addition happens > when the GUI is prepared to do so. > > -- > ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: > http://barzilay.org/ Maze is Life! > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From samth at cs.indiana.edu Tue Aug 26 08:27:50 2014 From: samth at cs.indiana.edu (Sam Tobin-Hochstadt) Date: Tue, 26 Aug 2014 08:27:50 -0400 Subject: [racket] sllgen:make-rep-loop in Racket 6.1 In-Reply-To: References: Message-ID: You should just be able to edit the relevant .rkt source file on Windows as well -- it should be in the racket/pkgs/eopl/private/sllgen.rkt file. Sam On Tue, Aug 26, 2014 at 7:45 AM, Sven Panne wrote: > 2014-08-25 17:16 GMT+02:00 Sven Panne : >> I've just updated my Racket installation to 6.1 (Windows 64bit), and >> something seems to be strange with sllgen:make-rep-loop: Although the >> auto-completion finds it (and other sllgen stuff), it seems to be >> unbound. [...] > > I've just found this problem in the bug tracker, but the issue is over > a year old, and there has been no reply so far: :-( > > http://bugs.racket-lang.org/query/?debug=&database=default&cmd=view+audit-trail&cmd=view&pr=13831 > > The commit which broke things is > http://git.racket-lang.org/plt/commit/b265e260b259d36d38239cbeeb6dc191a5a542ef. > The fix is easy, I think: Add sllgen:make-rep-loop to a provide in > share/pkgs/eopl/private/sllgen.rkt again. I can build from source on > Linux, but I need a fixed version on Windows, too. Can I just grab > share/racket/pkgs/eopl/private/compiled/sllgen_rkt.zo from the > compiled Linux version and put that into the corresponding folder on > Windows? I've got no clue if the *.zo files are portable or not, but > at least the "shared" in the path indicate that they might be. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From mflatt at cs.utah.edu Tue Aug 26 08:30:37 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Tue, 26 Aug 2014 06:30:37 -0600 Subject: [racket] Asynchronously inserting text to editor% In-Reply-To: References: Message-ID: <20140826123038.B798965018E@mail-svr1.cs.utah.edu> See also http://docs.racket-lang.org/gui/editor-overview.html#%28part._editorthreads%29 which explains why you probably need to make sure your changes from the non-main thread are always between `begin-edit-sequence` and `end-edit-sequence`. At Tue, 26 Aug 2014 07:25:37 -0500, Robby Findler wrote: > The real issue here is that the implementation of text% is not > thread-safe (nor are the GUI controls generally speaking). So when you > modify them from two threads, strange things can happen. > > Robby > > On Tue, Aug 26, 2014 at 6:11 AM, Eli Barzilay wrote: > > On Tue, Aug 26, 2014 at 6:46 AM, Dmitry Cherkassov > > wrote: > >> Thanks for your reply. I've found that `disable`-ing canvas of text editor > >> when inserting works too. But with downside that you cant select anything or > >> move the cursor when bulk of text strings are inserted. > > > > Well, that's why I said that you're much better off just doing the > > callback -- even if you disable things, you're likely to get the same > > problem later on. OTOH, doing a callback is easy, and can be done from > > a different thread with no issues, since the actual addition happens > > when the GUI is prepared to do so. > > > > -- > > ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: > > http://barzilay.org/ Maze is Life! > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From jensaxel at soegaard.net Tue Aug 26 10:48:24 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Tue, 26 Aug 2014 16:48:24 +0200 Subject: [racket] copy-shared-files and different platforms In-Reply-To: <20140825234602.37E26650199@mail-svr1.cs.utah.edu> References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> <20140825141158.88847650190@mail-svr1.cs.utah.edu> <20140825160738.0FA21650195@mail-svr1.cs.utah.edu> <20140825234602.37E26650199@mail-svr1.cs.utah.edu> Message-ID: 2014-08-26 1:46 GMT+02:00 Matthew Flatt : > At Mon, 25 Aug 2014 18:50:24 +0200, Jens Axel S?gaard wrote: >> > The "@loader_path" references mean that the shared libraries as >> > currently compiled work only when installed in the same scope as the >> > `racket/draw` libraries. Offhand, I don't have a good idea for solving >> > this problem. (FWIW, Windows installations won't have this problem.) > > I've changed `raco setup` to replace "@loader_path" in installed Mach-O > files with an absolute path as needed. Sounds great. I have a similar problem on Windows 7 Enterprise SP1. The dynamic library is copied into the result of (find-user-lib-dir) namely c:\Users\js\AppData\Roaming\Racket\6.1\lib The odd thing is that (ffi-lib "libpoppler-glib" '("8")) looks for "libpoppler-glib.dll.8" instead of "libpoppler-glib-8.dll". Should I just rename the file or is it a bug? /Jens Axel From mflatt at cs.utah.edu Tue Aug 26 11:04:45 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Tue, 26 Aug 2014 09:04:45 -0600 Subject: [racket] copy-shared-files and different platforms In-Reply-To: References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> <20140825141158.88847650190@mail-svr1.cs.utah.edu> <20140825160738.0FA21650195@mail-svr1.cs.utah.edu> <20140825234602.37E26650199@mail-svr1.cs.utah.edu> Message-ID: <20140826150446.5392C650185@mail-svr1.cs.utah.edu> At Tue, 26 Aug 2014 16:48:24 +0200, Jens Axel S?gaard wrote: > 2014-08-26 1:46 GMT+02:00 Matthew Flatt : > > At Mon, 25 Aug 2014 18:50:24 +0200, Jens Axel S?gaard wrote: > >> > The "@loader_path" references mean that the shared libraries as > >> > currently compiled work only when installed in the same scope as the > >> > `racket/draw` libraries. Offhand, I don't have a good idea for solving > >> > this problem. (FWIW, Windows installations won't have this problem.) > > > > I've changed `raco setup` to replace "@loader_path" in installed Mach-O > > files with an absolute path as needed. > > Sounds great. > > I have a similar problem on Windows 7 Enterprise SP1. > > The dynamic library is copied into the result of (find-user-lib-dir) > namely c:\Users\js\AppData\Roaming\Racket\6.1\lib > > The odd thing is that (ffi-lib "libpoppler-glib" '("8")) looks > for "libpoppler-glib.dll.8" instead of "libpoppler-glib-8.dll". > > Should I just rename the file or is it a bug? I think the way that version numbers are currently added to Windows DLL names is probably not useful, and I will look into adjusting that. Meanwhile, you could use `ffi-lib` on a different library name for Windows, which is how `racket/draw`, etc., currently work. Another detail for Windows is that you need to explicitly load a DLL X is that referenced by a DLL Y before loading Y. That's the flip side of not having to worry about something like "@loader_path": instead of a static reference to another library embedded in the DLL, the "path" is determined dynamically by loading a shared library before it is needed. That load-before-reference issue is partly why you see a list of DLLs at https://github.com/plt/racket/blob/master/pkgs/draw-pkgs/draw-lib/racket/draw/unsafe/cairo-lib.rkt Another reason for the list of libraries there (and why it shows up for Mac OS X, too) is to ensure that shared libraries are pulled along for stand-alone executables. The `define-runtime-lib` macro expands to `define-runtime-path-list` as well as `ffi-lib`. From jensaxel at soegaard.net Tue Aug 26 11:55:03 2014 From: jensaxel at soegaard.net (=?UTF-8?Q?Jens_Axel_S=C3=B8gaard?=) Date: Tue, 26 Aug 2014 17:55:03 +0200 Subject: [racket] copy-shared-files and different platforms In-Reply-To: <20140826150446.5392C650185@mail-svr1.cs.utah.edu> References: <20140823181203.C30D7650185@mail-svr1.cs.utah.edu> <20140825141158.88847650190@mail-svr1.cs.utah.edu> <20140825160738.0FA21650195@mail-svr1.cs.utah.edu> <20140825234602.37E26650199@mail-svr1.cs.utah.edu> <20140826150446.5392C650185@mail-svr1.cs.utah.edu> Message-ID: 2014-08-26 17:04 GMT+02:00 Matthew Flatt : > Another detail for Windows is that you need to explicitly load a DLL X > is that referenced by a DLL Y before loading Y. Thanks for the hint! I suppose libffi doesn't indicate in the error number whether loading failed due to a missing dependency or a missing lib? > That load-before-reference issue is partly why you see a list of DLLs > at > > https://github.com/plt/racket/blob/master/pkgs/draw-pkgs/draw-lib/racket/draw/unsafe/cairo-lib.rkt I'll copy the method. > Another reason for the list of libraries there (and why it shows up for > Mac OS X, too) is to ensure that shared libraries are pulled along for > stand-alone executables. The `define-runtime-lib` macro expands to > `define-runtime-path-list` as well as `ffi-lib`. Good point. Thanks, Jens Axel From lysseus at gmail.com Tue Aug 26 17:43:18 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Tue, 26 Aug 2014 14:43:18 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> Message-ID: <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> On Aug 24, 2014, at 2:09 PM, Matthias Felleisen wrote: > Before you make fondue, ask. As you can see, people answer and answer quickly. Indeed, Robby added an example to the Guide as he responded and pushed it out into the repo. The next release will have an example due to your posts. Thanks! > > Having said that, Racket is created by people who focus on systematic design of software. The contract system is an example of this; > > -- it serves the purpose of creating software systematically (continuing the so-called Design by Contract line of work) > -- it itself is developed systematically with inquires into the semantics of contracts because we took contracts way beyond the primitive notion from the 1980s and 1990s. > > But, the existence of ->i and ->d should give you a hint that we occasionally make mistakes and we try to correct them without modifying existing code. ->d is mostly okay, but ->i is better. When Robby created ->i, he also used his experience with ->d to force programmers to list dependency variables explicitly. That's why you have to say "(lst)", for example. In addition, the language grows and with it, we have to grow the contract system. Keyword arguments is an example of that kind. > > As for the philosophy behind our contract system, I think the guide's opening section on boundaries brings across the idea that separates our contracts from old-style stuff. It may not become immediately clear, but when you program with contracts for a while, you will appreciate it. Wow! I am increasingly appreciating this approach (along with Racket?s systematic approach to design). I?m slowly converting my modules over to use contract-out and the ->i form makes it easy to see at a glance what the domains and ranges are, and I?m thinking the notation might be useful in the function definition?s comments as well. Is there a way to integrate unit testing into this approach? The (module+ test ?) unit testing I?ve been doing is within the boundary of the mode and I wonder if there isn?t a way to simply move those test cases into another module (within the same file) and require it into the (module+ test ?) form? -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Tue Aug 26 17:53:21 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Tue, 26 Aug 2014 17:53:21 -0400 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> Message-ID: On Aug 26, 2014, at 5:43 PM, Kevin Forchione wrote: > > On Aug 24, 2014, at 2:09 PM, Matthias Felleisen wrote: > >> Before you make fondue, ask. As you can see, people answer and answer quickly. Indeed, Robby added an example to the Guide as he responded and pushed it out into the repo. The next release will have an example due to your posts. Thanks! >> >> Having said that, Racket is created by people who focus on systematic design of software. The contract system is an example of this; >> >> -- it serves the purpose of creating software systematically (continuing the so-called Design by Contract line of work) >> -- it itself is developed systematically with inquires into the semantics of contracts because we took contracts way beyond the primitive notion from the 1980s and 1990s. >> >> But, the existence of ->i and ->d should give you a hint that we occasionally make mistakes and we try to correct them without modifying existing code. ->d is mostly okay, but ->i is better. When Robby created ->i, he also used his experience with ->d to force programmers to list dependency variables explicitly. That's why you have to say "(lst)", for example. In addition, the language grows and with it, we have to grow the contract system. Keyword arguments is an example of that kind. >> >> As for the philosophy behind our contract system, I think the guide's opening section on boundaries brings across the idea that separates our contracts from old-style stuff. It may not become immediately clear, but when you program with contracts for a while, you will appreciate it. > > Wow! I am increasingly appreciating this approach (along with Racket?s systematic approach to design). > > I?m slowly converting my modules over to use contract-out and the ->i form makes it easy to see at a glance what the domains and ranges are, and I?m thinking the notation might be useful in the function definition?s comments as well. Is there a way to integrate unit testing into this approach? The (module+ test ?) unit testing I?ve been doing is within the boundary of the mode and I wonder if there isn?t a way to simply move those test cases into another module (within the same file) and require it into the (module+ test ?) form? Yes, you can use submodules to import the outer module thru the contract boundary and then run unit tests in the submodule: #lang racket (provide (contract-out (f (-> integer? integer?)))) ;; --------------------------------- ;; implementation (module+ test (require rackunit)) (define (f x) x) (module+ test (require (submod "..")) (check-equal? (f 1) 1) (check-equal? (f 'a) 'a)) We should probably document this little trick somewhere. -- Matthias From alex.mclin at gmail.com Tue Aug 26 20:38:09 2014 From: alex.mclin at gmail.com (Alexander McLin) Date: Tue, 26 Aug 2014 20:38:09 -0400 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> Message-ID: Thank you for this information. I had been trying to figure out how to test contracts from within a module+ only to give up and move my test cases to a different file. I think this reinforces that I should be asking more questions on the mailing list. Alexander McLin > On Aug 26, 2014, at 5:53 PM, Matthias Felleisen wrote: > > >> On Aug 26, 2014, at 5:43 PM, Kevin Forchione wrote: >> >> >>> On Aug 24, 2014, at 2:09 PM, Matthias Felleisen wrote: >>> >>> Before you make fondue, ask. As you can see, people answer and answer quickly. Indeed, Robby added an example to the Guide as he responded and pushed it out into the repo. The next release will have an example due to your posts. Thanks! >>> >>> Having said that, Racket is created by people who focus on systematic design of software. The contract system is an example of this; >>> >>> -- it serves the purpose of creating software systematically (continuing the so-called Design by Contract line of work) >>> -- it itself is developed systematically with inquires into the semantics of contracts because we took contracts way beyond the primitive notion from the 1980s and 1990s. >>> >>> But, the existence of ->i and ->d should give you a hint that we occasionally make mistakes and we try to correct them without modifying existing code. ->d is mostly okay, but ->i is better. When Robby created ->i, he also used his experience with ->d to force programmers to list dependency variables explicitly. That's why you have to say "(lst)", for example. In addition, the language grows and with it, we have to grow the contract system. Keyword arguments is an example of that kind. >>> >>> As for the philosophy behind our contract system, I think the guide's opening section on boundaries brings across the idea that separates our contracts from old-style stuff. It may not become immediately clear, but when you program with contracts for a while, you will appreciate it. >> >> Wow! I am increasingly appreciating this approach (along with Racket?s systematic approach to design). >> >> I?m slowly converting my modules over to use contract-out and the ->i form makes it easy to see at a glance what the domains and ranges are, and I?m thinking the notation might be useful in the function definition?s comments as well. Is there a way to integrate unit testing into this approach? The (module+ test ?) unit testing I?ve been doing is within the boundary of the mode and I wonder if there isn?t a way to simply move those test cases into another module (within the same file) and require it into the (module+ test ?) form? > > > Yes, you can use submodules to import the outer module thru the contract boundary and then run unit tests in the submodule: > > > #lang racket > > (provide > (contract-out > (f (-> integer? integer?)))) > > ;; --------------------------------- > ;; implementation > > (module+ test (require rackunit)) > > (define (f x) > x) > > (module+ test > (require (submod "..")) > (check-equal? (f 1) 1) > (check-equal? (f 'a) 'a)) > > > We should probably document this little trick somewhere. -- Matthias > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From comer at cemati.org Tue Aug 26 21:07:34 2014 From: comer at cemati.org (Enrique Comer) Date: Tue, 26 Aug 2014 18:07:34 -0700 Subject: [racket] [->] How to display math formulas using LaTeX in Scribble Message-ID: <1409101654.33368.YahooMailNeo@web160215.mail.bf1.yahoo.com> Hi Prof. Jens Axel: Under Windows 7 (32 bits) I installed again the racket-poppler package, for the current Racket snapshot version. Then I run the following shorter program #lang racket (require?racket-poppler/render-tex) And the result of running that code was: ffi-lib: couldn't open "C:\\Program Files\\Racket-6.1.0.5\\lib\\libpoppler-44.dll" (%1 no es una aplicaci?n Win32 v?lida.; errno=193) I copied the files?libpoppler-44.dll and?libpoppler-glib-8.dll to the lib folder in the Racket installation, but the error was the same. May be there is something more basic that I'm not doing right. Thank you very much for your support. Sincerely, Enrique C?mer -------------- next part -------------- An HTML attachment was scrubbed... URL: From comer at cemati.org Tue Aug 26 21:11:15 2014 From: comer at cemati.org (enrique comer) Date: Wed, 27 Aug 2014 01:11:15 -0000 Subject: [racket] Auto Response Message-ID: <707803.43505.bm@omp1006.mail.bf1.yahoo.com> An HTML attachment was scrubbed... URL: From lysseus at gmail.com Wed Aug 27 01:02:24 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Tue, 26 Aug 2014 22:02:24 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> Message-ID: <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> On Aug 26, 2014, at 2:53 PM, Matthias Felleisen wrote: > > > We should probably document this little trick somewhere. -- Matthias Yes please. It would be useful in the Contract documentation, perhaps as a link pointing to the illustration in the Modules documentation. So by requiring the enclosing module as a submodule the bindings are redefined (or reinitialized) as specified by the module?s provide? So if the enclosing module didn?t provide certain bindings would the module+ still have access to those bindings from the enclosing module? Also, this seems like such a useful construct that it might be nice to have a shorthand. e.g. (module++ ?)? -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Wed Aug 27 11:37:09 2014 From: clements at brinckerhoff.org (John Clements) Date: Wed, 27 Aug 2014 08:37:09 -0700 Subject: [racket] FYI: scheme looks good in this paper examining first-year data Message-ID: I can?t tell whether this paper was published *anywhere*, but Google told me about it because it cites me. It tries to mine data from ratemyprofessor to draw conclusions about what makes for a good first computing class. You can take all of this with many grains of salt, but the language most strongly correlated with clarity in a first-year class is Scheme. The major caveat is the number of samples, which is small for all languages but especially small (32) for Scheme, suggesting that it may be the good work of a few professors. On the other hand, it may well be the influence of HtDP. Anyhow?a small piece of good news to brighten y?all?s day. John http://aspiringminds.com/pages/assess/2014/camera_ready/paper/moretti_etal.pdf From lysseus at gmail.com Wed Aug 27 12:22:39 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Wed, 27 Aug 2014 09:22:39 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> Message-ID: <5EADF21B-7108-4D53-BD12-ABEA44AD4D1E@gmail.com> On Aug 26, 2014, at 10:02 PM, Kevin Forchione wrote: > > On Aug 26, 2014, at 2:53 PM, Matthias Felleisen wrote: > >> >> >> We should probably document this little trick somewhere. -- Matthias > > Yes please. It would be useful in the Contract documentation, perhaps as a link pointing to the illustration in the Modules documentation. So by requiring the enclosing module as a submodule the bindings are redefined (or reinitialized) as specified by the module?s provide? So if the enclosing module didn?t provide certain bindings would the module+ still have access to those bindings from the enclosing module? > > Also, this seems like such a useful construct that it might be nice to have a shorthand. e.g. (module++ ?)? > > -Kevin I?ve played around a bit with (module+ ?) and can rule out the idea that requiring the enclosing module would limit access to bindings not in the enclosing module?s provide form. But the provide does affect the innings of available within the (module+ ?) form. For example: #lang racket (provide (rename-out [foo bar])) (define (foo n) n) (module+ test (require (submod "..")) (foo 3) (bar 3)) This will return 3 from the foo function and 3 from the bar rename. So it seems logical that the contracts are imported into the module. The question then remains how? The following is interesting: #lang racket (provide (contract-out [foo (-> string? list?)]) (rename-out (foo bar))) (define (foo n) (list n)) (module+ test (require (submod "..")) (foo 3) (bar "3?)) Here foo violates the contract. Changing the argument to foo to ?3? and the argument to bar to 3 shows that bar does not violate the contract. So the contract is bound to foo and not to the rename. Quite interesting! -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From mb at mbtype.com Wed Aug 27 13:33:07 2014 From: mb at mbtype.com (Matthew Butterick) Date: Wed, 27 Aug 2014 10:33:07 -0700 Subject: [racket] web server + REPL-ish functions? Message-ID: The main engine of my Pollen system is a project webserver that's started from the command line, uses serve/servlet, and sends the usual status & error messages to the terminal window. I was thinking it would be handy to be able to keep an input prompt in that terminal window to be able to issue commands without stopping the server, switching to another window, etc. Is there a straightforward approach to this in terms of program design, or would it introduce annoying complications? My understanding of serve/servlet is that it can only do one thing, which is listen & respond to TCP requests on a certain port. So for this REPL-ish feature, there would have to be a separate listenener/response mechanism. Is that something one would accomplish with threads? Or is there a better way? (Or no way.) An approach I've seen with other web-development systems is to put an admin panel in the browser (by injecting it into the HTML of the output web page). But that's inherently hinky because it pollutes your output. From matthias at ccs.neu.edu Wed Aug 27 13:59:57 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Wed, 27 Aug 2014 13:59:57 -0400 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> Message-ID: <51787B11-5BF3-4EC3-A45F-571D5D2669CC@ccs.neu.edu> Yes, you can refer to non-exported definitions: #lang racket (provide (contract-out (f (-> integer? integer?)))) (define (f x) x) (define (g x) x) (module+ test (require rackunit (submod "..")) (check-equal? (f 1) 1) (check-equal? (g 1) 1)) On Aug 27, 2014, at 1:02 AM, Kevin Forchione wrote: > > On Aug 26, 2014, at 2:53 PM, Matthias Felleisen wrote: > >> >> >> We should probably document this little trick somewhere. -- Matthias > > Yes please. It would be useful in the Contract documentation, perhaps as a link pointing to the illustration in the Modules documentation. So by requiring the enclosing module as a submodule the bindings are redefined (or reinitialized) as specified by the module?s provide? So if the enclosing module didn?t provide certain bindings would the module+ still have access to those bindings from the enclosing module? > > Also, this seems like such a useful construct that it might be nice to have a shorthand. e.g. (module++ ?)? > > -Kevin From jay.mccarthy at gmail.com Wed Aug 27 13:58:59 2014 From: jay.mccarthy at gmail.com (Jay McCarthy) Date: Wed, 27 Aug 2014 13:58:59 -0400 Subject: [racket] web server + REPL-ish functions? In-Reply-To: References: Message-ID: Hi Matthew, You can run serve/servlet in a separate thread and continue to interact with any functions you want: (define server-t (thread (lambda () (serve/servlet ...)))) You could then use something like xrepl to start doing new stuff. There's nothing the Web server would need to do necessarily. However, if you wanted to change how the server was running, you might need to adjust some things. For instance, you could put the main request->response function in a box that you could change. You could kill the server-t thread and then create another one to restart the server with new parameters. Is that a useful sketch? Jay On Wed, Aug 27, 2014 at 1:33 PM, Matthew Butterick wrote: > The main engine of my Pollen system is a project webserver that's started from the command line, uses serve/servlet, and sends the usual status & error messages to the terminal window. > > I was thinking it would be handy to be able to keep an input prompt in that terminal window to be able to issue commands without stopping the server, switching to another window, etc. > > Is there a straightforward approach to this in terms of program design, or would it introduce annoying complications? > > My understanding of serve/servlet is that it can only do one thing, which is listen & respond to TCP requests on a certain port. So for this REPL-ish feature, there would have to be a separate listenener/response mechanism. Is that something one would accomplish with threads? Or is there a better way? (Or no way.) > > An approach I've seen with other web-development systems is to put an admin panel in the browser (by injecting it into the HTML of the output web page). But that's inherently hinky because it pollutes your output. > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- Jay McCarthy http://jeapostrophe.github.io "Wherefore, be not weary in well-doing, for ye are laying the foundation of a great work. And out of small things proceedeth that which is great." - D&C 64:33 From matthias at ccs.neu.edu Wed Aug 27 14:12:25 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Wed, 27 Aug 2014 14:12:25 -0400 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <5EADF21B-7108-4D53-BD12-ABEA44AD4D1E@gmail.com> References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> <5EADF21B-7108-4D53-BD12-ABEA44AD4D1E@gmail.com> Message-ID: <79A561BE-A1F5-4142-86F0-DAF74B5BEAD4@ccs.neu.edu> On Aug 27, 2014, at 12:22 PM, Kevin Forchione wrote: > > #lang racket > > (provide (contract-out [foo > (-> string? list?)]) > (rename-out (foo bar))) > > (define (foo n) (list n)) > > (module+ test > (require (submod "..")) > (foo 3) > (bar "3?)) > > Here foo violates the contract. Changing the argument to foo to ?3? and the argument to bar to 3 shows that bar does not violate the contract. So the contract is bound to foo and not to the rename. Quite interesting! > contract-out attaches a contract to foo so when you can call foo on 3, you get an error. provide also exports foo as bar w/o contract, so you can call it on anything you want. This is clearly what the words of the program imply, and the semantics of the language gives it to you. No problems! From lysseus at gmail.com Wed Aug 27 14:18:55 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Wed, 27 Aug 2014 11:18:55 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <79A561BE-A1F5-4142-86F0-DAF74B5BEAD4@ccs.neu.edu> References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> <5EADF21B-7108-4D53-BD12-ABEA44AD4D1E@gmail.com> <79A561BE-A1F5-4142-86F0-DAF74B5BEAD4@ccs.neu.edu> Message-ID: On Aug 27, 2014, at 11:12 AM, Matthias Felleisen wrote: > > On Aug 27, 2014, at 12:22 PM, Kevin Forchione wrote: > >> >> #lang racket >> >> (provide (contract-out [foo >> (-> string? list?)]) >> (rename-out (foo bar))) >> >> (define (foo n) (list n)) >> >> (module+ test >> (require (submod "..")) >> (foo 3) >> (bar "3?)) >> >> Here foo violates the contract. Changing the argument to foo to ?3? and the argument to bar to 3 shows that bar does not violate the contract. So the contract is bound to foo and not to the rename. Quite interesting! >> > > > contract-out attaches a contract to foo so when you can call foo on 3, you get an error. > > provide also exports foo as bar w/o contract, so you can call it on anything you want. > > This is clearly what the words of the program imply, and the semantics of the language gives it to you. No problems! Yes, I agree. Very useful! Is there a way to attach a contract to a renamed identifier? I tried wrapping contract around a rename form and it didn?t appear to like it. -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From comer at cemati.org Wed Aug 27 14:42:58 2014 From: comer at cemati.org (Enrique Comer) Date: Wed, 27 Aug 2014 11:42:58 -0700 Subject: [racket] [->] How to render math formulas with LaTeX under Scribble [solved] Message-ID: <1409164978.35713.YahooMailNeo@web160216.mail.bf1.yahoo.com> Hi Jens Axel: Really thank you very much. It work exactly as you said. Now I applied racket-poppler under scribble/manual with the following code, as a test: #lang scribble/manual @(require racket-poppler/render-tex pict) @(latex-path? ?(case (system-type) ? ?[(macosx) "/usr/local/texlive/2013/bin/universal-darwin/pdflatex"] ? ?[(unix) ? "pdflatex"]? ? ?[(windows) "c:/Archivos de programa/MiKTeX 2.9/miktex/bin/pdflatex.exe"])) ; personalized @title{Beautiful: @(latex->pict "$e^{i \\pi}=-1$") } Now we have just to learn how to scale the equation @(latex->pict "$e^{i \\pi}=-1$") to the right font size. Thank you very much Jens Axel Soegaard. And worked just fine. Thank you again for all your support, and by the way, congratulations for your number theory and linear algebra functions at the math library. Sincerely, Enrique P.S. It would be of great value, to be able to add latex functions to the plot library. Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Wed Aug 27 16:32:27 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Wed, 27 Aug 2014 16:32:27 -0400 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> <5EADF21B-7108-4D53-BD12-ABEA44AD4D1E@gmail.com> <79A561BE-A1F5-4142-86F0-DAF74B5BEAD4@ccs.neu.edu> Message-ID: <52642E0E-319A-4FCF-911E-6696C1EC56E2@ccs.neu.edu> #lang racket (module x racket (provide (contract-out (rename f g (-> integer? any/c)))) (define f displayln)) (require 'x) (g 'a) On Aug 27, 2014, at 2:18 PM, Kevin Forchione wrote: > > On Aug 27, 2014, at 11:12 AM, Matthias Felleisen wrote: > >> >> On Aug 27, 2014, at 12:22 PM, Kevin Forchione wrote: >> >>> >>> #lang racket >>> >>> (provide (contract-out [foo >>> (-> string? list?)]) >>> (rename-out (foo bar))) >>> >>> (define (foo n) (list n)) >>> >>> (module+ test >>> (require (submod "..")) >>> (foo 3) >>> (bar "3?)) >>> >>> Here foo violates the contract. Changing the argument to foo to ?3? and the argument to bar to 3 shows that bar does not violate the contract. So the contract is bound to foo and not to the rename. Quite interesting! >>> >> >> >> contract-out attaches a contract to foo so when you can call foo on 3, you get an error. >> >> provide also exports foo as bar w/o contract, so you can call it on anything you want. >> >> This is clearly what the words of the program imply, and the semantics of the language gives it to you. No problems! > > Yes, I agree. Very useful! Is there a way to attach a contract to a renamed identifier? I tried wrapping contract around a rename form and it didn?t appear to like it. > > -Kevin > From mb at mbtype.com Wed Aug 27 16:33:13 2014 From: mb at mbtype.com (Matthew Butterick) Date: Wed, 27 Aug 2014 13:33:13 -0700 Subject: [racket] web server + REPL-ish functions? In-Reply-To: References: Message-ID: Helpful, thanks. I have my `serve/servlet` within a `start-server` function rather than at the top level. Quick experimentation suggests that `thread-wait` is needed in this case (?): (define (start-server) (setup-chores ...) (define server-t (thread (lambda () (serve/servlet ...)))) (define repl-t (thread (lambda () ...))) (thread-wait server-t)) Otherwise, I'll see how far I get. On Aug 27, 2014, at 10:58 AM, Jay McCarthy wrote: > Hi Matthew, > > You can run serve/servlet in a separate thread and continue to > interact with any functions you want: > > (define server-t (thread (lambda () (serve/servlet ...)))) > > You could then use something like xrepl to start doing new stuff. > There's nothing the Web server would need to do necessarily. > > However, if you wanted to change how the server was running, you might > need to adjust some things. For instance, you could put the main > request->response function in a box that you could change. You could > kill the server-t thread and then create another one to restart the > server with new parameters. > > Is that a useful sketch? > > Jay > > > On Wed, Aug 27, 2014 at 1:33 PM, Matthew Butterick wrote: >> The main engine of my Pollen system is a project webserver that's started from the command line, uses serve/servlet, and sends the usual status & error messages to the terminal window. >> >> I was thinking it would be handy to be able to keep an input prompt in that terminal window to be able to issue commands without stopping the server, switching to another window, etc. >> >> Is there a straightforward approach to this in terms of program design, or would it introduce annoying complications? >> >> My understanding of serve/servlet is that it can only do one thing, which is listen & respond to TCP requests on a certain port. So for this REPL-ish feature, there would have to be a separate listenener/response mechanism. Is that something one would accomplish with threads? Or is there a better way? (Or no way.) >> >> An approach I've seen with other web-development systems is to put an admin panel in the browser (by injecting it into the HTML of the output web page). But that's inherently hinky because it pollutes your output. >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > > -- > Jay McCarthy > http://jeapostrophe.github.io > > "Wherefore, be not weary in well-doing, > for ye are laying the foundation of a great work. > And out of small things proceedeth that which is great." > - D&C 64:33 From lysseus at gmail.com Wed Aug 27 18:11:22 2014 From: lysseus at gmail.com (Kevin Forchione) Date: Wed, 27 Aug 2014 15:11:22 -0700 Subject: [racket] contracts ->i optional keyword syntax In-Reply-To: <52642E0E-319A-4FCF-911E-6696C1EC56E2@ccs.neu.edu> References: <4448938.852001408857855972.JavaMail.root@zimbra> <57C18324-4D69-49A9-9617-F4BC3CD4E391@ccs.neu.edu> <224CE99C-1D55-4BDB-AAAC-F338CCE91A4A@gmail.com> <1A4AC698-3B89-4AD4-AE4D-93E4755739D9@gmail.com> <5EADF21B-7108-4D53-BD12-ABEA44AD4D1E@gmail.com> <79A561BE-A1F5-4142-86F0-DAF74B5BEAD4@ccs.neu.edu> <52642E0E-319A-4FCF-911E-6696C1EC56E2@ccs.neu.edu> Message-ID: <26944234-1737-45EC-B303-8F25CC40EB16@gmail.com> On Aug 27, 2014, at 1:32 PM, Matthias Felleisen wrote: > #lang racket > > (module x racket > (provide > (contract-out > (rename f g (-> integer? any/c)))) > > (define f displayln)) > > (require 'x) > > (g 'a) Thanks! Nesting the contract in the rename there me. I was trying (among others): (provide (contract-out (rename f g) (-> integer? any/c))) -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.mccarthy at gmail.com Wed Aug 27 18:12:03 2014 From: jay.mccarthy at gmail.com (Jay McCarthy) Date: Wed, 27 Aug 2014 18:12:03 -0400 Subject: [racket] web server + REPL-ish functions? In-Reply-To: References: Message-ID: Yes, although I actually assumed that you would start your server from a real Racket REPL, rather than implement your own REPL, so you wouldn't need to wait on anything. But what you wrote will work too. Jay On Wed, Aug 27, 2014 at 4:33 PM, Matthew Butterick wrote: > Helpful, thanks. I have my `serve/servlet` within a `start-server` function rather than at the top level. Quick experimentation suggests that `thread-wait` is needed in this case (?): > > (define (start-server) > (setup-chores ...) > (define server-t (thread (lambda () (serve/servlet ...)))) > (define repl-t (thread (lambda () ...))) > (thread-wait server-t)) > > Otherwise, I'll see how far I get. > > > > On Aug 27, 2014, at 10:58 AM, Jay McCarthy wrote: > >> Hi Matthew, >> >> You can run serve/servlet in a separate thread and continue to >> interact with any functions you want: >> >> (define server-t (thread (lambda () (serve/servlet ...)))) >> >> You could then use something like xrepl to start doing new stuff. >> There's nothing the Web server would need to do necessarily. >> >> However, if you wanted to change how the server was running, you might >> need to adjust some things. For instance, you could put the main >> request->response function in a box that you could change. You could >> kill the server-t thread and then create another one to restart the >> server with new parameters. >> >> Is that a useful sketch? >> >> Jay >> >> >> On Wed, Aug 27, 2014 at 1:33 PM, Matthew Butterick wrote: >>> The main engine of my Pollen system is a project webserver that's started from the command line, uses serve/servlet, and sends the usual status & error messages to the terminal window. >>> >>> I was thinking it would be handy to be able to keep an input prompt in that terminal window to be able to issue commands without stopping the server, switching to another window, etc. >>> >>> Is there a straightforward approach to this in terms of program design, or would it introduce annoying complications? >>> >>> My understanding of serve/servlet is that it can only do one thing, which is listen & respond to TCP requests on a certain port. So for this REPL-ish feature, there would have to be a separate listenener/response mechanism. Is that something one would accomplish with threads? Or is there a better way? (Or no way.) >>> >>> An approach I've seen with other web-development systems is to put an admin panel in the browser (by injecting it into the HTML of the output web page). But that's inherently hinky because it pollutes your output. >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> >> -- >> Jay McCarthy >> http://jeapostrophe.github.io >> >> "Wherefore, be not weary in well-doing, >> for ye are laying the foundation of a great work. >> And out of small things proceedeth that which is great." >> - D&C 64:33 > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- Jay McCarthy http://jeapostrophe.github.io "Wherefore, be not weary in well-doing, for ye are laying the foundation of a great work. And out of small things proceedeth that which is great." - D&C 64:33 From mb at mbtype.com Thu Aug 28 10:45:48 2014 From: mb at mbtype.com (Matthew Butterick) Date: Thu, 28 Aug 2014 07:45:48 -0700 Subject: [racket] web server + REPL-ish functions? In-Reply-To: References: Message-ID: <57E4F594-2522-48F2-92FB-E982AB34DF3B@mbtype.com> Maybe starting the server from the REPL is the better idea. Right now I do it through raco (redirecting commands of form `raco pollen ...`, including `raco pollen start`, to a special pollen/raco module that handles them) On Aug 27, 2014, at 3:12 PM, Jay McCarthy wrote: > Yes, although I actually assumed that you would start your server from > a real Racket REPL, rather than implement your own REPL, so you > wouldn't need to wait on anything. But what you wrote will work too. > > Jay > > On Wed, Aug 27, 2014 at 4:33 PM, Matthew Butterick wrote: >> Helpful, thanks. I have my `serve/servlet` within a `start-server` function rather than at the top level. Quick experimentation suggests that `thread-wait` is needed in this case (?): >> >> (define (start-server) >> (setup-chores ...) >> (define server-t (thread (lambda () (serve/servlet ...)))) >> (define repl-t (thread (lambda () ...))) >> (thread-wait server-t)) >> >> Otherwise, I'll see how far I get. >> >> >> >> On Aug 27, 2014, at 10:58 AM, Jay McCarthy wrote: >> >>> Hi Matthew, >>> >>> You can run serve/servlet in a separate thread and continue to >>> interact with any functions you want: >>> >>> (define server-t (thread (lambda () (serve/servlet ...)))) >>> >>> You could then use something like xrepl to start doing new stuff. >>> There's nothing the Web server would need to do necessarily. >>> >>> However, if you wanted to change how the server was running, you might >>> need to adjust some things. For instance, you could put the main >>> request->response function in a box that you could change. You could >>> kill the server-t thread and then create another one to restart the >>> server with new parameters. >>> >>> Is that a useful sketch? >>> >>> Jay >>> >>> >>> On Wed, Aug 27, 2014 at 1:33 PM, Matthew Butterick wrote: >>>> The main engine of my Pollen system is a project webserver that's started from the command line, uses serve/servlet, and sends the usual status & error messages to the terminal window. >>>> >>>> I was thinking it would be handy to be able to keep an input prompt in that terminal window to be able to issue commands without stopping the server, switching to another window, etc. >>>> >>>> Is there a straightforward approach to this in terms of program design, or would it introduce annoying complications? >>>> >>>> My understanding of serve/servlet is that it can only do one thing, which is listen & respond to TCP requests on a certain port. So for this REPL-ish feature, there would have to be a separate listenener/response mechanism. Is that something one would accomplish with threads? Or is there a better way? (Or no way.) >>>> >>>> An approach I've seen with other web-development systems is to put an admin panel in the browser (by injecting it into the HTML of the output web page). But that's inherently hinky because it pollutes your output. >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> >>> -- >>> Jay McCarthy >>> http://jeapostrophe.github.io >>> >>> "Wherefore, be not weary in well-doing, >>> for ye are laying the foundation of a great work. >>> And out of small things proceedeth that which is great." >>> - D&C 64:33 >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > > -- > Jay McCarthy > http://jeapostrophe.github.io > > "Wherefore, be not weary in well-doing, > for ye are laying the foundation of a great work. > And out of small things proceedeth that which is great." > - D&C 64:33 From clements at brinckerhoff.org Thu Aug 28 13:59:32 2014 From: clements at brinckerhoff.org (John Clements) Date: Thu, 28 Aug 2014 10:59:32 -0700 Subject: [racket] Share a room at RacketCon / Strange Loop? Message-ID: <4A216EE6-D019-4F7F-BB9C-C961D5DBCD32@brinckerhoff.org> It looks like I?m going to RacketCon & Strange Loop, lucky me. Anyone want to share a room? John From mb at mbtype.com Thu Aug 28 19:40:16 2014 From: mb at mbtype.com (Matthew Butterick) Date: Thu, 28 Aug 2014 16:40:16 -0700 Subject: [racket] web server + REPL-ish functions? In-Reply-To: <57E4F594-2522-48F2-92FB-E982AB34DF3B@mbtype.com> References: <57E4F594-2522-48F2-92FB-E982AB34DF3B@mbtype.com> Message-ID: <58545CE8-8AD5-422B-8336-F339CDEF6984@mbtype.com> To implement your suggestion, I tried starting the web server from the real REPL by making `raco pollen start` invoke a system command along these lines: racket -i -l pollen/server -e '(define t (thread (lambda () (start-server))))' This works ? the web server responds properly, and the REPL stays active. The problem is that when invoked this way, the web server seems to get a lot slower. Is that the expected behavior, since Racket is "load balancing" between the two threads? Or should it not matter? Or is this not the way to go about it? On Aug 28, 2014, at 7:45 AM, Matthew Butterick wrote: > Maybe starting the server from the REPL is the better idea. Right now I do it through raco (redirecting commands of form `raco pollen ...`, including `raco pollen start`, to a special pollen/raco module that handles them) > > > On Aug 27, 2014, at 3:12 PM, Jay McCarthy wrote: > >> Yes, although I actually assumed that you would start your server from >> a real Racket REPL, rather than implement your own REPL, so you >> wouldn't need to wait on anything. But what you wrote will work too. >> >> Jay >> >> On Wed, Aug 27, 2014 at 4:33 PM, Matthew Butterick wrote: >>> Helpful, thanks. I have my `serve/servlet` within a `start-server` function rather than at the top level. Quick experimentation suggests that `thread-wait` is needed in this case (?): >>> >>> (define (start-server) >>> (setup-chores ...) >>> (define server-t (thread (lambda () (serve/servlet ...)))) >>> (define repl-t (thread (lambda () ...))) >>> (thread-wait server-t)) >>> >>> Otherwise, I'll see how far I get. >>> >>> >>> >>> On Aug 27, 2014, at 10:58 AM, Jay McCarthy wrote: >>> >>>> Hi Matthew, >>>> >>>> You can run serve/servlet in a separate thread and continue to >>>> interact with any functions you want: >>>> >>>> (define server-t (thread (lambda () (serve/servlet ...)))) >>>> >>>> You could then use something like xrepl to start doing new stuff. >>>> There's nothing the Web server would need to do necessarily. >>>> >>>> However, if you wanted to change how the server was running, you might >>>> need to adjust some things. For instance, you could put the main >>>> request->response function in a box that you could change. You could >>>> kill the server-t thread and then create another one to restart the >>>> server with new parameters. >>>> >>>> Is that a useful sketch? >>>> >>>> Jay >>>> >>>> >>>> On Wed, Aug 27, 2014 at 1:33 PM, Matthew Butterick wrote: >>>>> The main engine of my Pollen system is a project webserver that's started from the command line, uses serve/servlet, and sends the usual status & error messages to the terminal window. >>>>> >>>>> I was thinking it would be handy to be able to keep an input prompt in that terminal window to be able to issue commands without stopping the server, switching to another window, etc. >>>>> >>>>> Is there a straightforward approach to this in terms of program design, or would it introduce annoying complications? >>>>> >>>>> My understanding of serve/servlet is that it can only do one thing, which is listen & respond to TCP requests on a certain port. So for this REPL-ish feature, there would have to be a separate listenener/response mechanism. Is that something one would accomplish with threads? Or is there a better way? (Or no way.) >>>>> >>>>> An approach I've seen with other web-development systems is to put an admin panel in the browser (by injecting it into the HTML of the output web page). But that's inherently hinky because it pollutes your output. >>>>> ____________________ >>>>> Racket Users list: >>>>> http://lists.racket-lang.org/users >>>> >>>> >>>> >>>> -- >>>> Jay McCarthy >>>> http://jeapostrophe.github.io >>>> >>>> "Wherefore, be not weary in well-doing, >>>> for ye are laying the foundation of a great work. >>>> And out of small things proceedeth that which is great." >>>> - D&C 64:33 >>> >>> >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >> >> >> >> -- >> Jay McCarthy >> http://jeapostrophe.github.io >> >> "Wherefore, be not weary in well-doing, >> for ye are laying the foundation of a great work. >> And out of small things proceedeth that which is great." >> - D&C 64:33 > From jay.mccarthy at gmail.com Fri Aug 29 06:44:44 2014 From: jay.mccarthy at gmail.com (Jay McCarthy) Date: Fri, 29 Aug 2014 06:44:44 -0400 Subject: [racket] web server + REPL-ish functions? In-Reply-To: <58545CE8-8AD5-422B-8336-F339CDEF6984@mbtype.com> References: <57E4F594-2522-48F2-92FB-E982AB34DF3B@mbtype.com> <58545CE8-8AD5-422B-8336-F339CDEF6984@mbtype.com> Message-ID: Racket would definitely be 'load-balancing', but I'd be surprised if that would affect performance because the REPL thread should just be blocked on input. I'd be worried that the way the REPL was started ran the server without the JIT. Jay On Thu, Aug 28, 2014 at 7:40 PM, Matthew Butterick wrote: > To implement your suggestion, I tried starting the web server from the real REPL by making `raco pollen start` invoke a system command along these lines: > > racket -i -l pollen/server -e '(define t (thread (lambda () (start-server))))' > > This works ? the web server responds properly, and the REPL stays active. > > The problem is that when invoked this way, the web server seems to get a lot slower. Is that the expected behavior, since Racket is "load balancing" between the two threads? Or should it not matter? Or is this not the way to go about it? > > > > > On Aug 28, 2014, at 7:45 AM, Matthew Butterick wrote: > >> Maybe starting the server from the REPL is the better idea. Right now I do it through raco (redirecting commands of form `raco pollen ...`, including `raco pollen start`, to a special pollen/raco module that handles them) >> >> >> On Aug 27, 2014, at 3:12 PM, Jay McCarthy wrote: >> >>> Yes, although I actually assumed that you would start your server from >>> a real Racket REPL, rather than implement your own REPL, so you >>> wouldn't need to wait on anything. But what you wrote will work too. >>> >>> Jay >>> >>> On Wed, Aug 27, 2014 at 4:33 PM, Matthew Butterick wrote: >>>> Helpful, thanks. I have my `serve/servlet` within a `start-server` function rather than at the top level. Quick experimentation suggests that `thread-wait` is needed in this case (?): >>>> >>>> (define (start-server) >>>> (setup-chores ...) >>>> (define server-t (thread (lambda () (serve/servlet ...)))) >>>> (define repl-t (thread (lambda () ...))) >>>> (thread-wait server-t)) >>>> >>>> Otherwise, I'll see how far I get. >>>> >>>> >>>> >>>> On Aug 27, 2014, at 10:58 AM, Jay McCarthy wrote: >>>> >>>>> Hi Matthew, >>>>> >>>>> You can run serve/servlet in a separate thread and continue to >>>>> interact with any functions you want: >>>>> >>>>> (define server-t (thread (lambda () (serve/servlet ...)))) >>>>> >>>>> You could then use something like xrepl to start doing new stuff. >>>>> There's nothing the Web server would need to do necessarily. >>>>> >>>>> However, if you wanted to change how the server was running, you might >>>>> need to adjust some things. For instance, you could put the main >>>>> request->response function in a box that you could change. You could >>>>> kill the server-t thread and then create another one to restart the >>>>> server with new parameters. >>>>> >>>>> Is that a useful sketch? >>>>> >>>>> Jay >>>>> >>>>> >>>>> On Wed, Aug 27, 2014 at 1:33 PM, Matthew Butterick wrote: >>>>>> The main engine of my Pollen system is a project webserver that's started from the command line, uses serve/servlet, and sends the usual status & error messages to the terminal window. >>>>>> >>>>>> I was thinking it would be handy to be able to keep an input prompt in that terminal window to be able to issue commands without stopping the server, switching to another window, etc. >>>>>> >>>>>> Is there a straightforward approach to this in terms of program design, or would it introduce annoying complications? >>>>>> >>>>>> My understanding of serve/servlet is that it can only do one thing, which is listen & respond to TCP requests on a certain port. So for this REPL-ish feature, there would have to be a separate listenener/response mechanism. Is that something one would accomplish with threads? Or is there a better way? (Or no way.) >>>>>> >>>>>> An approach I've seen with other web-development systems is to put an admin panel in the browser (by injecting it into the HTML of the output web page). But that's inherently hinky because it pollutes your output. >>>>>> ____________________ >>>>>> Racket Users list: >>>>>> http://lists.racket-lang.org/users >>>>> >>>>> >>>>> >>>>> -- >>>>> Jay McCarthy >>>>> http://jeapostrophe.github.io >>>>> >>>>> "Wherefore, be not weary in well-doing, >>>>> for ye are laying the foundation of a great work. >>>>> And out of small things proceedeth that which is great." >>>>> - D&C 64:33 >>>> >>>> >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >>> >>> >>> -- >>> Jay McCarthy >>> http://jeapostrophe.github.io >>> >>> "Wherefore, be not weary in well-doing, >>> for ye are laying the foundation of a great work. >>> And out of small things proceedeth that which is great." >>> - D&C 64:33 >> > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- Jay McCarthy http://jeapostrophe.github.io "Wherefore, be not weary in well-doing, for ye are laying the foundation of a great work. And out of small things proceedeth that which is great." - D&C 64:33 From dbastos at toledo.com Fri Aug 29 10:27:59 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Fri, 29 Aug 2014 11:27:59 -0300 Subject: [racket] missing solution 19.1.6 ex:abs-sort Message-ID: A candidate for a solution. ;; sort1 : list-of-numbers -> list-of-numbers ;; to construct a list with all items from alon in descending order (define (sort1 cmp alon) (local ((define (sort alon) (cond [(empty? alon) empty] [else (insert (first alon) (sort (rest alon)))])) (define (insert an alon) (cond [(empty? alon) (list an)] [else (cond [(cmp an (first alon)) (cons an alon)] [else (cons (first alon) (insert an (rest alon)))])]))) (sort alon))) (check-expect (sort1 < (list 2 3 1 5 4)) (list 1 2 3 4 5)) (check-expect (sort1 > (list 2 3 1 5 4)) (list 5 4 3 2 1)) Source: http://www.htdp.org/2003-09-26/Solutions/abs-sort.html No Solution Written, yet Unfortunately, the solution to this exercise has not yet been written. To submit a solution you have written to this problem, or to complain that the solution isn't available, please contact Robby Findler . To see the list of solutions, visit the table of contents . Each of the hyperlinked exercise numbers has a solution. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mb at mbtype.com Fri Aug 29 13:21:54 2014 From: mb at mbtype.com (Matthew Butterick) Date: Fri, 29 Aug 2014 10:21:54 -0700 Subject: [racket] Should `raco pkg update ` presume --update-deps? In-Reply-To: References: Message-ID: Exhuming this thread because I've recently encountered this issue too ? expecting `raco pkg update ...` to update dependencies, and then it doesn't. Reviewing the correspondence we have: 1. The Hendershott option ? automatic dependency updating by default 2. The McCarthy option ? dependency updating only when asked I understand the logic of both. Yet we could add more options to the pile: 3. The user option ? `raco pkg update ...` puts up a user prompt if it notices that dependencies have changed (similar to what happens with `raco pkg install ...`) 4. The Not All Dependencies Are Equal option ? this is where I'm at. My Pollen package depends on two other packages that I maintain (Sugar & Txexpr) but also some packages I don't maintain (Markdown & Rackjure et al.) Some bugs that arise in Pollen are really bugs in Sugar or Txexpr. So in one sense, I would like `raco pkg update ...` to always update those dependencies. But Pollen doesn't depend as sensitively on Markdown et al. So, similar to Jay's secret-wiki-server example, I don't want to tell users to do `raco pkg update --update-deps ...` because it might bring in new versions of Markdown et al. that destabilize user installations. 5. The Just Use Versioning option ? I gather that I could manage all this manually by adding version requirements to Pollen's 'info.rkt' file. For instance: update the Sugar package, update the Sugar package version, update Pollen's dependency on with the new Sugar version number, and then `raco pkg update pollen` will get the Sugar update but leave others alone. But I don't like this option, because it a) puts me into the version-tracking business and b) feels it like undermines one of the nice principles of the Racket package system, which is letting us care about checksums rather than versions when that makes sense. As I say that, I wonder if a solution would be to allow a package maintainer to determine the behavior of `racket pkg update ...` from within 'info.rkt', perhaps by adding a 'latest option to the #:version field. For instance, here's the current Pollen dependency line: (define deps '(("base" #:version "6.0") "txexpr" "sugar" ("markdown" #:version "0.18") "htdp")) Right now `raco pkg update pollen` won't update Markdown unless I bump the #:version. I like that. But it won't update Txexpr or Sugar either. I don't like that. Whereas if I could do this: (define deps '(("base" #:version "6.0") ("txexpr" #:version 'latest) ("sugar" #:version 'latest) ("markdown" #:version "0.18") "htdp")) That could be the signal that `raco pkg update pollen` should always scoop up any available updates for Txexpr and Sugar too, while leaving Markdown alone as usual. On Mon, Nov 11, 2013 at 8:18 AM, Greg Hendershott wrote: > I agree this example isn't a good reason to make --update-deps the default. > > I expected `raco pkg update x` would update x and all its > dependencies. My expectation was wrong. What might be a good reason > would be if many other people shared this wrong expectation, but I > don't know that's the case. > > On Mon, Nov 11, 2013 at 10:07 AM, Jay McCarthy > wrote: > > On Mon, Nov 11, 2013 at 7:44 AM, Greg Hendershott > > wrote: > >> In response to my "I can't think of a situation" you raise with your > >> own "I can't think of a situation". Well played sir. :) > >> > >> The updated markdown parser is more likely to handle some corner cases > >> than the old one, e.g. being less finicky about requiring a blank line > >> after some element. > >> > >> I had updated Frog to be able to use the new version and give those > >> improved results, but still be compatible with the older version. > >> > >> I guess my thinking was, the newer parser was such a huge redesign, I > >> wanted the safety net of someone being able to revert to the older > >> version (at least temporarily). > >> > >> So that's why I bumped the ver on the markdown, but not the ver for > >> frog's dep on it. > >> > >> Probably I over-thunk it. And the new parser seems solid so far. As a > >> result, I should just bump frog's own version, and bump the version of > >> markdown it requires. And then all will be well. > >> > >> As for the general question: I think you're saying that with the > >> status quo `raco pkg update `, if an installed dep is older than > >> required, it will install the very latest version (perhaps newer than > >> required), otherwise it will do nothing? Whereas with --update-deps > >> it does the equivalent of an individual `raco pkg update ` on > >> every dep transitively, so you'll end up with the very latest of > >> everything? > > > > Yes, that's correct. As you mention "update = remove + install", I > > hope this result is predictable. Imagine, for a moment that someone > > used your old markdown package with my unreleased super-secret Racket > > Wiki server. Then, they decided that they wanted your blog engine too. > > You wouldn't expect installing "frog" to update the markdown package. > > Since "raco pkg update " is literally just removing the package and > > adding it again (with a tiny bit of a barrier in case the second > > install fails), it works the same way. > > > > I don't have a strong opinion about your suggestion of switching the > > default behavior, but I'm not sure your example is the best reason to > > switch it. > > > > My attitude is that when you "raco pkg update " you are planning on > > getting new behavior in and not "error fixes on and everything > > else that it uses" (where "better Markdown parsing" can be seen as a > > fixing an error in the old parser). But when you use "--update-deps" > > (or "-a") then you are planning on just looking for new versions of > > anything. I like the feeling of stability this pattern gives. > > > > One case where I think "--update-deps" should definitely be implied is > > when a package "implies" other packages, such as 'main-distribution' > > implying 'srfi', because the "implies" is transparent, so the user > > doesn't necessarily know which package is really providing the feature > > they want updated. > > > > In any case, I think I will probably be able to continuing living if > > "--update-deps" were the default, but I want a better example or a few > > +1s. > > > > Jay > > > > -- > > Jay McCarthy > > Assistant Professor / Brigham Young University > > http://faculty.cs.byu.edu/~jay > > > > "The glory of God is Intelligence" - D&C 93 > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mflatt at cs.utah.edu Fri Aug 29 14:08:01 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Fri, 29 Aug 2014 12:08:01 -0600 Subject: [racket] Should `raco pkg update ` presume --update-deps? In-Reply-To: References: Message-ID: <20140829180803.040B3650188@mail-svr1.cs.utah.edu> The `update-implies` declaration, which was added just a few weeks ago, implements the update behavior that you want. (Your suggestion of `latest` as a version specification is nicer, but `update-implies` creates fewer compatibility issues and touches less code.) We added `update-implies` with packages like "xrepl-test" and "xrepl-lib" in mind, where "xrepl-test" is so tightly bound to "xrepl-lib" that it only makes sense to update the former when also updating the latter. Also, those packages will always be in the same source repository, even though we want to keep them as separate packages to allow more precise dependency specifications. Although "pollen" doesn't seem so tightly bound to "txexpr" and "sugar", you make a fine case for adding (define update-implies '("txexpr" "sugar")) to the "info.rkt" of "pollen". At Fri, 29 Aug 2014 10:21:54 -0700, Matthew Butterick wrote: > Exhuming this thread because I've recently encountered this issue too ? > expecting `raco pkg update ...` to update dependencies, and then it > doesn't. > > Reviewing the correspondence we have: > > 1. The Hendershott option ? automatic dependency updating by default > 2. The McCarthy option ? dependency updating only when asked > > I understand the logic of both. Yet we could add more options to the pile: > > 3. The user option ? `raco pkg update ...` puts up a user prompt if it > notices that dependencies have changed (similar to what happens with `raco > pkg install ...`) > > 4. The Not All Dependencies Are Equal option ? this is where I'm at. My > Pollen package depends on two other packages that I maintain (Sugar & > Txexpr) but also some packages I don't maintain (Markdown & Rackjure et > al.) > > Some bugs that arise in Pollen are really bugs in Sugar or Txexpr. So in > one sense, I would like `raco pkg update ...` to always update those > dependencies. > > But Pollen doesn't depend as sensitively on Markdown et al. So, similar to > Jay's secret-wiki-server example, I don't want to tell users to do `raco > pkg update --update-deps ...` because it might bring in new versions of > Markdown et al. that destabilize user installations. > > 5. The Just Use Versioning option ? I gather that I could manage all this > manually by adding version requirements to Pollen's 'info.rkt' file. For > instance: update the Sugar package, update the Sugar package version, > update Pollen's dependency on with the new Sugar version number, and then > `raco pkg update pollen` will get the Sugar update but leave others alone. > > But I don't like this option, because it a) puts me into the > version-tracking business and b) feels it like undermines one of the nice > principles of the Racket package system, which is letting us care about > checksums rather than versions when that makes sense. > > As I say that, I wonder if a solution would be to allow a package > maintainer to determine the behavior of `racket pkg update ...` from within > 'info.rkt', perhaps by adding a 'latest option to the #:version field. > > For instance, here's the current Pollen dependency line: > > (define deps '(("base" #:version "6.0") "txexpr" "sugar" ("markdown" > #:version "0.18") "htdp")) > > Right now `raco pkg update pollen` won't update Markdown unless I bump the > #:version. I like that. But it won't update Txexpr or Sugar either. I don't > like that. > > Whereas if I could do this: > > (define deps '(("base" #:version "6.0") ("txexpr" #:version 'latest) > ("sugar" #:version 'latest) ("markdown" #:version "0.18") "htdp")) > > That could be the signal that `raco pkg update pollen` should always scoop > up any available updates for Txexpr and Sugar too, while leaving Markdown > alone as usual. > > > > > > On Mon, Nov 11, 2013 at 8:18 AM, Greg Hendershott > wrote: > > > I agree this example isn't a good reason to make --update-deps the default. > > > > I expected `raco pkg update x` would update x and all its > > dependencies. My expectation was wrong. What might be a good reason > > would be if many other people shared this wrong expectation, but I > > don't know that's the case. > > > > On Mon, Nov 11, 2013 at 10:07 AM, Jay McCarthy > > wrote: > > > On Mon, Nov 11, 2013 at 7:44 AM, Greg Hendershott > > > wrote: > > >> In response to my "I can't think of a situation" you raise with your > > >> own "I can't think of a situation". Well played sir. :) > > >> > > >> The updated markdown parser is more likely to handle some corner cases > > >> than the old one, e.g. being less finicky about requiring a blank line > > >> after some element. > > >> > > >> I had updated Frog to be able to use the new version and give those > > >> improved results, but still be compatible with the older version. > > >> > > >> I guess my thinking was, the newer parser was such a huge redesign, I > > >> wanted the safety net of someone being able to revert to the older > > >> version (at least temporarily). > > >> > > >> So that's why I bumped the ver on the markdown, but not the ver for > > >> frog's dep on it. > > >> > > >> Probably I over-thunk it. And the new parser seems solid so far. As a > > >> result, I should just bump frog's own version, and bump the version of > > >> markdown it requires. And then all will be well. > > >> > > >> As for the general question: I think you're saying that with the > > >> status quo `raco pkg update `, if an installed dep is older than > > >> required, it will install the very latest version (perhaps newer than > > >> required), otherwise it will do nothing? Whereas with --update-deps > > >> it does the equivalent of an individual `raco pkg update ` on > > >> every dep transitively, so you'll end up with the very latest of > > >> everything? > > > > > > Yes, that's correct. As you mention "update = remove + install", I > > > hope this result is predictable. Imagine, for a moment that someone > > > used your old markdown package with my unreleased super-secret Racket > > > Wiki server. Then, they decided that they wanted your blog engine too. > > > You wouldn't expect installing "frog" to update the markdown package. > > > Since "raco pkg update " is literally just removing the package and > > > adding it again (with a tiny bit of a barrier in case the second > > > install fails), it works the same way. > > > > > > I don't have a strong opinion about your suggestion of switching the > > > default behavior, but I'm not sure your example is the best reason to > > > switch it. > > > > > > My attitude is that when you "raco pkg update " you are planning on > > > getting new behavior in and not "error fixes on and everything > > > else that it uses" (where "better Markdown parsing" can be seen as a > > > fixing an error in the old parser). But when you use "--update-deps" > > > (or "-a") then you are planning on just looking for new versions of > > > anything. I like the feeling of stability this pattern gives. > > > > > > One case where I think "--update-deps" should definitely be implied is > > > when a package "implies" other packages, such as 'main-distribution' > > > implying 'srfi', because the "implies" is transparent, so the user > > > doesn't necessarily know which package is really providing the feature > > > they want updated. > > > > > > In any case, I think I will probably be able to continuing living if > > > "--update-deps" were the default, but I want a better example or a few > > > +1s. > > > > > > Jay > > > > > > -- > > > Jay McCarthy > > > Assistant Professor / Brigham Young University > > > http://faculty.cs.byu.edu/~jay > > > > > > "The glory of God is Intelligence" - D&C 93 > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From dbastos at toledo.com Fri Aug 29 16:37:21 2014 From: dbastos at toledo.com (Daniel Bastos) Date: Fri, 29 Aug 2014 17:37:21 -0300 Subject: [racket] missing solution 19.2.4 ex:para-non-empty Message-ID: Perhaps I didn't understand this exercise. The hint advises me to work with a particular case and then generalize. I did this, but it seems that even in a particular case the most natural solution seems to be the general one. The generalization took place only in the data definition, but it didn't seem to affect the function definition. ;; Exercise 19.2.4. Here is a parametric data ;; definition of non-empty lists: ;; A (non-empty-listof ITEM) is either ;; 1. (cons s empty), or ;; 2. (cons s l) where l is a (non-empty-listof ITEM) ;; and s is always an ITEM. ;; Develop the function last, which consumes ;; a (non-empty-listof ITEM) and produces the last ;; ITEM in that list. ;; Hint: Replace ITEM with a fixed class of data to ;; develop an initial draft of last. When finished, ;; replace the class with ITEM throughout the function ;; development. ;; Draft. a (non-empty-listof number) is either ;; 1. (cons s empty), or ;; 2. (cons s l) where l is a (non-empty-listof number) ;; and s is always a number. ;; last-number: non-empty-ls -> number ;; consumes a non-empty list of numbers and produces its last number (define (last-number non-empty-ls) (cond [(empty? (rest non-empty-ls)) (first non-empty-ls)] [else (last-number (rest non-empty-ls))])) ;; Generalizing to ITEM. ;; a (non-empty-listof ITEM) is either ;; 1. (cons s empty), or ;; 2. (cons s l) where l is a (non-empty-listof ITEM) ;; and s is always an ITEM. ;; last: non-empty-ls -> ITEM ;; consumes a non-empty list of ITEMs and produces its last ITEM (define (last non-empty-ls) (cond [(empty? (rest non-empty-ls)) (first non-empty-ls)] [else (last (rest non-empty-ls))])) (check-expect (last-number (list 1 2 3 4 5)) 5) (check-expect (last (list (list 1) (list 2) (list 3))) (list 3)) (check-expect (last '(a b c d e f)) 'f) -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthias at ccs.neu.edu Fri Aug 29 22:00:28 2014 From: matthias at ccs.neu.edu (Matthias Felleisen) Date: Fri, 29 Aug 2014 22:00:28 -0400 Subject: [racket] missing solution 19.2.4 ex:para-non-empty In-Reply-To: References: Message-ID: On Aug 29, 2014, at 4:37 PM, Daniel Bastos wrote: > Perhaps I didn't understand this exercise. The hint advises me to work with a particular case and then generalize. I did this, but it seems that even in a particular case the most natural solution seems to be the general one. The generalization took place only in the data definition, but it didn't seem to affect the function definition. Correct. The most appropriate solution is going to be: ;; Exercise 19.2.4. ;; Draft. a (non-empty-listof number) is either ;; 1. (cons s empty), or ;; 2. (cons s l) where l is a (non-empty-listof number) ;; and s is always a number. ;; last-number: non-empty-ls -> number ;; consumes a non-empty list of numbers and produces its last number (check-expect (last-number (list 1 2 3 4 5)) 5) (check-expect (last (list (list 1) (list 2) (list 3))) (list 3)) (define (last-number non-empty-ls) (cond [(empty? (rest non-empty-ls)) (first non-empty-ls)] [else (last-number (rest non-empty-ls))])) ;; Generalizing to ITEM. ;; a (non-empty-listof ITEM) is either ;; 1. (cons s empty), or ;; 2. (cons s l) where l is a (non-empty-listof ITEM) ;; and s is always an ITEM. ;; last: (non-empty-listof ITEM) -> ITEM ;; consumes a non-empty list of ITEMs and produces its last ITEM (check-expect (last '(a b c d e f)) 'f) (define (last non-empty-ls) (cond [(empty? (rest non-empty-ls)) (first non-empty-ls)] [else (last (rest non-empty-ls))])) ;; INSIGHT: in this case, the data-specific function and the ;; data-parametric one are identical because the former does ;; not exploit the knowledge about the nature of the list items. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gneuner2 at comcast.net Mon Aug 25 21:42:08 2014 From: gneuner2 at comcast.net (George Neuner) Date: Mon, 25 Aug 2014 21:42:08 -0400 Subject: [racket] Package installation VERY SLOW Message-ID: Hi all, I'm running Racket under 64-bit Win7 Home on an i7 with 12GB of RAM. Just upgraded to 6.0.1 from 5.3.4. I know it's a big leap and 6.1 is out already, but I tried 6.1 and quickly experienced several of those non-reproducible crashes I've been reading about in the lists. 6.0.1 is behaving itself, but installing new packages from PLaneT or migrating packages from the older version is taking HOURS ... virtually all of it spent processing .scrbl files. I have both 32 and 64 bit versions: doesn't matter which version I use, how much memory I give to Racket (in racket-prefs.rktd), or whether I use raco from the command line or the GUI-based package manager. Example: trying to install *just* Neil's CSV:2:0 took nearly an hour (yes, it has several dependencies). With 64-bit Racket configured for 3GB, memory use spiked over 1.9GB according to Process Explorer. And that was the *fastest* installation ... reducing the memory limit below 2GB just slows it down. [I didn't try running the 32-bit version with more than 1.5GB, but it behaved the same way ... reducing the memory limit just slowed it down.] For giggles I tried migrating CSV:1:7 (which has a single dependency not shared with 2:0) from 5.3.4. That still took almost 16 minutes, and again nearly all of it processing some .scrbl file. For more giggles, I nuked the PLaneT cache so as to start over: same 16 minutes for fresh install of 1:7. For comparison, 5.3.4 installs CSV:1:7 fresh in under 3 minutes. ??? Is anyone else running 6.x on Windows? I can't figure out what, if anything, I'm doing wrong. Subjectively, 6.0.1 feels sluggish compared to 5.3.4 (with same memory limits), but I haven't gotten to the point where I can objectively test much because a lot of my programs depend on external packages. Based on the few I have tried to install/migrate so far, Halloween may be past before I am able to do any real work with 6.0.1. George From neil at neilvandyke.org Sat Aug 30 06:43:13 2014 From: neil at neilvandyke.org (Neil Van Dyke) Date: Sat, 30 Aug 2014 06:43:13 -0400 Subject: [racket] Package installation VERY SLOW In-Reply-To: References: Message-ID: <5401AAC1.8030604@neilvandyke.org> FWIW, I just tried Racket 6.1 installing PLaneT "neil/csv:1:7", and two observations: * I don't immediately know why, but my Racket 6.1 (command-line "racket", and DrRacket) doesn't build the documentation when installing the PLaneT package. I can't look into this right now. * The performance looks fine, for not building the documentation. (This is on a 6+ year-old 32-bit x86 GNU/Linux laptop with slow spinning hard drive, running a Racket I built from source.) I haven't played with Racket 6.x much, since the main project I'm working on right now is still using Racket 5.3.4 (with Ryan's essential PostgreSQL SSL patch). (Aside, so I don't give the wrong impression... That project doesn't have anything against 6.x. When 6.0 came out, preliminary tests with it were fine, but we decided to take a wait&see, since the Racket architecture was being shaken up, and the timing wasn't great for us to evaluate stability and security. Since then, I haven't heard of any big issues with 6.x, and I ran a development tree OK under 6.1 incidentally recently, but there hasn't yet been a need or good opportunity to switch production to 6.x. For my personal and open source work, I use the latest released version of Racket.) If anyone finds a problem with my open source packages, please CC my personal email address, so that I'm sure to see your message. [~] rm -rf ~/.racket/6.1 ~/.racket/planet/300/6.1 ~/.racket/planet/300/packages/ [~] /usr/local/racket-6.1/bin/racket --version Welcome to Racket v6.1. [~] time /usr/local/racket-6.1/bin/racket -e '(begin (require (planet neil/csv:1:=7)) (csv->sxml "a,b"))' '(*TOP* (row (col-0 "a") (col-1 "b"))) real 0m21.526s user 0m18.365s sys 0m2.744s [~] time /usr/local/racket-6.1/bin/racket -e '(begin (require (planet neil/csv:1:=7)) (csv->sxml "a,b"))' '(*TOP* (row (col-0 "a") (col-1 "b"))) real 0m0.660s user 0m0.568s sys 0m0.088s [~] Neil V. George Neuner wrote at 08/25/2014 09:42 PM: > Hi all, > > I'm running Racket under 64-bit Win7 Home on an i7 with 12GB of RAM. > > Just upgraded to 6.0.1 from 5.3.4. I know it's a big leap and 6.1 is > out already, but I tried 6.1 and quickly experienced several of those > non-reproducible crashes I've been reading about in the lists. > > 6.0.1 is behaving itself, but installing new packages from PLaneT or > migrating packages from the older version is taking HOURS ... > virtually all of it spent processing .scrbl files. > > I have both 32 and 64 bit versions: doesn't matter which version I > use, how much memory I give to Racket (in racket-prefs.rktd), or > whether I use raco from the command line or the GUI-based package > manager. > > Example: trying to install *just* Neil's CSV:2:0 took nearly an hour > (yes, it has several dependencies). With 64-bit Racket configured for > 3GB, memory use spiked over 1.9GB according to Process Explorer. And > that was the *fastest* installation ... reducing the memory limit > below 2GB just slows it down. > [I didn't try running the 32-bit version with more than 1.5GB, but it > behaved the same way ... reducing the memory limit just slowed it > down.] > > For giggles I tried migrating CSV:1:7 (which has a single dependency > not shared with 2:0) from 5.3.4. That still took almost 16 minutes, > and again nearly all of it processing some .scrbl file. For more > giggles, I nuked the PLaneT cache so as to start over: same 16 minutes > for fresh install of 1:7. > > For comparison, 5.3.4 installs CSV:1:7 fresh in under 3 minutes. > > > > ??? Is anyone else running 6.x on Windows? I can't figure out what, > if anything, I'm doing wrong. > > Subjectively, 6.0.1 feels sluggish compared to 5.3.4 (with same memory > limits), but I haven't gotten to the point where I can objectively > test much because a lot of my programs depend on external packages. > Based on the few I have tried to install/migrate so far, Halloween may > be past before I am able to do any real work with 6.0.1. > > George > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From mflatt at cs.utah.edu Sat Aug 30 09:41:02 2014 From: mflatt at cs.utah.edu (Matthew Flatt) Date: Sat, 30 Aug 2014 07:41:02 -0600 Subject: [racket] Package installation VERY SLOW In-Reply-To: References: Message-ID: <20140830134103.935B165018C@mail-svr1.cs.utah.edu> At Mon, 25 Aug 2014 21:42:08 -0400, George Neuner wrote: > Just upgraded to 6.0.1 from 5.3.4. I know it's a big leap and 6.1 is > out already, but I tried 6.1 and quickly experienced several of those > non-reproducible crashes I've been reading about in the lists. Do you mean Evgeny's report on August 1, or did you have something else in mind? (I don't have the sense that there are widespread reports of problems with v6.1, so I may be missing something.) If you have time to help and you can quickly provoke crashes --- even if you're not sure what causes it --- that sounds promising for debugging. I'll ask more about that off-list. > 6.0.1 is behaving itself, but installing new packages from PLaneT or > migrating packages from the older version is taking HOURS ... > virtually all of it spent processing .scrbl files. It's probably no surprise to hear that it worked ok on my machine (about 1 minute) in a fresh v6.0.1 install. Can you say more about the ".scrbl" part? Is the process of installing a Planet package rebuilding documentation for the entire installation? Or is it getting stuck on just the documentation for the installed packages plus the main page and search index? > I have both 32 and 64 bit versions: doesn't matter which version I > use, how much memory I give to Racket (in racket-prefs.rktd), or > whether I use raco from the command line or the GUI-based package > manager. FWIW, the memory limit in the preferences file isn't supposed to affect package installation. From mb at mbtype.com Sat Aug 30 11:11:49 2014 From: mb at mbtype.com (Matthew Butterick) Date: Sat, 30 Aug 2014 08:11:49 -0700 Subject: [racket] Should `raco pkg update ` presume --update-deps? In-Reply-To: <20140829180803.040B3650188@mail-svr1.cs.utah.edu> References: <20140829180803.040B3650188@mail-svr1.cs.utah.edu> Message-ID: I'll take it! Thanks for your prescience. On Aug 29, 2014, at 11:08 AM, Matthew Flatt wrote: > The `update-implies` declaration, which was added just a few weeks ago, > implements the update behavior that you want. > > (Your suggestion of `latest` as a version specification is nicer, but > `update-implies` creates fewer compatibility issues and touches less > code.) > > We added `update-implies` with packages like "xrepl-test" and > "xrepl-lib" in mind, where "xrepl-test" is so tightly bound to > "xrepl-lib" that it only makes sense to update the former when also > updating the latter. Also, those packages will always be in the same > source repository, even though we want to keep them as separate > packages to allow more precise dependency specifications. > > Although "pollen" doesn't seem so tightly bound to "txexpr" and > "sugar", you make a fine case for adding > > (define update-implies '("txexpr" "sugar")) > > to the "info.rkt" of "pollen". > > At Fri, 29 Aug 2014 10:21:54 -0700, Matthew Butterick wrote: >> Exhuming this thread because I've recently encountered this issue too ? >> expecting `raco pkg update ...` to update dependencies, and then it >> doesn't. >> >> Reviewing the correspondence we have: >> >> 1. The Hendershott option ? automatic dependency updating by default >> 2. The McCarthy option ? dependency updating only when asked >> >> I understand the logic of both. Yet we could add more options to the pile: >> >> 3. The user option ? `raco pkg update ...` puts up a user prompt if it >> notices that dependencies have changed (similar to what happens with `raco >> pkg install ...`) >> >> 4. The Not All Dependencies Are Equal option ? this is where I'm at. My >> Pollen package depends on two other packages that I maintain (Sugar & >> Txexpr) but also some packages I don't maintain (Markdown & Rackjure et >> al.) >> >> Some bugs that arise in Pollen are really bugs in Sugar or Txexpr. So in >> one sense, I would like `raco pkg update ...` to always update those >> dependencies. >> >> But Pollen doesn't depend as sensitively on Markdown et al. So, similar to >> Jay's secret-wiki-server example, I don't want to tell users to do `raco >> pkg update --update-deps ...` because it might bring in new versions of >> Markdown et al. that destabilize user installations. >> >> 5. The Just Use Versioning option ? I gather that I could manage all this >> manually by adding version requirements to Pollen's 'info.rkt' file. For >> instance: update the Sugar package, update the Sugar package version, >> update Pollen's dependency on with the new Sugar version number, and then >> `raco pkg update pollen` will get the Sugar update but leave others alone. >> >> But I don't like this option, because it a) puts me into the >> version-tracking business and b) feels it like undermines one of the nice >> principles of the Racket package system, which is letting us care about >> checksums rather than versions when that makes sense. >> >> As I say that, I wonder if a solution would be to allow a package >> maintainer to determine the behavior of `racket pkg update ...` from within >> 'info.rkt', perhaps by adding a 'latest option to the #:version field. >> >> For instance, here's the current Pollen dependency line: >> >> (define deps '(("base" #:version "6.0") "txexpr" "sugar" ("markdown" >> #:version "0.18") "htdp")) >> >> Right now `raco pkg update pollen` won't update Markdown unless I bump the >> #:version. I like that. But it won't update Txexpr or Sugar either. I don't >> like that. >> >> Whereas if I could do this: >> >> (define deps '(("base" #:version "6.0") ("txexpr" #:version 'latest) >> ("sugar" #:version 'latest) ("markdown" #:version "0.18") "htdp")) >> >> That could be the signal that `raco pkg update pollen` should always scoop >> up any available updates for Txexpr and Sugar too, while leaving Markdown >> alone as usual. >> >> >> >> >> >> On Mon, Nov 11, 2013 at 8:18 AM, Greg Hendershott >> wrote: >> >>> I agree this example isn't a good reason to make --update-deps the default. >>> >>> I expected `raco pkg update x` would update x and all its >>> dependencies. My expectation was wrong. What might be a good reason >>> would be if many other people shared this wrong expectation, but I >>> don't know that's the case. >>> >>> On Mon, Nov 11, 2013 at 10:07 AM, Jay McCarthy >>> wrote: >>>> On Mon, Nov 11, 2013 at 7:44 AM, Greg Hendershott >>>> wrote: >>>>> In response to my "I can't think of a situation" you raise with your >>>>> own "I can't think of a situation". Well played sir. :) >>>>> >>>>> The updated markdown parser is more likely to handle some corner cases >>>>> than the old one, e.g. being less finicky about requiring a blank line >>>>> after some element. >>>>> >>>>> I had updated Frog to be able to use the new version and give those >>>>> improved results, but still be compatible with the older version. >>>>> >>>>> I guess my thinking was, the newer parser was such a huge redesign, I >>>>> wanted the safety net of someone being able to revert to the older >>>>> version (at least temporarily). >>>>> >>>>> So that's why I bumped the ver on the markdown, but not the ver for >>>>> frog's dep on it. >>>>> >>>>> Probably I over-thunk it. And the new parser seems solid so far. As a >>>>> result, I should just bump frog's own version, and bump the version of >>>>> markdown it requires. And then all will be well. >>>>> >>>>> As for the general question: I think you're saying that with the >>>>> status quo `raco pkg update `, if an installed dep is older than >>>>> required, it will install the very latest version (perhaps newer than >>>>> required), otherwise it will do nothing? Whereas with --update-deps >>>>> it does the equivalent of an individual `raco pkg update ` on >>>>> every dep transitively, so you'll end up with the very latest of >>>>> everything? >>>> >>>> Yes, that's correct. As you mention "update = remove + install", I >>>> hope this result is predictable. Imagine, for a moment that someone >>>> used your old markdown package with my unreleased super-secret Racket >>>> Wiki server. Then, they decided that they wanted your blog engine too. >>>> You wouldn't expect installing "frog" to update the markdown package. >>>> Since "raco pkg update " is literally just removing the package and >>>> adding it again (with a tiny bit of a barrier in case the second >>>> install fails), it works the same way. >>>> >>>> I don't have a strong opinion about your suggestion of switching the >>>> default behavior, but I'm not sure your example is the best reason to >>>> switch it. >>>> >>>> My attitude is that when you "raco pkg update " you are planning on >>>> getting new behavior in and not "error fixes on and everything >>>> else that it uses" (where "better Markdown parsing" can be seen as a >>>> fixing an error in the old parser). But when you use "--update-deps" >>>> (or "-a") then you are planning on just looking for new versions of >>>> anything. I like the feeling of stability this pattern gives. >>>> >>>> One case where I think "--update-deps" should definitely be implied is >>>> when a package "implies" other packages, such as 'main-distribution' >>>> implying 'srfi', because the "implies" is transparent, so the user >>>> doesn't necessarily know which package is really providing the feature >>>> they want updated. >>>> >>>> In any case, I think I will probably be able to continuing living if >>>> "--update-deps" were the default, but I want a better example or a few >>>> +1s. >>>> >>>> Jay >>>> >>>> -- >>>> Jay McCarthy >>>> Assistant Professor / Brigham Young University >>>> http://faculty.cs.byu.edu/~jay >>>> >>>> "The glory of God is Intelligence" - D&C 93 >>> ____________________ >>> Racket Users list: >>> http://lists.racket-lang.org/users >>> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users From dpavlov at ipa.nw.ru Sat Aug 30 18:54:03 2014 From: dpavlov at ipa.nw.ru (Dmitry Pavlov) Date: Sun, 31 Aug 2014 02:54:03 +0400 Subject: [racket] performance of iteration through a vector Message-ID: Hello, Consider the following program: (define n 100) (define vec (for/vector ((i (in-range n))) i)) (let ((t (current-inexact-milliseconds)) (sum 0)) (for ((j (in-range 1000000))) (for ((i (in-range n))) (set! sum (+ sum (vector-ref vec i))))) (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) (let ((t (current-inexact-milliseconds)) (sum 0)) (for ((j (in-range 1000000))) (for ((v vec)) (set! sum (+ sum v)))) (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) On my system (64-bit linux, Racket 6.1.0.2), it gives the following result: 1.016682861328125 6.3261611328125 So we can make a conclusion that (for ((v vec)) ...) is 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) Is it normal? Would you advise to use the explicit (vector-ref) when performance matters? Best regards Dmitry -------------- next part -------------- An HTML attachment was scrubbed... URL: From skanaley at gmail.com Sat Aug 30 19:20:04 2014 From: skanaley at gmail.com (Sean Kanaley) Date: Sat, 30 Aug 2014 19:20:04 -0400 Subject: [racket] performance of iteration through a vector In-Reply-To: References: Message-ID: The generic (for ([var seq]) is slow regardless of vector/list/etc. But there is often a specific "in-" form. On my machine (for ((j (in-range 1000000))) (for ((v (in-vector vec))) (set! sum (+ sum v)))) is very slightly faster than the explicit vector ref version, 7.3... vs. 7.6... (32 bit Ubuntu). On Sat, Aug 30, 2014 at 6:54 PM, Dmitry Pavlov wrote: > Hello, > > Consider the following program: > > (define n 100) > (define vec (for/vector ((i (in-range n))) i)) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((i (in-range n))) > (set! sum (+ sum (vector-ref vec i))))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((v vec)) > (set! sum (+ sum v)))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > On my system (64-bit linux, Racket 6.1.0.2), it gives the following result: > > 1.016682861328125 > 6.3261611328125 > > > So we can make a conclusion that (for ((v vec)) ...) is > 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) > Is it normal? Would you advise to use the explicit (vector-ref) > when performance matters? > > Best regards > > Dmitry > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mb at mbtype.com Sat Aug 30 21:18:13 2014 From: mb at mbtype.com (Matthew Butterick) Date: Sat, 30 Aug 2014 18:18:13 -0700 Subject: [racket] performance of iteration through a vector In-Reply-To: References: Message-ID: <769F57C9-E96F-4FD1-8A60-1D98D1C6D619@mbtype.com> Usually you'll get the best performance from `for` loops by using the in-* iterators. In this case, you can use `in-vector` [1], which on my machine is faster: (let ((t (current-inexact-milliseconds)) (sum 0)) (for ((j (in-range 1000000))) (for ((v (in-vector vec))) (set! sum (+ sum v)))) (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) I assume this is a synthetic example, but you can also improve performance by using appropriate versions of `for`. This is faster than the last one: (let ((t (current-inexact-milliseconds))) (for*/fold ([sum 0])([j (in-range 1000000)][v (in-vector vec)]) (+ sum v)) (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) And this is faster still: (let ((t (current-inexact-milliseconds))) (for*/sum ([j (in-range 1000000)][v (in-vector vec)]) v) (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) [1] http://docs.racket-lang.org/reference/sequences.html?q=in-vector#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._in-vector%29%29 On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov wrote: > Hello, > > Consider the following program: > > (define n 100) > (define vec (for/vector ((i (in-range n))) i)) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((i (in-range n))) > (set! sum (+ sum (vector-ref vec i))))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((v vec)) > (set! sum (+ sum v)))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > On my system (64-bit linux, Racket 6.1.0.2), it gives the following result: > > 1.016682861328125 > 6.3261611328125 > > > So we can make a conclusion that (for ((v vec)) ...) is > 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) > Is it normal? Would you advise to use the explicit (vector-ref) > when performance matters? > > Best regards > > Dmitry > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov wrote: > Hello, > > Consider the following program: > > (define n 100) > (define vec (for/vector ((i (in-range n))) i)) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((i (in-range n))) > (set! sum (+ sum (vector-ref vec i))))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((v vec)) > (set! sum (+ sum v)))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > On my system (64-bit linux, Racket 6.1.0.2), it gives the following result: > > 1.016682861328125 > 6.3261611328125 > > > So we can make a conclusion that (for ((v vec)) ...) is > 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) > Is it normal? Would you advise to use the explicit (vector-ref) > when performance matters? > > Best regards > > Dmitry > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -------------- next part -------------- An HTML attachment was scrubbed... URL: From robby at eecs.northwestern.edu Sun Aug 31 01:19:02 2014 From: robby at eecs.northwestern.edu (Robby Findler) Date: Sun, 31 Aug 2014 00:19:02 -0500 Subject: [racket] performance of iteration through a vector In-Reply-To: <769F57C9-E96F-4FD1-8A60-1D98D1C6D619@mbtype.com> References: <769F57C9-E96F-4FD1-8A60-1D98D1C6D619@mbtype.com> Message-ID: Or, use typed racket. Robby On Sat, Aug 30, 2014 at 8:18 PM, Matthew Butterick wrote: > Usually you'll get the best performance from `for` loops by using the in-* > iterators. > In this case, you can use `in-vector` [1], which on my machine is faster: > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((v (in-vector vec))) > (set! sum (+ sum v)))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > I assume this is a synthetic example, but you can also improve performance > by using appropriate versions of `for`. This is faster than the last one: > > (let ((t (current-inexact-milliseconds))) > (for*/fold ([sum 0])([j (in-range 1000000)][v (in-vector vec)]) > (+ sum v)) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > And this is faster still: > > (let ((t (current-inexact-milliseconds))) > (for*/sum ([j (in-range 1000000)][v (in-vector vec)]) > v) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > [1] > http://docs.racket-lang.org/reference/sequences.html?q=in-vector#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._in-vector%29%29 > > > On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov wrote: > > Hello, > > Consider the following program: > > (define n 100) > (define vec (for/vector ((i (in-range n))) i)) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((i (in-range n))) > (set! sum (+ sum (vector-ref vec i))))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((v vec)) > (set! sum (+ sum v)))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > On my system (64-bit linux, Racket 6.1.0.2), it gives the following result: > > 1.016682861328125 > 6.3261611328125 > > > So we can make a conclusion that (for ((v vec)) ...) is > 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) > Is it normal? Would you advise to use the explicit (vector-ref) > when performance matters? > > Best regards > > Dmitry > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > > > On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov wrote: > > Hello, > > Consider the following program: > > (define n 100) > (define vec (for/vector ((i (in-range n))) i)) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((i (in-range n))) > (set! sum (+ sum (vector-ref vec i))))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > (let ((t (current-inexact-milliseconds)) > (sum 0)) > (for ((j (in-range 1000000))) > (for ((v vec)) > (set! sum (+ sum v)))) > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > On my system (64-bit linux, Racket 6.1.0.2), it gives the following result: > > 1.016682861328125 > 6.3261611328125 > > > So we can make a conclusion that (for ((v vec)) ...) is > 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) > Is it normal? Would you advise to use the explicit (vector-ref) > when performance matters? > > Best regards > > Dmitry > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > From dpavlov at ipa.nw.ru Sun Aug 31 04:18:25 2014 From: dpavlov at ipa.nw.ru (Dmitry Pavlov) Date: Sun, 31 Aug 2014 12:18:25 +0400 Subject: [racket] performance of iteration through a vector In-Reply-To: References: <769F57C9-E96F-4FD1-8A60-1D98D1C6D619@mbtype.com> Message-ID: All, Thanks for the pointer to (in-vector). It indeed works faster than the explicit (vector-ref) or even (unsafe-vector-ref). And yes, I should get around to Typed Racket someday. Regards, Dmitry On Sun, Aug 31, 2014 at 9:19 AM, Robby Findler wrote: > Or, use typed racket. > > Robby > > On Sat, Aug 30, 2014 at 8:18 PM, Matthew Butterick wrote: > > Usually you'll get the best performance from `for` loops by using the > in-* > > iterators. > > In this case, you can use `in-vector` [1], which on my machine is faster: > > > > (let ((t (current-inexact-milliseconds)) > > (sum 0)) > > (for ((j (in-range 1000000))) > > (for ((v (in-vector vec))) > > (set! sum (+ sum v)))) > > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > > I assume this is a synthetic example, but you can also improve > performance > > by using appropriate versions of `for`. This is faster than the last one: > > > > (let ((t (current-inexact-milliseconds))) > > (for*/fold ([sum 0])([j (in-range 1000000)][v (in-vector vec)]) > > (+ sum v)) > > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > > And this is faster still: > > > > (let ((t (current-inexact-milliseconds))) > > (for*/sum ([j (in-range 1000000)][v (in-vector vec)]) > > v) > > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > > > > [1] > > > http://docs.racket-lang.org/reference/sequences.html?q=in-vector#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._in-vector%29%29 > > > > > > On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov wrote: > > > > Hello, > > > > Consider the following program: > > > > (define n 100) > > (define vec (for/vector ((i (in-range n))) i)) > > > > (let ((t (current-inexact-milliseconds)) > > (sum 0)) > > (for ((j (in-range 1000000))) > > (for ((i (in-range n))) > > (set! sum (+ sum (vector-ref vec i))))) > > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > > (let ((t (current-inexact-milliseconds)) > > (sum 0)) > > (for ((j (in-range 1000000))) > > (for ((v vec)) > > (set! sum (+ sum v)))) > > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > > > > On my system (64-bit linux, Racket 6.1.0.2), it gives the following > result: > > > > 1.016682861328125 > > 6.3261611328125 > > > > > > So we can make a conclusion that (for ((v vec)) ...) is > > 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) > > Is it normal? Would you advise to use the explicit (vector-ref) > > when performance matters? > > > > Best regards > > > > Dmitry > > > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > > > > > > > > On Aug 30, 2014, at 3:54 PM, Dmitry Pavlov wrote: > > > > Hello, > > > > Consider the following program: > > > > (define n 100) > > (define vec (for/vector ((i (in-range n))) i)) > > > > (let ((t (current-inexact-milliseconds)) > > (sum 0)) > > (for ((j (in-range 1000000))) > > (for ((i (in-range n))) > > (set! sum (+ sum (vector-ref vec i))))) > > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > > (let ((t (current-inexact-milliseconds)) > > (sum 0)) > > (for ((j (in-range 1000000))) > > (for ((v vec)) > > (set! sum (+ sum v)))) > > (displayln (/ (- (current-inexact-milliseconds) t) 1000.0))) > > > > > > On my system (64-bit linux, Racket 6.1.0.2), it gives the following > result: > > > > 1.016682861328125 > > 6.3261611328125 > > > > > > So we can make a conclusion that (for ((v vec)) ...) is > > 6x slower than (for ((i (in-range n))) ... (vector-ref vec i) ...) > > Is it normal? Would you advise to use the explicit (vector-ref) > > when performance matters? > > > > Best regards > > > > Dmitry > > > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > > > > > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gneuner2 at comcast.net Sun Aug 31 07:44:31 2014 From: gneuner2 at comcast.net (George Neuner) Date: Sun, 31 Aug 2014 07:44:31 -0400 Subject: [racket] Package installation VERY SLOW References: <5401AAC1.8030604@neilvandyke.org> Message-ID: Hi Neil, Thanks for responding. I do want to emphasize that my comments weren't meant to pick on you specifically: your CSV package happened to be the one I had just been installing so it was on my mind when I wrote the original message. I do appreciate the work that went into making the packages and I use a few of yours extensively. On Sat, 30 Aug 2014 06:43:13 -0400, Neil Van Dyke wrote: >FWIW, I just tried Racket 6.1 installing PLaneT "neil/csv:1:7", and two >observations: > >* I don't immediately know why, but my Racket 6.1 (command-line >"racket", and DrRacket) doesn't build the documentation when installing >the PLaneT package. I can't look into this right now. I wasn't able to install on 6.1 at all. With 6.1, right from the start I experienced problems with Racket locking up - completely unresponsive, 0% CPU use - and after half a day trying to get it working I gave up. >* The performance looks fine, for not building the documentation. (This >is on a 6+ year-old 32-bit x86 GNU/Linux laptop with slow spinning hard >drive, running a Racket I built from source.) > >I haven't played with Racket 6.x much, since the main project I'm >working on right now is still using Racket 5.3.4 (with Ryan's essential >PostgreSQL SSL patch). Your times for 1:7 are in line with what I'm seeing ... a bit less than 20 minutes for first install. 2:0 takes well over an hour. However I'm on a fairly new i7 with 12GB of RAM and a fast disk. I am using Windows rather than Linux/Unix. I have had this experience with every package that includes integrated documentation - whether a fresh download from PLaneT or imported into 6.0.1 from 5.3.4. Things that take minutes to install on 5.3.4 take 10s of minutes on 6.0.1. Also, I have tried both 32-bit and 64-bit Racket. The behavior is roughly the same - throwing more memory at it with 64-bit doesn't seem to make any difference. CPU usage varies, but is rarely over 30%. Once packages are successfully installed, there is no problem using them. Subjectively the 6.0.1 GUI feels to me to be slower than 5.3.4 GUI, but programs run acceptably fast and when run from the command line programs actually seem to be a hair faster. >Neil V. George From gneuner2 at comcast.net Sun Aug 31 07:44:31 2014 From: gneuner2 at comcast.net (George Neuner) Date: Sun, 31 Aug 2014 07:44:31 -0400 Subject: [racket] Package installation VERY SLOW References: <20140830134103.935B165018C@mail-svr1.cs.utah.edu> Message-ID: Hi Matthew, On Sat, 30 Aug 2014 07:41:02 -0600, Matthew Flatt wrote: >At Mon, 25 Aug 2014 21:42:08 -0400, George Neuner wrote: >> Just upgraded to 6.0.1 from 5.3.4. I know it's a big leap and 6.1 is >> out already, but I tried 6.1 and quickly experienced several of those >> non-reproducible crashes I've been reading about in the lists. > >Do you mean Evgeny's report on August 1, or did you have something else >in mind? (I don't have the sense that there are widespread reports of >problems with v6.1, so I may be missing something.) I don't recall Evgeny's report offhand and I can't find it just now. I have seen a different reports of issues with 6.1 in different places. On Windows 7 I experienced hanging with 64-bit 6.1 - completely unresponsive, 0% CPU. This happened numerous times doing different things: running package manager, editing, even just adjusting preferences. It seemed to be a GUI issue as raco worked from the command line. I had so much trouble with it that I didn't try very much. I uninstalled/reinstalled with fresh downloads a couple of times before giving up. 32-bit 6.1 did not hang, but it took almost 40 minutes to install [more than twice as long as 64-bit] and was so slow doing anything that I was convinced it was broken. Again I tried uninstalling/reinstalling without anything changing significantly. Then I read about the internal changes and decided to fall back to 6.0.1 until everything shakes out. >If you have time to help and you can quickly provoke crashes --- even >if you're not sure what causes it --- that sounds promising for >debugging. I'll ask more about that off-list. I got your note. I'd like to help but right now I'm in the middle of something and don't have a lot of time to muck around with it. I do have VS2010 available, but Racket was hanging rather than crashing, so the debugger didn't activate. Unfortunately I didn't think to attach to the hung process and see what was happening before killing it. >> 6.0.1 is behaving itself, but installing new packages from PLaneT or >> migrating packages from the older version is taking HOURS ... >> virtually all of it spent processing .scrbl files. > >It's probably no surprise to hear that it worked ok on my machine >(about 1 minute) in a fresh v6.0.1 install. > >Can you say more about the ".scrbl" part? Is the process of installing >a Planet package rebuilding documentation for the entire installation? >Or is it getting stuck on just the documentation for the installed >packages plus the main page and search index? It's hard to tell exactly because I'm not very familiar with the package install process, but it does get stuck "--- building documentation ---" for long periods with no output from raco. It seems to spend an inordinate amount of time "processing" scrbl files that are included with the packages. I don't mean rendering them - raco shows that separately - but just "processing" them. It would be nice if raco could timestamp its output. I can try to capture a procmon trace of a simple install if that would be any help. Ususally I find traces have too much information 8-( George From spdegabrielle at gmail.com Sun Aug 31 17:49:42 2014 From: spdegabrielle at gmail.com (Stephen De Gabrielle) Date: Sun, 31 Aug 2014 22:49:42 +0100 Subject: [racket] FYI: scheme looks good in this paper examining first-year data In-Reply-To: References: Message-ID: Looks like it ended up in 'Proceedings of the 7th International Conference on Educational Data Mining.' in a shorter form. http://educationaldatamining.org/EDM2014/index.php?page=proceedings http://educationaldatamining.org/EDM2014/uploads/procs2014/posters/97_EDM-2014-Poster.pdf -- Stephen De Gabrielle stephen.degabrielle at acm.org Telephone +44 (0)20 85670911 Mobile +44 (0)79 85189045 http://www.degabrielle.name/stephen On Wed, Aug 27, 2014 at 4:37 PM, John Clements wrote: > I can?t tell whether this paper was published *anywhere*, but Google told > me about it because it cites me. It tries to mine data from ratemyprofessor > to draw conclusions about what makes for a good first computing class. You > can take all of this with many grains of salt, but the language most > strongly correlated with clarity in a first-year class is Scheme. The major > caveat is the number of samples, which is small for all languages but > especially small (32) for Scheme, suggesting that it may be the good work > of a few professors. On the other hand, it may well be the influence of > HtDP. > > Anyhow?a small piece of good news to brighten y?all?s day. > > John > > > > http://aspiringminds.com/pages/assess/2014/camera_ready/paper/moretti_etal.pdf > ____________________ > Racket Users list: > http://lists.racket-lang.org/users > -------------- next part -------------- An HTML attachment was scrubbed... URL: