Introduction
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
If this rings a bell, this may be the article for you.
ECMAScript 6 has a range of quite neat functions – I’m looking forward to seeing what people come up with using it. One that caught my eye and rang several old, rusty bells was the ... operator used when destructuring data.
For anyone currently unfamiliar with destructuring data in ECMAScript 6 (we seriously need a better name for the language), it allows us to assign values to variables directly out of data structures.
For example,
1 2 |
var [a,b,c] = [1,2,3]; console.log(a); |
This snippet would assign the values of 1, 2, and 3 to a , b , and c . This is neat for a range of reasons, not only because it allows us to “return” multiple values from functions.
In this context, the ... operator consumes the unassigned portion of the list. For example,
1 2 |
var [a,...b] = [1,2,3]; console.log(b); |
This stores the value of [2, 3] in b . This ability to pull out some values in a list, and dump the rest in another variable, rang very strong Scheme / LISP bells. For anyone unfamiliar with these languages, you’re very lucky.
Okay, they’re not that bad – they’re a different mindset altogether, representing the functional programming paradigm that fans believe so strongly in. To modify a classic analogy – whereas in a procedural language, to open a door in a house you’d open the door, in a functional paradigm you’d build a new house where the door was already open.
JavaScript gets abused a lot – let’s see if we can abuse it in a functional way.
Data Manipulation
Two of the major functions in Scheme are car and cdr – car returns the first value in a list, whereas cdr returns the rest of the list. Hearing those bells?
We could implement those two functions (and a couple of their subfunctions, cddr , cadr , etc, which are really just repeated applications) using these new destructuring tools. For example, to implement car, we get the first value and throw the rest away.
1 2 3 4 |
function car(list) { var [a,] = list; return a; } |
cdr is exactly the same, just opposite.
1 2 3 4 |
function cdr(list) { var [, ...rest] = list; return rest; } |
And their sub-functions are just combinations:
1 2 3 4 5 6 7 |
function cadr(list) { return car(cdr(list)); } function cddr(list) { return cdr(cdr(list)); } |
We can also kind of simulate the cons function through sneaky use of [ ] and ... . Now that we can do this, we can recreate the ultimate expression of programming elegance – the Bubble Sort.
Bubble bubble…
I’ve basically recreated the Scheme implementation from here in ECMAScript 6, to give us a strangely Scheme-looking ECMAScript. This is obviously not efficient, just interesting to see how ECMAScript is evolving.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function bubbleUp(list) { if (!cdr(list).length) { return list; } if (car(list) < cadr(list)) { return [car(list), ...bubbleUp(cdr(list))]; } else { return [cadr(list), ...bubbleUp([car(list), ...cddr(list)])]; } } function bubbleUpRunner(length,list) { if (length == 0) { return list; } else { return bubbleUpRunner(length-1, bubbleUp(list)); } } console.log(bubbleUpRunner(8, [7,6,3,1,2,5,9,67])); |
This outputs
1 |
[1, 2, 3, 5, 6, 7, 9, 67] |
This is obviously the unoptimized version of Bubble sort – this is for nostalgia value, not speed.
Have way to make this more functional? More of a nostalgia trip? Let me know!
This is quite nostalgic. I’m glad Wits retained its abstract-down approach to CS after I graduated: Functional -> object-oriented/procedural. It was a great way to scare off first years 🙂
Afraid it became Python shortly after that.
A multi-paradigm language is, ironically, not the best way to teach multiple paradigms.