Functional Programming using JavaScript
scott.sauyet.com
scott.sauyet.com
[EDIT] it probably became a pattern because of browsers that didnt implement the history API, so all hashchange events were pushed onto the history stack.
If you're launching a link from a page you expected to come back to, surely opening the link in a new tab would be the way to accomplish this?
For that reason, I think that pushState here would make more sense. The state of the page does, after all, change.
When the user is in a linear sequence such as a slide deck, photo gallery or similar, the "previous"/"next" buttons don't map to the browser's back/forward buttons, they navigate the sequence. Littering the history with the navigation history of this sequence does not make sense.
However, it'd be nice if browsers could perhaps record the history (perhaps as some kind of sub-tree history), allowing me to see that I not only visited this slide deck, but that I also visited these specific slides.
I don't think this is better personally. I prefer the use of pushState and back button taking me to the previous slide.
If I really want to back all the way out of the slide deck I will notice after a couple of clicks I need to do something further to go 'all the way back' and right click the back button and click a 'non-slide-deck' selection from that menu.
In this case it doesn't make sense as you remain in the "slide" view the entire time.
https://developer.mozilla.org/en-US/docs/Web/API/Location.re...
* myname.com/about.html
* myname.com/projects.html
Would you want to jump out of myname.com entirely when you press back? If not, how do you differentiate that from slides with myname.com/slide1, myname.com/slide2?
Learn Haskell/OCaml and you'll see how to really take this kind of reasoning many, many orders of magnitude upward. Learn Coq/Agda to see yet another meteoric jump.
* In a large corporate office with heterogeneous skill-sets among developers, but where almost all had some experience with Javascript.
* Javascript Users Groups
In each case, the idea was to make the case that FP could offer them practical advantages. The goal was definitely not to teach them FP or to suggest the best FP tool.
There are definitely better languages in which to do FP. But if for whatever reasons you're working in Javascript, I would suggest that a functional style could be useful.
I, for one, don't know if I would have ever tried to start learning Haskell if I didn't discover some of the benefits of FP first hand through a familiar language.
I'm very serious about this, because as far as I can tell, the next best aspect of FP might be first class functions, but those are starting to be used more in mainstream languages (at least the technique of applying transformations on generic data rather than writing special classes everywhere or using templates).
I'm beginning to feel that the real advantages of FP are being obfuscated by unusual syntax. There should be no reason why we can't go from some of the FP notations to the plain old algebra style (x=y) of C-style languages like Javascript. With better references and immutable variables, we should be able to split calculations up over several lines and have the compiler figure out how to optimize it into basically FP code.
P.S. I do know lisp, so I'm asking for a rather more enlightened answer than just to research it further.
Functional javascript, or python, is not awesome because the default datastructures are mutable, and the ecosystem of libraries are written in an OOP style using mutable data structures. There is some small value in writing the code you control in as FP a way as possible, but you aren't going to have a ton of success in that unless you are willing to rewrite your dependencies to also be more functional.
ReactJS may be a killer app that can influence javascript's "opinions" at the ecosystem scale, but that is going to take more time. I've been using ReactJS since it came out as tech lead on small teams, and it was not without challenges to get an OOP trained team to use React well, and to avoid the OO parts of React.
Edit: In theory, yes, if you could somehow statically enforce that your C code (and dependencies, including the OS) have no side effects, then some hypothetical compiler could combine your imperative C statements into functional expressions, though I don't know what advantage that would give you. Maybe I have misunderstood your post.
That said, FP often involves the introduction of monads which restore sequencing (along with many other beneficial effects). A monadic FP computation is very similar to a plain imperative computation... just with all of the arbitrary details automatically selected to be coherent and optimal.
You can even pretty easily embed OO in FP languages (though it gets a little hairy sometimes) since as soon as you can simulate open recursion somehow you can get late-binding as you like. See Oleg's O'Haskell papers for this kind of nonsense.
[0] In this regard, even Haskell is impure since it allows for non-terminating computation which can be seen as an impurity since you cannot expect to just evaluate `let x = x in x` repeatedly and get anywhere meaningful. Other languages like Coq, Agda, Idris are terminating (thus not Turing Complete) and therefore truly pure.
Seeing how monads reintroduce temporal dependence is also an astounding insight, and I can't believe that I've never seen them described that way. That means that the monad has more in common with, say, the mutex, than it does with I/O. I've always tried to approach them with metaphors like sockets and utterly failed to grok anything for more than a couple of days.
I'm thinking that if Haskell is an "impure" functional language, then I would like to see a "pure" imperative language. I envision it as similar to Go but multithreaded and basically every function in the language would be its own process, communicating with sockets (so basically a shell with C-style syntax). The overhead could be largely eliminated with a stackless context switcher. It wouldn't be able to achieve the optimization of FP but it might be more approachable to the mainstream and by extension maybe iterate faster and lead to higher productivity. I’d like to see it take the place of OpenCL/CUDA and SIMD because I find them tedious compared to more elegant languages like MATLAB/Octave.
http://adam.chlipala.net/cpdt/
True purity actually doesn't look much like Go at all. Instead, it means that every expression literally can be evaluated and replaced with its value in a completely arbitrary order. This massively simplifies the meaning of a language and opens it up to bear much more structure (such as that of a mathematical proof).
So, maybe I'm just using the power of wishful thinking with my characterization above.
This actually sounds pretty nice to write as a shell pipeline (and that's a really good way to do it), but really, it's likely that you'd end up writing some code like
main() {
q = queue(5);
avg = 0;
while(!eof) {
r, eof = get_record();
t = transform(r);
if(q.size() >= 5){
avg -= q.pop();
}
avg += t;
q.push(t);
print avg/q.size();
}
}
or something, but it'd actually be annoying to extract out the logic for handling the rolling average and split it out from the looping code, at least if you want to maintain constant memory use, and if you had to do something similar in a few places, you'd end up duplicating code.I claim that it's possible to factor that code nicely out in Haskell, and still get the compiler to generate the same machine code as the C loop. This doesn't particularly use first class functions, and more relies on the combo of sufficiently smart compiler and sufficiently strong guarantees about what code will do.
I also take slight offense at calling C-style languages "plain old algebraic style", since it'd be really strange in algebra to say both x=5 and x=6. I would not hesitate to call FP languages where you can substitute equals for equals and such the algebraic languages.
Or that unusual syntax is precisely motivated by trying to seamlessly and naturally express FP code.
Either that or they were just being intentionally obtuse... come on, man. Which sounds more likely of these two? I'd personally never want to program in a language with the semantics of Haskell, and the syntax of a C-like language.
> With better references and immutable variables, we should be able to split calculations up over several lines and have the compiler figure out how to optimize it into basically FP code.
Or just dive the code up into whatever temporary and intermediate steps that you need with let-in expressions and where-declarations? I mean, why not? If what you want the compiler to process is FP code, then just divide it up like you would divide up FP code. FP /= one liners.
Most FP paradigms are natural and quite easy in JS.
And learning Haskell can also be described as an "uphill battle".
Or you know, stick to JS, because it's of course adorable that you can do functional programming in a functional language (we could do that since the 60s), but having access to the most prevalent language in the web and being employable is even better.
Even if the only reason (hint: it's not) were that Purescript uses familiar tooling such as NPM, node, CommonJS modules, bower, etc and would allow users to focus on learning functional programming faster.
For those that wasn't more than the examples, there is the wonderfully comprehensive, practical, and just plain fun Purescript book[1].
var getIncompleteTaskSummariesForMember_imperative = function(memberName) {
return fetchData().then(function(data) {
var tasks = data.tasks;
var results = [];
for (var i = 0; i < tasks.length; i++) {
var task = tasks[i];
if (task.member == memberName && !task.complete) {
results.push({
id: task.id,
dueDate: task.dueDate,
title: task.title,
priority: task.priority
})
}
}
results.sort(function(first, second) {
return first.dueDate - second.dueDate;
});
return results;
});
}
Still longer than the 10 lines of functional code, but a much more fair comparison.[0]: http://scott.sauyet.com/Javascript/Talk/2014/01/FuncProgTalk...
This would be the code I'd write for the same task, pure JS assuming that fetchData returns an ES6 Promise:
var getIncompleteTaskSummariesForMember = function(memberName) {
return fetchData().then(function(data) {
return data.tasks
.filter(function(task) {
return (task.member == memberName && !task.complete); })
.map(function(task) {
return {
id: task.id,
dueDate: task.dueDate,
title: task.title,
priority: task.priority
}; })
.sort(function(first, second) {
return first.dueDate - second.dueDate; });
}, function(reason) { console.log(reason); });
};
Now, does that count as functional? I'm not sure I really care, but it's certainly JavaScript-ish.I haven't read it yet.
I'd also recommend JavaScript Allonge on the same topic. https://leanpub.com/javascript-allonge
The reason for the question is that Clojurescript supports all the FP idioms of your slides more naturally and also has more FP features.
Book mark it and share it.
http://jsperf.com/oop-vs-ramda/3
TL;DR: Ramda is somewhat faster than OO one
http://jsperf.com/oop-vs-ramda/4
TL;DR: Imperative is faster than functional. Functional is shorter (33% slower in chromium, 83% slower in firefox), but might be more readable depending on your preferences.
Anyway, doing the same to the FP version yields almost equal speeds (Chromium):
The one remaining is the one after fetchData, which looks like it could be async and make use of a promise.
It only yields equal speeds in chromium (good to know), although if you try in firefox, imperative is still 4 times faster.
I can't find the talk, anybody got a link?
(Ramda is pretty bad ass.) http://ramda.github.io/ramdocs/docs/
--edit It's formatted kinda weird, where both up/down and left/right arrows navigate through the different sections.
``` return fetchData().get("tasks").filter(x => x.member === memberName).filter(x => !x.complete).map(x => {x.id, x.dueDate, x.title, x.priority}).call('sort'); ```