How to use phantom types in Swift

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

КОМЕНТАРІ • 32

  • @muadhhussam3539
    @muadhhussam3539 4 роки тому

    This is really quality content and it's rare that you find this level of quality is swift tutorials on UA-cam.

  • @MagnusWissler
    @MagnusWissler 4 роки тому +4

    I wish I could upvote this more than once, even though I don't fully understand it.

  • @tomladdus9264
    @tomladdus9264 4 роки тому +1

    Love the state machine example

  • @FlyingLS4
    @FlyingLS4 4 роки тому

    This actually blew my mind 🤯. Been using Swift since 1.1 and had no idea that this kind of compile safety is possible.

  • @DC4TH
    @DC4TH 4 роки тому +20

    Nice video.
    What about adding an extra layer of compiling validation with protocol. Something like:
    protocol BloodType {}
    enum OPositive : Blood Type {}
    struct BloodSample {...}
    So, now, not only cannot the compiler compare bloodsamples with different phantom type, now cannot compiles Bloodsamples with a Type that make no sense to use as a tag.

    • @petersuvara
      @petersuvara 3 роки тому

      Great idea, pity Paul never replies on videos.

  • @bobgodwinx
    @bobgodwinx 4 роки тому

    Nice explanation. T in the undefined func is the Base value because it represents the actually that is required to fill the hole. You can also see it as a generic placeholder. if print T you will see that it is either a String or Int depending on the Base type that wasn't defined.

  • @randomizednamme
    @randomizednamme 4 роки тому

    Really cool concept! I believe this is what RxSwift uses to represent Traits

  • @toadlguy
    @toadlguy 4 роки тому +1

    Great explanation! I appreciate this understanding so I can tell what is going on if I see it used in some code, however, I'm not sure that this is something I would do. Firstly, it seems like a compile error to declare a Generic without using the type. Secondly, at least in the examples given, there does not seem to be a reason for this. In the first example of generating a compile error by adding 2 ints of different usages, it is avoiding a bug that would be pretty easy to catch with proper naming conventions and would be mostly caused by an autocomplete typo and would actually eliminate the ability to properly add two ints where you might want to (like to create a hash or something). Seems just unnecessary. In the second case of not adding together blood volumes of different blood types, this could be done without any "phantom" types, just use non-phantom Generics and real enums, you could even do it with the types as shown, but probably would actually do it by exposing a method to add volumes of blood, not simply use the raw property and the + operator. It seems to add a level of "confusion" to the code rather than providing a real benefit that couldn't be achieved in some more implicit way.

  • @rondamon4408
    @rondamon4408 4 роки тому

    Very interesting. From now on, I'll use it everywhere.
    Good point the state machine!!

  • @samr.4692
    @samr.4692 4 роки тому +1

    Mind blowing! Thank you, Paul!

  • @paweambrozej2667
    @paweambrozej2667 4 роки тому +1

    Such a great explanation! Thank you!

  • @ShubhamGupta-qo2pt
    @ShubhamGupta-qo2pt 4 роки тому

    Nice explanation,
    Can we have more examples for PHANTOM types ?

  • @casperes0912
    @casperes0912 4 роки тому +1

    Why do you use empty enums instead of, for example
    enum BloodType {
    case: 0Positive
    case: APositive
    //Etc.
    }
    ?

    • @DC4TH
      @DC4TH 4 роки тому

      I think is cause in that case, as with Structures, you are able to make enum of that type, and the point of the phantom types is to not be able to make instances of those types; just use them to make the compiler fails.

  • @markaurelius61
    @markaurelius61 4 роки тому

    In the blood types example, if each one is a different type, you can't really have a variable or property that gives the user's blood type. This would have to be a set of separate declarations for processes where the risk of mixing types was so severe that you wanted to make it impossible to code for.

    • @AlanW
      @AlanW 3 роки тому

      You can, but you have to wrap it in an enum, and it gets a bit messy, and sort of turns a compile time check into a run-time check.

  • @KK-pq6lu
    @KK-pq6lu 4 роки тому

    Paul, amazing video.

  • @markuspfeifer8473
    @markuspfeifer8473 4 роки тому

    Regarding the state machine:
    One *could* utilize them in notifications. If you have an entirely event driven architecture and your state machines represent fully transient information, there's no actual need to store them. However, this is a great limitation of usefulness or one would have to come up with techniques that I'm simply not aware of.
    A compromise position could be if we enabled the Swift compiler to figure out that your generic type should be covariant:
    forums.swift.org/t/possibility-of-an-explicit-covariance-attribute-for-generic-types/13999/4
    Then, a machine in any state can simply be represented as Machine (I'm not aware that this would be possible today). One would have to downcast the machine then in order to apply the arrow (which introduces runtime checks and compromises the type safety), but at least composition of transitions can still be done in a safe way. This can still be useful if there is actually some logic in the transition function, e.g. each transition attaches some payload to the machine (meaning that one would have to write out the actual transitions for each pair of supported types).

  • @Lammax2012
    @Lammax2012 4 роки тому

    As usual - great lesson! =)

  • @Eugensson
    @Eugensson 4 роки тому

    Reminds me of Units of Measure feature in F#.

  • @PriestRipper
    @PriestRipper 4 роки тому

    Awesome!

  • @SteveHiemstraAKAspeg
    @SteveHiemstraAKAspeg 4 роки тому

    Wait, isn’t this supposed to be a plus article?

    • @twostraws
      @twostraws  4 роки тому +2

      It is; as it says near the beginning and at the end this is a free sample.

  • @soheilpakgohar6630
    @soheilpakgohar6630 4 роки тому

    amazing as usual

  • @mdeaconu
    @mdeaconu 4 роки тому

    So that generic should only be a enum?

  • @leiniel19
    @leiniel19 4 роки тому

    Great video!

  • @AkashPatel24
    @AkashPatel24 4 роки тому

    But database query returns role as property so mapping would require more effort

  • @salmansiddiqui9522
    @salmansiddiqui9522 4 роки тому

    Amazing Paul

  • @amber.k
    @amber.k 4 роки тому +1

    21:27
    So there is no compiler error for not defining generic type as it will infer from the function return type as it is the only statement which will infer it to return...
    Woah...so much inference 😅

  • @ConorMasterson
    @ConorMasterson 4 роки тому +1

    But... why?