What is the javascript `_|_`? - javascript

I was looking through a solution to a problem in javascript, namely parsing a string into its constituent names, operators, and brackets, when I saw this expression:
return accept(")") ? _|_ : e;
What is that _|_? Is that using node's _ feature? I've looked for documentation but not found any.
When I try using it myself, this happens:
> 5
5
> true ? _|_ : 0
ReferenceError: _ is not defined
at eval:1:1
at eval
at n.<anonymous>
As a clarification, the variable _ was not defined anywhere in the code.
This was run on Node v8.1.3, but also works fine on chrome native browser JS.
Here is the code:
function tokenise(string) {
const tokens = string.match( /[a-z]+|\(|\)|[!#$%&*+\-\/<=>#^_.,;]+/gi ) || [];
const accept = s => s===tokens[0] && tokens.shift() ;
const unaccept = s => s!==tokens[0] && tokens.shift() ;
const singles = (e) => ( e = unaccept(")") ) ? [ e, ...brackets() ] : [] ;
const brackets = (e) => accept("(") ? ( e = brackets(), accept(")") || _|_ , [ e, ...brackets() ] ) : singles() ;
try { let e = brackets(); return accept(")") ? _|_ : e ; }
catch(_) { return null; }
}

_|_ has no special meaning in JavaScript, it's just a | (bitwise OR) expression with the identifier _ on both sides of it.
That code checks the result of calling accept and, if it's truthy, returns the result of the | operation; if not it returns the value of e.
Is that using node's _ feature?
_ isn't special in Node code. In the REPL (only), it's a variable that receives the result of the most recently evaluated expression; details here.
As a clarification, the variable _ was not defined anywhere in the code.
That means that if accept(")") returns a truthy value, the code will throw a ReferenceError because _ is an undeclared identifier. If that's what the author intended, there's no need for the | operator at all, but in a now-deleted answer, georg pointed out that they may have used _|_ as an attempt to express the mathematical concept of bottom ("a computation which never completes successfully"), the symbol for which is ⊥. In any case, the author seems to use it to force an exception in an expression context (since throw is a statement; there's talk of possibly allowing it in expression contexts at some point, though).

It take a variable _ and uses a bitwise OR | with itself.
As result, you get a 32 bit integer number.

In addition to what has already been explained here in details, that your code is quite regular JavaScript, with nothing special about it...
I've come across similar code in more than one programming language when the syntax verbosity was used to generate supposedly funny expressions that resemble Text Art, aka ASCII Art, ones that while make the code look weird, are also 100% valid code.
Your code example reminds one of those stupid jokes, just like when someone introduces a function with a paragraph-long name.

Related

Referential transparency in functional programming

I am new to JS and was learning functional programming and came across the term "referential transparency". Also, I found this statement "Referential transparency says it's safe to replace a pure function with its value". Does it mean that the use of RT makes it easy for JIT compiler to replace function with its return value as long as function gets hot? Is that true?
Here's an example:
This is a pure function: it will always return the same output for the same input
const even = x => x % 2 === 0;
And let's create isTenEven() which will check wether 10 is an even number or not:
const isTenEven = () => even(10);
Since we're guaranteed that even(10) === true will always be true then we can indeed replace a function call with a value:
const isTenEven = () => true;
And your program would still work.™
However you wouldn't be able to do so if even wasn't pure!
Here's a silly example: once per month 10 won't be an even number anymore:
const even = x => (new Date()).getDate() === 15 ? false : x % 2 === 0;
Perhaps your program is excepting isTenEven() to return either true or false, so forcing it to always assume that it will return true could lead to unexpected consequences.
Of course in this particular case I'm not sure what those consequences would be but you never know... which is exactly the point.
Yes, that is exactly an advantage of RT. The compiler can not only inline a function but replace its invocations with the corresponding return value, that is it can eliminate common sub-expressions and rewrite code according to specific rules like you can rewrite formulas in math. This way of reasoning about a program is called equational reasoning and is also very helpful for the programmer.
But RT allows other optimization techniques as well, like lazy evaluation. If you want to automatically delay the evaluation of an arbitrary expression up to the point where its result is actually needed, you need the guarantee that this expression yields the same result no matter when you actually evaluate it. RT gives this guarantee.

Odd behaviour of comparison of object literals

I have searched but could not find logic behind following in JavaScript.
When I type in the Chrome console:
{} == null
it returns
Uncaught SyntaxError: Unexpected token ==
But
{} == {}
and
{} == function(){}
returns false
Why?
I assume you understand why {} == null throws SyntaxError. Long story short it is because { in the begining starting a block statement not an object literal. You could check the answer here
As of why {} == {} this works.
If you check chromium code that evaluates expressions in console. You could find the following (code)
if (/^\s*\{/.test(text) && /\}\s*$/.test(text))
text = '(' + text + ')';
executionContext.evaluate(text, "console", !!useCommandLineAPI, false, false, true, printResult);
This code wraps {} == {} code with parentheses making it a valid expression ({} == {}) comparing two empty object literals. Which evaluates to false because objects are compared by reference.
Node repl has the same behaviour src
if (/^\s*\{/.test(code) && /\}\s*$/.test(code)) {
// It's confusing for `{ a : 1 }` to be interpreted as a block
// statement rather than an object literal. So, we first try
// to wrap it in parentheses, so that it will be interpreted as
// an expression.
code = `(${code.trim()})\n`;
wrappedCmd = true;
}
You can find this in the specs under Statement (art. 12)
12 - Statement
Statement :
Block.
VariableStatement
EmptyStatement
ExpressionStatement
.
.
.
The first applicable rules are either Block or Expression Statement. So we need to look at 12.4.
In 12.4 the specs clearly state that an expression statement cannot start with a {.
though i haven’t yet found what makes example 2 an expression, maybe it’s implementation specific
12.4 Expression Statement
Syntax
ExpressionStatement :
[lookahead ∉ {{, function}] Expression ;
NOTE An ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration.
Semantics
The production ExpressionStatement : [lookahead ∉ {{, function}]Expression; is evaluated as follows:
Let exprRef be the result of evaluating Expression.
Return (normal, GetValue(exprRef), empty).
I would say this is a parsing issue, rather than a logic issue per se.
In Chrome I get the observed behavior.
In IE I get syntax errors whenever I put {} (or, it seems, any object literal) on the LHS of the ==.
In both browsers, putting () around the expression fixed things. Or first assigning the object to a variable
var x = {}
x == null
I would say it seems to me like a bug in the parsing. Whether that is true in an academic sense would take digging through specs and grammars; the practical answer is, there are simple enough work-arounds that the best bet is to not do that.
It’s because JavaScript sucks
The reason it doesn’t work is because
JavaScript takes the type the comparison is taking from the first object.
For instance
3+”1” = 4
But
“3”+1 = 31
The first example does the operation as a number because the first object is a number
The second example sees a string as the first object and treats the operation as concatenation of a string.
For your example
{} is an object but null can’t be converted to an object
It works the other way because
{} can be represented as a null object.

How do I test if a JS variable does equal either of two values?

Is there a short way to test if a variable is equal to two string, in plain JS5?
My code is like:
var type = 'display'
if (type === 'display' || type === 'filter') { ... }
Is there a way to make shorter, like:
if ( type === ('display' || 'filter') ) { ... }
I thought your original post was pretty straight forward and thought it was a perfectly fine answer to your problem.
Having said that you can use RegEx like #le_m mentioned. I just tested this in the console and this works.
The '//' tell the interpreter that we will be starting a regular expression. The parenthesis allow us to declare a subexpression. A subexpression that will be evaluated independently of other expressions.
The 'i' stands for insensitive. In this case it isn't entirely necessary but I think it might be useful for you down the road. The 'i' will allow you to avoid casing issues. Also, should you pass in longer strings that contain 'display', or 'type' in a sentence, this regex will also find those.
var type = 'display';
if (/(type|display)/i.test(type)) {
console.log('word found')
}

JavaScript: alert object name as a string

I'm trying to alert any JavaScript object as a string, in a function. This means if the parameter given to the function is window.document, the actual object, it should alert "window.document" (without quotes) as a literal string.
The following calls...
example(window);
example(window.document);
example(document.getElementById('something'));
...calling this function...
function example(o) {/* A little help here please? */}
...should output the following strings...
window
window.document
document.getElementById('something')
I've attempted to do this with combinations of toString() and eval() among some more miscellaneous shots in the dark without success.
No need insane backwards compatibility, newer ECMAScript / JavaScript features/functions are fine. Feel free to inquire for clarifications though the goal should be pretty straight forward.
This is not possible to do in a self contained script.
If using a preprocessor would be an option, then you could write one which converts example(whatever) into example('whatever'). Other than that I'm afraid you're out of luck.
The first problem is that objects don't have names.
The second problem is that from your examples, you're not really wanting to print the (nonexistent) name of an object, you want to print the expression that evaluated into a reference to an object. That's what you're trying to do in this example:
example(document.getElementById('something'));
For that to print document.getElementById('something'), JavaScript would have had to keep the actual text of that expression somewhere that it would make available to you. But it doesn't do that. It merely evaluates the parsed and compiled expression without reference to the original text of the expression.
If you were willing to quote the argument to example(), then of course it would be trivial:
example( "document.getElementById('something')" );
Obviously in this case you could either print the string directly, or eval() it to get the result of the expression.
OTOH, if you want to try a real hack, here's a trick you could use in some very limited circumstances:
function example( value ) {
var code = arguments.callee.caller.toString();
var match = code.match( /example\s*\(\s*(.*)\s*\)/ );
console.log( match && match[1] );
}
function test() {
var a = (1);
example( document.getElementById('body') );
var b = (2);
}
test();
This will print what you wanted:
document.getElementById('body')
(The assignments to a and b in the test() function are just there to verify that the regular expression isn't picking up too much code.)
But this will fail if there's more than one call to example() in the calling function, or if that call is split across more than one line. Also, arguments.callee.caller has been deprecated for some time but is still supported by most browsers as long as you're not in strict mode. I suppose this hack could be useful for some kind of debugging purposes though.
Don't know why you need this, but you can try walking the object tree recursively and compare its nodes with your argument:
function objectName(x) {
function search(x, context, path) {
if(x === context)
return path;
if(typeof context != "object" || seen.indexOf(context) >= 0)
return;
seen.push(context);
for(var p in context) {
var q = search(x, context[p], path + "." + p);
if(q)
return q;
}
}
var seen = [];
return search(x, window, "window");
}
Example:
console.log(objectName(document.body))
prints for me
window.document.activeElement

assistance require resolving jslint errors

I am currently running JSLint against the javascript in my web application and getting some errors that I require assistance with resolving.
a. First error I am getting is: JS Lint: Unused Variable 'n'.
$.each(collection, function (n, item) {
var temp = item.Id;
// do further processing
});
b. I have all my javascript declared in a self executing function like such:
(function ($, undefined) {
// further javascript code
}
(jQuery));
The above pattern can protect the $ from conflicting with other JavaScript libraries and also protect undefined from being redefined. However I get these errors from it:
JS Lint: Expected an identifier and instead saw 'undefined' (a reserved word).
JS Lint: Unused Variable 'undefined'.
c. JS Lint: Unescaped '-'.
if (value.match(/^[A-Z0-9._%+-]+#(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i)) {
return true;
}
d. JS Lint: Type confusion: 'printer-': string and '(': number.
var frameName = "printer-" + new Date().getTime();
I get numerous errors of Type confusion, sometimes with numbers, integers and other data types. Any idea as to how I can prevent getting these?
e. JS Lint: Insecure '^'.
var value = value.replace(/[^\d\.,\-]/gi, '');
f. JS Lint: Don't make functions within a loop.
for (i = 0, l = txts.length; i < l; i += 1) {
if (/^[0-9]+$/.test(txts[i].getAttribute("maxlength"))) {
var func = function () {
//do some processing
};
}
}
A.) See: http://api.jquery.com/jQuery.each/
you can use:
$.each(collection, function() {
doSomething(this); // this refers to the current iteration
});
B.) If you aren't actually using "undefined" you aren't protecting it from anything
C.) I'm not going to bother with regex lol EDIT: Perhaps it wants [A-Z0-9\-]
D.) You are concatenating string with number. Try 'string' + Date.getTime().toString() instead
See also JSLint Type Confusion: function and object with jQuery .css() for type confusion stuff, there are some oddities that I don't agree with
E.) Again I'm not going to try for the regex EDIT: Here's an identical question though: JSLint "insecure ^" in regular expression
F.) If you can create your function once outside of the loop and then use it inside the loop (as long as you do it well) it is a significant performance increase.
I see others have answered, so I'll at least put an attempt in for c)
c. JS Lint: Unescaped '-'.
if (value.match(/^[A-Z0-9._%+-]+#(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i)) {
return true;
}
C. Add a backslash before the - in 9- and +-
Sorry, can't help you with E), that regex looks ok to me.

Categories