One trade-off I think about for static typing vs dynamic is the degree of testing. With dynamically typed languages, you are buying into testing in a big way to keep quality high. With statically typed languages, you are paying an up-front cost (type annotations) to let the compiler automatically test for a specific class of issues. I think the primary failure of static typing is that developers tend to assume (or hope) that type checking will catch more than it does. And tests are neglected which really should be written. But in dynamic languages, you are conditioned to write tests although some type-related issues might slip through.
My personal preference is static type checking in a functional language with type inference and an expressive type system. Type inference makes the language feel more dynamic since you don't have to annotate types in many cases. And an expressive type system can allow you to make types that cannot be used incorrectly. My choices which fit this bill are F# and Elm.
Sometimes you hear people say "most error are not type errors". The thing is: yes they are. It's just that most people are not used to thinking of those errors as type errors.
In LISP you can use macros and simple parses to check for certain types of code at compile time and you can check the callstack to make sure properties keep, sometimes it seems easier to grok that than complex type systems. I have to say that Haskell is pretty nice, but it sometimes you could build inflexible code. Like its hard to know before hand if you want a pure function or a functor or a maybed function and if you get it wrong you could end up rewriting huge amounts of your code although when run it will most likely work at the first time.
Yep, you make a good point regarding testing. While static typing will pick up problems, it's not going to save you from the infamous Null Pointer Exception!
Type inference with static types definitely feels like you get the best of both worlds. While not exactly in the functional realm, it's one of the reasons I've been looking at Kotlin for future projects.
That's another good thing about F# and Elm. Null is not an allowable value***. Instead you use Option/Maybe when a value may not exist. That also explicitly forces you to deal with the non-existent case. You can't forget, because it won't compile.
*** F# is on .NET. Most .NET libraries are imperative. Especially at the boundary of applications (deserialization, loading from DB) you still have to deal with nulls. But your core code can be free of them.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
One trade-off I think about for static typing vs dynamic is the degree of testing. With dynamically typed languages, you are buying into testing in a big way to keep quality high. With statically typed languages, you are paying an up-front cost (type annotations) to let the compiler automatically test for a specific class of issues. I think the primary failure of static typing is that developers tend to assume (or hope) that type checking will catch more than it does. And tests are neglected which really should be written. But in dynamic languages, you are conditioned to write tests although some type-related issues might slip through.
My personal preference is static type checking in a functional language with type inference and an expressive type system. Type inference makes the language feel more dynamic since you don't have to annotate types in many cases. And an expressive type system can allow you to make types that cannot be used incorrectly. My choices which fit this bill are F# and Elm.
Agreed. I'd like to just add one thing:
Sometimes you hear people say "most error are not type errors". The thing is: yes they are. It's just that most people are not used to thinking of those errors as type errors.
Type systems can address all sorts of problems. From What To Know Before Debating Type Systems:
In LISP you can use macros and simple parses to check for certain types of code at compile time and you can check the callstack to make sure properties keep, sometimes it seems easier to grok that than complex type systems. I have to say that Haskell is pretty nice, but it sometimes you could build inflexible code. Like its hard to know before hand if you want a pure function or a functor or a maybed function and if you get it wrong you could end up rewriting huge amounts of your code although when run it will most likely work at the first time.
Yep, you make a good point regarding testing. While static typing will pick up problems, it's not going to save you from the infamous Null Pointer Exception!
Type inference with static types definitely feels like you get the best of both worlds. While not exactly in the functional realm, it's one of the reasons I've been looking at Kotlin for future projects.
That's another good thing about F# and Elm. Null is not an allowable value***. Instead you use Option/Maybe when a value may not exist. That also explicitly forces you to deal with the non-existent case. You can't forget, because it won't compile.
*** F# is on .NET. Most .NET libraries are imperative. Especially at the boundary of applications (deserialization, loading from DB) you still have to deal with nulls. But your core code can be free of them.