How do languages handle side effects of compound operators? - javascript

Assume such situation:
int a = (--t)*(t-2);
int b = (t/=a)+t;
In C and C++ this is undefined behaviour, as described here: Undefined behavior and sequence points
However, how does this situation look in:
JavaScript,
Java,
PHP...
C#
well, any other language which has compound operators?
I'm bugfixing a Javascript -> C++ port right now in which this got unnoticed in many places. I'd like to know how other languages generally handle this... Leaving the order undefined is somehow specific to C and C++, isn't it?

According to the ECMA Script specification, which I believe javascript is supposed to conform to, in multiplication and addition statements, it evaluates the left hand side before evaluating the right hand side. (see 11.5 and 11.6). I think this means that the code should be equivalent to
t = t - 1;
int a = t * (t - 2);
t = t / a;
int b = t + t;
However, you should not always trust the specification to be the same as the implementation!
Your best bet in confusing cases like this is to experiment with various inputs to the ambiguous lines of code in the original operating environment, and try to determine what it is doing. Make sure to test cases that can confirm a hypothesis, and also test cases that can falsify it.
Edit: Apparently most JavaScript implements the 3rd edition of ECMAScript, so I changed the link to that specification instead.

Practically speaking, if you have to ask or look up the rules for an expression, you shouldn't be using that expression in your code. Someone else will come back two years from now and get it wrong, then rewrite it and break the code.
If this was intended as a strictly theoretical question I unfortunately can't offer details regarding those other languages.

For javascript the following article should help.
This article clearly states whether a particular combination of
a OP b OP c goes from left-to-right and in which order.
I'm don't know about the other languages.

However, how does this situation look in: JS, Java, PHP, C#...
To be perfectly candid, int a = (--t)*(t-2); int b = (t/=a)+t; looks like crap.
It's nice to have fancy code that can be all pretty and elitist, but there's absolutely no need for it. The solution for every language when confronted with code like this is to add a couple more semi-colons (unless you're dealing with python):
--t;
int a = t * (t-2);
t /= a;
int b = t + t;
-or-
int b = t * 2;
-or-
int b = t << 1;
//whichever method you prefer
If a different order of operations is desired, the adjust the lines accordingly. If you're trying to fix old buggy code, fix the code, don't just re-implement someone else's spaghetti.
Edit to add:
I realized I never specifically answered the original question:
How do languages handle side effects of compound operators?
Poorly.

Related

When does it become more practical to use a variable rather than resolve an equation in terms of efficiency

I was wondering which option would be faster for a program I need to optimize (example given below).
Would it be more efficient to store a variable as the answer to an equation, or resolve the equation each time the problem is requested?
Example A
function(a,b){
return [a+b, //a+b is representing a more complicated math problem
a+b+1,
a+b+2]
}
or
Example B
function(a,b){
var x = a+b
return [x,x+1,x+2]
}
I know that it would not make much of a difference here, but in a larger project, I would really like to use the most efficient route.
I do agree with the comments on this question. I would write this answer as an opinion rather than a hard and a fast rule.
I feel this is more important in terms of readability and maintainability of codebase in log run. It's one of the basic principles of development to write DRY code, which not only helps us maintain the code but in turn end up optimising it as well.
To answer your question - I feel you should do it whenever you see a chance in a code which you are planning to push to production. However, if its more of a POC I'll leave that to you to decide.
Example C should be a tiny bit faster as less parsing, and less variables :
function(a, b) {
return [a = a + b, a + 1, a + 2]
}
But Example B is more readable

Sorting Special Characters in Javascript (Æ)

I'm trying to sort an array of objects based on the objects' name property. Some of the names start with 'Æ', and I'd like for them to be sorted as though they were 'Ae'. My current solution is the following:
myArray.sort(function(a, b) {
var aName = a.name.replace(/Æ/gi, 'Ae'),
bName = b.name.replace(/Æ/gi, 'Ae');
return aName.localeCompare(bName);
});
I feel like there should be a better way of handling this without having to manually replace each and every special character. Is this possible?
I'm doing this in Node.js if it makes any difference.
There is no simpler way. Unfortunately, even the way described in the question is too simple, at least if portability is of any concern.
The localeCompare method is by definition implementation-dependent, and it usually depends on the UI language of the underlying operating system, though it may also differ between browsers (or other JavaScript implementations) in the same computer. It can be hard to find any documentation on it, so even if you aim at writing non-portable code, you might need to do a lot of testing to see which collation order is applied. Cf. to Sorting strings is much harder than you thought!
So to have a controlled and portable comparison, you need to code it yourself, unless you are lucky enough to find someone else’s code that happens to suit your needs. On the positive side, the case conversion methods are one of the few parts of JavaScript that are localization-ready: they apply Unicode case mapping rules, so e.g. 'æ'.toUpperCase() yields Æ in any implementation.
In general, sorting strings requires a complicated function that applies specific sorting rules as defined for a language or by some other rules, such as the Pan-European sorting rules (intended for multilingual content). But if we can limit ourselves to sorting rules that deal with just a handful of letters in addition to Ascii, we can use code like the following simplified sorting for German (extract from by book Going Global with JavaScript and Globalize.js):
String.prototype.removeUmlauts = function () {
return this.replace(/Ä/g,'A').replace(/Ö/g,'O').replace(/Ü/g,'U');
};
function alphabetic(str1, str2) {
var a = str1.toUpperCase().removeUmlauts();
var b = str2.toUpperCase().removeUmlauts();
return a < b ? -1 : a > b ? 1 : 0;
}
You could adds other mappings, like replace(/Æ/gi, 'Ae'), to this, after analyzing the characters that may appear and deciding how to deal with them. Removing diacritic marks (e.g. mapping É to E) is simplistic but often good enough, and surely better than leaving it to implementations to decide whether É is somewhere after Z. And at least you would get consistent results across implementations, and you would see what things go wrong and need fixing, instead of waiting for other users complain that your code sorts all wrong (in their environment).

Why is there a need for javascript coding conventions?

Suppose I have to write a javascript function:
function(){
var a=1;
var sum=1;
for(var i=0;i<6;i++){
sum=sum+a+1;
}
console.log(sum);
}
Someone recommended me to write this function like this:
function () {
var a = 1;
var sum = 1;
for (var i = 0; i < 6; i++) {
var sum = sum + a +1;
}
console.log(sum);
}
With more blank space, I know this rule, but I don't how it works, or what can I benefit from it?
It is a matter of opinion what good style is, but in a general sense picking some style and consistently following it throughout your code makes it easier to read (both for other people and for you when you come back to it later).
In my experience most people find code easier to read with the extra spaces as shown in your second example.
I don't like putting a space between function and (). Or, where there is a function name I don't put a space between the name and the parentheses: function someName().
Note also that with modern code editors that have syntax highlighting (like Stack Overflow does) it is much easier than it used to be to read code that doesn't have spaces. Compare the following two:
for(var i=0;i<6;i++)
for(var i=0;i<6;i++)
Reading and editing the latter, all in black and white, really annoys me, but I don't mind the coloured version anywhere near as much. I still prefer it with the extra spaces though.
I'd make some other changes in your function:
function() {
var a = 1,
sum = 1,
i;
for(i = 0; i < 6; i++){
sum += a + 1;
}
console.log(sum);
}
The benefit of coding style is enhanced readability. It does not really matter what style you decide to stick to, as long as you DO stick with a uniform style, and can agree with your coworkers on its readability, which is not always easy.
These coding conventions are for humans, they increase readability. Suppose I have written an expression like this:
x=(a*b/2)+m-n+c*(d/e);
It looks clumsy and difficult to read. It would have been easier to understand if we had used spaces around operators like this:
x = (a * b / 2) + m - n + c * (d / e);
Again using blank line increases readability by denoting sections. For example:
function foo() {
var a;
var b;
// a blank line here to specify the end of variable declarations
if (some_cond) {
} else if (another_cond) {
}
// another blank line to specify end of some logic
//more codes here;
}
If you do not follow these guidelines and all team members do not agree in some convention then it will be very difficult to maintain a big project for long time.
Finally note that, the conventions are not for compilers, they are for humans. That's why it is called coding guidelines, not language syntax.
May be you should read more about javascript closure, and you can follow "Google Javascript Style Guide".
Following some uniform style guidelines when coding makes code easier to read and helps you writing beautiful code, and others understanding (and loving!) your code.
For sure there are loads of resources on the net (just by googling for a while you get some javascript guides or guidelines), but this one is quite easy, simple and complete:
http://javascript.crockford.com/code.html
It's not a rule. It's just coding convention style. You don't need to follow if you don't want. But this style can make your code more readable, easier to maintain, and cleaner. To me, I prefer to have space rather than narrow letters. Again, it's not a rule.
Coding style is always very personal; one person likes condensed code so that they can see as much as possible on one screen, another needs the opening and closing braces on a separate line, etc.
When only coding for yourself, you should choose whatever is best for you. But when you start working in teams and others have to maintain your code and visa versa, it becomes important to agree on one coding style ... and this can be hard.
I've sat in coding style discussions and they're very uncomfortable, because you're giving up some of your personal preferences albeit for the greater good. After a brief moment of discomfort you will get used to it ;-)
The second version isn't equivalent to the first, as it declares an inner 'sum' variable, unless Javascript doesn't do what it says on the tin with that.
The extra blank lines don't contribute anything much IMHO, but I probably wouldn't die in a ditch about them. However an equally valid concern is download speed, which is made worse by the suggestion.

How to convert a string equation to a numeric value with Javascript

Basically, I have a user input field where a user can enter a number. They would like to also be able to enter equations in the input field as well.
Something like "874.45 * 0.825 + 4000" and have that converted to its real numeric value.
All the solutions I found point to the dreaded eval() method. Especially with this being a user entered field, I'm concerned about just running eval("874.45 * 0.825 + 4000") and hoping to get a number out the back end.
I suppose I could do a web service call back to the server (ASP.NET), but I'm afraid a slight delay will create some frustration from the user.
Does anyone know of either a good technique or existing libraries?
What you really need here is an "expression parser", because you're trying to allow users to express their values using a small domain-specific language.
The basic mechanics work like this:
Tokenize their expression into operators and operands.
Based on the order of operations (e.g, where multiplication is evaluated with higher priority than addition), push the operators and operands onto a stack.
Pop the operands from the stack and push intermediate results back onto the stack. Repeat until the stack is empty.
I've done this a gazillion times for different "little languages" throughout my projects. But never in javascript. So I can't directly recommend a suitable parsing library.
But a quick googling reveals "PEG.js". Check it out here:
http://pegjs.majda.cz/
All of the examples in their documentation are for exactly the kind of "expression parser" you're trying to build.
Simply multiply it by 1 and it will force javascript to treat it as an integer from then on.
Eg
int = '2343.34' * 1;
int = input * 1;
And what is so wrong about the eval in this case?
As for me it perfectly fits in your task. If you want to shield its execution context then you can define function like:
function calc(str) {
var window = null, self = null, document = null;
// other globals like: $ = null, jQuery = null, etc.
try { return eval(str); } catch(e) {...}
}
and use it where you need to interpret the string. Simple and effective.
I think eval can pose a lesser security risk if you parse the resulting string and validate its content to be only digits and operators and execute the evaluation by faking the outer scope variables like document etc as 'var document = null'.

Good resources for extreme minified JavaScript (js1k-style)

As I'm sure most of the JavaScripters out there are aware, there's a new, Christmas-themed js1k. I'm planning on entering this time, but I have no experience producing such minified code. Does anyone know any good resources for this kind of thing?
Google Closure Compiler is a good javascript minifier.
There is a good online tool for quick use, or you can download the tool and run it as part of a web site build process.
Edit: Added a non-exhaustive list of tricks that you can use to minify JavaScript extremely, before using a minifier:
Shorten long variable names
Use shortened references to built in variables like d=document;w=window.
Set Interval
The setInterval function can take either a function or a string. Pass in a string to reduce the number of characters used: setInterval('a--;b++',10). Note that passing in a string forces an eval invokation so it will be slower than passing in a function.
Reduce Mathematical Calculations
Example a=b+b+b can be reduced to a=3*b.
Use Scientific Notation
10000 can be expressed in scientific notation as 1E4 saving 2 bytes.
Drop leading Zeroes
0.2 = .2 saves a byte
Ternery Operator
if (a > b) {
result = x;
}
else {
result = y;
}
can be expressed as result=a>b?x:y
Drop Braces
Braces are only required for blocks of more than one statement.
Operator Precedence
Rely on operator precedence rather than adding unneeded brackets which aid code readability.
Shorten Variable Assignment
Rather than function x(){a=1,b=2;...}() pass values into the function, function x(a,b){...}(1,2)
Think outside the box
Don't automatically reach for standard ways of doing things. Rather than using d.getElementById('p') to get a reference to a DOM element, could you use b.children[4] where d=document;b=body.
Original source for above list of tricks:
http://thingsinjars.com/post/293/the-quest-for-extreme-javascript-minification/
Spolto is right.
Any code minifier won't do the trick alone. You need to first optimize your code and then make some dirty manual tweaks.
In addition to Spolto's list of tricks I want to encourage the use of logical operators instead of the classical if else syntax. ex:
The following code
if(condition){
exp1;
}else{
exp2;
}
is somewhat equivalent to
condition&&exp1||exp2;
Another thing to consider might be multiple variable declaration :
var a = 1;var b = 2;var c = 1;
can be rewritten as :
var a=c=1,b=2;
Spolto is also right about the braces. You should drop them. But in addition, you should know that they can be dropped even for blocks of more expressions by writing the expressions delimited by a comma(with a leading ; of course) :
if(condition){
exp1;
exp2;
exp3;
}else{
exp4;
exp5;
}
Can be rewritten as :
if(condition)exp1,exp2,exp3;
else exp4,exp5;
Although it's not much (it saves you only 1 character/block for those who are counting), it might come in handy. (By the way, the latest Google Closure Compiler does this trick too).
Another trick worth mentioning is the controversial with functionality.
If you care more about the size, then you should use this because it might reduce code size.
For example, let's consider this object method:
object.method=function(){
this.a=this.b;
this.c++;
this.d(this.e);
}
This can be rewritten as :
object.method=function(){
with(this){
a=b;
c++;
d(e);
}
}
which is in most cases signifficantly smaller.
Something that most code packers & minifiers do not do is replacing large repeating tokens in the code with smaller ones. This is a nasty hack that also requires the use of eval, but since we're in it for the space, I don't think that should be a problem. Let's say you have this code :
a=function(){/*code here*/};
b=function(){/*code here*/};
c=function(){/*code here*/};
/*...*/
z=function(){/*code here*/};
This code has many "function" keywords repeating. What if you could replace them with a single(unused) character and then evaluate the code?
Here's how I would do it :
eval('a=F(){/*codehere*/};b=F(){/*codehere*/};c=F(){/*codehere*/};/*...*/z=F(){/*codehere*/};'.replace(/function/g,'F'));
Of course the replaced token(s) can be anything since our code is reduced to an evaluated string (ex: we could've replaced =function(){ with F, thus saving even more characters).
Note that this technique must be used with caution, because you can easily screw up your code with multiple text replacements; moreover, you should use it only in cases where it helps (ex: if you only have 4 function tokens, replacing them with a smaller token and then evaluating the code might actually increase the code length :
var a = "eval(''.replace(/function/g,'F'))".length,
b = ('function'.length-'F'.length)*4;
alert("you should" + (a<b?"":" NOT") + " use this technique!");
In the following link you'll find surprisingly good tricks to minify js code for this competition:
http://www.claudiocc.com/javascript-golfing/
One example: (extracted from section Short-circuit operators):
if (p) p=q; // before
p=p&&q; // after
if (!p) p=q; // before
p=p||q; // after
Or the more essoteric Canvas context hash trick:
// before
a.beginPath
a.fillRect
a.lineTo
a.stroke
a.transform
a.arc
// after
for(Z in a)a[Z[0]+(Z[6]||Z[2])]=a[Z];
a.ba
a.fc
a.ln
a.sr
a.to
a.ac
And here is another resource link with amazingly good tricks: https://github.com/jed/140bytes/wiki/Byte-saving-techniques
First off all, just throwing your code into a minifier won't help you that much. You need to have the extreme small file size in mind when you write the code. So in part, you need to learn all the tricks yourself.
Also, when it comes to minifiers, UglifyJS is the new shooting star here, its output is smaller than GCC's and it's way faster too. And since it's written in pure JavaScript it should be trivial for you to find out what all the tricks are that it applies.
But in the end it all comes down to whether you can find an intelligent, small solution for something that's awsome.
Also:
Dean Edwards Packer
http://dean.edwards.name/packer/
Uglify JS
http://marijnhaverbeke.nl/uglifyjs
A friend wrote jscrush packer for js1k.
Keep in mind to keep as much code self-similar as possible.
My workflow for extreme packing is: closure (pretty print) -> hand optimizations, function similarity, other code similarity -> closure (whitespace only) -> jscrush.
This packs away about 25% of the data.
There's also packify, but I haven't tested that myself.
This is the only online version of #cowboy's packer script:
http://iwantaneff.in/packer/
Very handy for packing / minifying JS

Categories

Resources