Live data from Hacker News

Things I Was Wrong About: Types

v5.chriskrycho.com

451–460 of 468 posts

Re: Things I Was Wrong About: Types

#451

Earlier quoted context omitted.

Any language that supports type inference will also support annotations if your taste/linter/boss demands it. That's fine. But hobbling the compiler by not including type inference at all, because you think it causes bugs, is quite definitely stupid. I literally don't understand how anyone could dispute this except by inexperience with type inference. Based on the sentence with the tangent about "optional or gradual"…

Did you follow the link I provided? Like I said, I'm definitely pro inference, in fact, I don't even mind a dynamic language (depending which one), give me a Lisp or Smalltalk and I don't even need any static type checking. Now, OCaml is actually next on my list, but I've done Rust, Haskell and Elm, used Kotlin, Scala, Fantom, and C#. And I've used core.typed on Clojure, for now, Clojure is my language of choice, but…

I'm not trying to deny Java's influence, just saying that it's bad. I do think it was worth bringing up (I upvoted your top-level comment), but mostly because we need to recognize the damage it has caused to the discussion around typing. People try to talk about "dynamic vs static", or worse run studies, when their only static language is Java. Their arguments are nonsense and their studies are wasted as far as I'm concerned, since they're dealing with a straw man. Java is treated as the poster child when it should be the black sheep. FFS, it still has null pointers.

Your examples are mostly not problems in reasonable languages. Just don't declare variables before initialization. Assigning a variable two incompatible types is an error, just like it would be without inference.

I'll grant the ABI one is interesting. In situations where separate compilation is on the table, maybe you want to annotate function types. But obviously the myriad of inferred languages don't suffer much from this. You could just as reasonably argue that the class author made a breaking change, and it should be treated exactly as if they changed the annotation.

Re: Things I Was Wrong About: Types

#452
post #341

Earlier quoted context omitted.

> missing features (like unions) when working with other languages. Which languages are missing unions? Off the top of my head, they exist in C/C++ and mypy python.

Typescript allows you to have literal type discriminators in their unions, which combined with control flow based type narrowing of unions effectively gives you sum types. That is what he is talking about, because most mainstream langauges don't have sum types and you need to go to strongly typed functional langauges (haskell, scala, etc...) or modern strongly typed langauges such as Rust to get access to such featur…

Yes, this. Sum types in most languages are approximated by something like kotlin's sealed classes. Sometimes you don't want to declare a whole new class hierarchy, you just want to say "this function can either return this or this".

Re: Things I Was Wrong About: Types

#453

Earlier quoted context omitted.

> As a Rubyist Are you a Rubyist, or a developer? > As I get older and more expensive, I need to be better than the 3 year experience 26 year old colleague. And if not better at least not noticeably worse. Yeah, I had this line of thinking. I don't recommend it. I eventually realized I don't want to play the same game as people who are willing to throw away more than I am. Specifically, I don't want to be in position…

> Younger devs will work longer, not have families I work in a country where work hours are 8.5 hours (the half hour is for lunch). Period. If you consistently do more than that you'd be seen as someone who can't get his work done in time. So it's just not culturally encouraged to do that. I come from a much more capitalistic society originally, so I know first hand these companies/societies you speak of exist, and I…

That's a bit of a strawman though. My initial premise was that learning on the side something orthogonal to what you use daily is beneficial to ones capabilities in general. Orthogonal being key here.

Re: Things I Was Wrong About: Types

#454
post #321
post #307

Earlier quoted context omitted.

You can use these features very easily in Vim with ALE. Map a shortcut to :ALEHover and that's it. https://github.com/dense-analysis/ale

Upvoting so that people who need this may see it and benefit from it. However, it's not that I'm not aware of features available to my editor of choice, it's that I specifically don't want an editor with those features. I don't want that functionality as part of my workflow. I prefer to reduce the noise and distraction so that I can keep concentrating on what's currently important to me. Bringing this back to what th…

I think you point to an important tradeoff. I also think it's clear the industry is leaning toward the decision that it is not worth giving up the advantages of static typing for the 0.1% of users who really don't want type info in their editor.

Your distinction between the code itself and editor-based tools I think is a false one. The types are part of the code, and while one can use them tolerably well on the command line alone, they are most helpful with things like type hovers. The line is blurry between language features and code structure on the one hand and the editor tooling that gets the most out of it on the other.

Re: Things I Was Wrong About: Types

#455

Earlier quoted context omitted.

Did you follow the link I provided? Like I said, I'm definitely pro inference, in fact, I don't even mind a dynamic language (depending which one), give me a Lisp or Smalltalk and I don't even need any static type checking. Now, OCaml is actually next on my list, but I've done Rust, Haskell and Elm, used Kotlin, Scala, Fantom, and C#. And I've used core.typed on Clojure, for now, Clojure is my language of choice, but…

I'm not trying to deny Java's influence, just saying that it's bad. I do think it was worth bringing up (I upvoted your top-level comment), but mostly because we need to recognize the damage it has caused to the discussion around typing. People try to talk about "dynamic vs static", or worse run studies, when their only static language is Java. Their arguments are nonsense and their studies are wasted as far as I'm c…

Seems fair.

What I wonder though is what about Java is bad? Like, is the lack of inference the key differentiator between good static type systems that help, and those that get in your way and slow you down?

Or are we actually claiming something more, that the paradigm of Java prevents its type system from being useful. Thus we're as much having a conversation about type systems as we are about functional vs imperative/oo programming and other such paradigms.

And in fact, if you think of it that way, maybe it isn't a type system you've been looking for after all, but a better language/paradigm. And you can see people moving away from Java to Erlang, Clojure, Elixir all have this "OMG this is so much better" feeling. Similarly, someone who moved from Java to Haskell, OCaml, and all also has this "OMG this is so much better feeling."

Where as one moves between Python/Ruby and Java, like the OP, and thinks, I don't see the big deal with static types?

Now someone could say, well, it's because you moved to a bad static type system. Try Haskell or OCaml instead. But that's not just Java with a different type system, now you've also fundamentally changed the paradigm and so much more.

It becomes difficult then to distinguish the type system from other aspects of the language.

Now, I'll show some bias here, but I've used Haskell and Clojure. The languages have a lot in common, one of the big difference between the two is the type system (ignoring purity). When moving between those, there's not a clear feeling of one being better, it's much more "hard to tell". The Haskell type system can be neat, can help me make sense of what is what in the code, what fields are available, what functions are supported, let me rename things with more confidence, etc. But it also does get in my way sometimes annoyingly, distracts me from my problem domain, and can feel limiting at times.

Amusingly, this is the same thing someone whose debating the pros/cons of Java's type system over Ruby or Python would say.

I guess where I'm going with this is too say that a type system is only a part of the story. And with Java, is it truly the type system that is the problem? I don't think so. In fact, I think maybe within the context of the semantics of Java, its type system is actually the best it can be.

By the way, I think the issue with Java's inference of mutable variable is that most of the time you want to infer the most generic type. Like say:

    var items = new ArrayList();
It be nice for items to be a List and not an ArrayList, that's what a programmer would have annotated.

If a method returned items, you'd want the method to be a List, so that clients don't break if you later decide to use a different type of List.

Another challenge now though becomes what is the type of elements in the List?

You can go by the type of the first added value, but if that is behind conditional branches like:

    var items = new ArrayList();
    if (thing == 1)
        items.add(100);
    else
        items.add("hello");
Now what?

I feel a lot of the mutable semantics of Java combined with the inheritance based subtyping makes type inference much harder, because of all these weird edge case.

Re: Things I Was Wrong About: Types

#456
post #217

Earlier quoted context omitted.

I think yes. I do F# for a lot of time, and looking at past code I can't just figure some stuff. Not only their type system look alike dynamic, it make you build some stuff that is IMPOSSIBLE to get without a serious look at the types: And the types are invisible and behind abstracts constructs. With python, for example, I can't at first see what a function need but at least see the body give huge clues, because pyth…

F# lets you specify the types of function arguments and return values. If it will make your code easier to read and reason about, why not just do that? I use Ocaml a lot, which is very similar to F# as you know... and I document the types of all toplevel values in my code. Not because the compiler needs it, but because it helps me navigate the code more easily.

Yeah, but it is not very idiomatic and if I need to put types everywhere, but is the point of it at the end? Is like people that type python: Is screaming is the wrong tool for the job :)

Re: Things I Was Wrong About: Types

#457
post #420
post #402

Earlier quoted context omitted.

I don’t care if my throw away CSV munger is formally safe/sound or maintainable. I care if it gives me correct results , once, as quickly and effortlessly as possible. Which is why very few people fire up GHCi/rustic/javac for that, but instead use awk/shell/Python or something similar.

OTOH, sometimes the CSV munger one writes today is still in use five years later, when the input CSV has a UTF-8 character for the first time, and suddenly it crashes and no-one knows where the bug could even be.

UTF-8 support is completely orthogonal to static typing. There are dynamically typed languages that handle it great, and statically typed languages which have garbage support for it.

In general I know what you mean though. “What if this CSV parser turns out to be really important?” If you think there’s a high probability of that, do it in a statically typed language then. 99.9% of data munging I’ve done have been throwaway programs to answer a question to inform some decision or help refine a mental model.

Re: Things I Was Wrong About: Types

#458

Earlier quoted context omitted.

I'm not trying to deny Java's influence, just saying that it's bad. I do think it was worth bringing up (I upvoted your top-level comment), but mostly because we need to recognize the damage it has caused to the discussion around typing. People try to talk about "dynamic vs static", or worse run studies, when their only static language is Java. Their arguments are nonsense and their studies are wasted as far as I'm c…

Seems fair. What I wonder though is what about Java is bad? Like, is the lack of inference the key differentiator between good static type systems that help, and those that get in your way and slow you down? Or are we actually claiming something more, that the paradigm of Java prevents its type system from being useful. Thus we're as much having a conversation about type systems as we are about functional vs imperati…

IMO Java's crippling flaw is that it is very verbose (largely but not entirely due to lack of type inference), but its type system nevertheless permits a lot of errors (notably NPEs) that other languages easily catch. In a lot of ways, it gets the worst properties of both static and dynamic languages, both the inflexibility and the unsafety, all the weight and precious little of the power. It would be a lot more tolerable if it was null-safe with proper algebraic Option types.

So yeah, a smart programmer who moves from Java to either Haskell or Clojure will likely find it a breath of fresh air, for very different reasons. Incidentally, the reason I recommend OCaml is because it's a HM-inferred language but with a much more pragmatic type system than Haskell's. You can just println wherever you please.

It's true that subtyping makes inference a lot harder. My reflex is that subtyping is overrated and you should just use interfaces and composition, but you would have a decent claim that I'm moving the goalposts or something. I'm sure OCaml has a semi-decent solution, given the O part of the name, but I don't know off hand what it is. Worst case, if the compiler chokes on your subtype-heavy code I would say to just annotate it. Annotations are certainly valid for when type inference fails or for generally forcing it to do your will in weird cases. Relatedly, I don't totally hate forcing top-level function signatures to be explicit, which would also solve the most-general-interface thing in most cases.

AFAICT your last example is just ill-typed and should not compile. This is another of the places where Java's type system just fails entirely. What is the caller who gets that thing supposed to do with it, except reflect on the type of the contents like we're writing Python?

Re: Things I Was Wrong About: Types

#459
post #423

Earlier quoted context omitted.

Coming from Haskell and Scheme, I'm now waiting for them to unify the syntactic handling of variables. At the moment, you have to put a $ in front of most variables, and no adornment for when you want to call something as a function. Reminds me of Common Lisp with its two name spaces for functions and other variables.

Yeah, the $ sigil for variables is a historical curiosity, but I don’t think it’s going anywhere. It would be an unacceptable BC break for codebases that have implicitly relied on this “two namespaces” behavior

Alas, yes. And it doesn't cause any real problems apart from aesthetics.

Re: Things I Was Wrong About: Types

#460
post #443

Earlier quoted context omitted.

> will ever swing back. Does it need to swing back? Python/JS/PHP/Ruby are still plenty popular. And no, JS isn't typescript.

Python/JS/PHP/Ruby are still plenty popular... but the weight they are putting on "dynamically typed" is decreasing over time. Basically, all the dynamic languages are creeping towards the statically-typed side with various partial annotations and optional features. But there are no statically-typed languages I know of rushing to add more dynamically-typed support to their languages. If you draw all those language tr…

I’m not so sure about that, the reason is that the total number of programmers in the world are just increasing and more importantly more and more non-programmers program code today than ever before.

It hard to convince non-programmers to see the beauty of a type system when they only want to print some html.

So what I see is a bright future for languages that can do both, types or no types.

Post reply on HN