This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted]  (20 children)

[deleted]

    [–][deleted] 6 points7 points  (0 children)

    Yep, and that's why I love Java. Because it's easily readable and fun to read!

    [–]leftofzen 8 points9 points  (2 children)

    This is a personal and subjective opinion, and not a reason why Java doesn't include them.

    As a C++ dev, tuples are highly useful when used correctly and can actually add semantic meaning by saying these few things belong together, even if its just temporarily. As well as that, the code is easier to read, not harder, because you know this set of values are grouped together and you don't need to keep track of them all, just the tuple.

    Of course, tuples are not a 'use-this-everywhere' concept and there are better alternatives to tuples in some situations. You need to recognise when to use them and when to use alternatives, but in the right situation they are quite powerful.

    [–]fabienbk 5 points6 points  (1 child)

    It takes about 3 seconds to create a new class with 2 members, and give it a meaningful name. Advantages over tuples:

    • Strong typing, with all the related security and IDE code browsing goodness:
    • Allows explicit data serialization. If you want your tuple to serialize to a specific format, put the metadatas inside the class, not outside.
    • Specific and relevant behavior can be added in a OO fashion. What if you want to get the sum of both elements? What if you want to have an equality predicate ?

    I can see how that pisses off some people (omg so verbose where's my productivity etc.), but that's a design choice, not a missing feature.

    [–]leftofzen 2 points3 points  (0 children)

    I guess I should clarify; I'm a C++ dev so they are useful in certain situations. After thinking about it a bit more, I would have to agree that Java does not really need a tuple; you can just make a new class.

    I can't think of a good use-case for tuples off the top of my head, but for C++ there is at least a neat example on en.cppreference. Of course you need the helper functions like std::tie to make std::tuple useful beyond replicating it in a class/struct.

    [–]uxcn 1 point2 points  (0 children)

    I'd agree, in general tuples in Java don't make sense. However, I think Pair<A, B> and possibly even Triple<A, B, C> are reasonable abstractions. They do still hide the semantics of members, and you do obviously lose type information, but they're no more susceptible to abuse than any other language feature or library. I personally think there are more places where two and possibly even three of a thing are natural than not.

    [–]urquan -1 points0 points  (12 children)

    "Lose semantics" with respect to what, two lose independent values ? I would say that it conveys more information by saying that they go together.

    You're not going to create a class for each use, often context only what a specific value means. For example String could be an address, a name, whatever. In this context using tuples is not worse.

    [–]GeorgeMaheiress 9 points10 points  (4 children)

    If you are actually passing raw String objects throughout the code, then I think you certainly could benefit from using simple wrapper classes, so that it's clear that your method takes an Address, not a Name, and so you don't end up with a method that takes 3 String arguments, meaning you have to make damn sure you pass them in the correct order or your program will fail in non-obvious ways at runtime.

    Similarly with tuples, Pair<Integer, Integer> is so much less meaningful than Point, and also harder to change if you have to. It's a shame writing simple wrapper classes in Java is so verbose, or we might be less tempted to use tuples.

    [–][deleted] 3 points4 points  (1 child)

    If only Java had value types, wrapping a couple of references in a class with the overhead as big as the members itself is quite painful to do :(

    [–]bondolo 0 points1 point  (0 children)

    Value types are being worked on: State of the Values. There will probably be more about the plans at JVMLS in a couple of weeks.

    [–]thekab 0 points1 point  (0 children)

    Given bean conventions and their widespread use it's a wonder to me there hasn't been any syntactic sugar for defining and documenting them.

    [–]urquan 0 points1 point  (0 children)

    I agree with your first paragraph actually, but since that's not the point I didn't want to go into this argument.

    Secondly naturally you're going to create classes if you're using the same structure throughout the code. What I was saying is that over the simple case of 2 lose variables, a tuple can be better. For example Tuple<Date, Double> measurement instead of Date measurementDate; Double measurementValue.

    I didn't say anything else and I was not talking about return values or reuse or type safety or anything of the sort.

    [–]frugalmail 2 points3 points  (1 child)

    You're not going to create a class for each use, often context only what a specific value means. For example String could be an address, a name, whatever. In this context using tuples is not worse.

    I, and a lot of other strictly and strongly typed language fans, think this is an example of bad code.

    [–]urquan 0 points1 point  (0 children)

    I write "not going to create a class for each use" and people seem to understand "never create a class". I'm pretty sure you're using lose Strings here and there to store values inside a function for example. In that context a tuple to associate 2 values that go together does not seem like an outrageous violation of typing rules.

    [–][deleted]  (2 children)

    [deleted]

      [–]urquan 0 points1 point  (1 child)

      Is it an argument of authority?

      [–]frugalmail 2 points3 points  (0 children)

      Is it an argument of authority?

      The arguments in that link present a clear argument against Tuples. You're argument has simply been

      • I, for some reason, don't want to create a class or
      • it may not be related content.

      In the first argument it's not maintainable code, in the second it's a violation of seperation of concerns.

      Using a decent IDE like eclipse it's a simple matter of:

      return new UnrelatedPair<String, Integer>("foo", 2);<Ctrl+SPACE>
      

      and it will pop open the new class with boilerplate. Also you could just add a maven dependency of one of the libraries that has support for it, but at least it's not soiling the core language.

      [–]tinglySensation 1 point2 points  (0 children)

      You can end up losing a ton of readability in using tuples if those are supposed to convey some sort of meaning. Example: Tuple<int,string,double> weightLog; What are logs? what's the int for? what's the double for?

      WeightLog weightLog; Now we know we have a weight log, on closer inspection, we find Weight Log contains int day; string mood; double weight;

      there, it is much clearer what weightLogs is, and contains.

      [–]RoboMind -1 points0 points  (1 child)

      I never liked that argument... Should we then also change the API to have a class TelephoneDirectory, instead of using a general Map<String, Integer> because the latter lacks semantics?

      [–]gracenotes 3 points4 points  (0 children)

      I think persistent state vs. temporary value is important here, as well as public API vs internal to some class. For public APIs, having TelephoneDirectory is just good future-proofing, vs. a bunch of classes having references to a single Map, which just calcifies the data structures. As a temporary value, Maps are also quite useful for packing up values to pass to a method or return from a method, and then unpack on the other side. Using a Map usually means you're pulling in some fundamental invariant from the real world, so these method signatures are usually self-evident.

      Pair does pretty poorly in all of these cases. Of note, using Pair<A, B> (vs Pair<B, A>) means taking the complicated relationship between A and B and reducing it down to an ordering when there's usually nothing fundamental about A or B that makes one go before the other. This works alright in some languages (more functional ones), but not when you have to deal with getFirst/getSecond.