3 ms·
Minor nitpicks, from someone who really likes Go: > It is possible to have both dynamic-like syntax and static safety Well, you can learn that one by coding
by krylon 9y ago
Minor nitpicks, from someone who really likes Go:
> It is possible to have both dynamic-like syntax and static safety
Well, you can learn that one by coding in C#, too. In fact, I have the feeling this is a general trend across several relatively popular languages these days - provide as much as possible of the benefits of dynamic typing while keeping the benefits of static typing.
I sometimes think how nice it would be if I could write my code entirely without type declarations and have the compiler or some preprocessor figure out as much of the type information as possible.
> It’s better to compose than inherit
It depends, really. Personally, I think composition is the simpler solution more often than inheritance, but sometimes it is not.
I completely agree about the error handling, though - at first it was very tedious to handle all errors explicitly, but after I while I came to appreciate it. Once I had fallen into the habit of checking for errors without having to think about it too much, detecting errors became much easier, and deciding if I could "deal" with some error or escalate it (possibly to the point of terminating my program) became more straightforward, too.
- skocznymroczny 9y ago> In fact, I have the feeling this is a general trend across several relatively popular languages these days - provide as much as possible of the benefits of dynamic typing while keeping the benefits of static typing. Some languages go the opposite way. Dart 1.0 has optional typing, but Dart 2.0 will be statically typed (with type inference though).
- rbehrends 9y ago> Dart 1.0 has optional typing, but Dart 2.0 will be statically typed (with type inference though). Not quite; it's more that compile time typing is getting cleaned up. You can still omit types, which will then either be inferred or set to `dynamic`. The following is valid strong mode Dart: f(n) { if (n <= 1) return 1; else return n * f(n - 1); } The following will no longer work: int x = "foo"; In short, you can still omit types. It's just that if you declare them, they are enforced [1]. Dart will also infer them if possible, i.e. the following is illegal: var x = 1; x = "foo"; Here, x is inferred to be `int`, which makes the assignment of a string illegal. However, the following works: var x = true ? 0 : []; x = "foo"; Here, the type of `x` cannot be inferred, so it becomes `dynamic`, and therefore the assignment of "foo" becomes valid. You can turn this off with --no-implicit-dynamic; with this option, all types must either be declared or have to be inferable. [1] Sometimes not at compile time, though: Dart allows implicit downcasts and covariant generics at compile time and will insert runtime checks to catch those situations.
- krylon 9y ago> with type inference though That is what I was trying to get at - with type inference, one can omit many of the type declarations (thus getting more flexibility and shorter code) without sacrificing type safety. Whether or not it is a good idea to omit type declaration is a different question, but in cases like "T a = new T(...)", the type declaration on the variable is kind of redundant anyway.
- brightball 9y agoIn my experience, I've found that inheritance becomes a significant burden on projects, especially when using 3rd party libraries. If you need to modify something up in a base object in a 3rd party library, you essentially have to fork the project creating a new maintenance burden and breaking the upgrade path OR rebuild the entire inheritance tree. It's one of the things that makes Ruby so useful as an object oriented language since I can write a patch that runs at startup to just monkey patch the base object in a couple of lines of code. I think the compos-ability approach gets it right in that regard.
- krylon 9y ago> In my experience, I've found that inheritance becomes a significant burden on projects, especially when using 3rd party libraries. I think inheritance is like any sufficiently powerful programming technique - with great power comes great potential for shooting yourself (and others) in the foot. But there are situations where inheritance is an elegant and natural approach. They just are not very frequent. Python's standard library for example has (or used to have at least, it's been a while since I looked) a framework for building network servers where you create a server by writing a class that inherits from two classes provided by the framework - one for the type of socket you'll be dealing with (TCP, UDP, Unix sockets), and one for defining how you want to do concurrency (forking, threading). The you just override one method that implements the actual request handler, and you're good to go. I consider that a clever and elegant use of inheritance. Just to be clear, all in all, I tend to agree with you, and in my own code I use inheritance only very rarely. But I think that it's wrong to all-out condemn a programming technique just because it can be abused. It just means one has to carefully consider the advantages and disadvantages.
- brightball 9y agoOh, I'm definitely not condemning it. Honestly, I think it makes more sense when you are dealing with a GUI or desktop application where an object can be more representative of elements that a user is interacting with. For server side projects is where I've experienced it causing problems over project lifetimes. The maintainability complexity is where I've been bitten the worst.