Open PeterWAWood opened 6 years ago
Link to REP: https://github.com/red/REP/blob/master/rep-0101.adoc
@PeterWAWood, could you mock up equivalents for the interface options from the REP, maybe starting with list comprehensions. I have some things on those, but more on ranges and generators that I could work up comparisons for. I'll also try to clear my mind and think of alternatives. Hard though, because, to me,
for [i = 1 to 100 step 2]
Seems much clearer than
for x in [x in range(100) if x % 2 == 0]
A bit late right now, so I'll try to give it a look with fresh eyes tomorrow.
Assuming that there is a range
function which has a tuple!
parameter. range 2.10.2
would return [ 2 4 6 8 10]
. range 1.10.1
would return [1 2 3 4 5 6 7 8 9 10].
So we could have:
even-up-to-ten: range 2.10.2
foreach i even-up-to-ten [ ... ]
foreach i range 2.10.2 [ ... ]
Assuming series comprehension syntax to be `block-from [foreach x a-block [if x = 2 [x * x ]], we could have:
numbers: range 0.100.1
even-squared-numbers: block-from [foreach x numbers [if x = 2 [x *x]]
for i even-squared-numbers [ ... ]
(I'm sure it is possible to come up with better syntax with some deeper thought).
Assuming there is a yield
function and that iterators signal stop by calling an iterator-end
function.
We could have something like:
infinite-ints: func [/local i] [
i: [1]
until [
yield i
i: i + 1
]
]
foreach i infinite-ints [ ... ]
I will mock up equivalents to the example given in the proposal when I have a little more time.
I guess we already have series comprehensions:
>> list: collect [foreach x [1 2 3 4 5 6 7 8] [if x % 2 = 0 [keep x * x]]]
== [4 16 36 64]
I've duplicated most of your examples for the proposal. The vast majority of them can be satisfied with a very simple range
function that I wrote. It couldn't handle the scientific notation example but I guess it could be enhanced to do so.
There was only one case where I needed to use something other than the range function. I used collect
as a block comprehension but it looks very clunky. There is probably some syntactic sugar that could make it look better.
My code is for-alternatives.red
Hi guys, old REP, but never mind here is a simpler solution (with a refinment to call an internal loop func, in case of pointer value needing)
For: function [pnter step target cmd /Fn /local c][
c: target
while [not (c = (pnter - 1))][
either Fn [
do rejoin [ cmd " " (pnter + (target - c ))]
][
do cmd
]
c: c - step
]
]
ForFn: function [pnter] [
print pnter
]
use cases:
>> For/Fn 1 1 3 "ForFn"
1
2
3
>> For 1 1 3 [print "hello"]
hello
hello
hello
>> For 1 -1 -3 [print "hello"]
hello
hello
hello
I believe there are better options to provide equivalent functionality in an easier to use way. The alternatives include:
foreach range
foreach [series comprehension]
foreach [lazy series generator]
Rust has
for x in 0..10
for ranges Python hasfor x in [x in range(100) if x % 2 == 0]
for series comprehensions Python hasfor x in itertools.count()
for lazy series generators.I think it would be much more worthwhile to add ranges, series comprehensions and lazy series generators.