Refactor this Lisp and Haskell style macro in JavaScript - javascript

Consider this Lisp macro:
(defmacro doif (x y) `(if ,x ,y))
The same in Haskell:
doif x y = if x then (Just y) else Nothing
Is it possible to achieve this elegance in the "lisp-y" language of JavaScript? (the use of the word "lisp-y" comes from the author of the JS language)

Yes, it is possible. If you simply want to a one-to-one mapping of the lisp-y code then you could use the conditional operator as follows:
x ? y : null // note that x and y are expressions, not values: they aren't eval'd
If you don't mind the result of the expression being a falsy value (instead of an explicit null value) then you could use the guard operator instead:
x && y // reminder: x and y are expressions - they aren't evaluated until needed
If you want to create your own doif syntax then you can use hygienic macros provided by sweet.js as follows:
macro doif {
rule { ($x:expr) ($y:expr) } => { $x ? $y : null }
}
The above macro allows you to write code like this:
doif (x < 100) (x + 1)
The above code gets converted to:
x < 100 ? x + 1 : null
When using either of these operators if the condition x is falsy then y is not evaluated.

You can implements macros in Javascript because the compiler is part of the runtime (you can eval a string and get back code). However to get close to Lisp you need to implement your own full language because eval can only produce full functions, not expressions.
If instead you're just thinking about delayed evaluation this can be done trivially by wrapping the code in a closure:
function my_if(condition, then_part, else_part) {
return condition ? then_part() : else_part();
}
my_if(foo < bar,
function(){ return bar -= foo; },
function(){ return foo -= bar; });
You can of course also create a closure that will encapsulate the whole operation by delaying also the test...
function my_if(condition, then_part, else_part) {
return function() {
return condition() ? then_part() : else_part();
}
}
var my_prog = my_if(function(){ return foo < bar; },
function(){ return bar -= foo; },
function(){ return foo -= bar; });
my_prog(); // executes the code

I suppose the usual way to emulate laziness in a non-lazy language is to manually thunkify. I don't know Javascript very well, so I'm going to write pseudocode instead and hope that you can paint Javascript syntax on the idea.
function doif(x, y) {
if(x) { return y(); }
else { return undefined; }
}
And a sample call:
function expensive() {
// do a lot of work here
}
doif(false, expensive); // runs very fast
doif(true , expensive); // runs very slow
doif(true , expensive); // runs very slow (unlike Haskell, but I think like Lisp)

Related

Snowflake UDF behaves differently while using "LIMIT"

I have created a UDF that evaluates rows. It works fine in most cases, but sometimes it acts weird. See example below. These are exactly the same query. One with "Limit" and the other without. The total record count here is 32 but I add Limit 1000 just for the example. Would you know why the these two queries behave differently?
Without Limit - Wrong Output
With Limit - Correct Output - Again total records is 32.
The function code:
create or replace function new_row_evaluator
(b varchar, m datetime, f DATETIME, t datetime )
returns string
language javascript
as '
if (typeof tmp_barcode === "undefined") {
tmp_barcode = B;
tmp_fromdate = F;
tmp_todate = T;
return "1";
}
if (tmp_barcode == B) {
if (M >= tmp_fromdate && M <= tmp_todate) {
return "0";
} else {
tmp_fromdate = F;
tmp_todate = T;
return "1";
}
} else {
tmp_barcode = B;
tmp_fromdate = F;
tmp_todate = T;
return "1";
} ';
I assume that the UDF is using some sort of global state tmp_barcode.
Global state
Snowflake usually preserves the JavaScript global state between iterations of a UDF. However, you should not rely on previous modifications to the global state being available between function calls. Additionally, you should not assume that all rows will execute within the same JavaScript environment.
a recommended pattern is to guarantee that relevant code is evaluated only once, using JavaScript’s global variable semantics. For example:
var setup = function() {
/* SETUP LOGIC */
};
if (typeof(setup_done) === "undefined") {
setup();
setup_done = true; // setting global variable to true
}
Note that this mechanism is only safe for caching the effects of code evaluation. It is not guaranteed that after an initialization the global context will be preserved for all rows, and no business logic should depend on it.

Declaring a variable then changing it with an if statement?

Is it necessary to add an if/else statement when declaring a variable within a function? Can I just set the variable first and then change it if a condition is met?
function doSomething() {
var a = 1;
if(something) {
a = 2;
}
}
vs
function doSomething() {
var a;
if(something) {
a = 2;
} else {
a = 1;
}
}
Yes you can do that (technically). Regarding understanding or code complexity, keep it as simple as possible.
I think your intentions would be even clearer if you used the conditional operator:
var a = something ? 2 : 1;
No, it's not necessary, as long as evaluating the second value in the initialisation has no side effects (in your case, the literal 1, it has none).
However, using if-else might show your intention better and make the code cleaner; though that is more a matter of style than functionality. Personally I would even prefer a conditional expression:
var a = condition ? 2 : 1;
Yes, you can do that - even shorter like this
var a = 1;
if (something) a = 2;

Extend the number class

I want to extend the number class to have instance functions such as odd and even so I can do something like this:
2.odd() => false
2.even() => true
1.even() => false
1.odd() => true
Extending classes is a good Ruby practise: "Ruby check if even number, float".
Is the same true in JavaScript, or does it cause performance issues or some other problem?
Anyway, I can't extend despite my best efforts:
var NumberInstanceExtensions = {
accuracy: function(){
return 'This is cool ' + this
}
}
$.extend(Number.prototype,NumberInstanceExtensions);
alert( $.type(5) ); //-> number
//alert( 5.accuracy() ); //-> Uncaught SyntaxError: Unexpected token ILLEGAL
http://jsfiddle.net/VLPTb/2/
How can I get this to work? The syntax error makes me think this isn't how JavaScript works on a fundamental level. Is my best bet extending the Math class and doing this instead:
Math.odd(2) => false
Math.even(2) => true
Math.even(1) => false
Math.odd(1) => true
That seems far more inelegant than 2.odd().
I think as long as you understand the side-effects of your "extension" then you're okay. I often modify the String prototype to add an "elipsis" method so I can do things like
"SomeString".elipsis()
But start at the beginning. You're not "extending classes" in JavaScript. JavaScript is a prototype-based language. You can modify prototypes to do what you need.
You won't be able to add a method directly to the number itself. You can, however modify the prototype of the Number object:
Number.prototype.even = function(){
return this.valueOf() % 2 === 0;
}
With this, you won't be able to use the following syntax:
10.even();
But, since you aren't hard-coding stuff, otherwise you wouldn't need this function anyways, you CAN do the following:
var a = 10;
a.even(); //true
I might say that you could consider adding a utilities object to do these things, because modifying primitive prototypes is not always guaranteed to be side-effect free.
This function does not really provide any gain for you. You're checking for odd and even, replacing one line of code with another. Think about the difference:
var a = 10;
var aIsEven = a.even();
vs:
var a = 10;
var aIsEven = a % 2 === 0;
You gain three characters of code, and the second option is less likely to break your "JavaScript".
You can extend natives JS objects by using (for example) Number.prototype.myFn = function(){}.
So you could do :
Math.prototype.odd = function(n){
return n % 2 === 0;
};
Math.prototype.even = function(n){
return n % 2 === 1;
};
And then use it like so :
var two = 2;
console.log(Math.odd(2)); // true
BUT I would strongly advise you against extending natives in JavaScript.
You can read more about it here
EDIT : After trying my code on JSFiddle, it appears the Math object has no prototype, you can read more about it here. The code above won't work !
Instead, you could do :
Math.odd = function(n){
return n % 2 === 0;
};
Math.even = function(n){
return n % 2 === 1;
};
console.log(Math.odd(2)); // true
or :
Number.prototype.odd = function(){
return this % 2 === 0;
};
Number.prototype.even = function(){
return this % 2 === 1;
};
console.log(new Number(2).odd()); // true
I'd like to point out that that is already available in the numbers class.
Just use the boolean methods, odd? and even?
2.odd?
=> false
2.even?
=> true
Hope this helps.
No need to create a new class, it already exists in the numbers class.

How can I use goto in Javascript?

I have some code that I absolutely must implement using goto. For example, I want to write a program like this:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Is there a way to do that in Javascript?
Absolutely! There is a project called Summer of Goto that allows you use JavaScript at its fullest potential and will revolutionize the way you can write your code.
This JavaScript preprocessing tool allows you to create a label and then goto it using this syntax:
[lbl] <label-name>
goto <label-name>
For example, the example in the question can be written as follows:
[lbl] start:
alert("LATHER");
alert("RINSE");
[lbl] repeat: goto start;
Note that you are not just limited to simple trivial programs like an endless LATHER RINSE repeat cycle—the possibilities afforded by goto are endless and you can even make a Hello, world! message to the JavaScript console 538 times, like this:
var i = 0;
[lbl] start:
console.log("Hello, world!");
i++;
if(i < 538) goto start;
You can read more about how goto is implemented, but basically, it does some JavaScript preprocessing that takes advantage of the fact that you can simulate a goto with a labelled while loop. So, when you write the "Hello, world!" program above, it gets translated to something like this:
var i = 0;
start: while(true) {
console.log("Hello, world!");
i++;
if(i < 538) continue start;
break;
}
There are some limitations to this preprocessing process, because while loops cannot stretch across multiple functions or blocks. That's not a big deal, though—I'm sure the benefits of being able to take advantage of goto in JavaScript will absolutely overwhelm you.
All above link that lead to goto.js library is ALL DEAD, here is links needed:
goto.js (uncompressed) --- parseScripts.js (uncompressed)
From Goto.js:
No. They did not include that in ECMAScript:
ECMAScript has no goto statement.
In classic JavaScript you need to use do-while loops to achieve this type of code. I presume you are maybe generating code for some other thing.
The way to do it, like for backending bytecode to JavaScript is to wrap every label target in a "labelled" do-while.
LABEL1: do {
x = x + 2;
...
// JUMP TO THE END OF THE DO-WHILE - A FORWARDS GOTO
if (x < 100) break LABEL1;
// JUMP TO THE START OF THE DO WHILE - A BACKWARDS GOTO...
if (x < 100) continue LABEL1;
} while(0);
Every labelled do-while loop you use like this actually creates the two label points for the one label. One at the the top and one at the end of the loop. Jumping back uses continue and jumping forwards uses break.
// NORMAL CODE
MYLOOP:
DoStuff();
x = x + 1;
if (x > 100) goto DONE_LOOP;
GOTO MYLOOP;
// JAVASCRIPT STYLE
MYLOOP: do {
DoStuff();
x = x + 1;
if (x > 100) break MYLOOP;
continue MYLOOP;// Not necessary since you can just put do {} while (1) but it illustrates
} while (0)
Unfortunately there is no other way to do it.
Normal Example Code:
while (x < 10 && Ok) {
z = 0;
while (z < 10) {
if (!DoStuff()) {
Ok = FALSE;
break;
}
z++;
}
x++;
}
So say the code gets encoded to bytecodes so now you must put the bytecodes into JavaScript to simulate your backend for some purpose.
JavaScript style:
LOOP1: do {
if (x >= 10) break LOOP1;
if (!Ok) break LOOP1;
z = 0;
LOOP2: do {
if (z >= 10) break LOOP2;
if (!DoStuff()) {
Ok = FALSE;
break LOOP2;
}
z++;
} while (1);// Note While (1) I can just skip saying continue LOOP2!
x++;
continue LOOP1;// Again can skip this line and just say do {} while (1)
} while(0)
So using this technique does the job fine for simple purposes. Other than that not much else you can do.
For normal Javacript you should not need to use goto ever, so you should probably avoid this technique here unless you are specificaly translating other style code to run on JavaScript. I assume that is how they get the Linux kernel to boot in JavaScript for example.
NOTE! This is all naive explanation. For proper Js backend of bytecodes also consider examining the loops before outputting the code. Many simple while loops can be detected as such and then you can rather use loops instead of goto.
Actually, I see that ECMAScript (JavaScript) DOES INDEED have a goto statement. However, the JavaScript goto has two flavors!
The two JavaScript flavors of goto are called labeled continue and labeled break. There is no keyword "goto" in JavaScript. The goto is accomplished in JavaScript using the break and continue keywords.
And this is more or less explicitly stated on the w3schools website here http://www.w3schools.com/js/js_switch.asp.
I find the documentation of the labeled continue and labeled break somewhat awkwardly expressed.
The difference between the labeled continue and labeled break is where they may be used. The labeled continue can only be used inside a while loop. See w3schools for some more information.
===========
Another approach that will work is to have a giant while statement with a giant switch statement inside:
while (true)
{
switch (goto_variable)
{
case 1:
// some code
goto_variable = 2
break;
case 2:
goto_variable = 5 // case in etc. below
break;
case 3:
goto_variable = 1
break;
etc. ...
}
}
This is an old question, but since JavaScript is a moving target - it is possible in ES6 on implementation that support proper tail calls. On implementations with support for proper tail calls, you can have an unbounded number of active tail calls (i.e. tail calls doesn't "grow the stack").
A goto can be thought of as a tail call with no parameters.
The example:
start: alert("RINSE");
alert("LATHER");
goto start
can be written as
function start() { alert("RINSE");
alert("LATHER");
return start() }
Here the call to start is in tail position, so there will be no stack overflows.
Here is a more complex example:
label1: A
B
if C goto label3
D
label3: E
goto label1
First, we split the source up into blocks. Each label indicates the start of a new block.
Block1
label1: A
B
if C goto label3
D
Block2
label3: E
goto label1
We need to bind the blocks together using gotos.
In the example the block E follows D, so we add a goto label3 after D.
Block1
label1: A
B
if C goto label2
D
goto label2
Block2
label2: E
goto label1
Now each block becomes a function and each goto becomes a tail call.
function label1() {
A
B
if C then return( label2() )
D
return( label2() )
}
function label2() {
E
return( label1() )
}
To start the program, use label1().
The rewrite is purely mechanical and can thus be done with a macro system such as sweet.js if need be.
const
start = 0,
more = 1,
pass = 2,
loop = 3,
skip = 4,
done = 5;
var label = start;
while (true){
var goTo = null;
switch (label){
case start:
console.log('start');
case more:
console.log('more');
case pass:
console.log('pass');
case loop:
console.log('loop');
goTo = pass; break;
case skip:
console.log('skip');
case done:
console.log('done');
}
if (goTo == null) break;
label = goTo;
}
Sure, using the switch construct you can simulate goto in JavaScript. Unfortunately, the language doesn't provide goto, but this is a good enough of a replacement.
let counter = 10
function goto(newValue) {
counter = newValue
}
while (true) {
switch (counter) {
case 10: alert("RINSE")
case 20: alert("LATHER")
case 30: goto(10); break
}
}
How about a for loop? Repeat as many times as you like. Or a while loop, repeat until a condition is met. There are control structures that will let you repeat code. I remember GOTO in Basic... it made such bad code! Modern programming languages give you better options that you can actually maintain.
There is a way this can be done, but it needs to be planned carefully.
Take for example the following QBASIC program:
1 A = 1; B = 10;
10 print "A = ",A;
20 IF (A < B) THEN A = A + 1; GOTO 10
30 PRINT "That's the end."
Then create your JavaScript to initialize all variables first, followed by making an initial function call to start the ball rolling (we execute this initial function call at the end), and set up functions for every set of lines that you know will be executed in the one unit.
Follow this with the initial function call...
var a, b;
function fa(){
a = 1;
b = 10;
fb();
}
function fb(){
document.write("a = "+ a + "<br>");
fc();
}
function fc(){
if(a<b){
a++;
fb();
return;
}
else
{
document.write("That's the end.<br>");
}
}
fa();
The result in this instance is:
a = 1
a = 2
a = 3
a = 4
a = 5
a = 6
a = 7
a = 8
a = 9
a = 10
That's the end.
Generally, I'd prefer not using GoTo for bad readability. To me, it's a bad excuse for programming simple iterative functions instead of having to program recursive functions, or even better (if things like a Stack Overflow is feared), their true iterative alternatives (which may sometimes be complex).
Something like this would do:
while(true) {
alert("RINSE");
alert("LATHER");
}
That right there is an infinite loop. The expression ("true") inside the parantheses of the while clause is what the Javascript engine will check for - and if the expression is true, it'll keep the loop running. Writing "true" here always evaluates to true, hence an infinite loop.
You can simple use a function:
function hello() {
alert("RINSE");
alert("LATHER");
hello();
}
To achieve goto-like functionality while keeping the call stack clean, I am using this method:
// in other languages:
// tag1:
// doSomething();
// tag2:
// doMoreThings();
// if (someCondition) goto tag1;
// if (otherCondition) goto tag2;
function tag1() {
doSomething();
setTimeout(tag2, 0); // optional, alternatively just tag2();
}
function tag2() {
doMoreThings();
if (someCondition) {
setTimeout(tag1, 0); // those 2 lines
return; // imitate goto
}
if (otherCondition) {
setTimeout(tag2, 0); // those 2 lines
return; // imitate goto
}
setTimeout(tag3, 0); // optional, alternatively just tag3();
}
// ...
Please note that this code is slow since the function calls are added to timeouts queue, which is evaluated later, in browser's update loop.
Please also note that you can pass arguments (using setTimeout(func, 0, arg1, args...) in browser newer than IE9, or setTimeout(function(){func(arg1, args...)}, 0) in older browsers.
AFAIK, you shouldn't ever run into a case that requires this method unless you need to pause a non-parallelable loop in an environment without async/await support.
// example of goto in javascript:
var i, j;
loop_1:
for (i = 0; i < 3; i++) { //The first for statement is labeled "loop_1"
loop_2:
for (j = 0; j < 3; j++) { //The second for statement is labeled "loop_2"
if (i === 1 && j === 1) {
continue loop_1;
}
console.log('i = ' + i + ', j = ' + j);
}
}
You should probably read some JS tutorials like this one.
Not sure if goto exists in JS at all, but, either way, it encourages bad coding style and should be avoided.
You could do:
while ( some_condition ){
alert('RINSE');
alert('LATHER');
}
goto begin and end of all parents closures
var foo=false;
var loop1=true;
LABEL1: do {var LABEL1GOTO=false;
console.log("here be 2 times");
if (foo==false){
foo=true;
LABEL1GOTO=true;continue LABEL1;// goto up
}else{
break LABEL1; //goto down
}
console.log("newer go here");
} while(LABEL1GOTO);
Another alternative way to achieve the same is to use the tail calls. But, we don’t have anything like that in JavaScript.
So generally, the goto is accomplished in JS using the below two keywords.
break and
continue,
reference: Goto Statement in JavaScript
Here is an example:
var number = 0;
start_position: while(true) {
document.write("Anything you want to print");
number++;
if(number < 100) continue start_position;
break;
}

What does this (useless?) javascript code do?

While debugging a javascript code that uses jQuery I found the following code:
[0, 0].sort(function()
{
baseHasDuplicate = false;
return 0;
});
By my understanding of javascript this code will sort array containing two zeroes with comparison function that will always set a global variable and will return equality, which has same effect as baseHasDuplicate = false;.
Coming from a valued source I think I missed something.
Did I miss something or is this a programming fail?
As you can see here (chinese), this code might be used to test for Chrome. EDIT: see below for the complete story..
As explained in the article, what happens is that Chrome optimizes the ".sort(...)" method in such a way that the [0, 0].sort(...) call won't execute the given comparison function.
From the article, Chrome's implementation of ".sort(...)" is something like:
function sort(comparefn) {
var custom_compare = (typeof(comparefn) === 'function');
function Compare(x,y) {
if (x === y) return 0;
if (custom_compare) {
return comparefn.call(null, x, y);
}
...
}
As 0 === 0 is true, it won't call comparefn.
In the case of jQuery, it won't set the global variable baseHasDuplicate to false.
EDIT: if you browse Sizzle's source code, here for example (go to the yellow section under "Sizzle CSS Selector Engine", called "Sizzle variables"), you will find the following explanation:
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
done = 0,
toString = Object.prototype.toString,
hasDuplicate = false,
baseHasDuplicate = true;
// Here we check if the JavaScript engine is using some sort of
// optimization where it does not always call our comparision
// function. If that is the case, discard the hasDuplicate value.
// Thus far that includes Google Chrome.
[0, 0].sort(function(){
baseHasDuplicate = false;
return 0;
});
Looks demystified!

Categories

Resources