Let C# Tuples Become Your Best Friends

Поділитися
Вставка
  • Опубліковано 18 гру 2024

КОМЕНТАРІ • 77

  • @CharlesBurnsPrime
    @CharlesBurnsPrime 10 місяців тому +11

    Your passion for software engineering is infectious.

  • @jrandallsexton
    @jrandallsexton 7 місяців тому +5

    IMO, your channel is far underrated. Please keep up the good work!

  • @ar_xiv
    @ar_xiv 10 місяців тому +10

    I've had this sitting in my source for a while:
    public static void Swap(ref T A, ref T B)
    (A, B) = (B, A);
    You can swap class and struct members like it's magic. Good in graphics programming, collision detection.

    • @Dr-Zed
      @Dr-Zed 10 місяців тому

      This is crazy, you can even make this an extension method!
      public static void Swap(this ref T left, ref T right) where T : struct
      {
      (left, right) = (right, left);
      }

  • @mattiasolsson2354
    @mattiasolsson2354 10 місяців тому +3

    As a amateur Common Lisp fan I relate this very much to how you use list of various length and types to transport data in a smooth way without using heavier implementations like arrays or objects. And I find myself using tuples in the same manner.

  • @SkyswordTK
    @SkyswordTK 10 місяців тому +1

    I generally agree with Tuples being underused. While shorter doesn't imply easier to read, reassigning multiple values where traditinally helper variables are required help keeping the code more tidy and take little time to adjust to. However I disagree with the final part, starting at 9:58 'Will defensive coding return to my design?': the var keyword conceals the type of "number" changing from int to a string during rewriting. For a user-interactive command line application, I have no issues with the presented solution since the result is converted to a string anyways, in this specific case, the code is clean. However conceptually in most use-cases the program will get an input n (likely not as user input in terminal) and will have to deal with the number (or sequence in this example) and not it's string representation. In that moment the program will have to defend against the input number being too high unless n is known to be small enough.
    I believe that a method's definition should indicate that it may not produce the correct result based on it's input (for example it could provide an out parameter (bool sequenceFinished or int finalIndex)). If it does not, it may cause worse consequences than an Exception "just" crashing the program.

  • @thygrrr
    @thygrrr 6 місяців тому +1

    Fantastic video, and I agree with it whole-heartedly (also the feel of it, and I already "stole" your quote on having lost already if you need to defend).
    Yet - at 9:00 You say "safe by design", but I would like to add "and also quietly wrong by design".
    Whether that's acceptable depends heavily on the use case. I hope this software doesn't go in a self-driving car . ;-) However, and this is what many OOP-maximalists forget - what will the car do if it encounters an unhandled (because it was unexpected) exception?
    So there's no clear winner here on that front, and if in doubt I'd always say the more concise, more clear soluton wins.
    All in all there's many nuanced discussions to be had here; I make video games, generally I'd prefer the "return sensible data and never crash" approach of Zoran. Except for payment fulfillment code. I would not want my user who wanted to buy 100 iterations of something only receive the first couple of values that fit into the integral type backing the count and receive a transaction receipt for the full amount stating that everything went well. ;)

  • @Tymon0000
    @Tymon0000 10 місяців тому +6

    I appreciate any syntax that requires less code while maintaining clarity. Approved!

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +4

      This video came after I got a comment like "this code is alien to me". If we look at the pace at which new syntax is added to C#, it is about one item every six months.
      I just don't see how someone who works in C# every day can come into the situation to say that something is alien after being around for 6-7 years.

    • @1992jamo
      @1992jamo 10 місяців тому +2

      @@zoran-horvat If that was me, I can't thank you enough for this video. This is incredibly insightful and useful. A day where you learn a new feature and can see where it can be used and the benefits is an extremely good day. Thank you.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +1

      @@1992jamo I've looked into the history and yes, it was you :)

    • @MC_DarkMaster
      @MC_DarkMaster 10 місяців тому

      @@1992jamo Kudos

  • @WDGKuurama
    @WDGKuurama 10 місяців тому +3

    Honestly impressive and i feel like i can clear up and focus on more tuple and functionnal programming logic with linq moving forward.

  • @AlexUkrop
    @AlexUkrop 9 місяців тому +1

    Supper! Adore all of your Pluralsight lectures as well. Thanks a lot

  • @goldmund67
    @goldmund67 10 місяців тому +1

    Sorry, was there something in this video about using tuples? I got completely distracted by writing the Fibonacci algorithm without recursion. I froze up during an interview while trying to write it out on a whiteboard, so whenever someone uses it as an example, I'm like Frodo putting the Ring on one too many times.

  • @blgrnboy
    @blgrnboy 10 місяців тому +2

    Great content as always! Thank you!

  • @1992jamo
    @1992jamo 10 місяців тому

    I have to admit that prior to your previous video I'd only seen and used Tuple and not ValueTuple.
    I've used System.Tuple a fair few times but it was very clunky and if I understand correctly, it looks like ValueTuple is like a mutable struct, is a value type, and exposes it's items as fields rather than properties? That's awesome! The syntax looked weird to me at first but I can see how useful this is. I will certainly use this.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +1

      System.Tuoke is an old type which I only used a few times and gave up entirely. But when ValueTuple type appeared, it was an entirely new story, 100% oriented towards performance and simplicity. Once we got them, it turned out that it is nearly impossible to write custom code that performs better, which means that we have all the reasons to always use the new tuples.

  • @georgeblazhev
    @georgeblazhev 10 місяців тому +2

    I've used tuples in a service where I had to execute parallel tasks and aggregate the responses of all of them, then map them based on the responses of the tasks, this was wrapped in a switch expression. (I explain it badly, but there was no logic in the mapper)

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +2

      That is a typical use for tuples, and much faster than anonymous types of the past.

  • @bobweiram6321
    @bobweiram6321 10 місяців тому

    A tuple is an ideal datatype for a _Point_ containing *x, y* members, but it falls apart if you decide to represent _Voxel_ containing an additional *z* member. A strongly typed static list, *(int a, int b, string c, float d)* with the same decomposition and list comprehension features as a _Tuple_ *(a, b, c, d) = (1, 2, "apple", 0.5)* would be far more useful.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому

      I am not sure if I can understand what you are suggesting and how precisely tuples fail in 3D space.

    • @bobweiram6321
      @bobweiram6321 10 місяців тому

      @@zoran-horvat Tuples can only have two values, whereas lists can have as many as needed.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +3

      @@bobweiram6321 It seems like you are taking "tuple" as synonymous to "pair", which it is not. The tuple implementation in any programming language, including C#, corresponds to what we call N-tuple in mathematics. Of course you can define a triplet, a quadruplet, a pentuplet or anything you wish using C# tuples syntax. Though it starts hurting clarity as you keep piling up new components, the syntax will not stand in the way.

  • @FunWithBits
    @FunWithBits 10 місяців тому +1

    Thanks for the reminder to use these and that they are acceptable to use. I was just thinking about this today and was going to use it, but I changed my mind.
    BTW - I like the "This is an opinionated implementation." I know some people who would like this (like myself also) and others who wouldn't. Sometimes, when 75% of the developers like it a certain way, I will always go that way...also depends how I feel that day. (I not sure if this falls under those 75% thing.)

  • @KOMEK1999
    @KOMEK1999 4 місяці тому +1

    Amazing Teacher ❤

  • @David-id6jw
    @David-id6jw 10 місяців тому

    The only nitpick I have is that you changed the behavior of the program. The initial version put the last Fibonacci number in brackets, while the tuple version didn't.
    You could probably fix that in the Select() statement, using a conditional (whether f.n == n) to choose the formatting. So no real change to the program flow.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +1

      Yeah, I ignored that detail on purpose, because I wanted the viewers to focus on the substance - the expression. Anyway, your point is valid.

  • @tore28
    @tore28 9 місяців тому

    This should make it easier to organize code and handle local variables that change state throughout your methods. But the length of the tuple must be not too long, spotting errors in tuples of length of 3 should be okay, if there are like to say an example of many variables - seven variables you set like this :
    (t1, t2, t3, t4, t5, t6, t7) = (v1, v2, v3, v4,v5,v6,v7);
    Well errors might pop up, but trying to juggle with 7 variables separated with newlines and set one by one is not easy either.

    • @zoran-horvat
      @zoran-horvat  9 місяців тому

      Sure, that quickly becomes a case for records.

  • @FunWithBits
    @FunWithBits 10 місяців тому

    I like this feature and how they improved it over the "item1/item2". It feels cleaner to me (most of the time) if items being returned are in the return of a function. To me, "(int quotient, int remainder) = Divide(int a, int b)" is cleaner than "int quotient = Divide(int a, int b, out int remainder)". I wonder if this is best practice or not.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому

      Returning a tuple is usually seen as a better alternative to using ref or out parameters.

  • @BrunoLeonidio
    @BrunoLeonidio 10 місяців тому

    This approach on your example reminds me ".reduce()" method in javascript and gimme an excellent idea. Thx !
    Also, I got a question (sorry if it seems silly): tuples are very similar to dictionary, right ? Whats the difference between both where tuples can shinny more ?

    • @Tymon0000
      @Tymon0000 10 місяців тому

      Do you mean that Tuples are similar to KeyValuePair that is used in dictionaries? You can create a Tuple that has more than 2 elements and assign different names to them not just "Key" and "Value".

    • @BrunoLeonidio
      @BrunoLeonidio 10 місяців тому

      @@Tymon0000 Indeed. However, using tuples with more than 3 values may compromise the understanding of code, IMO. But, yes, it's possible to assign more than 2 values .

  • @tarsala1995
    @tarsala1995 10 місяців тому +5

    Even if you don't like the coding style, I think it's healthy to be exposed to it

    • @1992jamo
      @1992jamo 10 місяців тому

      That's why I'm subbed. I'm learning loads even though the coding style is very different to mine.
      The line "(a, b) = a == 0 ? (1, 0) : (a + b, a);" has five operators, I'd probably have written it like:
      (a, b) = a == 0
      ? (1, 0)
      : (a + b, a);
      However, style aside I'm really seeing some value Zoran's videos.

  • @Cool-Game-Dev
    @Cool-Game-Dev 3 місяці тому

    As a game dev, I have one rule for code like this, and that's KEEP IT OUT OF THE UPDATE FUNCTION THAT NEEDS TO RUN EVERY FRAME

    • @zoran-horvat
      @zoran-horvat  3 місяці тому +1

      @@Cool-Game-Dev Game development has other immediate goals than business applications.

  • @brotherlui5956
    @brotherlui5956 9 місяців тому

    C# becomes more and more like Python. Coming from Python i really appreciate this.

  • @Cool-Game-Dev
    @Cool-Game-Dev 9 місяців тому +1

    C# go brrr

  • @swekster
    @swekster 10 місяців тому

    Love, love, love tuples - however with I find that I tend to use value records for a lot of cases that I used to use tuples for.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +4

      That is perfectly fine. Actually, I normally use tuples in private members and records in public. It is because a tuple is assignable to any tuple with the same shape, even when that would model a different concept that only has the same component types by chance. The same assignment is not valid in records because those would be the two separate types.

  • @adambickford8720
    @adambickford8720 10 місяців тому +1

    I pronounce it "too pull" just to add bad blood to the .gif wars

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +1

      Yeah, that's the other pronunciation. I tried that, too, but my tongue muscle always returned to this one. It appears to have its own will.

  • @yoseffixler6551
    @yoseffixler6551 10 місяців тому

    This video is great!
    Now we need a video about avoiding tuples' abuse.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +1

      Well, yes. Once you start sending objects between objects, tuples are not a good vehicle. That is where they should attain a strong type, such as a record.

  • @HOSTRASOKYRA
    @HOSTRASOKYRA 10 місяців тому +1

    Thank you. It was interesting and usefull.

  • @tunawithmayo
    @tunawithmayo 10 місяців тому

    My problem with Tuples is that their parts are unnamed. Its like a variable named 'x'. What is X?

    • @zoran-horvat
      @zoran-horvat  10 місяців тому +3

      Tuples support component names. You can use any names you like the same way you do with variables.

  • @nickbarton3191
    @nickbarton3191 10 місяців тому

    In framework, you had to install an additional package for tuples; probably put people off from using it.

    • @zoran-horvat
      @zoran-horvat  10 місяців тому

      That was years ago.

    • @nickbarton3191
      @nickbarton3191 10 місяців тому

      @@zoran-horvat Maybe but there is still plenty of legacy support going on. Took us years to get off Winforms/Framework, even now we still have some legacy systems to support.
      Dies hard, and people don't necessarily keep-up-to-date, not everyone is like you and me!
      A vendor recently told me that only 3% per year of Framework based systems are being upgraded. A bit of a concern given that support runs out 2026.
      BTW I programmed a new feature with tupples today, you'll be glad to hear. Yes, sure does compress the code.

    • @nickbarton3191
      @nickbarton3191 10 місяців тому

      @@zoran-horvat Tried to reply twice but keeps getting deleted. You're forgetting the enormous amount legacy code out there.

    • @nickbarton3191
      @nickbarton3191 10 місяців тому

      Probably the reply was too long. Took us years to get off legacy. Habits die hard, not everyone keeps up.

    • @nickbarton3191
      @nickbarton3191 10 місяців тому

      @@zoran-horvat You'll be glad to hear I used tuples even today :) Yes, sure does compress the code.

  • @triGataro
    @triGataro 10 місяців тому +1

    I will use more tuples

  • @Wizatek
    @Wizatek 10 місяців тому

    I always thought it was pronounced tuuples

    • @zoran-horvat
      @zoran-horvat  10 місяців тому

      Both pronunciations are in use.

  • @nathanel1313
    @nathanel1313 8 місяців тому

    I'm sorry but while I love your solution I just can't get over `(f => f.n

    • @zoran-horvat
      @zoran-horvat  8 місяців тому

      I guess that typing a four times longer piece of code will wipe that smile off your face. Pun intended.

    • @nathanel1313
      @nathanel1313 8 місяців тому +1

      @@zoran-horvat no no I get it, I love it (although I can imagine someone arguing that it mildly contradicts your own advice to use strong types in business modelling instead of using value types), it just struck me randomly how strange programming languages can look.

    • @zoran-horvat
      @zoran-horvat  8 місяців тому

      @@nathanel1313 That is true. Languages change towards a more condensed form.
      What strikes me personally is how close the languages today are becoming to what ML did in the 1970s or so. It is the predecessor of OCaml and, subsequently, F#, but now C# is spring much of its style. It almost looks like reinventing the same simplicity again, 50 years later.

  • @1Eagler
    @1Eagler 10 місяців тому +1

    I love tuples as a return values:
    Return ( value, errorMessage)