7 ms·
So Go supports both structural and duck typing? Why is that a problem?
by loosescrews 2y ago
So Go supports both structural and duck typing? Why is that a problem?
- tgv 2y agoIt doesn't support duck typing in the usual sense, but unchecked type casting 'any' to an interface does indeed compile. To any type, as a matter of fact.
- randomdata 2y ago> It doesn't support duck typing in the usual sense The article is about how it does support duck typing in the usual sense. Why do you disagree?
- tgv 2y agoIt doesn't try to call the method. It never gets there. The value/object is never seen as a Duck. It's not using a value as an arbitrary type. It was cast to any (which always succeeds), and then to something with a specific interface. It panics on the type cast. That's in the language spec: if you type-cast without checking the result, you can get a panic. I don;t consider C a duck typing language too, because you can write ((Bird*) ptr)->swim(), but perhaps you do?
- randomdata 2y ago> It doesn't try to call the method. It never gets there. Sure, same as any other language with duck typing. Consider Ruby, which is famous for its duck typing. `variable.not_a_method` raises NoMethodError. How do you think it knows to do that? That's right, it first performs a type check and, since that check fails, it doesn't try to call the method and instead raises the exception. Exactly the same as Go panicking under the same circumstances. > and then to something with a specific interface. That is a type assertion, not a cast (Go doesn't have support for casts anyway). It merely asks the runtime: "Does this value satisfy the given type?" There is no change in type. Now, let's take this further: It is generally agreed upon that duck typing differs from structural typing only in that it is evaluated dynamically instead of statically. Go's interface is quite clearly a structural type when evaluated statically. And what do you think the type assertion does in the example given? That's right: It performs a type assertion on a "structural type" at run time. Duck typing, by definition! > I don;t consider C a duck typing language too, because you can write ((Bird) ptr)->swim(), but perhaps you do?* No. First and foremost, where would the typing come into play? That will actually try to call the method, whether the pointed memory is suitable or not. There is no type checking to steer you around mistakenly calling something that shouldn't be called. Not at compile time, not at run time. It is literally called duck typing, not duck valuing. "Type" has significance. Where do you find it here?
- moritzwarhier 2y agoI have a stupid question (web dev, but also have used Java and C#). TypeScripts type system is commonly described as implementing "structural types" (not "duck" typed) And there are a ton of pragmatically sound gotchas around this, such as the importance of whether an object is used as an argument or a parameter, or if it is declared using an object literal. (focusing on objects here because for primitives I'd assume that TS has almost nominal typing) So, is there an ELI5 for the difference between structural typing and duck typing? I'd guess that duck typing is more similar to the callee perspective in TS (give me an object with the properties I need), while structural typing is more similar to the checks performed when initializing an object literal with a declared type? But I'm not sure if I'd be able to differentiate both terms succinctly. What is the relationship between duck typing and "type narrowing"? Or is that more of a "structural typing" thing?
- randomdata 2y ago> So, is there an ELI5 for the difference between structural typing and duck typing? While similar, structural typing is seen statically (think compile time), duck typing is seen dynamically (think run time).
- moritzwarhier 2y agoThanks, this makes sense, TS type narrowing only works with information known at compile-time (even when using runtime constructs for type narrowing). So I will go on to imagine duck-typing as the classic JS way where functions started with often pretty extensive runtime checks of their parameter values. I guess this also means that duck-typing is inherently tied to checking primitive types and/or object structures, return values etc at runtime.
- neonsunset 2y ago> So, is there an ELI5 for the difference between structural typing and duck typing? Likely just semantics. You could argue that the sliver of difference is just treating something like a particular API shape hence duck typing over structurally matching to an interface. For practical purposes however it does not matter. The runtime vs compile time argument is purely an implementation detail that has no relation to structural matching aka duck typing (heh) otherwise. In practice, I find this idea rather uncomfortable and C# has been avoiding it except for few very defined cases that are least likely to cause this confusion, like GetEnumerator and Enumerator.MoveNext+Current (it could be used as an enumerable in foreach loops but unless the type implements IEnumerable, you can't coerce it to the type). For the cases where specialization is needed, it is usually written as // could also be Handle<T> where T: IDataArg to avoid boxing for structs // as struct generics in .net are zero-cost via monomorphization void Handle(IDataArg arg) { if (arg is IPooledArg pooled) { var rented = arg.Rent(); // do something with the arg rented.Return(); } // slow path } No type confusion is possible as whatever is passed to the method has to declare it implements IDataArg. Same applies to 'arg' being 'IPooledArg' - it could have methods with names that would make it match the interface structurally but this is, quite literally, not a type-safe assumption. The authors may have explicitly decided not to expose it, or to provide explicit interface implementation that differs from pre-existing names. All this is very upfront and you won't be finding yourself having to rename methods or be surprised when your objects or structs are used in a way they are not supposed to because their triangle-shaped type happened to fit in a square-shaped interface hole.
- deleted 2y ago[deleted]