Live data from Hacker News

Things I Was Wrong About: Types

v5.chriskrycho.com

421–430 of 468 posts

Re: Things I Was Wrong About: Types

#421
post #380

Earlier quoted context omitted.

And mypy is still very immature. You can’t denote a recursive type (e.g., a JSON type) or specify a callback that takes keyword arguments. Even getting it to load type annotations from third party packages is hard in many cases. Worse, it seems to be improving at a snail’s pace if at all.

A "JSON" type in Python is just an untyped dictionary. Is that not what you're looking for? Also, python's type-hinting supports forward-references which are what you would use for recursive or "self-referencing" types. Personally, I like the slow pace they're taking with the typing. It's touching the core usage of the language in a fundamental way and I don't think that can be rushed. We're seeing lots of community…

Untyped dictionaries are a superset of JSON. JSON is (more or less) precisely:

   Dict[str, JSON] | List[JSON] | str | float | int | bool | None

Re: Things I Was Wrong About: Types

#422
post #128

Earlier quoted context omitted.

Sum types even work when you actually have the multiple of the same return types. (Ie in Haskell `Either String String` works just as well as `Either String Int`; the types don't have to be distinctive.)

That follows from the definition being tagged 'Left'/'Right': Either a b = Left a | Right b

Yes, the magic is in the tagging. Tagging also solve the issue of `Maybe (Maybe a)` that the other reply mentioned.

Re: Things I Was Wrong About: Types

#423
post #124

Earlier quoted context omitted.

Apropos PHP: I hate it with such as much passion as the next guy, but I am quite impressed with what Facebook managed to do with Hack! (Including adding lots of types.)

Don't forget, much of that effort has now trickled down into the PHP language itself. We've long had scalar types for function parameters and return values, but with 7.4 and 8.0 we've added union types[1], nullable types[2], and typed properties[3]. While not a part of the language yet, generics can be annotated with the linting tools PHPStan and Psalm[4], and native support for these annotations is coming to the nex…

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.

Re: Things I Was Wrong About: Types

#424
post #396
post #351

Earlier quoted context omitted.

I don't buy this "choose the right tool for the job" thing. I'd always advise you to choose the tool that your company has the most knowledge in. If there's a problem that cannot be solved in that programming language, then you can look for a better tool. But you shouldn't pick a language that nobody else understands, just to save a few lines or some time when doing the initial implementation - just to realize that y…

I consider that one of the most important criteria when picking the right tool for the job (if you're writing something to be maintained by other people in a company).

Okay, maybe. But usually this is not part of the description of "choosing the right tool for the job".

Re: Things I Was Wrong About: Types

#425
There is no preacher like a recent convert.

For me, using C++, types have always been expected to do the heavy lifting. A language without sturdy types is a language that doesn't help you; you are left to do everything by hand.

C++, like Haskell and, to a lesser degree, Rust, make types power tools, engines of coding automation. Java types, by contrast, do not much for you, and C types are little better than none.

If you are new to programming with strong types, you will not reflexively unburden youself onto your types, and continue doing things the hard way. That will feel comfortable, but will limit your reach. To level up, you will need to consciously, and frequently, ask yourself if a type could shoulder another burden. You will know you are succeeding when features you didn't notice you were coding pop up, unbidden.

Re: Things I Was Wrong About: Types

#426

Earlier quoted context omitted.

> There are huge opportunities that emerge from pushing yourself to explore new paradigms and domains. What are those opportunities? As a Rubyist, to me it makes more sense to become really good in Ruby. 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. Learning Elixir, Go, Haskell or you name it isn't gonna help m…

> 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'm hesitant to ever go back also because of this issue. The sad thing is I know for sure I write shit code after 8 hours, and I'm sure it's true for most people. So while some startups can churn out young devs like that and get away with it, I'm sure there are businesses that actually care about code quality. Even in the most capitalistic of societies. But we stray: within web dev, the question is how can I be more valuable to a Ruby team - as someone who did 3 years python, 3 years php and 3 years elixir or as someone who did 9 years Ruby?

Re: Things I Was Wrong About: Types

#427

Earlier quoted context omitted.

Ya, that's why I think each language kind of benefit to different levels of having static type checkers and of various features as well. You can't just blanket say all type checkers are bad, or all language without one are bad. Clojure is a good example here, it actually can be used with a very powerful static type checker core.typed, yet its users chose not too for reasons that say in JavaScript maybe a different ch…

Does anyone still use core.typed? My impression was that Circle CI's article announcing that it was moving away from core.typed was effectively a death blow to its community. One of Circle CI's founders later went on to use OCaml instead of Clojure on his next project (Dark) precisely for its static type system. None of that is to say OCaml is "superior" to Clojure in some way. I disagree with a lot of the ways that…

The thing is, core.typed is a really powerful type system, but the ergonomics with the way Clojure works didn't work out, so people prefer not to use it when developing with Clojure.

That's what I find interesting about it. Not all language benefit from a type system in the same ways, some, like Clojure, actually get crippled. Now, it can mean that you need to find the right kind of type checker that provides the correct ergonomics for Clojure and maybe that would work. But it's still quite interesting.

For example, Erlang has a bit of a similar thing, Dyalizer made specific choices to work within Erlang's design. Had it not done so, it probably wouldn't have found adoption. Same with TypeScript.

So what's interesting here is that you have an apples to apples comparison where a language is found to be better without the constraints of static type checking.

When you look at other statically typed languages, they're oftened designed around the static type checker. That's the main focus, and the language itself revolves around that. So obviously in such a language, the type checker would be a necessity, as it's the main draw. So it's interesting to look at Clojure for a counter example.

That said, JavaScript you could argue is also an apples to apples comparison, and people opted for types. It'll be interesting to see also where Ruby and Python go, now that they have type checking features as well.

Re: Things I Was Wrong About: Types

#428
Without types, the complexity is shoved elsewhere (in someone’s head). Types make the inputs and outputs explicit.

He is right about a good type system being able to infer and being smart at the same time allow placing enough guards around things to truly express the authors intentions of how things ought to be used.

One of the reasons why I am not a fan of golang. It’s type system is not that great. You have to do a lot of hacks and copy pasta.

Rust, C# and Typescript get it. Python with its new py3 typings syntax is great but it still needs a lot of work to be able to express things like Union types, nullable types, partial types, Recursive types , conditional types, type transforms, genetics etc.

There’s a lot that goes on in a good type system. The balance of letting the user express their problem at the same time keeping errors meaningful and preserving the code guarantees.

Re: Things I Was Wrong About: Types

#429

Earlier quoted context omitted.

I can see you disagree on a matter of principle and personal experience. And that's alright. I just think it's as valid an opinion as all the others. There are some who like explicitly defined types of various levels. Those who want it all infered or partially infered, and those who don't want them at all, or want them optional or gradual, etc. And none has been able to make a claim over the others even now years lat…

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 definitely like a functional language with a fully infered type system compared to the imperative flavours.

But there is a segment of the static checking world which is dedicated to non Hindley-Milner, mostly imperative, mostly OO scene, and I feel denying Java's influence on static typing I think would be reductionary, as it is one of the most widely used statically typed language.

Anyways, I just wanted to bring their voice to the conversation, even if I don't agree, and am a big fan of local type inference that Java 10 added. Which maybe the fact that they finally added it shows they recon being wrong about it.

Now, for cause of error. One of the one they describe is "action at a distance" like this:

    var result;
    // many lines of code
    result = new ArrayList();
Now here because the assignment could be way later in the code, someone might mistake the type of the variable since it isn't obvious what it would be,.since the assignment is so far away from the declaration.

Another issue they talked about was multiple assignment. For example:

    var x = "Hello"
    // multiple lines later
    x = new CustomerName();
Now what should the type of x be? Java could infer that it must be the closest common ancestor, which might be Object in this case. That's most likely not correct though, and the rest of the type checking now will probably lead to weird errors. Like why doesn't x work with String methods or CustomerName methods?

Another issue is with ABI compatibility. If the return type of a method is infered, and compiled. And a dependent class uses it. A programmer could change the implementation and have the inference infer a compatible but different type all of a sudden, like say it now infers ArrayList instead of the interface type List. Now the client code is broken, because it assumed the List type, and this is probably not the intent of the programmer, but a side effect of the inference having changed without their notice.

I think they talk about more stuff here. You got to dig into the mailing lists and JEPs and all to find most of it.

Re: Things I Was Wrong About: Types

#430

Earlier quoted context omitted.

If you use String for all your data types than you are no better than a dynamic language. There are many string like things that benefit from their own types, e.g. currency, identifiers, post codes. Such types should only be created from a parse of valid strings, i.e. no empty strings, whitespace, illegal values etc. They do not have to be Alan Kay "objects", despite what your language or thought leadership is tellin…

> If you use String for all your data types than you are no better than a dynamic language. I once read a Haskell (I believe, may have been SML or OCaml, this was a while ago) tutorial (can't find it anymore) that did this. It was infuriating as it completely hid the benefit of the type system. Essentially, details fuzzy, it was creating a calculator program. Imagine parsing is already done and had something like thi…

Yes, every statically-typed language has a dynamic language as a subset. It is up to the author to use and apply types. One can certainly write Haskell where everything is in IO and everything uses Strings.
Post reply on HN