DEV Community

Discussion on: Is JavaScript the most confusing programming language?

Collapse
 
danielkun profile image
Daniel Albuschat

Having worked in many languages, I can confirm that JavaScript was the most confusing one for me. I think what makes JavaScript hard is that it uses concepts that look very similar to common patterns on the surface, but work totally different underneath. Favorite examples are this and the prototype-chain. I'd make a bet that a great majority of devs that do JavaScript only occasionally get their code working by accident only, and not because they understand how and when their this is bound.
This is more difficult to master than learning new concepts from scratch, because you have to unlearn things that you might have learned from other languages before.

Collapse
 
waterlink profile image
Alex Fedorov

good developers get their code working intentionally by using tests ;)

Collapse
 
combinatorylogic profile image
combinatorylogic

Good languages do not force you to write tons of boilerplate tautological tests to merely get things working at all. The best languages do not even need any tests whatsoever.

Thread Thread
 
waterlink profile image
Alex Fedorov • Edited

Sorry, there is no need to write any "boilerplate tautological" tests in any programming language.

Only write tests for behavior that the business and user needs. No real need to write tests for mistyped inputs at the unit level, because at the integration and e2e level you’re going to prove that nothing in your application is passing these mistyped inputs, only by writing tests that matter to business and user.

Thread Thread
 
waterlink profile image
Alex Fedorov • Edited

The best languages do not even need any tests whatsoever.

Just read this. Sorry, that is just not professional.

Tests are the best way (known today) to make sure that the quality of the software is high.

Any of the advanced type-contract-self-proof things (like in Idris) will still require the developer to write tests at the compile-time level to ensure that the contract doesn't have any mistakes in it. Essentially, in these languages the type definition becomes a programming language of its own, that can have bugs, and need tests.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

In theory - yes, of course.

In practice - nope, most of the tests for the primitive dynamically typed labguages are nothing but a poor men substitute for a type system.

Thread Thread
 
waterlink profile image
Alex Fedorov • Edited

Excuse me, I’ve worked with various JS-based projects on both front-end and back-end in different teams. We all did TDD and ATDD, and we’ve never written these "type-system-substitute" tests.

Instead, we’ve tested only behavior from the user perspective.

In these codebases, I’m pretty sure, there are few functions here and there, that would behave incorrectly if you were to call them with e.g. a number instead of a string argument. But that is not a problem because nobody does that, because there are higher-level acceptance tests (e2e + integration) that ensure that behavior is consistent.

So the "in theory, but in practice" argument kind of doesn’t stand. At least not in my view of the world and experience.

Thread Thread
 
danielkun profile image
Daniel Albuschat

I'm sure that tests have little to do with static or dynamic typing, or statically proven languages. Every corner case or circumstance that your function can be called in should be tested. It is true, however, that in dynamic languages there are more circumstances under which you function can be called. I don't find it a significant difference, though.

As of statically proven languages, the only difference is that your tests don't need to run - but they need to exist.

Having said that, after working with C++ for 15+ years, I now value dynamic typing for it will not break your whole build if some detail does not work correctly or is not yet implemented - especially the last part is valuable, IMHO. You can write the code that calls your function before having written it at all, and still execute the rest of your tests. Feels good for gradually turning tests green.

Thread Thread
 
danielkun profile image
Daniel Albuschat

(The last part of my comment is still a detail and personal preference, though!!)

Thread Thread
 
waterlink profile image
Alex Fedorov • Edited

Every corner case or circumstance that your function can be called in should be tested

I agree with this ONLY if we’re talking about a library that is exposed to any user out there potentially.

If we’re talking about the application code where the team has full ownership of the full stack (as it should be), then there is no need to be testing the function how you do not expect to be called (but it could be potentially).

That’s because you’re not writing a function in isolation, it is part of one or multiple code paths of a bigger size. Potentially several layers of architecture, and if e.g. your business domain code is calling this function only with strings (and it would be absolutely non-reasonable to call it with something else), why should you spend your time and time of everyone else in the future (when running test suite) on testing what will happen if you pass a number (or anything else)?

When you have higher-level tests, that check what happens when multiple components and layers are integrated within various user/business acceptance scenarios, you’re going to confirm that function indeed is called properly at all occasions (implicitly).


Of course, if you don’t trust your team members to do the right thing, then you should work on that trust issue, find its root cause(s) and work through fixing it. Please, don’t fix people problems with technological complexity.

Thread Thread
 
danielkun profile image
Daniel Albuschat

You're totally right. The statement came out a bit too pedantic, and yes, I was thinking more of code used by a wider audience. Because, from my usage experience of libraries in dynamic languages, I've learned that it is very frustrating when you accidentally passed in the wrong type, just to get seemingly random error messages four calls down the stack. And that partly confirms @combinatorylogic 's statement "most of the tests for the primitive dynamically typed languages are nothing but a poor men substitute for a type system.", although, as I said, I don't think that the tests that do substitute a type system are too much of a burden.
Again, I'm talking about widely used code here, not your team's shared libraries where you can tap the original author on the shoulder to get help with it if it spills out gibberish error messages.

Thread Thread
 
combinatorylogic profile image
combinatorylogic

You're doing it the right way then, good! I'd always take integration tests vs. any amount of unit tests. The problem is with all the people who perceive weak typing as an invitation to write tons of pointless unit tests, I'm sure you've seen it happening a lot.