You can replace "javascript" with other languages here. Basically what I've found from reading is that python actively encourages the use of exceptions and a series of if tests to manage code. Often readability is cited as well as cleaner looking code when 'duck-typing'
However, often when working in javascript or some other languages, it seems that best practices suggest trying to 'code defensively' and cover as much as you can in if statements and return types in order to avoid using exceptions. The reason most often cited is because exceptions are a very expensive operation.
Here's an example:
https://stackoverflow.com/a/8987401/2668545
Does python face the same exceptions cost as javascript and the best
practices are such because there's more emphasis about
readability/debuggability than performance?
Does python have a different way of handling exceptions than javascript or other languages that don't recommend using exceptions?
Am I misinterpreting the advice?
Or is it something else?
My take on this would be that though Python is a dynamically typed language, it is strongly-typed at the same time, see the explanation here. This means that if something goes wrong deep down the call hierarchy (like trying to convert an empty string to an integer, division by zero, etc.), the interpreter raises an interrupt that bubbles up the call graph.
Javascript and many other interpreted languages tend to gloss such things over and continue silently computing (rubbish) as long as possible. Essentially, the programmer has to defend against Javascript itself.
It is thus consistent when a user-defined Python module behaves in the same way as the standard library modules and the interpreter itself: achieve the expected result or raise an exception.
The advantages are:
Improved readability: the expected sequence of actions is not mixed with error handling.
Extra polymorphism. It can be possible to pass any object as a function argument, and things will work out if the object has the properties/members used by the function. The programmer writing the function does not have to know in advance the exact type of the argument (dynamic typing). If something goes wrong, there will be a call trace to investigate. Defensive checks are likely to be too restrictive and not 100% bullet-proof at the same time.
The considerations of readability and extensibility are probably more important than the ones of performance.
Related
If I write by myself the code behind the layer of abstraction of a native method, instead of using that method (which will behind scenes do the same that I write manually), have a good impact on the app performance or speed?
There are (at least) three significant advantages of using a built-in function instead of implementing it yourself:
(1) Speed - built-in functions generally invoke lower-level code provided by the browser (not in Javascript), and said code often runs significantly faster than the same code would in Javascript. Polyfills are slower than native code.
(2) Readability - if another reader of your code sees ['foo', 'bar'].join(' '), they'll immediately know what it does, and how the join method works. On the other hand, if they see something like doJoin(['foo', 'bar'], ' '), where doJoin is your own implementation of the same method, they'll have to look up the doJoin method to be sure of what's happening there.
(3) Accuracy - what if you make a mistake while writing your implementation, but the mistake is not immediately obvious? That could be a problem. In contrast, the built-in methods almost never have bugs (and, when spotted, usually get fixed).
One could also argue that there's no point spending effort on a solved problem.
Yes, there is a difference in efficiency in some cases. There are some examples in the docs for the library fast.js. To summarize what they say, you don't have to handle all of the cases laid out in the spec so sometimes you can do some things faster that the built in implementations.
I wouldn't take this as a license to make your code harder to read/maintain/reuse based on premature optimization, but yes you may gain some speed with your own implementation of a native method depending on your use case.
With the flexibility of JavaScript, we can write code full of side-effects, or just purely functional.
I have been interested in functional JavaScript, and wanting to start a project in this paradigm. And a linter about that can surely help me gathering good practices. Is there any linter to enforce pure functional and side-effect free style?
Purity Analysis is equivalent to Solving the Halting Problem, so any kind of static analysis that can determine whether code is pure or impure is impossible in the general case. There will always be infinitely many programs for which it is undecidable whether or not they are pure; some of those programs will be pure, some impure.
Now, you deliberately used the term "linter" instead of static analyzer (although of course a linter is just a static analyzer), which seems to imply that you are fine with an approximate heuristic result. You can have a linter that will sometimes tell you that your code is pure, sometimes tell you that your code is impure, and most times tell you that it cannot decide whether your code is pure or impure. And you can have a whitelist of operations that are known to be pure (e.g. adding two Numbers using the + operator), and a blacklist of operations that are known to be impure (e.g. anything that can throw an exception, any sort of loops, if statements, Array.prototype.forEach) and do a heuristic scan for those.
But in the end, the results will be too unreliable to do anything serious with them.
I haven't used this myself but I found this plugin for ESLint: https://github.com/jfmengels/eslint-plugin-fp
You cannot use JS commpletely without side effects. Every DOM-access is a side effect, and we could have an argument wether the whole global namespace may also fall under that definition.
The best you can do is, stay reasonable. I'm splitting this logically into two groups:
the work horses (utilities): their purpose is to take some data and to process it somehow. These are (mostly) side effects free. mostly, because somethimes these functions need some state, like a counter or a cache, wich could be argued to be a side effect, but since this is isolated/enclosed into these functions I don't really care. like the functions that you pass to Array#map() or to a promises then(), and similar places.
and the management: these functions rarely do some data-processing on their own, they mostly orchestrate the data flow, from whereever it is created, to whatever processing(-utilities) it has to be run, up to where it ends, like modifying the DOM, or mutating an object.
var theOnesINeed = compose(...);
var theOtherOnesINeed = compose(...);
var intoADifferentFormat = function(value){ return ... }
function(event){
var a = someList.filter(theOnesINeed).map(intoADifferentFormat);
var b = someOtherList.filter(theOtherOnesINeed);
var rows = a.concat(b).map(wrap('<li>', '</li>'));
document.querySelector('#youYesYou').innerHTML = rows.join('\n');
}
so that all functions stay as short and simple as possible. And don't be afraid of descriptive names (not like these way to general ones :))
I'm building my first open-source JavaScript library as a node module, it's solving a very simple problem and thus it's a very simple module, specifically, it is a single prototype object.
To offer context, I'm from a purely web-tech background and only in the past year have I started to look into other languages, falling in love with statically typed, truly OOP and class-oriented languages and I'm beginning to see the breadth of pros and cons for the languages on either side of the camp.
As far as I understand, when constructing a class with class-oriented you should return nil to specify that construction has failed allowing a user to check with if(instance === nil) for it's success. Alternatively I've seen return 421 for example to provide an error code, I then also assume some also return string e.t.c. But importantly, I've seen that you shouldn't throw an exception.
Is this correct? Also what are the reasons for that? Is this also a problem with prototype-oriented languages or does javascript's dynamic nature make it acceptable?
This leads onto my next question, I've seen a lot of javascript libraries over the years, had a tinker and whatnot. I've found that it's rare to not only to build prototypes in an OOP-ish pattern but it's also rare to come across any frequently implemented type detection or type checking, many people are relying on the convenience of the dynamic typing to offer that productivity boost, but I'd like to mix up the pros and cons of each type system by starting with dynamically typed but also introduce a more stable architecture using some statically typed patterns and methodologies.
To get to the point, is it an acceptable (or even good?) practice to heavily type check javascript scripts? I would love to add serious type checking code to my prototypes constructor and methods but as it's an open-source project I'm worried how the community will approach it, would they want it to be more dynamically typed? I can only assume many people use dynamically typed languages for their... uhh.. dynamic typing, but its worth a ponder.
DISCLAIMER
I understand have seen that many people say javascript is "untyped" rather than "dynamically" typed, but using dynamic purely for its proliferation.
TLDR-Q1: Can I throw exceptions in constructor methods? What about in javascript prototypes? Why!? How should I handle it?
TLDR-Q2: Can I introduce heavy type checking and throw exceptions to give javascript scripts a poor mans static type? Do developers like this? Am I being ignorant and this a really common thing?
TLDR-Q1: Can I throw exceptions in constructor methods? What about in
javascript prototypes? Why!? How should I handle it?
Yes, you can throw exceptions in a constructor. If truly invalid arguments have been passed, then that is probably the cleanest way to do things.
I, myself, would not generally design an expected path of the code to throw an exception, but would instead reserve it for the type of error that probably signifies bad data or wrong usage by the programmer. Exceptions get logged nice and cleanly in the debug console and are one of the quickest ways to communicate to someone using your constructor that they've messed up as it will get logged and you can put a nice descriptive message in the error object when you throw and the developer gets a stack trace.
Returning null is not such a clean or helpful way and adds code the developer probably doesn't normally need to check for null all the time.
TLDR-Q2: Can I introduce heavy type checking and throw exceptions to
give javascript scripts a poor mans static type? Do developers like
this? Am I being ignorant and this a really common thing?
You can write Javascript type checking as much as you need. IMO, you should only do so when you're trying to determine if an argument passed in is valid or not. If you need a string and the developer passes in a number and a numeric string is a reasonable input for the function, then I don't see why you should not just use Javascript's string conversion automatically and let things go.
Javascript developers like type checking when it helps them identify a mistake they've made. Javascript developers don't like type checking when it's just being pedantic and an auto or explicit type-conversion would have worked just fine.
Also keep in mind that you should rarely insist that a passed object is a particular type of object (say using instanceof) because it should be perfectly valid to pass any object that works like the expected object. For example, a promise in Javascript can pretty much be any object that has the desired methods that follow the proper specification. It does not have to be one particular type of object class with one particular constructor.
Javascript isn't a strongly typed language and there really is no reason to try to make it behave like it is something that it isn't. Check types when that's required for the proper operation of your code, not because you're trying to make Javascript behave as strictly as Java. I wouldn't suggest adding type checking just because you think all languages should have type checking. If that's your line of thinking, then perhaps you should write in TypeScript or something like that that adds type specification to the language.
Edit Please answer if you have knowledge of node's inner workings.
I've been really interested lately in diving into c++ add-ons for node. I've read a lot of articles on the subject that basically state you should reduce chatter between c++ and node. I understand that as a principle. What I'm really looking for is the why.
Again, why is the interaction between a c++ add-on and javascript expensive in node.js?
I can't speak to any knowledge of the inner workings of Node, but really it would boil down to this: the less stuff your code does, the faster (less expensive) it will be. Interacting with the Node API from the add-on is doing more stuff than not interacting with the API. For (a contrived) example, consider the difference between adding two integers in C++:
int sum = a + b;
...and evaluating an add expression in the JavaScript engine, which would involve creating a function variable, wrapping any arguments to this function, invoking the function, and unwrapping the return value.
The required wrapping/unwrapping/value conversions for C++/JS communication itself is justification enough to try to minimize the number of interactions between the two layers. Keep in mind that the C++ type system and JS type system are really different, what with JS not having ints, strings being implemented differently, objects working differently, etc.
Many programmers say it is a bad practice to use the eval() function:
When is JavaScript's eval() not evil?
I'd like to take a moment to address the premise of your question - that eval() is "evil"...
Is this eval() dangerous?
Buggy evaled code can violate security properties just as easily as buggy source code...
Why not eval() JSON?
There are a number of ways that your security may be compromised...
Is there ever a good reason to use eval()?
Yes - when there is no other way to accomplish the given task with a reasonable level of clarity... This eliminates 99% of cases where eval is used...
Why is eval unsafe in javascript?
The danger of eval only rears its ugly head when you are serving a script written by alice to user bob for bob's browser to eval...
So why does it exist in the first place?
Because sometimes there is a need. All the same reasons for/against using eval in JavaScript can likely be shared with the use of reflection in Java, for example.
However, I agree with everything you quoted in your question. Many reasons for using it are ill-advised, and best done differently - but sometimes, there is still a need, or it is simply the "best choice" over other available alternatives. (I'd focus on the answers to Is there ever a good reason to use eval()? for additional reasons.)
+1 to your question for good research.
eval() exists because sometimes you want to give complete programmatic control of your application to code passed in at run time.
Languages without an eval() feature can definitely provide (a subset? all?) of this functionality by asking each programmer to essentially write their own eval() -- lex the input, parse the input, create new objects as necessary, run methods or functions on them via simple string comparisons or similar. In essence, duplicate the entire interpreter that already exists and is debugged and fast.
Eval is actually a powerful feature and there are some things that are impossible to do without it. For example:
Evaluate code received from a remote server. (Say you want to make a site that can be remotely controlled by sending JavaScript code to it?)
Evaluate user-written code. Without eval, you can't program, for example, an online editor/REPL.
Creating functions of arbitrary length dynamically (function.length is readonly, so the only way is using eval).
Loading a script and returning it's value. If your script is, for example, a self-calling function, and you want to evaluate it and get it's result (eg: my_result = get_script_result("foo.js")), the only way of programming the function get_script_result is by using eval inside it.
Re-creating a function in a different closure.
And anything else you'd want to do that involves creating code on the fly.
The reason it is considered "evil" is because it's classicaly used by novices to do things that the language can handle natively. For example, the code below:
age_of_erick = 34;
age_of_john = 21;
person = "erick";
eval("console.log('age_of_"+person+"')");
And the code below:
age = {erick:34, john:21};
person = "erick";
console.log(age["erick"]);
Both do the same thing, except one parses a string, generates code from it, compiles into machine code and then runs, while the other reads a value from a hash, which is a lot faster.
There's a research publication exacty on this topic:
The Eval That Men Do -- A Large-scale Study of the Use of Eval in JavaScript Applications
Mirror on Wayback Machine
It is to me the most comprehensive answer to this question to date.
Quote from the abstract:
We have recorded the behavior of 337 MB of strings given as
arguments to 550,358 calls to the eval function exercised in over
10,000 web sites.
Amongst other, they identified 9 categories of recurring eval:
JSON - A JSON string or variant.
JSONP - A padded JSON string.
Library -One or more function definitions.
Read - Read access to an
object’s property.
Assign - Assignment to a local variable or
object property.
Typeof - Type test expression.
Try - Trivial
try/catch block.
Call - Simple function/method call.
Empty -
Empty or blank string.
A snippet from the conclusion (which is too long to be quoted entierly):
[...] While many uses eval were legitimate, many were unnecessary and
could be replaced with equivalent and safer code. We started this work
with the hope that it would show that eval can be replaced by other
features. Unfortunately our data does not support this conclusion.[...]
A paper well worth reading.
The eval() feature is like scissors. You're an adult, it's your responsibility to not run with them.
I've seen the design philosophy of dynamic languages (like JavaScript) summarised as preferring to enable smart people to do clever things above trying to prevent stupid people from doing silly things. (Unfortunately I can't recall the original source or phrasing.)
If you're worried about introducing bugs with eval, you can use strict mode. It seems to prevent some of the problems with how the feature is designed. (That is, as a "magic" function allowed to clobber your namespace.)
Eval exists to simplify tasks in JavaScript. You can use it evaluate multiple statements. Instead of having to find another way you can use eval to do such things. Even though it is discouraged it has considerable power and use.