4 ms·
> If you're going to dismiss safety issues in your approach with "Yes, it’s possible for programmers to write bugs." then there's no point having the conversati
by louthy 9y ago
> If you're going to dismiss safety issues in your approach with "Yes, it’s possible for programmers to write bugs." then there's no point having the conversation, because that's an equally good argument for not having a type system at all.
Absolute nonsense. I didn't dismiss safety issues at all. I dismissed your claim that having to specify a `struct` constraint somehow makes the feature unworthy.
C# has null, that's a fact of life, it's not dismissive to realise that a (granted, very annoying) part of the job of writing C# is dealing with null. So, using this doesn't make this technique any less safe than any other way of writing code in C#. So, yes, programmers will occasionally write null-dereference bugs in C# - that's the price we pay for bad language implementation decisions.
Stating "that's an equally good argument for not having a type system at all." is clearly hyperbolic nonsense.
> If we were willing to be unsafe we could just cast to the desired type.
But it isn't unsafe! Not specifying a `struct` constraint is a bug. If you provide the constraint then it's safe. Trying to compare that to a dynamic cast where you have no type-system enforcement to one where you do is just idiotic.
> I'd sooner pass the module dictionary explicitly, like one does in ML, than adopt a technique that would normalize having "default(...)" in my codebase.
At no point was this trying to force you to use this technique. It was a reply to "Once you've got return type polymorphism, you really start to miss it in other languages. The simplest example possible is mempty".
I use this technique very successfully a lot, and the exact mechanism (of using `default`) is in the process of being wrapped up into a new type-classes grammar for C# [1]. So, I guess you'd probably prefer to wait for that...
[1] https://github.com/MattWindsor91/roslyn/blob/master/concepts/docs/csconcepts.md https://github.com/MattWindsor91/roslyn/blob/master/concepts...
- lmm 9y ago> C# has null, that's a fact of life, it's not dismissive to realise that a (granted, very annoying) part of the job of writing C# is dealing with null. So, using this doesn't make this technique any less safe than any other way of writing code in C#. If using this technique requires breaking one of the rules that you have to follow to avoid getting nulls in C# then the technique is a safety problem. > Not specifying a `struct` constraint is a bug. If you provide the constraint then it's safe. Ok, but how do you enforce that? If you've got a technique that requires manual review and reasoning at a distance to use safely, then again we're no better off than we would be using dynamic casts. > At no point was this trying to force you to use this technique. It was a reply to "Once you've got return type polymorphism, you really start to miss it in other languages. The simplest example possible is mempty". If you don't have a typesystem feature in a safe way, you don't have it.
- louthy 9y ago> Ok, but how do you enforce that? If you've got a technique that requires manual review and reasoning at a distance to use safely, then again we're no better off than we would be using dynamic casts. More hyperbole. Failing to constrain may lead to a null reference exception. Just like passing a reference to any method anywhere in C#. It is no better and no worse than any other C# code. However it does allow for ad-hoc polymorphic return values. Which is the entire point. That is not the same as returning a dynamic value, which is a type that propagates dynamic dispatch wherever it's passed. A failure to capture a null reference bug means on first usage it will blow up - so you fix the code and everything is type safe. > If you don't have a typesystem feature in a safe way, you don't have it. The feature is safe. Your argument is the same as saying C# doesn't have classes because a reference can be null, or C# doesn't have fields because a field can be null. All throughout this frankly tedious discussion you have somehow conflated having a bug in an application with having no type system at all. C#'s type system is obviously nowhere near as impressive as Haskell, but C# is actually used in the real world much more, and so if someone wants polymorphic return values then they can. I mean they can anyway through inheritance, never mind the ad-hoc approach I demonstrated - but whatever yeah?
- lmm 9y ago> Failing to constrain may lead to a null reference exception. Just like passing a reference to any method anywhere in C#. But you can adopt a small set of rules that are locally enforceable (and practical to use in an automatic linter) to prevent this happening (just as Haskell is safe even though unsafePerformIO exists, because you can adopt a small set of locally enforceable rules like "never use unsafePerformIO"). Unfortunately one of those rules has to be to never use default(). > That is not the same as returning a dynamic value, which is a type that propagates dynamic dispatch wherever it's passed. A failure to capture a null reference bug means on first usage it will blow up - so you fix the code and everything is type safe. Unfortunately default() isn't fail-fast in all cases - when used with e.g. a struct type containing a reference type, it will create the value in an invalid state (containing a null reference) but you won't necessarily notice until you come to use the value, arbitrarily many compilation units away. So it's just as dangerous as a dynamic value. > All throughout this frankly tedious discussion you have somehow conflated having a bug in an application with having no type system at all. In almost any language you can have polymorphic return values without complete type safety. The feature that Haskell has here isn't that you can have polymorphic return values - it's that you can have polymorphic return values safely. Showing an unsafe implementation of polymorphic return values in some other language is pointless and irrelevant.