Jump to content
Sign in to follow this  
lynkfs@gmail.com

ES2015

Recommended Posts

I read an article the other day which caught my attention, 

 

"anamorphisms in javascript" describes functions to increase or decrease the number of dimensions in data-structures

 

 


 

I like to think of the integer 5 as having all the whole numbers except for five to be folded up inside itself

 

 

 

It then describes how this can be used to split traversing loops (for var i := 0 to length-1 do something) into traversing functions and do-something functions.

 

I thought I would try that out

 

However the code fragments in this article have been written in ES6, or rather ECMA-262 6th Edition, the ECMAScript 2015 Language Specification

 

I've not been exposed to this upgrade of the JS language much, but I see there are lots of changes

'use strict';
 
function unfoldWith(fn) {
  return function * unfold (value) {
    let { next, element, done } = fn(value);
 
    if (!done) {
      yield element;
      yield * unfold(next);
    }
  }
}
 
const butLast = (array) => array.slice(0, array.length - 1);
const last = (array) => array[array.length - 1];
 
const inReverse = unfoldWith(
    (array) => array.length > 0
      ? {
          element: last(array),
          next: butLast(array)
        }
      : { done: true }
  );
 
[...inReverse(['a', 'b', 'c'])]
 

The above code for a reversal function looks sort of weird, in any case much different from what I know as 'normal' javascript.

 

I suppose DWScript will not compile to ES6 any time soon, if at all (question to Eric : will it ?)

 

The solution is to convert it back to the current flavour of js using online tools such as Babel

 

This translates the above snippet into

'use strict';
 
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
 
function unfoldWith(fn) {
  return regeneratorRuntime.mark(function unfold(value) {
    var _fn, next, element, done;
 
    return regeneratorRuntime.wrap(function unfold$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _fn = fn(value), next = _fn.next, element = _fn.element, done = _fn.done;
 
            if (done) {
              _context.next = 5;
              break;
            }
 
            _context.next = 4;
            return element;
 
          case 4:
            return _context.delegateYield(unfold(next), 't0', 5);
 
          case 5:
          case 'end':
            return _context.stop();
        }
      }
    }, unfold, this);
  });
}
 
var butLast = function butLast(array) {
  return array.slice(0, array.length - 1);
};
var last = function last(array) {
  return array[array.length - 1];
};
 
var inReverse = unfoldWith(function (array) {
  return array.length > 0 ? {
    element: last(array),
    next: butLast(array)
  } : { done: true };
});
 
[].concat(_toConsumableArray(inReverse(['a', 'b', 'c'])));

which to me is more recognisable, but not more readable.

Worst thing is it exposes functions which are not even defined in these snippets, so you need to include the babel.js lib (hosted on CDN somewhere)

 

Anyway, after all that it all does work as expected

 

See code or demo for an Array object with a 'reverse' function

 

So getting back to the article, the question is: is it something worthwhile keeping in mind or is it more a solution looking for a problem?

 

Probably the latter

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×