"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:Just one issue I see (as with SQL) is the absence of a first(int) or top(int) method (or do we call them functions now?) in the Stream class. And yes, I realise that it can probably be done in other ways that make far less sense to me.
[OCP 17 book] | [OCP 11 book] | [OCA 8 book] [OCP 8 book] [Practice tests book] [Blog] [JavaRanch FAQ] [How To Ask Questions] [Book Promos]
Other Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, TOGAF part 1 and part 2
Jeanne Boyarsky wrote:[I think I might be missing the point here. In SQL, getting the first X rows isn't hard. Granted, it varies by database, but it isn't hard.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Jeanne Boyarsky wrote:
I think I might be missing the point here. In SQL, getting the first X rows isn't hard. Granted, it varies by database, but it isn't hard. For example, in Postgres, we have:
Is a database that doesn't have some keyword for this? Or is it just that it isn't standard?
In SQL, it is a pain to do paging though. Trying to get the third through 6th rows is a nested query.
In Java, it is easier:
SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6 - OCEJPAD 6
How To Ask Questions How To Answer Questions
Rob Spoor wrote:
Rob Spoor wrote:
I think you forgot a skip in there:
That's one of the reasons I prefer to put each operation on its own line - it's a bit too easy to miss a statement in a long chain. Plus, exceptions can be easily traced this way (the line the exception occurred on has only one statement).
[OCP 17 book] | [OCP 11 book] | [OCA 8 book] [OCP 8 book] [Practice tests book] [Blog] [JavaRanch FAQ] [How To Ask Questions] [Book Promos]
Other Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, TOGAF part 1 and part 2
Winston Gutkowski wrote:In SQL you need a "rosetta stone" to understand how to do it, because each vendor has its own idea of how to implement it (I don't even know if it's part of the latest SQL standard yet; but wouldn't be at all surprised if it isn't); but the requirement for things like "top n" lists is so pervasive in computer applications that I wonder why the writers of data-directed languages have resisted it for so long.
To me it's an absolute requirement; and if Java doesn't get its act together, the same thing will happen with its shiny new Streams. Either that, or we'll simply work with logic and structures we're more familiar with, and bang off "the first ten".
Why couldn't they just have called it first()?
Stephan van Hulst wrote:I'm also *really* peeved that they don't have a takeWhile(Predicate<T>) method, so much so that I wrote my own Stream extension class.
SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6 - OCEJPAD 6
How To Ask Questions How To Answer Questions
Stephan van Hulst wrote:Just in case you were serious, first() would not have been correct, because first() implies an order on the stream.
And even if the stream is ordered, are they still the first elements after you perform a skip()?
I'm also *really* peeved that they don't have a takeWhile(Predicate<T>) method, so much so that I wrote my own Stream extension class.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:Me too, although it probably wouldn't have occurred to me for a while. And thanks for the code, very informative. Have a cow.
It does, however, suggest to me a fragility of things like Streams - and possibly of the functional paradigm in general:
There is a much bigger onus on the designer to "get it right".
In OO, we're used to there being "gaps" in the functionality of existing classes - indeed the whole ethos of OO is to build on existing code to "do your own thing", so we're taught very quickly how to extend and wrap and decorate.
This doesn't seem to be anywhere near as easy with Streams though, and without your code, it wouldn't have occurred to me to even try to extend something that to me is basically a "black box".
What did occur to me though, was that if I needed to do something like your logic above, I could write something like:which suggests to me that
(a) A more generic solution is probably available on the same basis.
(b) I think Oracle were stupid not to have BaseStream extend Iterable, because it's the only reason the cast is required.
It must surely have occurred to someone that it IS an Iterable, so why make us jump through hoops to use it as one?
Stephan van Hulst wrote:I can not overstate the last bit. It's actually caused me some headache with more recent APIs I've tried to design. Iterables and Streams are two very distinct and incompatible concepts. Streams are more like Iterators than Iterables, except that you tell them about what operations to use ahead of time, instead of during the iteration.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:OK, but I don't think my code violates that principle. And it could certainly be rewritten to use an Iterator instead, which suggests to me that the pattern could be "generified" to implement a Streams (or perhaps Collectors?) takeWhile() method without having to extend (or wrap) Stream.
I like Streams and pipelines because they remind me of script programming, where you combine small additive filters and processes on lines of data to do really cool things; but I'm still a beginner when it comes to applying them to objects.
Winston Gutkowski wrote:OK, but I don't think my code violates that principle...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:Which begs another question: Is there a way of "cloning" a Stream? Because it seems to me that the only reason that a Stream is NOT an Iterable is because the act of iteration changes its state, rendering it useless for further traversal.
If, on the other hand it was possible to say "give me an Iterator for the whole of this Stream" - as you can with a script that includes the tee command in Unix - you could perform all sorts of processing without affecting the Stream object itself. Or is that what Spliterators are for?
Stephan van Hulst wrote:If you have some spare time, I *really* recommend checking out Haskell. It really changed the way I look at programming. The main problem I have with functional programming is that its communities have a background in mathematics, and have a habit of using very short and cryptic identifier names. If you can get past that, Haskell is really a lot of fun to work with. Here's a really nicely written tutorial: http://learnyouahaskell.com/
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Stephan van Hulst wrote:Another remark, I believe your initial doubts about Streams being "black boxes" to which it's difficult to add new operations is a little bit unfounded, because you could say the same about extending Map, Set or List.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:I do worry a bit though that we're being "guided" to do things functionally, when it may not necessarily be the best, or "simplest" (ie, most readable) - or indeed fastest - way of doing things.
IMO, Java's great strength is that it allows us many ways to "do stuff" - procedural, objective, and (now) "functional" - and the best practitioners are going to continue to be those who can pick and choose the best elements of the language to do what they want.
Winston Gutkowski wrote:
Stephan van Hulst wrote:Another remark, I believe your initial doubts about Streams being "black boxes" to which it's difficult to add new operations is a little bit unfounded, because you could say the same about extending Map, Set or List.
Hmmm. Not sure about that, because there's no AbstractStream class to help you to implement your own. I'm also aware that there are many different types of "stream", including open-ended series like Fibonacci, so I'd like to see a few variants of "skeleton implementation" for duffers like me.
Stephan van Hulst wrote:Functional code is great when transforming data...
I'm becoming a fan of C#, which does this whole functional programming thing much better than Java does.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:not least its inclusion of 'struct' from C.
What I don't like is it's "hybrid" notion of final - IMO, the best (and most underrated) keyword in the Java language.
But that's for a different thread...
Winston Gutkowski wrote:
Stephan van Hulst wrote:Functional code is great when transforming data...
Yes, that's definitely the impression I get; and it IS a big part of our work...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:Imagine, instead of having to deal with that monstrosity called ResultSet, we can return the results of SQL queries to Streams of POJOs that WE define. I wouldn't be at all surprised to see that in v9 or v10 - especially given our new masters.
Winston
Stephan van Hulst wrote:Ewww. I think structs are a step back. They are great for low level languages, but keep them out of my abstractions :P
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Dave Tolls wrote:How long before we can stop calling them "new"?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Don't get me started about those stupid light bulbs. |