I am looking get to grips with functional programming concepts.
I've used Javascript for many years for client side scripting in web applications and apart from using prototypes it was all simple DOM manipulation, input validation etc.
Of late, I have often read that Javascript is one of the languages that supports functional programming.
With my familiarity and experience with Javascript, my preference is to use it to learn functional programming. I expect I would be able to concentrate more on the main functional concepts and not get bogged down or distracted by a completely new syntax.
So in summary, is Javascript a good choice to learn functional programming concepts? What capabilities in Javascript are relevant/support functional programming?
JavaScript supports first class functions. See Use functional programming techniques to write elegant JavaScript.
Higher Order Javascript is a great way to get familiar with the functional aspects of javascript. It's also a relatively short read in case you want to get your feet wet without diving into a larger book.
I would say that although you can quickly grasp some functional programming concepts with JavaScript, using JavaScript consistently like a functional programming language is not a common practice. At least not obviously common. Most people don't post tutorials that pinpoint how to do functional programming with JavaScript -- the one marxidad pointed out is actually a pretty decent example, but you won't find a lot of that. The functional aspects are not often apparent, just like when people use closures in JavaScript, but are unaware that they are doing it.
The idea that you would pass two functions through as arguments to a third function, and then have the return value be some execution related to the first two functions is an advanced technique that almost always appears only in the core of full-blown libraries like jQuery. Self executing anonymous functions and the like have gained ground, but are still not used consistently. The majority of tutorials often focus instead on JavaScript's OO capabilities, like how to create properties and methods, scope, access control and also how to use the prototype property of constructors. Honestly, if functional programming is what you want, then I would choose a language known strictly for this capability.
I don't remember who said it, but javascript has been called "Scheme with Algol syntax". So for learning Scheme/Lisp, Javascript isn't a bad start. Note though that functional languages like Lisp are quite different from pure functional languages, such as Haskell.
Apart from "first-class functions" (Meaning that functions are values, that can be assigned to variables), lexical scope is also an inherent part of what makes a functional language.
Higher Order Javascript and The Little Javascripter has been mentioned already. They are both excellent texts. In addition, Higher Order Programming in Javascript may be an easier start.
Although javascript supports FP to some degree, it does not directly encourage it. That's why projects like Oliver Steele's Functional exist, to fill in the gaps. So I wouldn't recommend it for learning FP. Check out F# instead.
I would recommend reading The Little Schemer, which is a fairly slim book about recursion and is a good introduction to the functional style. Whilst it's focused on Scheme it can easily be applied to JavaScript, see http://javascript.crockford.com/little.html. I found it really helpful in my javascript development, although it gets quite tricky towards the end.
Javascript is a multi-paradigm language. If your goal is to learn functional language concepts, try starting with a pure functional language like OCaml or Haskell.
Also, Eloquent JavaScript: Functional Programming chapter.
Related
The following answer to this question does a great job explaining the differences between classical inheritance and prototypal inheritance. this was of interest to me to understand because I started working in Java, but moved over to Javascript.
In his answer, he states for prototypal inheritance that, "All of the business about classes goes away. If you want an object, you just write an object."
Yet there is so much documentation and questions on how to "write classes" in Javascript.
Why is there push to make the language something it is not. I'm looking for concrete examples of cases where using classes in JS applications are more sensible in this prototypal language and the benefits of awkwardly fitting a square peg into a round hole. As Aravind put it, why are people learning Javascript by comparing it to others, and not as it was intended... and why is this practice seemingly encouraged?
Bottomline question: Why are classes being introduced in ECMAScript 6?
The masses like classes.
There's nothing "more" or "less" natural about prototypal inheritance, this is entirely subjective. JS is its own language, just like Smalltalk and Self had different ideas about what it meant to be an object.
ES6 classes are syntactic sugar. They normalize/clean up how inheritance/etc are to be used in JS.
Similar to CoffeeScript, they attempt to standardize how OOP is done in JS, and make it more familiar to people that aren't used to prototypal inheritance.
Why are people learning Javascript by comparing it to others, and not
as it was intended?
This gets into cognitive and learning theory, but the short version is that humans like things that are familiar, and one of the ways we learn is by relating new ideas to knowledge we already have.
Why are classes being introduced in ECMAScript 6?
Classes were almost introduced in ECMAScript 4, actually. I think there are good arguments for OOP being a useful pattern for writing complex software, and class based inheritance is more familiar to many programmers than is prototype based inheritance. I think an equally valid question might be "why does JavaScript still implement prototype based inheritance when most people who learn it will be more comfortable with class based inheritance?"
If you're curious what classes in JavaSCript might look like, take a look at ActionScript 3, which is based on that draft of EMCAScript 4 with class based inheritance.
Of course, just because ECMAScript adds class support does not mean that JavaScript will, or at least that it will any time soon.
I found this article by Zakas explaining it clearly, that it's just syntactic sugar, and at the end of the day Javascript will work the same way.
Don't worry about having to learn classes or having to shift your programming styles, nothing changes. :)
Why are classes being introduced in ES6? Sugar, of the syntactic variety.
Classes are very good for people who come to JavaScript from object-oriented languages (like Java).
This is the experience I've made several times already. I had a number of J2EE web projects with good Java dev teams, who had some JavaScript knowledge, but not much. Almost the first thing I did was to explain prototypes, prototypal inheritance and how one can implement the OOP paradigm using prototypes - basically the pseudoclassical inheritance. (Now I routinely do a "JavaScript for Java Developers" workshop almost in every project of that kind.)
With that approach I mostly saw good code coming out. Most Java developers tend to stick to the pseudoclassical pattern and are quite happy with it. This is most probably not what JS ninjas out there would write, but, frankly, I don't care. The code is easy to understand and to maintain, people had a good learning curve and were productive very fast.
Prototype languages, like JavaScript, are really great for small scale, short term projects that don't require a lot of testing or maintenance. Their simple and flexible functionality really shines in this realm.
Class based languages on the other hand tend to be a little more rigid and require more setup, which isn't as great at the little stuff but the extra structure is helpful to keep the larger, long term projects scalable and manageable.
When JavaScript first started, its primary function was to manipulate static DOM elements, which is a great application for a prototype language. Fast, flexible and simple -- no fuss. Now, however, the role that JavaScript fills is much more complex and is more and more an application than a simple script. Adding classes to a prototype language does sound a little funny, but the added structure classes provide, along with their widespread familiarity could very easily help teams of developers handle the complexity of modern JavaScript applications.
I come from a background in Haskell. I'm very used to getting things done with recursive functions and the typical higher-order functions (folds, maps, filters, etc) and composing functions together. I'm developing in node.js now, and I'm seriously tempted to write my own modules implementing these functions so I can use them in my code in a way that makes sense to me.
My question is, basically: is Javascript set up to handle this type of burden? I understand that the aforementioned recursive functions can be easily refactored into iterative ones, but often times I find myself calling a lot of functions within functions, and I don't know if Javascript can handle this type of thing well. I know that things like Underscore exist and implement some FP principles, but my question basically boils down to: is it good practice to program functionally in Javascript? If not, why not?
I also apologize if this question is a little too soft for SO, but I don't want to start putting together my own tool set if it's just going to break everything once it gets too large.
In my opinion, the short answer to your question is yes -- applying functional programming principles is viable in Javascript! (I believe that this is also true for most other languages -- there's usually something to be gained from applying FP principles).
Here's an example of a functional parser combinator library I built in Javascript. (And here it is in action). It was important to be functional because: 1) it allows me to build parsers by composition, which means I can build and test small parsers independently, then put them together and have confidence that the behavior will be the same, and 2) it makes backtracking super easy to get right (which is important because the choice operator backtracks when an alternative fails).
So these are FP principles (note the absence of recursion, folds, maps, and filters from this list) that I found extremely useful in building my library:
avoiding mutable state
pure functions (i.e. output depends only on input)
composition: building complex apps by gluing together simple pieces
It's usually quite easy and pleasant to apply these in Javascript because of Javascript's support for:
first-class functions
anonymous functions
lexical closures
but here are some things to watch out for:
lack of popular library of efficient functional data structures
lack of tail-call optimization (at least at the moment)
partial application is more syntax-heavy than in Haskell
lots of popular libraries are not especially functional
the DOM is not functional (by design)
However, your last comment -- "I don't want to start putting together my own tool set if it's just going to break everything once it gets too large" -- is a good one. This is basically a problem for every approach, and I can't tell you whether FP in Javascript will be more problematic than "mainstream" techniques when things get too large. But I can tell you that in my experience, FP in Javascript helps me to prevent things from getting too large.
There are lots of articles and posts explaining how JavaScript inheritance works, but why was JavaScript implemented using prototypal inheritance instead of classical inheritance?
I love JavaScript, so I'm not saying it's bad thing... I'm just curious.
Here's what Brendan Eich has to say about what happened:
https://brendaneich.com/2008/04/popularity/
As I've often said, and as others at Netscape can confirm, I was recruited to Netscape with the promise of "doing Scheme" in the browser. At least client engineering management including Tom Paquin, Michael Toy, and Rick Schell, along with some guy named Marc Andreessen, were convinced that Netscape should embed a programming language, in source form, in HTML.
The diktat from upper engineering management was that the language must "look like Java". That ruled out Perl, Python, and Tcl, along with Scheme.
I'm not proud, but I'm happy that I chose Scheme-ish first-class functions and Self-ish (albeit singular) prototypes as the main ingredients. The Java influences, especially y2k Date bugs but also the primitive vs. object distinction (e.g., string vs. String), were unfortunate.
JavaScript was originally supposed to be very much like Lisp. Even after the syntax was changed to more closely resemble C/Java, it is still Lisp in C's clothing. I think the answer lies in it's functional programming origins. In pure FP, there is no mutable state, which means no mutable objects. If you relax the rules a bit and get slightly creative, you end up with something like protypal inheritance, i.e., you can extend objects but not modify the original object. It provides the same power as inheritance and still gives you some immutability.
Finally, twist the language around to make it look like C++ and Java, and viola, you have new someFunction() and the rest is history.
Because it was heavily influenced by Self. Both Wikipedia and the ECMA-spec mention this.
I think it was chosen because it is easy to implement, needs no extra keywords and users don't need to understand it to be able to use the language. It is also more powerfull and flexible than class based inheritance.
It's a natural choice for a untyped language. The main advantages of class based inheritance are that it allows static typing and thus type checking and a faster table based lookup implementation.
Prototypical inheritance (with closures) allows others to do things that were never envisioned. It's the meshing of several paradigms that have come together to achieve general purpose programming.
With a prototype language, you can have "mix-ins" for your classes. You can accomplish the level of encapsulation you desire, without language specific keywords. In short, prototype languages are awesome.
I hate to say it, but JavaScript, plus some libraries, can do everything I need it to. It was subversive in its development (supposed to be subservient to Java). It has much power, in the simplest of implementations.
With enough study / playing around, you'll begin to see the advantages of it's inspiration. JavaScript is one of the few languages that "hid" it's potential intentionally. You gotta get into the politics if you want to know the "why." But, it's for this reason, that it's awesome.
I am likely to be part of the teaching team for the web programming course at my University next semester and I was wondering what kind of Javascript assignment to hand out to the students. The course is not an introductory one from a programming perspective.
It is assumed that the students are familiar with OOP, data structures and algorithms, functional programming concepts and working knowledge of networking protocols (HTTP included). This is the first course in which they come in contact with JavaScript
I was thinking to give out something framework-specific (using jQuery perhaps) that involves DOM traversal, some animations and AJAX. The three questions I have in mind are:
should they use a framework or should I have them write vanilla JavaScript?
should I focus more on the functional programming part and on the prototypal inheritance part (more on the language than on working with the DOM)?
how do I automate testing for this? It's better if they have a clear idea on how they will be evaluated. Also, automated testing ensures objectivity and saves me time :).
Outcome
I made them do Tic Tac Toe as a jQuery plugin and the results were mostly satisfactory (70% of the students submitted, generally the submissions were ok).
To prevent copying code from the net, I thought out an API which they had to implement. At least, they'd have to understand the code they found on the net before copy&pasting it into the methods :).
I used QUnit for automated testing, but I also tested each assignment manually because this was the first JavaScript assignment they'd had and I wanted to give relevant feedback.
Thank you all for your ideas, they all helped a lot.
Cheers,
Alex
I think its useful for the students to know fundamentals about the language before working with frameworks. They need to know about JS Scopes, closures, prototypes, the memory model, and everything that makes JS unique.
After that, introduce them to frameworks and the DOM. They'll appreciate them much more since they'll be able to understand the implementation.
As for testing, automated testing might be easy if you have them generate a DOM that you can walk and validate. Mozilla might be able to help you out, esp with JSUnit. You can find info here
I always like the idea of making games to learn new programming concepts. You get a well-defined problem domain that's as simple or complex as you need it, and it's usually more interesting and fun to implement than other problems.
When I wanted to learn Ajax programming I used jQuery and Java server-side to implement the game of chess. It was a fun project, but pretty complicated (at least for me, but I'm primarily a server side programmer). I think something like Tic-Tac-Toe would be substantially simpler, and might be a good idea for a project assignment.
As for the 3 questions:
If this is the only JavaScript assignment, then I'd probably use vanilla instead of jQuery. But if they have a chance to do some assignments before this, I'd consider jQuery, because it just makes JavaScript so much less annoying, and it's also good to know jQuery for future employment possibilities.
I'd place an equal emphasis on both the language and the DOM, because the primary purpose of the language IS to work on the DOM, and the DOM does take some getting used to.
I think Selenium might work for the testing you're trying to do. JsUnit could also be used for unit testing the individual methods.
Start off with vanilla JavaScript to learn the basics. You don't want to create a group that relies on any particular framework that wouldn't know how to do things without it.
I would most definitely have them write vanilla JavaScript. It will encourage all students to better understand the abstractions that frameworks/libraries provide in particular environments i.e. for the most part, in the browser working with the DOM.
I highly recommend having a good text for the course. Object Oriented JavaScript by Stoyan Stefanov is in my mind a great text for learning the language, including some of the topics that many people have difficulty with (prototypes, objects, closures, inheritance, etc). I've read numerous JavaScript books and feel that this particular text best balances the core of the language and it's application in the modern client-side development realm.
You may then want to look at dissecting certain pieces of the source of a particular JavaScript library to gain insight into patterns and practices used in a real-world scenario.
I would have them write vanilla javascript AND also learn how to use jQuery. jQuery is javascript after all, and they need a working knowledge of the language anyway. They'll also need to become SWAT (skills with advanced tools), and I believe anyone not using one of the JS frameworks (or at least their own!) in today's environment is at a serious disadvantage.
See answer 1. I'd teach them about prototypal inheritance in vanilla JS, and about DOM manipulation in jQuery.
Automated testing could be achieved in several ways. 1: produce the correct output given some sample code to start with for the parts that deal with learning JS. 2: for the parts that deal with jQuery, you could provide a reference image for how you expect the result to look, provide an original document, and have them recreate the reference image using jQuery manipulation... sort of like the ACID tests http://acid3.acidtests.org/
Should they use a framework or should I have them write vanilla JavaScript?
To me, it is overwhelmingly import that people new to the language start with the language proper, not modified versions or advanced/fancy libraries that do a lot of the work for you. Besides, if you're starting off not working with the DOM, then you're not getting much benefit from using almost any library, as the bulk of most JavaScript libraries has to do with handling the DOM. Also, it's easier to spot "bad" or ill-performant code when teaching and learning in a "vanilla" environment since you don't have libraries abstracting away the nitty-gritty.
Should I focus more on the functional programming part and on the prototypal inheritance part (more on the language than on working with the DOM)?
Yes! On one hand, the DOM is not not that big of a deal; yet it is also the core of what JavaScript is used to interact with. For starters, I suggest that if you're going to be using a browser environment, you should initially avoid the DOM by using Firebug's console.* methods for output so that you can focus on the "functional programming part and on the prototypal inheritance" and other core concepts. After these core concepts have been covered, then start introducing the DOM. It's best to introduce the DOM later as time will need to be dedicated to cross-browser compatibility, which will only confuse the subject if you are trying to teach the core concepts in tandem.
How do I automate testing for this? It's better if they have a clear idea on how they will be evaluated. Also, automated testing ensures objectivity and saves me time :).
Before (and after) the DOM is introduced, you could use something like JSUnit. Also, see this question: Automated Unit Testing with JavaScript. Once you introduce the DOM, you may want to have the students generate a document that you can walk and validate as SB suggested.
We have a CMS built on Java and it has Mozilla Rhino for the server side JS. At the moment the JS code base is small but growing. Before it is too late and code has become a horrible mess I want to introduce some best practices and coding style.
Obviously the name space control is pretty important. But how about other best practices - especially for Java programmers?
Here's some tips from the front lines:
Like Java, use docblocks in Doxygen/JsDoc style for functions
Unit test. Personally like JsTestDriver, as it can be executed automatically from CI server too.
Use JSLint. It will nitpick about bad code
Consider using Google Closure Compiler. It will nitpick about code like JSLint, but it can be helpful for spotting poor doc blocks etc.
Make sure everyone on your team understands how closures work. Otherwise it'll lead to headaches
As you mention, namespaces are important especially if you want your code to work nice with other JS libraries (var myns = myns || {};)
Personally I find using a library which provides OOP helpers like classes etc. helpful. You could use prototypal inheritance but it's often a bit trickier that way.
As Douglas Crockford likes to say, JavaScript is the worlds most misunderstood programming language. Though many people don't know it, there is a right way to code in JavaScript. I have no doubt that if you let Java developers start coding before understanding how to write good JavaScript you will run into serious trouble.
The first thing to do would be to make sure everyone has read Mozilla's excellent article, A re-introduction to JavaScript (https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript). One of the biggest problems with JavaScript is that there are many ways to do most common tasks, and this article should get people on the same page. Another essential reference is Douglas Crockford's work, including JavaScript: The Good Parts.
One other thing that gets a lot of Java/C++ programmers is that JavaScript uses function scope NOT block scope. This can cause some very tricky problems. There's a great article about this issue at A List Apart called Binding in JavaScript.
To summarize the major issues talked about in the above resources, the most crucial differences to learn are
how to write object oriented code using prototypal inheritance (vs.class based inheritance)
how to use closures and lambdas
how to utilize the power of dynamic objects
how to write function-scoped code
Since you have a JS engine in Java, make it a habit to write unit tests for your JS code. Select a coding style and apply it vigorously. If possible, use tools to check that the code submits to the coding style.