Let C# Tuples Become Your Best Friends

Поделиться
HTML-код
  • Опубликовано: 27 ноя 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 9 месяцев назад

      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.

  • @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.

  • @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

  • @thygrrr
    @thygrrr 5 месяцев назад +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. ;)

  • @AlexUkrop
    @AlexUkrop 9 месяцев назад +1

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

  • @FunWithBits
    @FunWithBits 9 месяцев назад +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.)

  • @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.

  • @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.

  • @Cool-Game-Dev
    @Cool-Game-Dev 2 месяца назад

    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  2 месяца назад +1

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

  • @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.

  • @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.

  • @KOMEK1999
    @KOMEK1999 3 месяца назад +1

    Amazing Teacher ❤

  • @FunWithBits
    @FunWithBits 9 месяцев назад

    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  9 месяцев назад

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

  • @brotherlui5956
    @brotherlui5956 9 месяцев назад

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

  • @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.

  • @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.

  • @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.

  • @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.

  • @Cool-Game-Dev
    @Cool-Game-Dev 8 месяцев назад +1

    C# go brrr

  • @tore28
    @tore28 8 месяцев назад

    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  8 месяцев назад

      Sure, that quickly becomes a case for records.

  • @HOSTRASOKYRA
    @HOSTRASOKYRA 10 месяцев назад +1

    Thank you. It was interesting and usefull.

  • @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.

  • @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 .

  • @triGataro
    @triGataro 10 месяцев назад +1

    I will use more tuples

  • @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 9 месяцев назад

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

    • @zoran-horvat
      @zoran-horvat  9 месяцев назад

      That was years ago.

    • @nickbarton3191
      @nickbarton3191 9 месяцев назад

      @@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 9 месяцев назад

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

    • @nickbarton3191
      @nickbarton3191 9 месяцев назад

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

    • @nickbarton3191
      @nickbarton3191 9 месяцев назад

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

  • @Wizatek
    @Wizatek 9 месяцев назад

    I always thought it was pronounced tuuples

    • @zoran-horvat
      @zoran-horvat  9 месяцев назад

      Both pronunciations are in use.

  • @1Eagler
    @1Eagler 10 месяцев назад +1

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

  • @nathanel1313
    @nathanel1313 7 месяцев назад

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

    • @zoran-horvat
      @zoran-horvat  7 месяцев назад

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

    • @nathanel1313
      @nathanel1313 7 месяцев назад +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  7 месяцев назад

      @@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.