Closed GoogleCodeExporter closed 9 years ago
I would put it in Ints/Longs rather than Iterables/Iterators.
Original comment by fin...@gmail.com
on 3 Feb 2010 at 9:37
`Suppliers.count()` (returning an instance of `Supplier<Integer>` and/or
`Supplier<Long>`; maybe the latter would be sufficient?) might be a conceivable
place
for it, too.
Original comment by j...@nwsnet.de
on 8 Feb 2010 at 9:34
This is one of the things our forthcoming Range stuff will support. There may
still
be value in a "shortcut" method like this in Itera*s, but we'll see at the
time, and
it wouldn't be called "count" (since I expected that to mean "count the number
of
elements left in the iteration).
Original comment by kevinb@google.com
on 12 Feb 2010 at 5:08
As long as these ranges are `Iterable`s (and are lazy) and support an "open
end",
I'll be fine.
Original comment by j...@nwsnet.de
on 14 Feb 2010 at 5:23
Any news regarding the promised Range stuff?
Original comment by j...@nwsnet.de
on 18 Aug 2010 at 1:08
Issue 506 has been merged into this issue.
Original comment by boppenh...@google.com
on 30 Dec 2010 at 1:21
Original comment by boppenh...@google.com
on 30 Dec 2010 at 1:22
Original comment by fry@google.com
on 26 Jan 2011 at 10:40
Original comment by kevinb@google.com
on 27 Jan 2011 at 6:16
Issue 429 has been merged into this issue.
Original comment by kevinb@google.com
on 27 Jan 2011 at 6:17
Any news regarding this? Having ranges would also allow simplifying or even
replacing some of those ugly `for` loops.
Original comment by j...@nwsnet.de
on 31 Mar 2011 at 12:06
Original comment by kevinb@google.com
on 8 Apr 2011 at 2:06
Original comment by kevinb@google.com
on 3 May 2011 at 10:48
How is this class meant to be used? I see neither a public constructor nor a
public factory method nor classes like `Ints` implement methods that would
yield a range.
Oh, and is `apply(C)` going to be deprecated forever and right from the start
because the name inherited from `Predicate` is ambiguous for ranges?
Original comment by j...@nwsnet.de
on 5 May 2011 at 12:46
You use the Ranges class to create Ranges. And yes, I imagine apply(C) is going
to be deprecated forever because you should always use the more descriptive
contains(C) when calling a method directly. Only code treating the Range as a
Predicate should be using apply.
Original comment by cgdec...@gmail.com
on 5 May 2011 at 2:16
We treat the meaning of @Deprecated as: "there is no good reason that your
code should invoke this method (directly)." It's a common misconception that
deprecation is only about "I'm going to delete this." Ordering.from(Ordering)
is another example of a deprecated method we expect to have forever.
Original comment by kevinb@google.com
on 5 May 2011 at 2:31
Oh, I totally forgot about `Ranges` while taking a deeper look into `Ranges`
and its Javadocs.
But I still can't imagine how this can be used to solve my initially (though
maybe not sufficiently explicitly) described use case of iterating over ranges
of numbers. I'd expect something like `for (Integer x : Ranges.closed(1, 100))`
to work, as a cleaner and less error-prone alternative to incrementing an int
in a `for` loop, and similar to Scala's `1 to 100` or Python's `range(1, 101)`,
for example.
`Ranges.atLeast(20)` resembles my above `count(20)` example, but I still need
to be able to iterate over it for as long as I decide not to break the loop
over it (which, as I'd expect, has to be ultimately done with open ranges
anyway).
What did I miss this time? I guess it doesn't implement `Iterable` or something
like that for a reason, including the above one about not terminating by itself
in case of (half-)open ranges.
Original comment by j...@nwsnet.de
on 6 May 2011 at 9:09
Indeed, that is somehow unexpected.
It looks like the automated generation of numbers isn't supported by Range,
which is the main reason why I starred the bug: a python-like range().
Current implementation of Range is interesting but much less than the initial
request that yo...@nwsnet.de initially asked.
Original comment by ogregoire
on 6 May 2011 at 11:56
For this, you need to combine a Range with a DiscreteDomain:
for (int i : Ranges.closed(1, 100).asSet(DiscreteDomains.integers()))
Original comment by nev...@gmail.com
on 6 May 2011 at 12:17
@nev..., I believe the initial request was that there would be an iterator that
would generate the next number on-the-fly ("in a memory-efficient way"), rather
than "keep the whole range in memory".
Personally, I don't think this would be a particularly complicated thing to
implement yourself, and I don't know how much it would really add for general
use (though that's not my call).
Original comment by raymond....@gmail.com
on 6 May 2011 at 1:14
@raymond: The ImmutableSet returned by asSet(DiscreteDomain) (note that it
isn't called "toSet") *does* generate numbers on the fly in a memory-efficient
manner.
Original comment by cgdec...@gmail.com
on 6 May 2011 at 1:44
My mistake--very well then :)
Original comment by raymond....@gmail.com
on 6 May 2011 at 5:29
As you can tell from
for (int i : Ranges.closed(1, 100).asSet(DiscreteDomains.integers()))
it is clearly not a design goal of Ranges to support this use case cleanly.
Why? Because even if we did the best we could to support it, it would *still*
be better to do this:
for (int i = 1; i <= 100; i++)
Original comment by kevinb@google.com
on 6 May 2011 at 11:11
Well, the for loop is not the only use case. Personally, I won't use that much.
I really wanted Ranges to implement Iterable in order to easily create data
structure of numbers that follow a simple rule, transform the lists, filter
them, etc.
Looks like I'll be stuck with the ugly asSet(DiscreteDomain.integers()), which
vocabulary is absolutely correct, but not understandable for the common of
developers, especially non-native English speakers.
Original comment by ogregoire
on 7 May 2011 at 6:28
Hm, bummer.
The discrete domain stuff is far too complicated for being used commonly. Also,
while `asSet` is returning an immutable set with a fixed iteration order, it is
irritating as a reader would expect a range to return some kind of list or
another iterable that is not looking as it wouldn't care about ordering.
My issue with counting `for` loops is they are hard to grok *in detail* at a
quick glance and thus easily hide off-by-one errors. ("Modern") "scripting"
languages, e.g. Ruby, became really popular for a reason; clean ways to create
ranges is one tiny part of the story.
I'd happily add some chars to the `for` one-liner in order to gain clarity.
A counting iterator indeed is easy to implement, but it still could be used in
lots of places even in smaller projects. And there are various number types
this could be useful for (int, long, BigDecimal), too, which would require
additional implementations. That's why I think a library should contain these.
In any case, even with the code in comment #19, I don't consider my original
request fixed.
However, regarding the issue, I can imagine the addition of an `IntRange`
subclass which would provide such functionality. But that's just a quick
thought.
Original comment by j...@nwsnet.de
on 9 May 2011 at 10:15
By far the most common Range->Set usage for me would be to generate an integer
set. So I think it would be a nice bit of syntactic sugar to provide as
asIntegerSet() method which simply uses asSet(DiscreteDomains.integers())
behind the scenes. Obviously the user can write the method themselves but this
way it's explicitly provided in the direct API instead of specified by the user
in an indirect way.
Also it's too bad that only continuous ranges were provided. R-trees or
inversion lists would have been more generally useful.
Original comment by ted.zlat...@gmail.com
on 9 May 2011 at 2:20
> Also, while `asSet` is returning an immutable set with a fixed iteration
order, it is irritating as a reader would expect a range to return some kind of
list or another iterable that is not looking as it wouldn't care about ordering.
It returns an ImmutableSortedSet, so the fact that it's ordered should be clear.
> So I think it would be a nice bit of syntactic sugar to provide as
asIntegerSet() method which simply uses asSet(DiscreteDomains.integers())
behind the scenes.
It doesn't make sense to have an asIntegerSet() method on a Range<Foo>, were it
even possible.
Original comment by cgdec...@gmail.com
on 9 May 2011 at 10:01
> It doesn't make sense to have an asIntegerSet() method on a Range<Foo>, were
it even possible.
I think it makes sense for any Range<Number> or at least any numbers that can
be mapped on the number line (forgive my ignorance of all the Number variations
in Java).
Original comment by ted.zlat...@gmail.com
on 10 May 2011 at 1:26
My point was that Range is a general-purpose class that can be used with many
things that aren't numbers. In any case, I think using static imports might
make this read a little more like you want: range.asSet(integers())
Original comment by cgdec...@gmail.com
on 10 May 2011 at 2:19
I think this issue was about creating a convenient method for iterating. The
proposed Range is more about mathematical notion of intervals. I think there
already is such a feature - it is the AbstractLinkedIterator.
I created an Iterable around it, which takes a first value and a function for
computing the next value. I added static factory method for this Iterable,
which I call unfold.
Examples:
@Test
public final void numsFrom() {
assertThat(limit(unfold(5, successor), 3), hasItems(5, 6, 7));
}
@Test
public final void squares() {
final Iterable<Integer> squares = transform(unfold(0, successor),
new Function<Integer, Integer>() {
@Override
public Integer apply(final Integer input) {
return input * input;
}
});
assertThat(limit(squares, 6), hasItems(0, 1, 4, 9, 16, 25));
}
@Test
public final void primes() {
final Iterable<Integer> primes = unfold(2, new Function<Integer, Integer>() {
private Predicate<Integer> sieve = alwaysTrue();
@Override
public Integer apply(Integer input) {
while (!sieve.apply(input)) {
input++;
}
final Integer prime = input;
sieve = and(sieve, new Predicate<Integer>() {
@Override
public boolean apply(final Integer number) {
return number % prime != 0;
}
});
return prime;
}
});
assertThat(get(primes, 300), is(1987));
}
I think this might be a better temporary solution until it is clear what sort
of Ranges people really want.
Original comment by gscerbak@gmail.com
on 10 May 2011 at 12:08
Should I make a request for a NumberRange class? The specific case where the
range is numeric has specific uses and optimizations that can't apply to
general Ranges.
Original comment by ted.zlat...@gmail.com
on 12 May 2011 at 2:37
I don't think NumberRange is a good idea. The thing that people are asking for
is Range for DiscreteDomain, especially with convenient Iterables. It looks
similar to IndexedIterable, which is in the idea graveyard, but I don't know
for what reasons. As AbstractLinkedIterator got into the library, it could be a
viable alternative to implement something similar to such Iterable with it, as
I showed above.
Original comment by gscerbak@gmail.com
on 12 May 2011 at 2:53
OK, I'll go with that since it's so easy to use Range as a NumberRange. Thanks.
Original comment by ted.zlat...@gmail.com
on 12 May 2011 at 3:05
I think the ranges is an excellent addition to the library. All new language or
library additions will be hard to grok at first. Anyways, I had a small
question regarding ranges:
I previously implemented some utilities to handle Ranges (intervals in our
system).
For simplicity sake, we forced intervals to have a closed left and
open right. We stumbled a bit when we wanted to decide whether an open
interval contains another open interval when the bounds are equal (eg.
[0, 1) and [0, 1)). As far as I know (I'm not a mathematician), this
is only true when the measures of both intervals are equal, which
cannot be guaranteed. Therefor, I opted to have it return false, but I
was wondering why Guava decided to return true instead.
With kind regards,
Original comment by g.e.dej...@gmail.com
on 6 Jun 2011 at 12:50
This issue has been migrated to GitHub.
It can be found at https://github.com/google/guava/issues/<id>
Original comment by cgdecker@google.com
on 1 Nov 2014 at 4:16
Original comment by cgdecker@google.com
on 3 Nov 2014 at 9:10
Original issue reported on code.google.com by
j...@nwsnet.de
on 3 Feb 2010 at 9:29