14 ms·
I am glad to see that this is optional. We need languages that mix compile/parse time (static) and run time (dynamic) types, to mix what fits best to each situ
by Roboprog 10y ago
I am glad to see that this is optional. We need languages that mix compile/parse time (static) and run time (dynamic) types, to mix what fits best to each situation.
Of course type checking can catch some problems. The more extremist elements of the static types proponents seldom seem to ask the cost of adding types, and making some otherwise generic/overloaded operations harder to implement (e.g. - excess clutter in some "wordy" type systems, particularly in the C lineage where declared identifier names follow the other verbiage). We need more tools that allow us to easily nail down fixed interfaces to avoid errors, but still allow flexible / dynamic / metaprogramming type code when needed, without having to jump through hoops in either case.
Don't be a static typing extremist! (or throw the baby out with the bath-water, either, I guess)
- jjnoakes 10y ago> Of course type checking can catch some problems. Keep in mind, static types can also help performance, tooling (refactoring, cross-referencing, etc) and human understanding. This is not an argument for or against static types; it is simply a longer list of what they can be useful for in the many situations.
- Roboprog 10y agoSorry to vent on you, specifically, but many people seem to have missed the point where I said I wanted them. I just don't want to be forced into a jail cell 100% of the time. I want an escape hatch to do the needful once in a while to do something that the language designer never planned for.
- bjz_ 10y agoI dunno, I find static types to be a core design tool that are highly beneficial from the earliest stage of a project. They help you probe a problem space as you develop, and offload a great deal of cognitive burden to your tools. I actually find myself working a great deal slower on new dynamically typed projects because I have to juggle a great deal more context in my head, and am encumbered by larger test suites that are more difficult to change. Note that I am referring to type systems with succinct syntax, type inference, structural typing and ADTs.
- jstimpfle 10y agoIf you can't keep the "types" of your design in your head, your design might be broken. I have a real bad short-term memory and can probably juggle less things in my head than most programmers. Yet with good taste for design / decomposition that's not much of a problem. Most of my code now is structured as tables, which greatly simplifies many transformations. There is no pressing need for typing tables, and anyway most of these type systems really suck at "tables transformation algebra". Here is a little list of drawbacks of static type systems with features like you describe (parametric types, ADTs...): Type dependency hell (banana, monkey, jungle, etc), having to fight/convince the type inferencer to accept any but the simplest things, having to type many things twice. Looking at Haskell, "almost everything is inferred" is a lie in my experience. You are encouraged to write code using higher-order and highly parametric functions. If you do, the error messages you'll get if you don't annotate are plain sick. Another problem is that the type system provides no convenient escape hatches, while it's not powerful enough for typical programs. Many "successful" example designs I've seen are either _really_ simplistic (to the point where it's obvious that the better design wasn't chosen simply because the type system makes it really inconvenient), or have some _really_ terrible internals hacking in it (which might be the largest part, be impossible to understand by most developers, and break with the next compiler version). Looking at C++, a practical example is vector. It's a useful tool (automatic memory management), and very likely to be all over in your function signatures. This is very bad in terms of modularity / reusability, because your functions are not defined using reasonably general types (pointers to arrays). Many of these very real pains just aren't there with Python code, which has better modularity at the cost of being a little sloppier. These days I look at static types mostly as tools for generating fast machine code (I doubt that much more than C types is needed here) and as tools for enabling nice syntax (OOP protocols like in Python can do that too, but they are very dirty). These things however are only needed at the very optimized parts of your average project. So I think a good way in many cases is to go the Python route, and check types dynamically at strategic points to assert value integrity and enable transition to highly optimized (with static types) routines.
- vilhelm_s 10y agoI'd be interested to hear more about Haskell projects where the type system causes bad designs. Maybe you could write a blog post about it or something?
- wyager 10y agoA sufficiently good static type system won't make generic operations harder to implement. It can even make them easier to implement in terms of guiding you towards good generalization techniques. You can also do full Python-style "duck typing" statically. It's called structural typing, with native support from languages like typescript, purescript, etc. It's used a lot in web dev because it works well with Javascript's object model.
- catnaroek 10y agoOCaml-style structural typing cannot handle deciding at runtime what fields an object has. Arguably it's best to know this statically, but dynamic language users make extensive use of the ability to dynamically add fields to an object.
- nine_k 10y ago...which, of course, make it easier to assume the presence of a particular field and crash. Using an explicit map for dynamic attributes at least makes you aware what is guaranteed and what is optional. This removes much of the neat magic that such a dynamic approach affords to languages like Ruby, JavaScript, and, to a lesser extent, Python.
- jon_smark 10y agoIn the case of OCaml, the structural subtyping of object fields can never cause a crash, because it is verified at compile-time.
- duaneb 10y ago> A sufficiently good static type system won't make generic operations harder to implement. This is true for the JVM definition of 'generics', but it doesn't mean that arbitrary operations on a collection of types can be easily expressed with a given (static) type system. Run time type information + a dynamic type can ameliorate some of this, but that's shoehorning optional types into a static type system, and I don't think that's quite what you meant. Think about a generic operation to diff two data structures: you need access to the members of the struct in a generic way. I don't think this is easily solved with static types.
- massysett 10y agoI can already mix static and dynamic types. Use Haskell. With Data.Dynamic you get all the dynamic types you want.
- Roboprog 10y agoI don't know Haskell, but that sounds good. Thanks.
- friendzis 10y agoSome time ago on HN there was Facebook exploit posted where it was possible to track your friends. All this was possible mainly because lacking real types the only stable interface becomes string and everything becomes stringly typed. Static types are not only strings and numbers and static types are about something more than typed variables. Too many times have I run into situation when I call some API in dynamic language and have absolutely no idea what can I do with the thing being returned. In dynamic language I have to either read the docs (hoping they are good) or introspect in a REPL, IDE won't help. And In Python world, the wrapper library method I'm calling forwards kwargs to some underlying library and I have absolutely no idea what can I pass without getting familiar with the underlying library. Dynamically typed abstractions are very prone to leaking.
- _pmf_ 10y ago> We need languages that mix compile/parse time (static) and run time (dynamic) types, to mix what fits best to each situation. C# has the dynamic keyword (not to be confused with type inference via the var keyword), which basically allows to break out to dynamic typing. I find this to be significantly saner than the other way around.
- Roboprog 10y agoSomebody, somewhere, is waiting until runtime to check for a property, and they will burn in Hell for their sins! Even if they don't do it very often, even if the IDE infers properties most of the time anyway, even if there's less code to have to be refactored, and most of the refactoring that could be automated is still automated. I would rather use types most of the time for clarity and to help the compiler / editor help me, just not always. :-)
- leshow 10y agoI think there's a false distinction between static/dynamic types. As if all static type checkers offered the same benefit. IMO writing a type annotation, or knowing whether a type is an int or a string, is the of minimal help in pushing errors into the type system. A good type system you don't even have to write the type of things, it's inferred. Better 'statically typed' languages allow you to push more errors into the type system and give you tools for creating stronger abstractions.