Re: [racket-users] IO in racket is painful
Sorry for reviving an old thread. As someone who did a lot of programming competition in the past, I can totally see why IO in Racket is difficult. As mark.engelberg said, the goal is to solve as many problems as possible. After the competition is over, it's over. No one is going to care about maintainability or good coding practice if it makes coding slower. For this reason, I wouldn't use parsack if possible. While elegant, there's too much to write which is a waste of time. Luckily, major programming competitions (say, Facebook Hacker Cup, Google Code Jam, early IOI, ACM-ICPC, etc.) usually have simple input format. Data are usually separated by spaces. Rarely spaces matter. rom gcb says that the input is: 3 [04, foo, 03.5] [05, bar, 04.6] [06, fun, 05.7] but in these competitions, the input is more likely to be: 3 04 foo 03.5 05 bar 04.6 06 fun 05.7 What really gets in the way is that strings in the input could be something that Racket's (read) doesn't recognize. As an example, a string might be #asd. This would cause (read) to error "read: bad syntax `#a'". Indeed, using (read-line) along with regex would solve the problem. The downside is that it requires a lot of writing and is heavily task-dependent. What I want is a uniform way to extract data easily like scanf. I write the following module for this purpose. It's a lot of code, so it would be useless in closed competitions like ACM-ICPC. However, for online competitions like FB Hacker Cup, I find it pretty useful. #lang racket (provide (all-defined-out)) (define read-next (let ([buffer #f]) (lambda (#:to-eol [to-eol #f]) (define (more!) (set! buffer (read-line)) (read-next #:to-eol to-eol)) (match buffer [(? string?) (cond [to-eol (let ([ret buffer]) (set! buffer #f) ret)] [else (set! buffer (string-trim buffer #:right? #f)) (match (regexp-match #px"\\S+" buffer) [(list ret) (set! buffer (regexp-replace #px"^\\S+" buffer "")) ret] [#f (more!)])])] [_ (more!)] (define (%list n typ) (thunk (for/list ([_ n]) (typ (define (%gets) (read-next #:to-eol #t)) (define (%num) (string->number (read-next))) (define (%str) (read-next)) (define-syntax-rule (scan [v m] ...) (begin (define v (m)) ...)) (module+ test (require rackunit) (parameterize ([current-input-port (open-input-string (string-append "2 3 \n" "123\n" " 4 5 6\n" " \n" " \n" " \n" "\n" " '\"has-quotes\"' blah blah "))]) (scan [n %num] [m %num] [matrix (%list n (%list m %num))] [trailing-spaces %gets] [str-with-quotes %str] [line-with-space %gets]) (check-equal? n 2) (check-equal? m 3) (check-equal? matrix (list (list 1 2 3) (list 4 5 6))) (check-equal? trailing-spaces "") (check-equal? str-with-quotes "'\"has-quotes\"'") (check-equal? line-with-space " blah blah "))) For example, https://code.google.com/codejam/contest/6254486/dashboard#s=p1 can be solved as follows: (scan [n %num]) (for ([i n]) (scan [s %str]) (define simp (regexp-replaces s '([#px"\\++" "+"] [#px"\\-+" "-"]))) (define len (string-length simp)) (printf "Case #~a: ~a\n" (add1 i) (match (list (string-ref simp 0) (even? len)) [(or (list #\+ #t) (list #\- #f)) len] [(or (list #\+ #f) (list #\- #t)) (sub1 len)]))) -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Understanding compilation costs and creating persistent values
On Thu, Jul 20, 2017 at 2:56 PM, Matthew Flattwrote: > Adding to other replies: > > At Thu, 20 Jul 2017 13:32:49 -0400, David Storrs wrote: > > Will any of the above items be compiled away? > > You can compile a module with `raco make` and look at the compiled code > with `raco decompile`. If I put your code in a module and try that, the > output includes > > (define-values > (_foo) > (lambda () > >(begin > (values (file-size '"/some/path")) > (let ((local22 (file-size '"/some/other/path"))) >(begin > (|_displayln:p@(lib "racket/private/misc.rkt")| > (#%sfs-clear local22)) > '#t) > > So, you can see that the compiler discarded an addition that always > produces 2, and it discarded the unused `bar` function. It also got rid > of the unused `size` variable, but it preserved everything else as a > run-time computation. > Brilliant. Thank you Matthew, this is really useful to know. > > > Perl has the 'state' declaration, which says "Declare this as a local > > variable, but keep it around with its value preserved after you exit the > > function." > > Assuming that you really want to do that and you really want a `state` > form: > > (define-syntax (state stx) > (syntax-parse stx > [(_ var:id rhs:expr) >(with-syntax ([lifted-var (syntax-local-lift-expression #'rhs)]) > #'(define-syntax var (make-rename-transformer #'lifted-var)))])) > > (define (f v) > (state accum 0) > (set! accum (+ v accum)) > accum) > > (f 1) > (f 2) > > Man, Racket is amazing. > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Racket7 Conceit
Yes, my first question was definitely answered already. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Understanding compilation costs and creating persistent values
Adding to other replies: At Thu, 20 Jul 2017 13:32:49 -0400, David Storrs wrote: > Will any of the above items be compiled away? You can compile a module with `raco make` and look at the compiled code with `raco decompile`. If I put your code in a module and try that, the output includes (define-values (_foo) (lambda () (begin (values (file-size '"/some/path")) (let ((local22 (file-size '"/some/other/path"))) (begin (|_displayln:p@(lib "racket/private/misc.rkt")| (#%sfs-clear local22)) '#t) So, you can see that the compiler discarded an addition that always produces 2, and it discarded the unused `bar` function. It also got rid of the unused `size` variable, but it preserved everything else as a run-time computation. > Perl has the 'state' declaration, which says "Declare this as a local > variable, but keep it around with its value preserved after you exit the > function." Assuming that you really want to do that and you really want a `state` form: (define-syntax (state stx) (syntax-parse stx [(_ var:id rhs:expr) (with-syntax ([lifted-var (syntax-local-lift-expression #'rhs)]) #'(define-syntax var (make-rename-transformer #'lifted-var)))])) (define (f v) (state accum 0) (set! accum (+ v accum)) accum) (f 1) (f 2) -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Understanding compilation costs and creating persistent values
David Storrs wrote on 07/20/2017 01:32 PM: sub foo { state $x = 0; say $x++; } # $x is not visible in this scope foo(); foo(); foo(); (define foo (let ((x 0)) (lambda () (printf "~s~n" x) (set! x (add1 x) ; x is not visible in this scope (foo) (foo) (foo) Doing this with mutable variables is usually a bad idea. For major historical example, an analogous practice resulted in a headache of "non-reentrant" C library functions when we started doing multithreaded programming. And you're going to have to think about concurrency implications. Of course, sometimes it's appropriate. It's another of those things that people usually shouldn't do unless and until they know why it's usually a bad idea, they understand the possible alternative approaches, and they know why it's appropriate in this case. It's more often a good idea if `x` is immutable. Like, `x` is referenced only in that procedure, and has a constant value that you want to initialize at/after load time (e.g., constructing a value using info or code that's not available until load time). Before Racket got `#rx` syntax, I'd sometimes use this to compile regular expressions, and just keep them "close to" the procedure that used them, readability/maintainability-wise. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Understanding compilation costs and creating persistent values
> Will any of the above items be compiled away? To answer your first question, I would recommend taking a look at the optimization coach. It can help you figure out what code was inlined away and what wasn't. You can find it in: View -> Show Optimization coach > How many times will each thing be expanded and compiled -- is bar defined and > compiled five separate times, only once, or not at all? Even if `bar` is not inlined, it will still only be compiled once. However, it will close over 5 different sets of variables (containing num, size, etc.) > Is there a simple way to achieve the same thing in Racket? Yes there is. Although I must state that if you find yourself doing this, stop, and rethink things, because more often then not there is a simpler way to write your code. However, if this is one of the rare cases where `state` variables (so to speak) are needed, I find using `(let () ...)` blocks to be helpful. Take the following code: (define inc (let () (define x 0) (lambda () (set! x (+ x 1)) x))) Here, `inc` is a function that takes no arguments, but has a so-called `state` variable that increments with each call. > (inc) 1 > (inc) 2 > (inc) 3 ... Again, when you find yourself doing that, I strongly recommend stopping and rethinking your solution. Hope that helps. ~Leif Andersen On Thu, Jul 20, 2017 at 1:32 PM, David Storrswrote: > Given this code: > > (define (foo) >(define num (+ 1 1)); result > of a function that is program-local >(define size (file-size "/some/path")) ; result of a > function that touches the disk, but result never used >(define other-size (file-size "/some/other/path")) ; result of function > that touches disk, result is used >(displayln other-size) >(define x 7) ; > binding of constant value, binding is never used >(define (bar) ; > binding of function, function is never used >(displayln "bar")) >#t) > > (for ((i 5)) > (foo)) > > Will any of the above items be compiled away? How many times will each > thing be expanded and compiled -- is bar defined and compiled five separate > times, only once, or not at all? > > > Separate but related question: > > Perl has the 'state' declaration, which says "Declare this as a local > variable, but keep it around with its value preserved after you exit the > function." For example: > > sub foo { state $x = 0; say $x++; } > # $x is not visible in this scope > foo(); > foo(); > foo(); > > > Output: > 0 > 1 > 2 > > Is there a simple way to achieve the same thing in Racket? > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Understanding compilation costs and creating persistent values
Given this code: (define (foo) (define num (+ 1 1)); result of a function that is program-local (define size (file-size "/some/path")) ; result of a function that touches the disk, but result never used (define other-size (file-size "/some/other/path")) ; result of function that touches disk, result is used (displayln other-size) (define x 7) ; binding of constant value, binding is never used (define (bar) ; binding of function, function is never used (displayln "bar")) #t) (for ((i 5)) (foo)) Will any of the above items be compiled away? How many times will each thing be expanded and compiled -- is bar defined and compiled five separate times, only once, or not at all? Separate but related question: Perl has the 'state' declaration, which says "Declare this as a local variable, but keep it around with its value preserved after you exit the function." For example: sub foo { state $x = 0; say $x++; } # $x is not visible in this scope foo(); foo(); foo(); Output: 0 1 2 Is there a simple way to achieve the same thing in Racket? -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.