Is there any operator that can let me rewrite (for/sum ([i (in-range 1 11)]) (sqr i))
as something like following more concise form? (sum (map sqr (range 1 11)))
I know there is stream-map, but there isn’t a corresponding stream-sum.
Or even better some generic operator that can perform on anything sequential as List, Sequence or Stream.
@wanpeebaw there is stream-fold
: (stream-fold + 0 (stream-map sqr (range 1 11)))
Note that (range 1 11) will allocate a list with 10 elements. So for/sum
is more effecient especially for large ranges.
in-range
should work with stream-map
, but I assume that stream-fold
+ stream-map
will still be slower than for/sum
. sequence-{fold,map}
are also available.
Perhaps @notjack’s rebellion can be used as an alternative? https://docs.racket-lang.org/rebellion/Streaming_Computations.html?q=rebellion
Some combination of reducer-map and into-sum.
specifically, it would be this: (transduce (in-range 1 11)
(mapping sqr)
#:into into-sum)
(as @samdphillips pointed out in #api-design earlier)
Also, if you really want stream-sum
, just create one?
(define (stream-sum xs)
(for/sum ([x (in-stream xs)]) x))
consider accepting the more general sequence interface
(define (sequence-sum xs)
(for/sum ([x xs]) x))
will automatically work with streams, as well as tons of other things
And unfortunately slower :disappointed:
Why can’t (for ([x xs]) body)
be compiled into:
(cond
[(list? xs) (current-for ([x (in-list xs)]) body)]
[(vector? xs) (current-for ([x (in-vector xs)]) body)]
...
[else (current-for ([x xs]) body)])
All for loops blow up to 20x size in compiled code
Hmm. You are right
Oh, perhaps thunking body
first?
Especially in Racket CS, calling functions should be drastically cheaper
So just thunking body couldn’t do it, you would need to have a lambda that binds the parameter x
.
But I think that would still generate more code than it should. One way of solving that is by putting more things into pre-defined functions. For the simple case of one sequence-clause, the functions for-each
, vector-for-each
, stream-for-each
, and sequence-for-each
already exist.
And what does sequence-for-each
do? Does it use a cond like the code above, or does it do something else, better or worse?
(define (sequence-for-each f s)
(unless (procedure? f) (raise-argument-error 'sequence-for-each "procedure?" f))
(unless (sequence? s) (raise-argument-error 'sequence-for-each "sequence?" s))
(for ([vs (in-values*-sequence s)])
(if (list? vs)
(apply f vs)
(f vs))))
:joy:
huh, it’s almost like those OOP folks had a point
Wouldn’t the goal be to expand to some :do-in
form?
Is there a standard or recommend way to access command line parameters when using a (module+ main ...)
declaration for a main function? In particular, are there any examples of such? I’m trying to write a small stand-alone program that uses places, and I am under the impression that using module+ main
is considered a good way to implement things, but the examples I can dig up never seem to use command line parameters.
I have a working non-parallel version that just uses (define (main param1 param2)...)
style, but I think that doesn’t work when you introduce a module+
.
Are you please able to point me towards any examples? The Racket Reference page isn’t totally clear to me.
There should be an example about halfway down that page
Thanks :slightly_smiling_face:
Also (current-command-line-arguments)
returns a vector of strings of the arguments
Thanks folks, that’s definitely been a big help
Is there a hotkey to quickly comment and uncomment code blocks in DrRacket?