Re: [racket-users] Best way to write run-once-and-cache functions?
On Wednesday, April 26, 2017 at 9:48:56 AM UTC-7, David K. Storrs wrote: > On Wed, Apr 26, 2017 at 12:21 AM, Jon Zeppieriwrote: > I don't know that there's a right way, but if your functions are > > nullary, then promises are a decent fit: > > > > (define conf > > (delay > > (with-input-from-file ...))) > > > > Then just (force conf) whenever you want the value. > > > > Yeah, that works well. Thanks! > > > Any thoughts on how to do it for non-nullary functions? For non-nullary functions, you're looking for memoization / caching. There's a couple packages that do this, along with relate - In the `sugar` package, the `sugar/cache` module gives you exactly this, in the form of a `define/caching` macro. - The `tmemoize` package provides similar functionality for Typed Racket functions. - The `with-cache` package gives you promise-like behavior for thunks that use an external storage system. - The `remember` package gives you caching behavior for compile-time expressions that can be remembered across compilation runs. -- 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] Best way to write run-once-and-cache functions?
On Wed, Apr 26, 2017 at 12:48 PM, David Storrswrote: > > > On Wed, Apr 26, 2017 at 12:21 AM, Jon Zeppieri wrote: >> >> I don't know that there's a right way, but if your functions are >> nullary, then promises are a decent fit: >> >> (define conf >> (delay >> (with-input-from-file ...))) >> >> Then just (force conf) whenever you want the value. > > > Yeah, that works well. Thanks! > > Any thoughts on how to do it for non-nullary functions? >> The more complicated your function signatures get, the more worthwhile it will be to use the memoize package. But for, say, unary functions you can easily use a hash table: #lang racket (define read-conf (let ([h (make-hash)]) (λ (arg) (hash-ref! h arg (thunk ...) You can extend this to multiple arguments by using lists as keys, if you want. Of course, you need to make sure that `equal?` is usefully defined on your argument types. -- 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] Best way to write run-once-and-cache functions?
On Wed, Apr 26, 2017 at 12:21 AM, Jon Zeppieriwrote: > I don't know that there's a right way, but if your functions are > nullary, then promises are a decent fit: > > (define conf > (delay > (with-input-from-file ...))) > > Then just (force conf) whenever you want the value. > Yeah, that works well. Thanks! Any thoughts on how to do it for non-nullary functions? > > > > On Wed, Apr 26, 2017 at 12:12 AM, David Storrs > wrote: > > Reading configuration files is a good example of a run-once function. > It's > > effectively self-memoizing -- it should run once, cache its result, and > on > > future calls just return the cached value. I could pull in > > https://docs.racket-lang.org/memoize/index.html or > > http://docs.racket-lang.org/mischief@mischief/memoize.html to do that, > but > > adding an extra module to the project just for one or two functions feels > > pretty heavy. (Also, memoizing is overkill if the functions are > thunks.) Is > > there a simple way to do this in pure Racket? > > > > In Perl I would do something like this (for simplicity I'm ignoring > encoding > > and assuming that the config file is JSON): > > > > use JSON; > > sub read_conf { > > state $conf = do { > > local $/; > > open my $fh, "<", "db.conf" or die "failed to open config: $!"; > > from_json( <$fh> ) > > }; > > $conf > > } > > > > > > I could do this in Racket using set!, but that's not very Rackety: > > > > (require json) > > (define conf #f) > > (define (read-conf) > >(or conf > > (begin > >(set! conf (with-input-from-file "db.conf" (thunk > (read-json > >conf))) > > > > > > I could do it with a parameter but that's only sweeping the above > ugliness > > under the rug: > > > > (define conf (make-parameter #f)) > > (define (read-conf) > >(or (conf) > > (begin > >(conf (with-input-from-file "db.conf" (thunk (read-json > >(conf > > > > What is the right way? > > > > -- > > 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] Best way to write run-once-and-cache functions?
#lang racket (define read-conf (let [(conf (delay (with-input-from-file “db.conf" (thunk (displayln "hello") (read)] (thunk (force conf (read-conf) (read-conf) -- 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] Best way to write run-once-and-cache functions?
On Wednesday, April 26, 2017 at 5:21:41 AM UTC+1, Jon Zeppieri wrote: > (define conf > (delay > (with-input-from-file ...))) > > Then just (force conf) whenever you want the value. I tend to call promises xxx-promise (e.g. conf-promise), to remind me not to use them without force'ing them. Does anyone else hold to a convention for naming promises? Tim -- 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] Best way to write run-once-and-cache functions?
I don't know that there's a right way, but if your functions are nullary, then promises are a decent fit: (define conf (delay (with-input-from-file ...))) Then just (force conf) whenever you want the value. On Wed, Apr 26, 2017 at 12:12 AM, David Storrswrote: > Reading configuration files is a good example of a run-once function. It's > effectively self-memoizing -- it should run once, cache its result, and on > future calls just return the cached value. I could pull in > https://docs.racket-lang.org/memoize/index.html or > http://docs.racket-lang.org/mischief@mischief/memoize.html to do that, but > adding an extra module to the project just for one or two functions feels > pretty heavy. (Also, memoizing is overkill if the functions are thunks.) Is > there a simple way to do this in pure Racket? > > In Perl I would do something like this (for simplicity I'm ignoring encoding > and assuming that the config file is JSON): > > use JSON; > sub read_conf { > state $conf = do { > local $/; > open my $fh, "<", "db.conf" or die "failed to open config: $!"; > from_json( <$fh> ) > }; > $conf > } > > > I could do this in Racket using set!, but that's not very Rackety: > > (require json) > (define conf #f) > (define (read-conf) >(or conf > (begin >(set! conf (with-input-from-file "db.conf" (thunk (read-json >conf))) > > > I could do it with a parameter but that's only sweeping the above ugliness > under the rug: > > (define conf (make-parameter #f)) > (define (read-conf) >(or (conf) > (begin >(conf (with-input-from-file "db.conf" (thunk (read-json >(conf > > What is the right way? > > -- > 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] Best way to write run-once-and-cache functions?
In this very simple case, I would probably not define a function at all, just something like (define conf (with-input-from-file "db.conf" read-json)) You may also find yourself wanting define-runtime-path from racket/runtime-path. On Tue, Apr 25, 2017 at 11:12 PM, David Storrswrote: > Reading configuration files is a good example of a run-once function. > It's effectively self-memoizing -- it should run once, cache its result, > and on future calls just return the cached value. I could pull in > https://docs.racket-lang.org/memoize/index.html or > http://docs.racket-lang.org/mischief@mischief/memoize.html to do that, > but adding an extra module to the project just for one or two functions > feels pretty heavy. (Also, memoizing is overkill if the functions are > thunks.) Is there a simple way to do this in pure Racket? > > In Perl I would do something like this (for simplicity I'm ignoring > encoding and assuming that the config file is JSON): > > use JSON; > sub read_conf { > state $conf = do { > local $/; > open my $fh, "<", "db.conf" or die "failed to open config: $!"; > from_json( <$fh> ) > }; > $conf > } > > > I could do this in Racket using set!, but that's not very Rackety: > > (require json) > (define conf #f) > (define (read-conf) >(or conf > (begin >(set! conf (with-input-from-file "db.conf" (thunk (read-json >conf))) > > > I could do it with a parameter but that's only sweeping the above ugliness > under the rug: > > (define conf (make-parameter #f)) > (define (read-conf) >(or (conf) > (begin >(conf (with-input-from-file "db.conf" (thunk (read-json >(conf > > What is the right way? > > -- > 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] Best way to write run-once-and-cache functions?
Reading configuration files is a good example of a run-once function. It's effectively self-memoizing -- it should run once, cache its result, and on future calls just return the cached value. I could pull in https://docs.racket-lang.org/memoize/index.html or http://docs.racket-lang.org/mischief@mischief/memoize.html to do that, but adding an extra module to the project just for one or two functions feels pretty heavy. (Also, memoizing is overkill if the functions are thunks.) Is there a simple way to do this in pure Racket? In Perl I would do something like this (for simplicity I'm ignoring encoding and assuming that the config file is JSON): use JSON; sub read_conf { state $conf = do { local $/; open my $fh, "<", "db.conf" or die "failed to open config: $!"; from_json( <$fh> ) }; $conf } I could do this in Racket using set!, but that's not very Rackety: (require json) (define conf #f) (define (read-conf) (or conf (begin (set! conf (with-input-from-file "db.conf" (thunk (read-json conf))) I could do it with a parameter but that's only sweeping the above ugliness under the rug: (define conf (make-parameter #f)) (define (read-conf) (or (conf) (begin (conf (with-input-from-file "db.conf" (thunk (read-json (conf What is the right way? -- 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.