Sunday, November 9, 2014

ES6 is functional, imperative, and OO

Yes, I know that, lately, there has been a fad about functional programming. Examples include C++ and Python getting lambdas, people envying those with Haskell/OCaml/etc. experience, and so on. But, in my experience, JavaScript has always been in the grey area. It's been called functional, imperative, "Lisp in C's clothing", object oriented, and so many other things. Yet, none of these actually describe the language, which is, in reality, a mixture of all these things.

Now, here's why I believe ES6 to be functional, imperative, and object oriented, all three.

Functional

ES6 has a new arrow function syntax, one most JavaScript programmers who have been keeping up already know pretty well.

let f1 = x => doSomething(x);
let f2 = (x, y) => doSomething(x, y);
let f3 = () => doSomething();

let identity = x => x;
let noop = () => {};

This is generally considered functional, but combine it with Array.prototype.{map,reduce}, and it'll start really looking more functional:

// generically
let doubleGeneric = xs =>
    Array.prototype.map.call(xs, x => x*2);
let doubleArray = xs => xs.map(x => x*2);

let sum = xs => xs.reduce((x, y) => x+y);

As you might have already noticed in the above examples, some of the Array.prototype methods are more generic as well.

Also, the two Underscore methods map and each could become a lot simpler to write:

function* range(n) {
    for (let i = 0; i < n; i++)
        yield i;
}

export const map = (xs, fn) => {
    let array = [];
    for (let i of range(n))
        array.push(fn(xs[i], i));
    return array;
};

export const each = (xs, fn) => {
    for (let i of range(x))
        fn(xs[i], i);
};

You could always use Array.from in each of these cases as well, making them far smaller and a little more functional (albeit a little slower):

export const map = (xs, fn) => Array.from(xs).map(fn);

export const each = (xs, fn) => Array.from(xs).each(fn);

There are also Promises, already known to be monads, and they're now in the standard library. It is easy to make a promisifying function for Node-style callbacks:

function promisify(fn) {
    return function (...args) {
        return new Promise((resolve, reject) =>
            fn(...args, function (err, ...retArgs) {
                if (err != null) {
                    reject(err);
                } else {
                    resolve(...retArgs);
                }
            }));
    };
}

// Example
let fs = require('fs');
let readFile = promisify(fs.readFile);

readFile('foo.txt')
    .then(data => doSomething(data))
    .catch(err => console.error(err));

There are also generators, which are lazy, while Arrays are eager. You can write equivalents to most Array.prototype methods easily for generators.

function* map(gen, fn) {
    let i = 0;
    for (let val of gen)
        yield fn(val, i++);
}

function each(gen, fn) {
    let i = 0;
    for (let val of gen)
        fn(val, i++);
}

function reduce(gen, fn) {
    gen = Generator(gen); // shallow copy
    let last = gen.next().value;
    let res = last;
    for (let val of gen)
        [res, last] = [fn(val, last), val];
    return res;
}

// Array.prototype.contains is ES7-specific
function contains(gen, ...vals) {
    for (let i of gen) {
        if (vals.contains(i))
            return true;
    }
    return false;
}

function* filter(fn) {
    let i = 0;
    for (let val of gen) {
        if (fn(val, i))
            yield val
    }
}

// etc...

I can't end this section properly without at least mentioning the new Array methods:

  • [].some(fn) - true if fn returns true for any element, false otherwise)
  • [].every(fn) - true if fn returns true for all elements, false otherwise)
  • [].copyWithin(target, start, end = this.length) - copies entries in-place from the range start to end to the range of same length starting at target. Example: [1, 2, 3, 4, 5].copyWithin(0, 3) //=> [4, 5, 1, 2, 3]
  • [].entries() - returns an iterator (like a generator) for the array
  • [].find(fn) - returns the first entry that fn returns true for, undefined otherwise.
  • [].findIndex(fn) - like [].indexOf(val), but for functions. Returns first index that fn returns true for, -1 otherwise.
  • [].keys(), [].values() - mainly for consistency with {Map,Set}.prototype.keys() and {Map,Set}.prototype.values().

Imperative

It is already pretty well established that JavaScript has its imperative components. There is no reason to cover this in detail; just look at some of the examples above. Sometimes, you have no choice but to split things into separate statements.

Object-Oriented

Yes, JavaScript has always been object-oriented since its creation, and it is well known that ES6 has its own class syntax.

class Foo {
    constructor(arg) {
        this.bar = arg;
    }

    sayBar() {
        console.log(this.bar);
    }
}

class Bar extends Foo {
    constructor(x, ...args) {
        super(...args);
        this.x = x;
    }
}

let bar = new Bar(1, 3);
bar.sayBar(); // prints '3' to console
bar.x; // 1

But, the new syntax also builds on JavaScript's object-orientedness substantially. Now, there are also static methods you can add to classes, and it is easier to extend classes (like above), so ES6 classes are a lot more declarative, clear, and concise. You can even subclass builtins now.

class Baz extends Foo {
    static from(obj) {
        return new Baz(obj.bar);
    }
}

// Even this is allowed.
class MyArray extends Array {
    constructor(prop, ...args) {
        super(...args);
        this.prop = prop;
    }
}

Conclusion

ES6 will add to the confusion of what JavaScript really is, albeit in an awesome way. There are three primary categories people typically try to lump JavaScript into, and they're all (mostly) right:

  • Functional: arrow functions, more generic Array methods, some new Array methods, lazy generators.
  • Imperative: relatively self-explanatory
  • Object-oriented: simpler class declaration syntax, more deeply integrated with the language, may make more parts of the DOM possible to implement in JavaScript.
    • DOM Level 4 will replace HTMLCollections and NodeLists with Elements, an actual ES6-style Array subclass with two additional methods: Elements.prototype.query() (akin to element.querySelector) and Elements.prototype.queryAll (akin to element.querySelectorAll). This will make the DOM even easier to work with and an even better fit for both functional and OO programming.

Tuesday, August 5, 2014

Society in a nutshell

There are two factions: people who religiously cling to the past, and the people who are disillusioned. These two seemingly endlessly conflict over most things. Then, there are the decisively ignorant. These people either pick a side but don't fight, or they disacknowledge the very existence of either.

Monday, July 28, 2014

I like ES6...works well, even for golfing (factorial demo hack)

Disclaimer: All code in this post is licensed under the BSD license.


Update: updated much of the code, made the JS smaller and the assembly half the instruction size. Also made the comments fit a little better space-wise.

Everyone knows about JavaScript and the basic factorial function, and here's the basic recursive implementation:

// ES5 and previous
function fact(n) {
  if (x > 0) {
    return n * factorial(n - 1);
  } else {
    return 1;
  }
}

// ES6
let fact = n => n > 0 ? n * factorial(n - 1) : 1;

But, I find this hack fairly cool: it basically takes enormous advantage of precedence and how logic statements work in ECMAScript. The hack assumes integer input.


// ES5 and previous
function fact(n) {
  return +(n < 1) || n * fact(n - 1);
}

// ES6
let fact = n => +(n < 1) || n * fact(n - 1);

The hack version also takes advantage of an implicit boolean-to-integer cast, which is usually quicker than a conditional. Code golfing is a little fun for these kinds of hacks, so let's compare a golfed C/C++ version to this ECMAScript hack unminified (using the ES6 versions):


int f(int n){int r=1;while(n--)r*=n;return r;} // Golfed C/C++
let fact = n => +(n < 1) || n * fact(n - 1); // Unminified ES6
function fact(n) { return +(n < 1) || n * fact(n - 1); } // Unminified ES5

And minified:

int f(int n){int r=1;while(n--)r*=n;return r;} // C/C++
function f(n){return +(n<=0)||n*f(n-1)} // Minified ES5 and previous
let f=n=>+(n<1)||n*f(n-1); // Minified ES6

Here's an explanation of the hack, comments inline:


// This works in all ECMAScript standards, from ECMAScript 3 through
// ECMAScript 6 and beyond.
function fact(n) {
  return +(n < 1) // This implicitly casts from boolean to
                  // integer, retaining truthiness.
                  // If true, this returns 1 and does not
                  // evaluate the right side.
         ||       // If false, evaluate the next part.
         n * fact(n - 1); // Here's some pseudocode explaining
                          // this:
                          //
                          // 1. Remember n in a pseudo-variable
                          //    x.
                          // 2. Decrement n by 1.
                          // 3. Apply the factorial function to
                          //    n.
                          // 4. Multiply it by the pseudo-
                          //    variable x.
                          // 5. Return the value.
}

Here's the function without comments:

function fact(n) {
  return +(n <= 0) || n * fact(n--);
}

let fact = n => +(n <= 0) || n * fact(n--);

You'll never beat assembly in speed, though... (this is written for x86 using Intel syntax)


; And almost in size...this is surprisingly short.
_fact: pop ecx    ; assumes cdecl calling convention, returns
       mov eax, 1 ; on eax
.loop: mul ecx
       loop .loop
       ret

Tuesday, May 27, 2014

User friendliness and SEO optimization for clients without JS using <noscript>, <meta>

The following is a simple HTML hack to really help with detecting clients without JavaScript enabled or supported and serve them better content accordingly:

In the <head>, add this code:
<noscript><meta http-equiv="refresh" content="0; url=www.example.com/no-js-version" /></noscript>
The URL can be any of your choosing, and it matters none what it is. It is just meant to point to a version that does not require JavaScript. This is best placed as the first tag after the <meta charset="utf-8" /> element in the <head>.

There is a caveat to this: it only validates as HTML5. This means nothing to modern browsers, but it could provide potential issues if compatibility with older browsers (e.g. IE8 or earlier) is needed.

Basis of all our society's problems

Summary: Don't fight to elevate yourself - that is why our society is in shackles. You can be wrong, just as your opponents can be. Fight to put people in their place - that can and will resolve virtually any conflict in the world.



We all know that our society has it's fair share of issues. From all the violence against homosexuals to violence and vicious legal battles being waged against right-to-work proponents and opponents to abortion, it seems like our society has come to a moral crumble. Greed seems rampant, especially given the media and all of its "wisdom", and even the news media itself is becoming rather biased in general, generally refusing to give legitimate coverage of much of anything that is actually good or supports the views of its managers.

The root of all these issues may seem like a few people being greedy and/or self-righteous. There are plenty of examples of these problems, and here's a list of some, not intended to be comprehensive or complete:
  • Attacks being committed against homosexuals (self-righteous)
  • Union agents attacking workers, both legally and violently (greedy)
  • Obama using the IRS to target political opponents (greedy, self-righteous)
  • Corporations fighting for ability to control bandwidth to specific sites (greedy)
  • Some people in Congress fighting for Internet censorship (greedy, self-righteous)
  • Abortion proponents fighting for required insurance coverage of it, including by institutions opposing it (self-righteous)
  • White House supporting NSA activities, in disagreement with the rest of America and the world (greedy)
That is just on the surface. All these have something even more basic as a common root. That root is the "greater than thou" mindset.

This mindset is nothing new. Before I go on to explain how that is with current issues, here's a couple past examples:
  • In the Civil Rights Era, both blacks and whites had the "better than you" mindset. It hadn't shown itself very well during the time of Martin Luther King, Jr., since he had guided everyone to practice nonviolent protest, civil disobedience, and peaceful petition. Both before he gained his influence and after he passed, there were somewhat frequent riots committed by both blacks and whites. This definitely came from people of all colors thinking they are better than the other group.
  • In the era of women's suffrage, many men had tried so hard to stop it, and on multiple occasions, they had rioted violently against the activists. Some of the men had sided with the women, but they were constantly ridiculed not too far off of how several anti-gays ridicule straight supporters of gay rights. Some of the suffrage activists had let the movement get into their head, and started getting hostile on occasion to the men themselves. What it took for the male opponents to concede was the idea of them being able to convince their wives to vote for specific people on their whim. Both the men against the movement and several of the women part of the movement had the common notion of being "greater than thou".
Now, here is how that mindset translates to today.
  • The "pro-marriage" people strongly support marriage only being between people of the same sex. Every person in that group sees homosexual relationships as wrong, and many of them believe they should make sure everyone else believe the same thing, not always in a peaceful way. Several people in this group also literally hate gays, in the same sense many Nazis literally hated people of Jewish ancestry. Many of these people will point to the parable of Sodom and Gomorrah as a major reason against homosexuality when it is more about their strong desire for sex and prostitution. These people's strong insistence to force their will, even through lobbying to guarantee its passage as law, really shows their desire to show their opinions as being "greater than thou".
  • The cases of union agents becoming violent is from the unions themselves supporting the violence internally, with the agents being specifically instructed to use whatever means possible to bring people into unions, even by force. Several corporations have tried to rid themselves of the union requirement for their employees through elections, a relatively standard process. Conversely, many union officials will rig these elections and/or use voter suppression, often through intimidation, to try to tilt the election in their favor. This, combined with constant legal threats and pressure and lobbying in Congress, is definitely a show of their greed and lust for power. This clearly demonstrates their desire to be "greater than thou".
  • Obama's targeting of specific groups through the IRS, with one notable example being Tea Party supporters, is a fairly obvious example of one area his administration tries to prove itself as "greater than thou".
  • Corporations fighting to be able to control bandwidth between them and specific sites displays a very significant degree of corporate greed among those, one of which will drive many Internet businesses into the ground and reduce the usage of the Internet. This corporate greed will end up turning on them and driving them to the ground as a result. ISPs apparently aren't looking that far, and their corporate greed is a case of them wanting to be able to show themselves as "greater than thou".
  • Several people are trying to encourage Internet censorship in Congress, with ISPs fighting for one reason, but the Congresspeople are fighting for another. Members of Congress in support of this are interested in the ability to control what people see and don't see. This would give them enormous amounts of power and control over the people, and it would also enable them to dictate to the people what is right and wrong. Hitler convinced the people that hating the Jews was the right thing to do because of his own personal quote: "Make the lie big, make it simple, keep saying it, and eventually people will believe it." Obama, his administration, and Congress all know that they would have this ability and power if they could censor the Internet. The desire of Obama and much of the Senate and House really boils down to the desire for many of them to prove themselves as "greater than thou".
  • The pro-choice lobby has been fighting for a while to make abortion a right for all, and they also want to make sure all insurers can and will cover it if a person wants to have one. They don't care that they are also catching religious institutions staunchly against it, including many Christian charities and the Catholic Church. Most of these groups have actually dropped their insurance coverage of their clergy as a result of this. This forcing of beliefs upon other people is wrong on many levels, and is a prolific example of the "greater than thou" attitude.
  • Obama, the White house, and a few influential Congresspeople support the NSA and its Internet surveillance, including of millions of American citizens. This goes right along with the Presidential and Congressional support of Internet censorship as to why this shows those groups' desire to be "greater than thou".
The common root cause of all these conflicts, just as plenty of past ones, is the desire to be greater, and in many of these cases, it is the desire to try to become "God". I mean this in the most religiously agnostic way possible, and I mean that entirely symbolically. People want power, some more than others, and some will only stop if they are "king of the world". Some know they shouldn't go trying to own everyone's lives, and they are usually the most enjoyed. These people also leave the most permanent marks on humanity for years to come.
  • Jesus is still honored two thousand years after his death.
  • The writers of the Magna Carta left a mark on the structure and purpose of government almost a thousand years later.
  • The members of the Protestant Reformation forced people to reconsider their beliefs and not to blindly follow tradition or believe what the majority believes.
  • The Founding Fathers of our country are still remembered and honored internationally to this day, most notably George Washington.
  • Frederick Douglass had been almost to the Civil War era as Martin Luther King, Jr. was to the Civil Rights Era. He had helped make the North in almost full opposition against slavery, while simultaneously keeping both supporters and opponents of his teachings from getting too violent. He was a former slave himself, but even captivated plantation owners. He had kickstarted the beginnings of the women's rights movement.
  • Gandhi has been known internationally for a while for his actions in lessening the strength of the caste system in India and reducing government oppression against the people, especially against the lower caste.
  • Martin Luther King, Jr. has been known internationally for years for his work in making the Civil Rights cause actually become successful.
  • Ronald Reagan and his views are still being praised internationally to this day, not only Reaganomics, but also his diplomatic ability and decision-making in both foreign and domestic affairs.

The closest we have to this kind of person is either Pope Francis or Rand Paul, but these aren't the average people. These people made the world better.



There are also the people who think they are better than everyone else, and were intent on ruining other people's lives just to make sure of it. Adolf Hitler was a relatively famous example of it, but he is far from the worst (and not the most psychotic, either). Here are some examples of people throughout history who tried to prove that they are "greater than thou".
  • King George III, many of his appointed governors, and his actions almost solely are responsible for us declaring independence from imperial Britain.
  • "Bloody Mary" (Mary I) of England had burned any person who even vaguely disagreed with her at the stake as soon as she had found out. Adolf Hitler was not this indiscriminate with the Holocaust.
  • Saddam Hussein had not only invaded countries for no reason, but one way he took his frustration out was on people with poison gas.
  • Mao Zedong had killed more people in his 31 year reign in China than both Hitler and Stalin had combined--almost twice that total. If you do the math, this comes out to a higher killing rate than Hitler had in his six-year reign.
  • Russian Tsar Ivan IV was named "Ivan the Terrible". In a trip of his to Ukraine, he sentenced a thousand people to be executed daily.
  • Henrich Himmler was the person that orchestrated many of Hitler's killings, and he headed the Gestapo, the German national police. He was the primary one encouraging many of the torturing and killing techniques, such as using cyanide. He was the primary architect of the Holocaust, with little intervention or help from Hitler.

This is a rather brief summary of the effects of the desire to be "God". These people had that desire, and they were able to get significant power to elevate themselves. I am by no means an anarchist, but this is the direction many people in our government are trying to send us in.

The second person in the list, "Bloody Mary", and Adolf Hitler were more extreme cases of why hatred against anyone is costly. The Nazi supporters of Hitler's reign saw the Jews as less than human, much like the stronger proponents of segregation in the Civil Rights Era. People still hold this mentality against gays, and that is where all the violence comes from. This is why that needs to end. This is why gays should be at least partially respected. Humility settled the women's suffrage movement. Humility settled the Civil Rights conflict. Humility will settle the anti-gay sentiment.

Internet surveillance and censorship is standard in China. They have no right to even protest the most mundane things. If a person says anything that is in contrast to the government, he or she is severely risking death. If we end up with such here, we will fall into the same pit they already are in.

Union violence isn't new. These conflicts have been around since before the days Franklin D. Roosevelt was in office. Opponents have been beaten for decades now. In some of the coal towns in the 1800s, some of the children were effectively brainwashed through the curriculum that unionization was good for the community, even though the unions were why several workers couldn't assemble to try to push for better wages, etc. These workers were limited by their unions, with their wages being cut to next to nothing with fees, apparently for living expenses, etc. that cost about half the price they were paying. Unions used manipulation and the same tactics used by Hitler to breed hatred against the Jews to keep people and companies under their influence and power. They have been using violence and intimidation for decades against companies. Although not recently, unions have been known to in the past bring hit squads into factories to enforce their unionism. Roosevelt had simply subdued some of those activities while he was in office - before and after, plenty of things happened "behind closed doors".

This is getting plenty of media coverage as something so "outrageous", but that has been a reality for much longer. I'm not trying to paint it as insignificant - it's not - but this violence and intimidation needs to end at some point. The sooner this disappears, the sooner a very major issue with society dies.

Abortion in the sense being debated in society today is defined by Merriam Webster (def. 1b) as: "the termination of a pregnancy after, accompanied by, resulting in, or closely followed by the death of the embryo or fetus: as induced expulsion of a human fetus". To summarize: the first part means the pregnancy ends with the fetus dying, and the second part is almost the medical definition of birth. Medically, the requirement is that the baby does not survive the (usually) premature birth (in more mundane terms). One thing to note is that the medical field does not draw a significant distinction between the natural, involuntary one, normally termed as a miscarriage, and the artificial, voluntary one, that most people consider to be an abortion.

It doesn't take a rocket scientist to tell that if a fetus dies from an intentionally ended pregnancy, then the death was intentional. An intentionally caused death is by definition intentional killing. Thus, by this simple logic, abortion is the act of killing a fetus before it was born. Is it right to kill anyone? An abortion ends up with a fetus killed, a fetus that hasn't had a chance to become a baby.

Also, abortion clinics are becoming known to try to cover up botched abortions. If the mother ends up having a live baby instead of a dead one, then clearly the medicine given to kill the baby inside did not work. In that case, the abortion is botched. The baby born is then whisked away as quickly as possible to be killed out of sight of the woman. Another thing that has been getting out is the lack of sterility in the environment; for example, unclean tools are used on a regular basis in several abortion clinics.

Abortion is another issue that needs to be finished quickly. The Roman Catholic Church made up their mind officially just after 400 AD. I'm not trying to sound self-righteous here myself, but please use some logic before making up your mind.

Another thing I have covered already, but is worth restating, is that the pro-choice lobby is even willing to try to force religious institutions to cover for people who want abortions, even when it is against their beliefs. They try to manipulate teens to have abortions when they get pregnant, even on rare occasion by intimidating them or their parents. This doesn't really show as pro-choice. This is definitely them trying to forcefully prove to everyone that they are right and "greater than thou".

You see all the ways this "holier than thou"/"greater than thou" attitude can drive a society into shackles? It drove many societies throughout history into the ground. It got Gandhi shot. It got Martin Luther King shot. It caused the Holocaust. It drove our country to existence. It caused the Civil War. It created riots. It caused hostility. It gave reason for evil. This attitude - this "holier than thou"/"greater than thou" attitude - is evil. Lose the attitude, lose the evil. Learn humility, learn good. Gain acceptance, gain perfection.

You learn to accept that you aren't always right, you learn to see the world for what it is. It has evil in it, but let good win. Good requires acceptance, even acceptance that you aren't always right and acceptance that not everyone will agree with you. Do not force your beliefs upon anyone. One of the easiest ways to anger an atheist is to constantly drill into him or her that God exists. An easy way to anger a commercial farmer is why he doesn't buy his vegetables and meat at some supermarket or Walmart.



Don't judge, for you will never be perfect. You will make a mistake at some point. You will lie at some point. You will be wrong at some point. Why judge if you can and likely will make a mistake?
So, don't fight to elevate yourself. The abolitionists had, and it led to the Civil War. The blacks had after Martin Luther King died, and it led to mass riots. Don't fight to elevate yourself. Fight to bring those who have back to the ground. People elevate themselves with the "greater than thou" attitude, and that only leads to evil. Bring them back to the ground; they can do less evil.
If you draw anything out of this whole essay, take this advice:

Don't fight to elevate yourself - that is why our society is in shackles. You can be wrong, just as your opponents can be. Fight to put people in their place - that can and will resolve virtually any conflict in the world.