4 ms·
> It [C++] can't. You have to follow explicit conventions in order for it to do that, and an untrusted shared library can completely subvert the model. Point t
by catnaroek 10y ago
> It [C++] can't. You have to follow explicit conventions in order for it to do that, and an untrusted shared library can completely subvert the model.
Point taken.
> BS. Java's type system gives you an ability to know the type of a given parameter with a high degree of confidence. For the majority of cases, you only have one possible type, and Java does a great job of validating those cases.
If that's the entire point, why have complicated features like wildcards and F-bound polymorphism? ML and Haskell (no GHC extensions) give you stronger guarantees than that, with far less complicated type systems: in fact, their type systems are simple enough that global type inference is decidable!
> Sure it's a simple thing, but I'd rather have a tool that at least does the simple things for me, rather than one that doesn't.
Well, for me, everything is ultimately subject to a benefit/cost analysis. Ceteris paribus, more static guarantees is better, but marginally more static guarantees than Python in exchange for a lot of additional ceremony isn't a tradeoff I find attractive enough.
> If nothing else, IDE developers have demonstrated that a lot of value can be unlocked from these simple assurances.
By heroically overcoming expressiveness limitations that shouldn't be there in the first place?
> Maybe in your type model, it has a maybe referee, but you're artificially throwing in the notion of None as a crucial bit of the type system
It's not artificial if it reflects what's actually going on. An incomplete league schedule doesn't always contain a `Referee` in every referee slot, and I have to model this fact.
> Java's type system basically makes all reference variable types "maybe" types.
This isn't true. `Maybe`s compose. You can have a `Maybe (Maybe Foo)`, which isn't the same thing as a `Maybe Foo`, and the type checker will require you to be very aware. OTOH, `null` can't be layered in this way, and that's why, for example, `TreeMap.get()` returns `null` in two qualitatively different circumstances.
> Python's type system basically makes all variables "maybe" for any type.
Again, this isn't true. Python has a single static type: the type of every Python expression.
> Amazingly, if you look at Java code, the vast majority of the time, programmers are able to find more specific types to tag their variables, and rarely need to use instanceof or the visitor pattern.
At the price of never knowing whether their case analyses are exhaustive.
> That's great, and I'm sure from your vantage point all that matters is arithmetic, but it turns out a lot of other programs and programmers write code that largely has nothing to do with arithmetic.
What matters to me, as I've made explicit above, is accurate modeling. Sometimes it involves arithmetic, other times it doesn't. Sometimes it doesn't even involve types! But, when types don't help, I prefer them to get out of the way.
- cbsmith 10y ago> ML and Haskell (no GHC extensions) give you stronger guarantees than that, with far less complicated type systems: in fact, their type systems are simple enough that global type inference is decidable! Java's type system is terrible because it has been introduced incrementally and with an eye towards backward compatibility. That's the "why". I'd point out though that ML & Haskell's type systems might be simpler from a theoretic stand point, the ugly Java model appears to be easier for humans to reason about. There's a whole ton of programmers who can't figure out what to do with ML & Haskell, but get along well enough with Java. > Ceteris paribus, more static guarantees is better, but marginally more static guarantees than Python in exchange for a lot of additional ceremony isn't a tradeoff I find attractive enough. You make it sound like it is trivial to validate those static guarantees in Python. Have you built some trace framework for Python that validates all the types that can be passed to a particular function? That'd be super handy. > By heroically overcoming expressiveness limitations that shouldn't be there in the first place? I wasn't talking about code generation. There's a whole bunch of code analysis/interpretation logic that is much harder to achieve in Python. For the most part, the IDE's that support both just provide a watered down Python feature set. > It's not artificial if it reflects what's actually going on. An incomplete league schedule doesn't always contain a `Referee` in every referee slot, and I have to model this fact. You don't have to model that fact as a distinct type in the type system... and people often don't. Often, people implement business logic in code, rather than in the type system... else you couldn't get anything done with JavaScript (which I'm told is not actually the case, despite appearances ;-). > OTOH, `null` can't be layered in this way, and that's why, for example, `TreeMap.get()` returns `null` in two qualitatively different circumstances. Yup. No composition. Then again, you can handle that logically in other ways. In the case of a TreeMap, the right to handle it would be to have a way to access the Map.Entry associated with a key. You sort of have that, but it is all around floor/ceiling/range type queries, rather than the get because... well, you rarely need the feature and you can get by with using the containsKey() test. The nice thing is that if I can't remember if get() returns the Map.Entry or just the value, the type system can catch me on it, because the return types are indeed different. In Python, I'd actually have to test it or look at the documentation. > Again, this isn't true. Python has a single static type: the type of every Python expression. That's semantics for the same thing as saying the variable can point to any type. That "single static type" can be tied to any Python type, making all variables intrinsically maybes... just like all of Java's reference types. > At the price of never knowing whether their case analyses are exhaustive. You can totally know whether you've properly handled all the null cases. There's lots of tools that do exactly that, even taking advantage of the @NotNull attribute to help winnow down the possibilities. For more complex case analyses, you can use Enum's & EnumMap's to know if you have complete coverage. It can be done through static analysis... just not purely from the type system. > What matters to me, as I've made explicit above, is accurate modeling. Sometimes it involves arithmetic, other times it doesn't. Sometimes it doesn't even involve types! But, when types don't help, I prefer them to get out of the way. You're ignoring all the other cases where types do help, because the type system doesn't help with your pet case. In short, when it comes to static typing, you throw out the baby with the bath water. I get it, you don't like it, and it is incredibly annoying looking at that narrow uncanny valley to the thing you do like, but let's not rationalize it by asserting it doesn't help.