Introducing hadoop in 20 pages.
We have been working with hadoop for the last couple of years Patches, but we still find it tough to get other people in our company started on it. I came up with this blog as a starting point and was kinda popular internally, so am moving it here now.
Introducing hadoop in 20 pages is a concise document to briefly introduce just the right information in right amount, before starting out in-depth in this field. This document is intended to be used as a first and shortest guide to both understand and use Map-Reduce for building distributed data processing applications.
Topics covered or concisely presented.
- Introduction to hadoop.
- What is Map-Reduce and how it works ? (With example on how to write an algorithm)
- What is hadoop streaming ? ( A great tool for a newbie ).
- What is HDFS and where is it most suitable ?
- Serialization in hadoop – “how to go about it” and why not use java serialization ?
- Distributed cache.
- Job scheduling in hadoop.
Appendix: 1A on Avro serialization and its benefits over standard techniques.
Appendix: 1B documented examples from hadoop repository.
Accepted 1 HADOOP-7971 2 MAPREDUCE-3532 3 MAPREDUCE-3316 4 MAPREDUCE-3212 Available 5 MAPREDUCE-3131 6 HDFS-2725 7 MAPREDUCE-3360 8 MAPREDUCE-2493 9 MAPREDUCE-3504 10 MAPREDUCE-3115 Involved 11 MAPREDUCE-3193 12 MAPREDUCE-3204 13 HADOOP-7726 14 MAPREDUCE-3140 15 MAPREDUCE-3494 16 MAPREDUCE-3070 17 MAPREDUCE-3354
A brief introduction to R.
First course.
To begin with download a dataset and load it into R.
Lets take a dataset from datamarket.com. For example compensations per hour of Manufacturing Sector.
To load the above downloaded CSV into R call the ‘read.csv’ function as follows.
> compensation = read.csv("compensationperhour.csv",header=TRUE,
+ sep=";",quote="\"",dec=".",fill=TRUE)
you can check if the above data is a data.frame of R.
> is.data.frame(compensation) [1] TRUE
To view the columns of dataset
> ls(compensation) [1] "Manufacturing.Sector" "Quarter"
ls function lists the sub datasets of a data.frame.
You can use rm(data) function to remove a particular data from a dataset.
>rm(compensation)
Do not run the above mentioned command. Lets not delete what we just uploaded.
Now lets explore measures of the center and spread of above data.
‘$’symbol below can be used to select the columns we are interested in. There are many ways to do that, lets follow this for now.
> mean(compensation$Manufacturing.Sector) [1] 79.90603 > sd(compensation$Manufacturing.Sector) [1] 21.8031
The most used measures of center and spread are the mean and standard deviation due to their relationship with the normal distribution, but they suffer when the data has long tails, or many outliers.
>median(compensation$Manufacturing.Sector) [1] 74.4225
A median is described as the numerical value separating the higher half of a sample, a population, or a probability distribution, from the lower half. It is one of the resistant measures for handling above mentioned problem with mean and standard deviation.
The idea of a quantile generalizes this median. The p quantile, (also known as the 100p%-percentile) is the point in the data where 100p% is less, and 100(1-p)% is larger. If there are n data points, then the p quantile occurs at the position 1+(n-1)p with weighted averaging if this is between integers.
For example for the above data.
> quantile(compensation$Manufacturing.Sector,c(.25,.75)) 25% 75% 62.07575 99.73125
The lower hinge is then the median of all the data to the left of the median, not counting this particular data point (if it is one.) The upper hinge is similarly defined.
> fivenum(compensation$Manufacturing.Sector) [1] 49.0040 61.9970 74.4225 99.9350 119.7230
Returns Tukey’s five number summary (minimum, lower-hinge, median, upper-hinge, maximum) for the input data.
Another way of viewing many details at once. You can use the summary function as follows.
> summary(compensation$Manufacturing.Sector) Min. 1st Qu. Median Mean 3rd Qu. Max. 49.00 62.08 74.42 79.91 99.73 119.70
More resistant measures of centre and spread.
R has function IQR() for viewing Inter Quantile range and MAD() median average deviation.
MAD(data) does this “median(abs(sals – median(sals)))”
> mad(compensation$Manufacturing.Sector) [1] 27.16642 > IQR(compensation$Manufacturing.Sector) [1] 37.6555
Now plotting the data and analyzing it visually.
R allows a very simple function to plot the data points.
>plot(compensation)
For drawing a histogram of a univariate data.
A simple R command would be.
> hist(compensation$Manufacturing.Sector)
You can also specify the breaks for histogram as follows.
>hist(compensation$Manufacturing.Sector,breaks=6)
OR >
>hist(compensation$Manufacturing.Sector,breaks=c(49,65,67,70,80,85,90,92, +max(compensation$Manufacturing.Sector)))

Boxplots
A box plot is a convenient way of graphically depicting groups of numerical data through their five-number summaries: the smallest observation (sample minimum), lower quartile (Q1), median (Q2), upper quartile (Q3), and largest observation (sample maximum).
Boxplots display differences between populations without making any assumptions of the underlying statistical distribution: they are non-parametric. The spacings between the different parts of the box help indicate the degree of dispersion (spread) and skewness in the data, and identify outliers. Boxplots can be drawn either horizontally or vertically.
For example :
> boxplot(compensation$Manufacturing.Sector ,horizontal=TRUE)
Designing by intuition
Designing by intuition
Sometime during winter last year, I moved to a used cold shell apartment. I had to fit a new geyser in my bathroom. The most obvious place to fit the geyser was close to the ceiling near the water line outlets. The old apartment bathroom had broken plasters and other traces of a geyser fitted by the earlier tenant. Also, I could see a firmly fitted clamp from the wall, still in good shape. I was anticipating some additional trouble since the old clamp has to be removed and a new clamp has to be fitted.
When the plumber came he was very sure about his task and quickly had tools to remove the old clamps & fit the new one. I just asked him to pause and see if my new geyser can actually be hooked on to the old clamp.
“Sir, Your geyser is a 7ltr one and these clamps are for a 2-3 ltr ones, Please let me remove these ones…” said the confident plumber. Though I wasn’t as surefooted as the plumber, I asked him to give it a try. After a bit of disputation the plumber with contempt agreed to check if it can be reused. I had to give the plumber a hand in lifting it up to the ceiling and all the while I was worried because it would be waste of his time if it doesn’t fit.
“Wow! This fits like a magic. May be it’s an illusion that the clamps are looking smaller than what they are!” grinned the plumber.
Certain times going by intuition can save huge amount of time, effort, resources & bring in some serendipity. Caution: It can also backfire. If the old clamp didn’t fit the new geyser, the plumber would have cribbed about waste of time and might even try to tinker the old clamp in desperation. And the reuse strategy might result in unsatisfactory end result.
What could be the scrupulous way to solve a problem?
Conventional process: e.g. measuring the geyser clamp holder size & comparing it with the old clamp size before trying to fix it?
or
Precautionary / Anticipatory design! : e.g. It could be done much earlier by inspecting the geyser location even before buying one. But doesn’t it sound crazy to buy a geyser to fit a clamp?
There has to be a balancing act of taking a gut call, against time + effort + resources.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Collaborative problem definition
In one of my projects, the client wanted us to design an app for a targeted set of users to make suggestions based on user’s context. The design briefs were typically of this format:
“We want something magical in life of a traveller to happen.”
“The app should surprise the user every time they open it up.”
While the client’s views gave us lot of inspiration & encouragement to jump into designing prototypes for the product, the very need to understand the users & the problem in-depth was missing.
This constant race between inspirational briefs from the client vs the urge to impress the clients with designs end up in multiple iterations and distress after a point of time.
The clients anxiety shoots up by trying out all permutation-combinations of the various components in the prototypes and the designers get restless because even after multiple iterations, they still don’t know what do the client expect nor the real user’s need.
Can every designer be Philippe Starck working for Alessi? To get the revolutionary “Juicy Salif” out of the sketches made on a pizzeria napkin during a holiday?
This juicy salif attained the status icon to product design and a decorative object/ornament. But if the initial brief were to be designing an ornament out of some juicer then Starck might have not ended up designing something like Juicy Salif.
If the early stage of the project is well spent on understanding the user/business needs, it could lead to a well-defined problem statement. If articulating the problem statement very precisely demands too many questions to clients, should designers hesitate? “A prudent question is one half of wisdom.”
What if the client has only a vague idea of the market they are targeting at?

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Embellished systems thinking
Assuming that day-to-day money transactions involve lot of coins & currency notes to be exchanged, A Company decides to develop an innovative product that helps people to easily handle and use money in the market. The company (stakeholders) now approaches a design firm to share their dream of producing this “smart wallet”. Designers are equally exited and feel that it will be a very useful product.
Stakeholder’s inspirational briefs –
“The wallet should be smart enough to dispense the money required, based on user’s need.”
“The device should be easy to handle huge amount of money”
“The device should be compact enough to carry along”
“It should be easy for the users to refill their wallet”
Since the stakeholders and the designers feel it’s a common problem they don’t see a need to spend time to understand and analyze the problem/need in-depth. So, the designers start to prototype taking into account their understanding of the problem & the inspirational briefs from the stakeholders.
Designers explorations includes -
A wallet with a meter to input the currency needed and it will dispense it to the user. Diverse forms and material as explorations. It doesn’t stop here… There are also these additional features like – Denominations display after the money is been dispensed, The total amount spent for a day, Beep from the wallet when the wallet goes low balance.. Etc.
These could be brilliant ideas, but are they still addressing the core need? These ideas are probably in sync with the inspirational brief. If the designers where to understand the real user’s need and had a better knowledge of the system they could have ended up designing something like a “transaction card” or a “Debit/Credit card” which actually even questions the very need of carrying currency! & That’s called systems thinking.

What if the designers go a mile ahead combining the systems thinking to the inspirational briefs from the stakeholders! They could have come up with something like an “ubiquitous transaction” with just mobile device or even with watches.. And that would be an embellished systems thinking!
New Facebook: Time of Your Life

The wait is over. Mark Zukerberg unveiled a host of new updates to Facebook at the F8 Conference. Just after Google’s attempts to shake up the social network scene a bit with the uber sexy G+, there was a widespread speculation among the tech community on Facebook’s ability to react and survive. But it looks like they are well-prepared for the Social Networking war.
Facebook is preparing to make a giant leap from being your Social Activity Stream to being your Life’s Stream and a one-stop Media and Entertainment Hub. They are planning to move towards this goal with two key concepts – Timeline and Open Graph.
Timeline
Timeline is a refreshingly radical concept which can redefine the way social content is created and consumed and will eventually phase out the Profile view of the user.
The current FB Profile page presents your recent activities to others (as controlled by your privacy settings) in a list view. But in its current avatar it is just a chronological report which does not really communicate who you are. This has been a major problem for social feeds- a lack of visceral clues and activity based structural data to define the personality of the user. In the absence of which there is too much cognitive load in consuming social data presented on Profiles. Insights from the pathbreaking app Flipboard, for its way of representing social data in a visual magazine like format and micro blogging service Tumblr for stunning presentation of micro blogging must have inspired the FB designers to review the Profile experience. Instead of an often meaningless list of recent activities, you now have a view of a user’s life stream – presented as a continuous UI that scrolls from current events to the time of birth. Most interesting entries are identified by Facebook’s underlying Graph Rank algorithms and are presented in a two column layout.
Zukerberg says FB wants to give its users something they feel as their home, a space they would love to maintain and curate. They have a whole new set of possibilities defined at this new home. You can interact with your life at any point in time. Did not have a Facebook account when you were born? (Not a silly question as I know many parents who have created email IDs and FB accounts for kids while they were in their mom’s womb!) Not to worry, the next time you find that childhood naked picture from your family album, click a picture on your mobile and post it to your childhood on the Timeline. You can add events that happened in your life before Facebook was even born.
This opens up a whole new paradigm in the perception of social media interactions. For example, a news application can present content in a timeline view allowing for better context.
The user experience is polished and smooth. There are few rough edges though. For example, the ads overlapping with the timeline anchors or the poor touch on Tablets. But overall, it really brings a wow factor that’s usually not associated with the Facebook and user experience.
Open Graph
Facebook introduced Open Graph in 2010 to integrate web pages into user’s social Graph. This has become an instant hit and revolutionized the way content is currently shared over the Internet. Just by clicking a “Like” button anywhere on the web you could add that as part of your social graph. This way Brands/ Authors could reach out to specific consumers who liked their product/ content.
The new Open Graph takes this to new heights. You can now add more specific user “Actions” apart from the “Like” action to Facebook Apps. You can also define different content “Objects”. This creates many possibilities. A book club app can have several actions defined to its interaction objects- Read, Like, Recommend, Edit, Hate, Reviewed etc. The objects can be a Short story, Fiction or a book on Technology. More specifically, interactions can be truer to the concept of the App rather than an odd integration with the “Like” button. For example, an app for causes can now incorporate support, object or volunteer actions to an entry rather than an ambiguous “Like” action. Facebook calls this Frictionless Experience. Also, Open Graph lets applications to push these actions to its social channels- Ticker, Timeline and Newsfeed seamlessly.
As a result, users can selectively consume content created by these apps and brands can derive more meaningful insights from user’s activity on their apps. The new graph also allows deeper integration into social channels offered by Facebook. Apps can be added to users Timeline, and their activity on the app can be aggregated meaningfully and presented. Services like Spotify, Washington Post and Hulu have already made their presence felt by creating social discovery Apps that enable recommendation and synchronous streaming of media between friends.
Missing Links
The new updates are not without its concerns. As of now it is not clear if the users will get to control what actions they want to share. While allowing social updates to selected lists at a high level, Facebook may not give users much control over the actions that are being broadcast. This is in line with Zukerberg’s controversial belief that sharing in public is the new social norm.
While the user’s activity on an app can be viewed on a timeline, there does not seem to be a direct way of showing the overall activity of all the app users on one single timeline. This will be an interesting concept to explore for brands.
It is also unclear as to what will happen to branded pages. Although it is easier to visualize them as a timeline view, one may wonder why there are no updates from FB on pages in light of new Open Graph concepts or what type of social signals are generated with user’s existing brand affinities on FB.
The experience is certainly not optimized for tablets. While previewing app on Safari on iPad, the time line editing and touch interactions on the tiny highlight bubbles just did not happen. The mobile version is not yet out for public use, but from the visuals shown, the timeline interactions seem optimized and well integrated for mobile screens and touch interactions.
Why should you care?
While there is a widespread hue and cry over the new changes, it is certainly a bold attempt from Facebook which pushes online social interactions to newer heights. From the user experience point of of view, once the initial surprises are over, the interface is a definite upgrade to current FB experience. For brands and publishers, it is time to rethink their social marketing strategies in terms of the new Open Graph ideas and targeted content consumption.
After a brief lull, the social app market is surely going to heat up once more.
gui for mongodb
We have been using mongodb for few of our projects for the last few years. One of the things we have missed a lot is a gui for doing some of the routine things, try a query, look at some of the data, a few collections and the other usual fun stuff. Though there are a few GUI apps already available, we wanted something light (read web based like Futon for couchdb) which would not need any install steps and would be fast.
Over the next few weeks we developed mViewer (MicroViewer). A light web based GUI for mongo which uses YUI and mongos java api. Currently we offer json and treeble view.
Some of the other available features are:
- Managed db and collections (usual add/drop of collections and drop of db)
- Viewing collection and db stats (count, size, storage et al)
- query executor
- Mongo stats
We are open to feature requests, would try to fit them with the available date. The code is available at
https://github.com/Imaginea/mViewer
See it in action
Javascript reverse engineering
One of the things that I miss in js is a simple trace utility that will show me all the functions executed for a particular flow. I solved my problem with this simple firebug extension “fireflow”, hope it will help you too.
It can be installed from xpi location
You can also download the xpi to a local folder and install from the local folder (File->Open).
Given below is screenshot of a trace captured using this plugin
See it in action
In this screencast, requestTree calls getVisibleSlicesPgTop, then requestSlices which calls findRequest and so on.
How to use
Assume that I am working on the page given in the screenshot and am trying to enhance the “Execute Query” flow, the sad part is I was not the first guy to work on the functionality, so am not sure what functions are actually involved. Using this plugin my task to track the functions would be as simple as
1. Open Firebug, navigate to “FlowTrace”
2. Press Start in the extension menu bar
3. Click on “Execute Query” in the actual page.
4. Press Stop once I see the result of “Execute Query”
A trace of all js functions invoked during this time would be displayed. The trace contains information about the script source, the line number and number of invocations. All the nodes in the trace are linked to their actual source.
How it works
This plugin hooks into the firefox debugging framework and registers for method callbacks. Each method call is thus recorded and then represented in this tree format. The current version excludes all anonymous functions and all functions coming from *-min.js sources.
Difference between this and profiling
While profiling is about getting a list of all invocations irrespective of the order, this tool gives a in order execution chain. We are interested in code flow rather than profiling.
Future Work
Instead of using arbitrary filters, am planning to work on exposing include and exclude rules to the end user. Feel free to request any features or enhance it.
testing a evolving codebase
We are all fans of automated testing. In our adoption of this principle over the last three years using selenium, we have come across a few pertinent challenges and a few ways to get around them. This blog narrates some of these experiences, starting with the challenges and then our solutions.
Problems
- Common Steps
- Rich UI
- Pure Client Side approach
- Language choice
Every test has some common steps, for example all our tests start with login. Sadly any change to these common steps break all our tests. In a evolving code base, these changes are more common than we would want them to be.
A lot of code is generated especially with frameworks like GWT, it is imperative for automation test authors to understand which locators they can count on, is it xpath, id, css or some other strategy. In our experience, css is the best bet, as all buttons would uniformly belong to the same style.
Some things can not be validated or completed with a pure client side approach. For example we want to search a order, the assumption for this test is that the order exists, an independent test would like to create the actual order and then search for it. Searching is the only part that we are actually interested in from the testing perspective, having a server side support for quickly creating this order from the test system is really handy.
It is far easier to debug a test in selenese with the IDE, however selenese only supports javascript eval which at times comes short for some operations. We can use any of the drivers, but that trades off some of the readability and the reverse syncing. For example once I have written a java test, if any of the locators change, I can not rely on the IDE to make this change easily.
Solution
- DSL
- Smart Locator
- Java Javascript Collaboration
A simple DSL that is built on using composite commands solves the common step issue. Selenium has a very extensible command execution model, a few hooks into the selenium-executionloop.js and this can be achieved. For example we can create a login command, which is made of opening a site, typing in the uid and pwd and clicking the submit button. Since the common steps do not need to be repeated in each test now, any change to them is restricted to one place.
Selenium locators already understand that for recording clicks on link, it is enough to just record the actual text associated with the link. Once we externalize the styles, for example that all buttons have a class “btn” and tie it up to the locators, we are able to find a button based on the style class and the text which is actually recorded in the test. If we externalize this text and the style class, any changes to the class, can now be restricted to one place.
We have a simple java layer that can execute selenese in headless mode (converting them into the selenium java driver calls) and hooks in selenium IDE (using LiveConnect) which can execute java commands. This helps us get around pure client side limitations and language issues. One of the keys in this approach is to make writing a custom java command as simple as possible, in our implementation one plain class with a annotation in a magic package does it.
Implementing Event Delegation and Custom Events in JavaScript Using JQuery & Prototype.js
Events play a very vital role in developing a dynamic UI. Events are generated as a response to an User Action or to state changes in the Event source. An Event source is the one which notifies that the user has done some action . An Event Listener is the one which waits for notification from Event source and does Event Handling .
Event Delegation
Nowadays, event binding is done completely using Javascript to make it unobtrusive. In this approach event handlers are bound to the respective element when the DOM elements are loaded. One of the problems with this approach is the loss of event handlers when the DOM structure changes. Some of the use cases where traditional event binding is not useful are:
1) Consider a Div element in the document , to which an event handler is bound . if this Div element is removed at the later stages and added again. the event handler will be lost.
2) Binding an event handler to the element, which is going to be added to the document dynamically in later stages.
This opens the door to a new way of event binding, which is called Event Delegation. Events traverse in the document in two phases which are
So, its enough to add event handler to the top most element and identify the element on which event has occurred. To identify the element on which the event has occurred, the following Event methods are used
event.Target; //for firefox
event.srcElement; //for IE
The general idea with Event Delegation is to have just one (or a few) events on elements far higher up in the HTML hierarchy, and from there, trace on what target element the event actually occurred, and then take appropriate action. Let’s explore the API present in the Javascript libraries that support Event Delegation.
Event Delegation Using Prototype.js
Prototype Introduced the following API, to achieve Event Delegation.
$(element).on(eventType,context selector,handler);
Event Delegation Using JQuery.js
Initially, JQuery Introduced the following API, to achieve Event Delegation.
$.live(eventType,handler);
However , the live API method had some performance drawback. since one needs to wait for the event to traverse to the top most element of the document.It has no support for method chaining, to solve this, Delegate API was introduced, Delegate lets us bind the event handler to the nearest parent element
$.delegate(context selector,event Type,handler)
Custom Events
As Browser supports Document Object Model (DOM) , it supports DOM Events. When a user does any interaction on any DOM element,a DOM event is triggered by the browser and Event Listener gets notified.An example of this is a “click” event. whenever a user performs “click” action on the element , the click event is triggered and will notify the Listener, where a event handler function can be added .
Limitation of the DOM Events
Since DOM events are very limited in number, we need Custom Events. Consider the simple use case of adding an event listener for hide, this is difficult to do as there is no DOM event called “hide”.
Custom Events are simple to create and a utility method can be written to handle it. In my experience some of the points to consider while writing an utility function are:
An utility Function containing a variable to store the list of events.
function Event(){
this.events = {};
}
An observe method is added, which binds the event listener with event source. this observe function takes three parameters
i)DOM element on which the event has occurred
ii)Event type which has occurred
iii)Event handler function, which does the event handling
Event.prototype.observe = function(el,evt,handler){
var isDomEvent = checkDomEvent(evt);
if(typeof evt != undefined && typeof evt == "string" ){
if(isDomEvent){
if(el.addEventListener){
el.addEventListener(evt,handler,false);
}else{
el.attachEvent("on"+evt,handler);}
}else{
if(this.events[evt] instanceof Array){
this.events[evt].push(handler);
}else{
this.events[evt] = [handler];
}}}}
A fireEvent method , to fire the event manually and notify the handler
Event.prototype.fireEvent = function(el,evt){
for(var i=0,j=this.events[evt].length;i)
try{
this.events[evt][i](this);
}catch(e){
continue;
}
}}
Element.observe(“custom:event”,Handler);
Element.fire(“custom:event”);
Element.bind(“custom event”,handler);
Element.trigger(“custom event”);
kill by name
on *nix at times I miss a “kill by name ” utilitly, my life mostly involves running a java task, which takes a bit too long and then I want to terminate it. Here is a simple Kill by name implementation
killByName() {
args=(“$@”)
processLine=`ps -ef |grep ${args[0]} |grep ${args[1]}`
processToKill=`echo $processLine |awk ‘{print $2}’ `
kill -9 $processToKill
}
Add this to your bashrc file and we can kill programs by their name. For example if I spawned a process with
java com.pramati.DoesNotTerminate
I can kill it with
killByName java DoesNotTerminate
All this little function does is look for processes that have java and DoesNotTerminate, gets their pid using awk and runs kill with the awk output as xargs.
Closures in JavaScript
I often find that all the great goodies that JavaScript comes with literally leaves me groping for equivalent luxury in other programming languages. One such super cool concept is that of ‘closure’.
So, what’s a closure? The term closure has several meanings depending on the context it’s being used in. In computer science, in simplest of words, it refers to a first class function that retains access to variables defined in the same scope as the function. Also, I might need to explain the phrase ‘first class function’ – it basically refers to a function that is an object, an instance of a type that defines functions, which enables you to treat a function just like any other object.
Now, let’s use an example to take this further -
function getMultiplier(m){
return function(n){
//m in the following statement will always refer
//to the variable m available in the same scope as this function
return n*m;
}
}
var get5x = getMultiplier(5);
get5x(3);//returns 15
get5x(5);//returns 25
From the above code, notice that the function that is created and returned inside getMultiplier, will always have access to the variable m. However it is important to note that we are not just referring to the value of the variable m. Let us look at another example.
function Fruit(aName){
var name = aName;
this.getName = function(){
return name;
}
this.setName = function(aName){
name = aName;
}
}
var mango = new Fruit("Mango"),//any function in JS can be used as a constructor
apple = new Fruit("Apple");
mango.getName();//returns Mango
mango.setName("Green Mango");
mango.getName();//returns Green Mango
Observe that in this example, the way we use the variable name, reminds us of private variables. The only way we can access the variable ‘name’ is through the closure functions getName and setName. More importantly it also gives us a clear cut example of how closures work on variables/memory – not just on the values contained in the variables when the function was created. Also note that we have two closure functions defined here, in the same context, sharing the ‘name’ variable.
I hope this explanation gives you enough information on understanding the basics of closures. Closures have a great role to play in object oriented JavaScript. And of course, closures are possible in many other languages, Python being one of the other prominent ones.





