3 ms·
I don't think Java is obvious at all apart the aforementioned simple statements. With generics you have actually no idea of what type you receive at runtime, yo
by tigershark 10y ago
I don't think Java is obvious at all apart the aforementioned simple statements.
With generics you have actually no idea of what type you receive at runtime, you receive just an object. If the goal of the code is to return some sensible default for a specific type in Java you cannot use generics. And it's not obvious at all for anyone that doesn't know the generics implementation details.
About closures, do you think that it is more obvious to define an entire anonymous inner class when you really just need to define a method delegate or an anonymous method? For me it's completely counterintuitive other than it makes my eyes bleed. If I need a local variable I obviously define it, I don't create a class which exposes an encapsulated field and use it. And it's exactly the same thing when I need an anonymous method.
When the goal is reading a file why should be more obvious to create a buffered reader that encapsulates a file reader that wraps a file and use it to read when I can just do File.ReadAllLines() in C#?
What is the added value of calling stream() on everything before using any enumerable? In C# obviously you just call Extension Methods on an IEnumerable. You even get IntelliSense. Why should be obvious to call stream() on an object that is already a collection?
- jdmichal 10y ago> With generics you have actually no idea of what type you receive at runtime, you receive just an object. That's kind of the point of generics? I don't understand this argument at all. If you need a specific kind of type, then bound the generic using `extend` and you can use the bounding type's methods and fields. [0] You're still using a different definition of obvious, despite my having defined it for this use case. For instance: > Why should be obvious to call stream() on an object that is already a collection? That's the very definition of obvious. You are making it quite clear that you intend to use this collection as a stream. It's extremely obvious. Same with the buffered reader; Readers are unbuffered, and it's very obvious that you are buffering the reader when you wrap it. (Also, Java has `java.nio.Files.readAllLines` [1], so I'm not sure what you're going on about.) Extention methods are very non-obvious; where is an extension method defined? The answer is anywhere; it can live in any type you imported. It's not obvious looking at the line of code where execution is going to flow. (And yes, an IDE will track it down for you. Just because an IDE can do the work for you, doesn't mean that there's not work to be done.) [0] http://docs.oracle.com/javase/tutorial/java/generics/bounded.html http://docs.oracle.com/javase/tutorial/java/generics/bounded... [1] http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#readAllLines%28java.nio.file.Path,%20java.nio.charset.Charset%29 http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files...
- tigershark 10y agoThe point of generics is to pass generic arguments to a method/class, as the name says. In Java you are losing every type information and at runtime your method will accept objects, not arguments with a generic type. There are several situation in which preserving the type information is extremely useful. For this reason in Java you still find a lot of libraries that receive a type as argument, while in C# you can just specify the generic type. For me it is far more obvious in the c# way given that I cannot see why I should pass the type of an argument in a generic method. For the streams it is honestly ridiculous. I want to apply a filter, a map, a reduce or wathever to an Iterable. The stream is a very well known and completely different concept and it is widely used in reactive programming, they just stole that concept to use it in a completely non obvious way. For the other streams I still can't see how it is obvious that I should do manually all that wrapping that is completely counterintuitive and makes you lose track of the code purpose. Finally extension methods are perfectly obvious. They are just syntactic sugar for static methods, I hope that at least you agree that static method are the gist of obviousness.
- jdmichal 10y agoI've got plenty of dislike for type erasure, and I do agree that it makes the language more complicated. An instance where the Java language was sacrificed to ease virtual machine implementation and backwards compatibility. > The stream is a very well known and completely different concept and it is widely used in reactive programming, they just stole that concept to use it in a completely non obvious way. Java streams seem to meet the ideas of stream processing to me. Given a sequence, apply transformations in order, possibly in a transparently parallel fashion. Compare the Wiki definition with the `BaseStream` interface documentation: https://en.wikipedia.org/wiki/Stream_processing https://en.wikipedia.org/wiki/Stream_processing http://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html http://docs.oracle.com/javase/8/docs/api/java/util/stream/Ba... > Finally extension methods are perfectly obvious. They are just syntactic sugar for static methods, I hope that at least you agree that static method are the gist of obviousness. Yes, I of course agree. My problem is that extension methods hide where they live, by pretending to live on the type. And to be fair, I have the same issue with static imports in Java. When I look at a function or method call, it should be immediately apparent where control flow is going to go. That's not the case with either static imports or extension functions; I have to resolve the method name first.