Name: Anonymous 2017-02-02 10:34
@davetchepak "What can C# do that F# cannot?"
NullReferenceException :-)
Educating the imperative gorillas about sum types:
https://chadaustin.me/2015/07/sum-types/
@davetchepak "What can C# do that F# cannot?"
NullReferenceException :-)
Window* window = get_focused_window();
window->close_window();
Oops! What if there is no focused window? Boom. The fix:
Window* window = get_focused_window();
if (window) {
window->close_window();
}
window && window->close_window();
Nothing prevents code from accessing .paint in the case that type is CLICK. At all times, every possible field in event is visible to the programmer.
window
was already checked for null before close_window
got called? Then the check inside close_window
would be superfluous, hurting performance with no need. check everything for null a hundred timesIts checked when its needed, and often function have special "default behavior" with null. If you afraid of NULL so much you can force get_focused_window to return Default_Window dummy object instead of NULL.
sum types don't have anything to do with OOP polymorphismThis is OOP polymorphism with syntax sugar, the case is the static method dispatch on overload of window - which is exactly the same as close_window(Window) C code.
Its checked when its neededAnd also when not needed.
you can force get_focused_window to return Default_Window dummyMore bloat.
This is OOP polymorphism with syntax sugarNo, this is category theory. Sum types are dual to product types.
No, this is category theory.Does C++ implement category theory?
Unfortunately, C compilers do not verify that the null case is always handled, and this is a particularly prevalent source of errors in C code, since there is a tendency to ignore exceptional cases.Hahaha C is shit.
T + 1
types like Option
or Maybe
, so they bring no performance overhead.This usage of Option to create safe nullable pointers is so common that Rust does special optimizations to make the representation of Option<Box<T>> a single pointer. Optional pointers in Rust are stored as efficiently as any other pointer type.
C, C++, Java, C#, Python etc still do not[have tagged unions].
enum ShapeKind { Square, Rectangle, Circle };
struct Shape {
int centerx;
int centery;
enum ShapeKind kind;
union {
struct { int side; }; /* Square */
struct { int length, height; }; /* Rectangle */
struct { int radius; }; /* Circle */
};
};
int getSquareSide(struct Shape* s) {
assert(s->kind == Square);
return s->side;
}
void setSquareSide(struct Shape* s, int side) {
s->kind = Square;
s->side = side;
}
/* and so on */
foo (OuterConstructor (MidConstructor bindingForWhole@(InnerConstructor binding1 binding2 binding3)))
| binding1 > 10 = bindingForWhole
| otherwise = InnerConstructor binding1 (binding2 + binding3) (binding2 - binding3)
foo (OuterConstructor (SomeOtherConstructor _)) = ...
Some(5)
may be a separate branch than Some(x)
, with the second one handling all values of payload x except 5), makes deconstruction of values correspond syntactically and structurally to their construction. And yes, C allows inspecting the payload of a tagged union without checking the tagC doesn't have tagged unions or set-theoretic unions. They're a ``design pattern'', not a language feature.
the result is undefined behaviour or some such crap.Why would you expect a compiler to check and understand design patterns? You might as well complain that the compiler doesn't understand your comments.