Semicolons are just an example, and a fairly minor one. A bigger pet peeve of mine is C-style type declarations. If I create a binding for X and initialize it to 1, the compiler should be able to figure out that X is an integer without my having to tell it.
In fact, all type declarations should be optional, with run-time dynamic typing as a fallback when type inferencing fails. Type "errors" should always be warnings. There should be no dichotomy between "statically typed" and "dynamically typed" languages. There should be a smooth transition between programs with little or no compile-time type information and programs with a lot of compile-time type information, and the compiler should do something reasonable in all cases.
> with run-time dynamic typing as a fallback when type inferencing fails.
I've seen the code that comes out of this, and how difficult it can be to refactor. I definitely prefer strict typing in every situation that it can't be inferred, if you're going to have a language with static types.
It works the other way too. Ive seen plenty of code with strict typing that could have its cognitive load reduced greatly by dynamic typing. A far bigger problem is hidden sideffects and static typing does nothing to fix that
I work in dynamically typed languages a lot, so I don't have many opportunities to feel the way you do. Could you give an example where moving from static to dynamic would reduce cognitive load?
For the opposite example, here's where my preference comes from: I'm editing a function. There's an argument called order, and most likely it's either an instance of some Order class, which has some attribute I need, or it's an integer representing the I'd of such an order, or it's null. I'm hoping to access that attribute, so I have to figure out the type of order.
In a dynamically typed language, I'll have to look at the caller of my function (goes on my mental stack), see where it gets it order from, potentially go to the caller of that function (goes on my mental stack), etc until I hopefully see where order is instantiated and figure out it's type, so I can take the call sites off of my mind, and just keep the type of order in my mental stack.
But actually, this is wrong, because my function is called by way more functions than the ones I examined. So really, all I know now is that _sometimes_ order is of type Order. To be sure, I have to go to _all_ callers of my function, and all their callers, etc. This grows exponentially.
But let's say I manage, and I find the type of order, and keep it in my mind. Then I need to repeat the same process for other arguments I want to use, which is now harder because I'm keeping the type of order on my mental stack. If I manage to succeed, I can go and edit the function, keeping the types of whatever variables I'm using in my head. I pray that I didn't miss a call site, and that the logic is not too complicated, because my mental stack is occupied with remembering types.
Here's how to do this in a statically typed language: read the type signature. Done.
just think of any obvious function where type is obvious. surely writing typing information in those cases is reddundant to the extent that it wouldnt even help with optimisation. but think about something like this:
bool function1(x y z):
bool function2(x y z)
immagine function2 besides returning true/false mutates x in some major way. this is a far bigger and more common problem than typing. a dynamic language with capabilities of runtime debugging is far better equiped to inspect code like this
also i am not saying that typing is worse than no type information. im saying that typing should be optional as far as the compiler is concerned and typing information should be like documentation that is useful to the compiler. common lisp can be an example of a language that is both dynamic and strongly typed (see SBCL) to the extent that you can implement a statically typed language (ala ML) in it
Sometimes when people decry lack of typing, it turns out that it's actually a lack of the ability to define a named structure type with named fields, rather than faking one out with an ad hoc hash table representing a collection of properties.
> a dynamic language with capabilities of runtime debugging is far better equiped to inspect code like this
Have you used a robust, modern debugger, like IntelliJ or Visual Studio? You can do a whole heck of a lot of very, very robust debugging. You can watch, run commands, run sets of commands, inspect anything in great detail, write new code in the watcher, and so on.
I use them and compared to what I can do with my Common Lisp programs on a far less computationally intensive IDE it is many times poorer. An even more interesting aspect because it is entirely people dependent, is that I find code in an average common lisp project far more readable and understandable than what is regarded as a very good java aplication
to further expand on this, in common lisp i can build up my program dynamically in the repl, allowing me to progrssively make more readable and understandable code after making it do what i want, and then do the final tidying up with type i formation amd necessary documantation when i compile it. i fail to see how any i can program with less cognitive load in any other language, especially strictly static ones
there are "repls" and repls. even java has a "repl". forget about dynamic/static dychtomy, im yet to see a non-lisp repl. one which provides a true interactive experience with your running program
and even though static languages can have "repls" as an afterthought (eg GHCi), rest assured that their static typing property is a completely unnecessary cognitive load (at least cognitive but very likely a performance one too) to their functioning
Sure, but often != always. And if your language forbids type inference then you are burdened with the cognitive load of worrying about types every single time whether there is a good reason in that instance or not.
In fact, all type declarations should be optional, with run-time dynamic typing as a fallback when type inferencing fails. Type "errors" should always be warnings. There should be no dichotomy between "statically typed" and "dynamically typed" languages. There should be a smooth transition between programs with little or no compile-time type information and programs with a lot of compile-time type information, and the compiler should do something reasonable in all cases.