Saturday, February 1, 2014

Thoughts through Tweets

This is a collection of some thoughts that I've expressed over tweets...

Using profanity doesn't make us expressive, it simply shows we're vulgar and lacking.

I think, history will say, Scala & Clojure are to FP as C++ is to OOP.

"safety" in type safety is as comforting as "security" in social security.

Design patterns are the cliches of software design.

I've found intuition and gut feeling to be the most useful tools for design so far.

I don't want my project stakeholders to be guests on my projects, I want them to have a "skin in the game," investing their time & effort.

Learning a lib, a lang is easy. To improve code & change development style is hard-requires discipline & great self awareness.

"My boss is not convinced" is euphemism for "I'm not convinced, but I'm in denial (& it feels good to blame it on the boss)."

Relying heavily on some of our key strengths sometimes tends to be our major weakness.

I prefer a healthy dose of skepticism over naive optimism or incessant pessimism.

As engineers, we're good at telling boss what won't work. We should learn to explain what'd work & how it'll help the business.

Jumping into Scrum without practices to promote sustainable dev is like jumping into marriage with no real commitments.

There's usually a point in time when a project can be turned to success, but that opportune moment is rarely at the end.

Each time someone hears the words "best practice" God kills a few neurons.

You know you work for an enterprise when you dial long distance to schedule guy in the next room to fix your projector.

If work is not "having fun" you're likely holding on to a stinking job than being in pursuit of a passionate profession.

When getting into TDD, be prepared not to learn, but to unlearn; the more experience writing code, the more unlearning there is.

Architecture for a product is like salt for a meal–essential, must be in right proportion, & can't be self-serving.

Shaving head, losing shirt, walking barefoot doesn't make us Gandhi; at best only a cheap imitation of a 1/2 naked fakir.

A professional who doesn't learn to fail, fails to learn.

Given a choice between code that's simply sensible vs. hypothetically extensible, I prefer the former any day.

Let's be driven by inspiration, and not desperation, to attain that success that we can relish.

The words static and synchronized are menace to TDD.

Be opinionated, but unbiased. "The man who never alters his opinion is like standing water, and breeds reptiles of the mind" William Blake.

Continuing to use miserable developer tool is like being complacent in an abusive relationship-why not get out for a better life?

They say "end does not justify the means." But, in agile development, do we expect means that justify the end?

"We learn more by looking for the answer to a question and not finding it than we do from learning the answer itself." Lloyd Alexander

The irony of our industry, we brave to automate the world, yet we fear automating our projects.

IMHO, a great talk/book has both high information density & velocity; how much quality info is given & its pace.

If your company wants you to follow only standard practices, they're asking you to follow the path to mediocracy.

Dear company, owning code your programmers can't understand is worst than losing the code.

Zinnser: "Easy writing makes hard reading; hard writing makes easy reading" Not just writing, it's apt for coding.

If your code is not testable, it simply means your design sucks.

Ignorance is a tumor, remove early.

The only little predictable aspect of our lives is its unpredictability.

"It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle.

In Java, you work for the compiler; in Scala the compiler works for you.

Trying to release product fast by compromising quality is like trying to lose weight fast by smoking.

"Methods to gain wisdom: by reflection (noblest), by imitation (easiest), and by experience (bitterest)"—source unknown.

What's the difference between a mafia and the government? Mafia doesn't require you to do paper work for the money they take away from you.

Dear developer, pride not developing complex software; strive instead to develop a capable and useful software.

Two sets of people scare me: those who can't follow instructions and those who can only follow instructions.

A good programmer should never fear throwing away code.

A framework that's your darling today is the one you'll hate in two years (make that four if you're a fanboy).

Some people teach me how to live; others how not to. I learn from both. Thankfully, however, each day I get to meet more of the former.

My mentors did not change the word, but hey they changed my world. Be a mentor.

You can't be Agile if your code sucks

If you think a piece of code is unusable, design for reuse to remove all doubt.

Complain to the one who can fix, praise to the one who can benefit.

It's not a mistake that the design has to change, it's a mistake not to make it feasible and cost effective to evolve (within reason).

"Yes" is nice to hear, "No" not so much, but "Yes" followed by inaction is the most difficult to deal with.

Decades ago I wrote bad code without knowing, today there's no doubt anymore, what a difference :)

If programmers are like (aspiring) musicians, some create music, others merely noise.

Stuff we create deserves checkin, not when it's perfect, but so we can evolve it fearlessly.

Checkins also serve as a form of information radiator.

What surprises me the most is not the realization I was wrong, but the strength of the conviction I had before that.

It's funny that most of us think the world has to change, but rarely think twice about ways to change ourselves.

Learning's like peeling the onion, you have to go through layers, & it involves tears...of frustration and then of joy.

Sometimes the hardest part of solving a problem is realizing and accepting the simple solution that's been there in front of you all along!

Depth of knowledge + ability to communicate + with a touch of humor + engaging the audience == a great presentation

If there's one thing we can learn, it's that we can't achieve desired results, leave alone perfection, in one try; results evolve.

hope is contagious

Success comes not from agreement, but from alignment.

There are no good people and bad people, three are only good behaviors and bad behaviors through the eyes of a context.

A key design skill we need to develop is the ability to discern accidental complexity from inherent complexity.

Theory is to programmers as vegetables are to children, essential but you can't just feed them bland.

Why do companies waste time asking questions in interview? Ask candidates to do real work, that's what you're hiring for.

A great business touches many pockets, a great person touches many hearts.

Passion is necessary but not sufficient; passion in the absence of hard work is like a seed with no soil.

Knowledge is a wealth that grows as you give.

If all we care about is speed, be prepared to end up fast in the ditch. Agile's about both speed & direction or relevance.

When problem solving, half the solution, an essential skill, is to eliminate unnecessary details.

I love it when someone, instead of complaining, takes time to research & sends a solution to problem. Lots of respect for folks like this.

The only constant is that Heraclitus quote about the only constant.

I admire the human quest to create new powerful devices, so fellow humans have options like never before to play solitaire.

Every moment, every interaction is an opportunity to learn, some teach us what we could be, other what not to be.

Greater the ignorance, larger seems to be the conviction.

Languages we learn should fundamentally change the way we think, challenge, shake the roots we've come to believe & rely upon.

Seems to be nothing more fulfilling & motivating than writing a todo list on a piece of paper & striking items off as they're completed.

The effort is not in writing, it's really in rewriting.

Rather than searching for agile practices to follow, pick a problem worth fixing & look for ways to realize that.

I find it helpful to understand the economic reasons for actions and the economic impact of the change.

TDD is a skill, it involves a decent amount of unlearning, relearning, and reevaluation. Let's not expect to get good at it instantly.

Sure TDD requires discipline, its a way of thinking, and all that, but I feel programmers need a sense of awareness to benefit from it.

The rigor in development must be in proportion to the cost and consequences of failure.

Languages are like vehicles, they all help us get around, some better than others. Travel on a few, based on the needs.

Curiosity - it's the pathway from good to great.

Everyone's complaining about someone, so collectively we all suck. Now that we got that figured, can we do something useful?

It's perfectly safe, no one has ever died of an extra act of kindness.

How others acts is not in our control, but how we react is entirely; We have the right of way on the civil parkway.

Quietness is a state of mind that can be experienced even in a noisy environment.

Most humans seem to be much better at critiquing than creating. We can channel this wisely thru feedbacks for a greater good.

It's much more fun to laugh with people than to laugh at them.

Does anyone keep track of their MTBYS - Mean Time Between Yak Shaving .

Conflicts & war arises, not due to respect for one's belief, religion, group, gender, or sect, but from the lack of it for the others.

My marriage has matured to the level that my wife and I can now fluently communicate... using airport codes.

Number one rule of collective ownership, we should never get into merge hell... we should only give it... with frequent check ins.

Those feeling strong that an organization must change, seriously start & follow the answers to question "how can I change."

Kicking ourselves often out of our comfort zones is a safe way to broaden that zone.

No matter where we reside, lets avoid living in the state of denial.

A better measure of audience or colleagues is not the answers they give, but the questions they ask.

A great leader, rather than instructing, motivates people to realize their organization's goals.

The first step in effecting change is to give it a fighting chance, most people seems to be convinced system's too rooted to change.

Each of us is living a dream, we just have to check often that it's ours and still ours.

Can't pause the passage of time, but every moment's an opportunity to turn growing old into a fruitful act of growing up

Sure there're so many things we can't change, but let's improve things_ however small_that's glaring at us and we 'can' change.

Good habits don't come from simply talking about them, but honed by sincere, disciplined, continuous, and deliberate practice.

Each day seems to be a realization of this inequality: Know < things forgotten << ignorant

a functional language in the hands of a dysfunctional team is like my junk in the hands of the TSA-it's not solving the real problem.

It's really not about what we learn, but how we learn it. So much of what we know builds and feeds on each other.

Failure is the stepping stone of success, but look up frequently to ensure the stones lead us in the right path & not in circles.

Speaking and writing, like any activity, gets better once we begin to enjoy it.

Use of the word "they" in the same sentence as "build" or "test" is a sign the team needs to improve the ways.

So much code being developed "design by accident" rather than "design with intent."

Agile in the absence of disciple and commitment is like marriage in the absence of love and trust - not sustainable.

We all want to create simple design, but the act of creating such a design is not that simple.

The mindset I prefer is to have a mind that's not set in ways.

You know it's time to stop and get back to important stuff when you hear yourself say "aren't these yaks cute."

Experience is not the passage of time but a measure of how our efforts have critically altered the ways we think and act.

Each generation faces atrocities of madmen & their group of thugs, only to prove that kindness & courage of the common hardworking prevails.

For a programmer, a day without a yak to shave is like a day without sunshine.

Some are too eager to teach lessons, not realizing, the student for lessons is not someone else, but the deserving inner self.

When will the software industry realize that the only true measure of estimates is in units of yak shavings.

I admire the innate resilience of programmers, without it the first set of compiler errors would have put an end to the field.

It's been discovered the darkest place in the world is located in the state of denial.

An important skill for programmers to develop is their sense for code and design smells, especially in their own code.

Best practices are like pills, targeted prescription with expiration date. Not wise to swallow them, ignoring the label.

learn to practice, practice to learn.

Everyone has three ages: the calendar age, the how-I-feel age, and how-others-feel based on the maturity they display.

writing is throwing the ingredients together, rewriting is seeing it turn into a sauce.

There are no good people and bad people, only developed minds and developing minds.

The weak put up with bureaucratic nonsense, the brave fight it, the wise simply work around it, never taking eyes of the goals to realize.

Having observed multiple enterprises I've come to realize that "stage-gate" is where their process and productivity goes to die.

you are the stories you tell.

A sense of prolonged professional comfort is a sign of setting into complacence.

The more I interact with organizations, the more I realize how important competent people are to the core of their success.

It's not much of a charm, but emotional stability and willingness to make things work, are essential qualities for customer-interacting jobs.

The most difficult to learn aren't the ones that add to our knowledge, but those that demand changes to our habits and behaviors.

convention over configuration is awesome when we know and can remember the conventions.

Reboot seems to be a proven solution, not just for windows, but from treadmills to airplanes!

it's interesting to meet organizations where management wants devs. to create quality code, but devs feel their management won't let them.

We looked at this problem and said we can solve it using a pool of threads. Now we have a pool of problems.

I really hate being distracted from my distractions.

It's quite clear how poor my design abilities were 10 years ago. What's not clear is how it sucks today, what I'll tell 10 years from now.

Weak can turn strong with diligence while the strong may turn weak from complacency.

Our field has fundamentally transformed in the last two decades, from devs fighting DLL hell to fighting assembly and jar hell.

It's quite dangerous when the experts quit listening and insists on the world accepting their dogmas and prescriptions.

Those who can't spend time and effort on automated feedbacks have to expend a greater magnitude on the aftermath.

If they hear you say "change" they ask you "Why?" If they see you succeed, they ask you "How?"

Have scientist figured this phenomenon that slows time to a crawl when you get on the treadmill?

You know it's time to take a break when you're fixated to review and fix code printed on the back of someone's T-shirt.

Good communication skill is not just having a nice fluency of words but must be accompanied by fervorous good attitude.

Software development is not an act of spewing code but a balanced art and economics of evolving and refactoring just enough code.

I fear my children becoming programmers one day, and start to ask questions, and discover my dark past—coding with COM and CORBA.

It appears, most of the "we can't convince our management" comments come from those who've not taken the time/effort to convince themselves.

Code smell is a wonderful metaphor (coined by @KentBeck); the more we put up with bad smell, the sooner we impair our senses to recognize.

The first step in paying technical debt is to check if we're actively acquiring avoidable new debt each day.

Professionalism is an act where we openly compliment and critique our ideas in a civil manner and end the day with a cheerful handshake.

There's cure for ignorance, and even incompetency, but all is lost in the presence of complacency.

A good learning should not merely fill our brains with more knowledge, but influence a change in our behavior, so we can achieve more.

A perfect way to fail is to be bent on making things perfect instead of valuable.

The biggest challenge is not the availability of tools or techniques, but the strong resistance to explore, experiment, & adapt.

It's critical to know if a low cost service is a result of higher efficiency or lower quality.

Son: "Dad can I have it?" Me: "302" Son (to my wife): "Mom?" Wife: "404"

So many of us confuse listening with agreeing, but they both are quite orthogonal.

There are but two constants, the first, as Heraclitus said, is change, and the second is the inborn human resistance to it.

One of the biggest services a mentor can provide is help people quickly get out of their comfort zone.

I am, but a work in progress, being debugged and evolved every day of my life, with a few bugs in me fixed, and a few new ones added.

Automated test is an act of self discipline where we're willing to invest time now for a greater saving later. Reaping that benefit today.

I think it takes some courage to invest in ourself.

Worry not if the American dream is dying, instead wake up to realize your dreams.

Asking someone to comment poorly written code is like asking them to take a higher interest loan to play their current debt.

Create fast should not imply drop quality, but to focus on the most essential features and business value.

Why do people speed like crazy on the roads and stand still on escalators?

Passion is the alarm that wakes you up, so you can go realize your dreams.

Let's give variables the names they deserve.

Expect a good mentor to serve as a ladder than as an escalator or an elevator/lift.

Each of us have two personalities, one before we have our first caffeinated drink of the day, and a gentler one after.

Let's judge code, not people.

There's often a tradeoff between more vs. better of something.

Ruby: 'Hey dude, we're about the same age :snicker' ~ Java: "eh, you're as cool as you think?{grunt}" ~ Lisp: (damn juveniles)

The problem with those of us who strive for perfection may be we believe we're perfect in defining perfection.

It's not the syntax or the idioms that we should pickup first in programming, but a sense for code smells.

My estimations skills are only surpassed by my ability to produce bug free software.

Giving in to the fear of failure is the biggest of all failures.

10% of the time, we write ugly code for performance reasons, the other 90% of the time, we write ugly code to be consistent.

Software is never written, it's only evolved.

If we ever figure a way to time travel, I will go back and stop that dude who put space in the directory name "Program Files"

Exercising is hard, but it makes the rest of the day so much easy.

The most important investment we make each day is on ourself, for if we don't trust, how silly to expect others to.

The irony of software dev_a field where most practitioners claim things change real fast, and, yet vehemently resist that very change.

Martin Luther King effected change, not by yelling America sucks, but by telling the dreams he had for her better future.

Oh, the pattern name you're looking for is "coding in desperation."

So many of us are eager to find an answer, but without knowing the question.

Instead of hearing "we're agile!" I'd like to hear "we're successful and here's why."

A programmer's command of the computers is in proportion to how often, and how comfortable, they're on the command line.

An expert is shaped, not by all the answers they've learned, but by the questions they've not been embarrassed to ask.

My days would be so much better if I don't have to constantly deal with… myself.

In programming, the variable flag is pronounced "smell."

The problem with most of us is not the one of misconception, but the one of conviction, that what have it all figured out.

Jealousy's a feeling we don't wanna work hard to attain what others have. Inspiration motivates us to attain & exceed. Cultivate the latter.

change is easy when we change often.

I like meeting someone negative and snobbish from time to time, they remind me, and make me thankful, how wonderful rest of the world is.

Let's not confuse experience & comfortable. One requires constantly getting out of the comfort zone, the other settles in.

programmers should care about warning as they care about errors.

Flying worldwide has given me insights on how reservation systems handle concurrency. It's called "yell out the passenger's seat number."

Ego is like cholesterol---there are good parts and bad parts.

The word to define the behavior of postponing to the last minute is not agile. It's called unorganized, lack of discipline.

Education is not a pursuit of a degree but the elevation and broadening of ones mind.

In programming, exceptions have become anything but.

I don't mind people talking to me when I'm working, as long as they don't expect me to actually listen. :)

I realize I can never convince anyone. At the best, I can merely lay down good reasons to help others convince themselves.

More advices are given than taken.

We may get better results if, rather than appraising employees' performance, managers focus on nurturing a good team culture.

It's an irony that fields where rapid feedback's hard are longing while the field where it's largely affordable's wants all up front.

You've shown what great things a simple man with discipline and perseverance can truly achieve. You live in our memories. #Mandela

Few things are satisfying as literally seeing tears of joy fill the eyes of someone, at the moment of their hard earned success.

There's no excuse worst than the one we give to ourself.

Quality of a presentation = inspiration * information

One of the easiest way to reduced quality of any activity is to cram it all on or near the due date.

We have no way to influence the state of the world we enter, but, I hope, we can do something good about it before we exit.

It's better to be an exceptional you than an average imitation of someone else you consider exceptional.

I don't take new year resolutions, I prefer more frequent, everyday resolutions. It's lot easier and fun to fail each day than once a year.

On any given day, I meet two sets of people: those living to die and those dying to live. The latter is so much fun to hang around with.

Every design, I bet, looked like a good idea at that time, however long ago and short lived that time period was.

Any seemingly good set of practices may yield better results when used contextually instead of prescriptively.

Experience is the passage through time where we gain the ability to look at our own past and say "what the heck was I thinking then?"

I hear that TDD is mainstream, most organizations follow Threat Driven Development.

In the digital age, developing the skills to ask the right questions is more important than having the right answers.

Success is a garland of small failures tied together with a thread of perseverance.

Teaching is not only about helping students acquire knowledge, but help them pick up better learning skills and work habits.

It's unintelligent to repeat the mistakes of yesterday. Get creative, go make new ones for today.

Trust is like hard earned wealth, we have to work each day to build it and use caution not to lose it all in one foolish act.

I think that authors who write more than one book suffer from short term memory. Why else would they take on the pain yet again? :)

What's being spoken is often not what's being heard.

It's not about fixing a bug, but learning how things actually work.

A good mission in life is not to rush to perform what others do, but fill the gaps in a passionate area where others won't.

The hardest step in solving any problem seems to be asking for help.

Functional programming is cool, but the real charm is in what it makes easy—lazy evaluation.

A design lesson I've learned over the years: behavior over state.

Most of us have to fix just one thing - attitude - rest of it gets fixed fairly easily.

When coding, null should be pronounced smell.

I really like TV... turned off.

agility is about delivering value early without compromising a reasonable quality of the product or the heath of the developers.

I don't prepare for talks, the talks prepare me—there's so much learning that happens.

Strive to be an informed constructive critique and a contributor, not a troll.

Know thy audience.

The best gift I've received from anyone is the warmth of their company and the lasting memory of good times with them.

Sorry, you have to wait, I will get to complaining about your flaws as soon as I fix mine.

Never deprive people the pleasure of enlightenment through discovery.

At some point we've to realize that effecting change in an organization start with us overcoming our own fears.

Efficiency is attained not by doing tasks better or faster, but by avoiding those that shouldn't be done in the first place.

always fun when in a room with two people, one telling the code is terse while the other pointing it's verbose.

There are only two options: adapt or perish. The first one's really fun once we break the inertia.

Complain as much as possible, but armed with facts, not with prejudice.

Let IDEs minimize typing not remove thinking.

Being content with available language/lib capabilities is as dangerous as being ignorant of them, given how nascent our field really is.

Every day is an opportunity to refactor our minds.

A good code should read like a story, not like a puzzle.

History bestowed us with Lincoln, Gandhi, MLK, Theresa, Mandela,... wish the world was truly blessed so these heroes were not needed.

what if we quit coding and start expressing?

The most rewarding, yet the hardest, part of writing seems to be the willingness to remove words to strengthen the sentences.

Values are not what we teach about, but the ones we live by.

It's not the failures that leads to success but the perseverance to apply the lessons learned.

A maintainable code is a gift we give ourselves for the future.

Most of what we reject is not due to the lack of viability of an idea, but one of fear from unfamiliarity with it.

Lesson this morning: Sometimes if it seems hard it may not need an added thrust but an extra thought.

The first human who turned noise into music is the true genius.

If there's is a lesson life has thought me, it's that there's no single way to ever look at anything.

Education shouldn't be an attempt to fill heads with knowledge, but an act of maturing minds to continuously learn & adapt.

Let's not compromise quality in favor of quantity.

I'm honored to have great students who teach me well.

If it's getting hard to effect change, chances are the organization may be stifled by a big circle of finger pointing.

It's quite ironic, but anything (tool, API, library,...) with the word 'simple' in its name rarely is.

Wednesday, September 25, 2013

JavaOne special books discount

It's exciting to be at JavaOne 2013. I'm giving six talks at the event and attending a lot more of great sessions. Here's the link to the interview I gave before the event.

I'm delighted to announce that the nice folks at PragProg have issued a 25% discount on all of my books.

Discount: 25%
Code: venkat_books

Please click on the images below to go to the purchase page of the books:


It's a lot of fun to hangout with developers. I hope to see you at an event soon.

Sunday, September 22, 2013

The Perils of Mixing Paradigms

Most of the mainstream languages in use today strongly support the object-oriented (OO) programming paradigm. Most of these languages also have adopted the functional style of programming (FP), leading to the support of mixed paradigms. While this is more power in the hands of programmers, there are some hidden perils. In this blog we will explore some of that.

In FP we use lambda expressions and higher order functions. In a pure FP language we can't mutate state. Quite a few facilities provided in these languagess rely upon honoring immutability. When we use these features in languages that don't enforce immutability, at the least, the result can lead to surprises. If we're not careful, it can lead to errors.

I've seen programmers, me included, fall into traps in languages like Ruby, Groovy, and C# when mixing paradigms. Let's explore this with some examples (in C#, Groovy, Ruby, and Java 8).

Here's a C# code using mutability and external iterators.

//C# external iterator example
List functions = new List();
for (int i = 0; i < 3; i++)
{
    functions.Add(() => Console.WriteLine("value is {0}", i));
}

functions.ForEach((function) => function());

In the above C# example we have a loop that runs over a range of index value i from 0 to 2. For each step through the iteration, we create a lambda expression that can print the value of the index variable i. The variable is accessible within the lambda expression through lexical scoping. We promptly add the created lambda expression to a list. Once we step out of the loop we iterate over the list of lambda expressions, evaluating each one of them.

What's the output of this code? Before you run it, take a moment to think through and write down the response you think the code would provide. In the mean time, let's take a look at the same code in Groovy (for the sake of programmers who code on the JVM).

//Groovy external iterator example
def functions = []

for(i in 1..3) {
  functions << { -> println "value is $i" }
}

functions.each { it() }

And, the following code is for Ruby aficionados:

#Ruby external iterator example
functions = []

for i in 1..3
  functions << lambda { puts "value is #{i}" }
end

functions.each { |function| function.call() }

Now that we have seen the same code in three different languages, let's go over the behavior of the code. The code mixes two paradigms here, imperative and functional. Where's the mutability here? Sure the lambda expressions we created are added to the list of functions. However, that's not the only mutability here. The index variable i in the for loop is a mutable variable that is assigned a new value (0, 1, 2) through each step through the iteration. When the iteration is completed, the final value of the index variable i is 3.

If we run the above code samples, all the three languages produce the following result:

value is 3
value is 3
value is 3

If we really wanted the result to reflect the individual values through the iteration, we'd be disappointed. What went wrong?

Lexical scoping is quite powerful and gives an opportunity for us to bind variables within lambda expressions with variables in the defining scope. However, this makes a whole lot of sense to reliably use when that variable is immutable. The problem in the above code is that these languages permitted us to bind, from within a lambda expression, to a mutable variable in the defining scope. It's easy for us to get confused with code where variables that we bind to continue to change in the outside context.
Let's refactor the code samples above to eliminate these concerns.

In the next C# example, we trade the external iterator for an internal iterator.

//C# internal iterator example
var range = new List() { 0, 1, 2 };
var functions = range.Select((i) => () => Console.WriteLine("value is {0}", i));
functions.ToList().ForEach((function) => function());

Study the above version of this code and jot down the response you think the code would provide.

Again, the Groovy equivalent of this code for folks coding on the JVM:

//Groovy internal iterator example
def functions = (0..2).collect { i -> { -> println "value is $i" }}
functions.each { it() }  

The Ruby version is here:

#Ruby internal iterator example
functions = (0..2).map { |i| lambda { puts "value is #{i}" }}
functions.each { |function| function.call() }

At first though we may say that the external iterator and the internal iterators are equivalent and do the same. That is not true, they are world apart when it comes to mutability and scope.
In the internal iterators, the index variable i has a limited scope, it lives only for the duration of one iterative step. At the end of the iteration that variable dies and a new variable, with the same name i, in this example, is created. In other words, rather than mutating a variable each time through the iteration, new variables are created each time. This is much like how if we invoke a function

def foo(int value) { .... }

say, five times, we get different parameters named value for each call. Between multiple calls to the function, the same variable is not mutated. A new variable comes to life at the beginning of the call and dies at the end.

If we run this modified version of the program in all the three languages, the output will be:
value is 0
value is 1
value is 2
This output is more along the lines of what we'd desire.
There are two lessons here for us to learn.
1. When exercising functional style of programming, we should honor immutability. We should use constructs that promote immutability and avoid those that quietly perpetuate mutability.
2. As languages begin to mix these two paradigms, they must make it harder for programmers to fall into traps. They can gently prevent programmers from accessing mutable variables from within a functional style context. Java 8, for example, does just that. Let's take a look at the above two examples in Java 8.
//Java 8, using external iterator
List functions = new ArrayList<>();

for(int i = 0; i < 3; i++) {
  functions.add(() -> System.out.println(i));
}

functions.forEach(function -> function.run());

If we compile this code, we will get a prompt compilation error.

...error: local variables referenced from a lambda expression must be final or effectively final
      functions.add(() -> System.out.println(i));
                                             ^
1 error

The compiler does not permit us to bind to the variable i in the defining context here because the variable is being mutated.

On the other hand, if we modify the code as follows:

//Java 8 using for-each instead of for
List functions = new ArrayList<>();

List range = Arrays.asList(0, 1, 2);
for(int i : range) {
  functions.add(() -> System.out.println(" value is " + i));
}

functions.forEach(function -> function.run());

The compiler does not complain here and the result of running the code is:

value is 0
value is 1
value is 2

It turns out that while the traditional for loop creates a mutable index i, the for-each construct binds a new value to new variable named i each time through the loop. The variable i is not available outside the scope of the for-each. If we try to modify that variable within the for-each (which is a bad idea), then the compiler will not permit the use of that variable within the lambda expression. The reason is that the variable would no longer be effectively final, that is, it's being mutated.

This check and balance in Java 8 is pretty darn good and will help reduce programming errors when we mix paradigms. Having said that, Java 8 does not entirely prevent access to mutable variables from within lambda expression. For example, we can still modify fields within instances or invoke methods that in turn modify state.

We can further eliminate mutability in the above Java 8 code by using internal iterators, like so:

//Java 8 using internal iterators
Stream functions =
  Arrays.asList(0, 1, 2)
        .stream()
        .map(i -> () -> System.out.println(" value is " + i));

functions.forEach(Runnable::run);

To summarize, when mixing OO and functional style, as programmers we should take care to avoid binding to mutable variables from within lambda expressions. It would be great if more languages, like Java 8 does, simply prevented that. This will reduce the burden on programmers who mix the paradigms to put the language capabilities to good use.

Tuesday, August 20, 2013

Picking a JVM Language: Which one is right for you?

Picking a JVM Language: Which one is right for you?

This year I've given a presentation titled "Picking a JVM Language: Which one is right for you?" at various conferences including NFJS. At the end of the presentation I use a spreadsheet to rank languages. I've been asked a few times to post that spreadsheet and I finally got around to it. Here's the link to the HTML version of the spreadsheet.

Comments and suggestions for improvements are most welcome.

Wednesday, March 6, 2013

My Publisher did it again

  "I must finish [writing this letter] now, because I've got to write
  at breakneck speed—everything's composed—but not written yet."—Mozart.
  
Mozart nailed it and this is a great way to write books as well. Composing the content in mind over a period and then writing it down, in that breakneck speed has worked quite well for me. But that's only possible because of a great team.

Back in 2008 I wrote this blog How long does your publisher take to publish your book?—How about 1 month from draft to beta? My favorite publisher has done it again.

The busy year was winding down and the entire month of December looked free on my schedule. A great time to write a book on something that has been composed, but not written yet. On December 1st, I set out on a two-weeks sprint to create the first draft of Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions—the checkin activities are shown in the figure below (lines are really a count of lines of code and paragraphs of text rather than sentences).


After writing a few chapters of the book, I contacted the nice folks at the Pragmatic BookShelf. Susannah Pfalzer, the Managing Editor at the publisher, helped me through the submissions and evaluations. Hearing my desire to be once again on a fast-track, she helped get through the initial procedures fairly quickly.

The first draft was complete on December 13th and Jackie Carter came on board as the editor. I had not worked with Jackie before, but I soon realized that she's not one of those run-off-the-mill editors. Not only was she swift in reviewing the contents starting on December 14th, she would then call me to spend a couple of hours to help tease some concepts out of my head. As you can see in the figure below, the draft blossomed under her care within the first two weeks of development edits.


Yes, you're seeing it right, she was very kind to worked through the holidays so I can get this to tech reviews before I went on my crazy trips starting January 12th (I have traveled 50,000 miles since then to today, it was critical to get this done before I took off).

As you can imagine, writing a book in a short amount of time can be pretty stressful. During the long hours, my family gave me the space and slid food under the door so I can work undisturbed. Each call from Jackie at the end of most days were highly therapeutic. She would ask me good questions, guide me along in areas that needed rewriting, and the entire conversation motivated me to take on more tasks the next day.

The book went into the able hands of the tech-reviewers in mid January. Then came in their reviews. I am fortunate to have some incredibly talented reviewers, who were so willing to volunteer their precious time; here's an excerpt from the book, thanking them:


The reviews were very constructive and there were so many great suggestions. They pointed out where I needed more content, things I needed to fix, and at the same time, indicated things they really liked. It took me a couple of weeks to make the changes based on their reviews, each one of their suggestions were golden.

I'm thrilled that the beta version of the book has been released today.

The team working on Java 8 has done a great job in bringing lambda expressions and functional style of programming on board. I thoroughly enjoy keeping up with the language as it continues to evolve. I thank them for making this open and accessible.

Mozart was right on, it is a lot of fun to compose first and then write it in a breakneck speed, but that only works when you have the support of such incredible people. I am blessed to have that. Many thanks to each one who helped on this project.

Update:
It's been an exciting journey, keeping up with Java 8 releases, and learning along the way. Here are the release of the book so far:

B7.0 - 27 January 2014

  • Fixed a few minor errors/typos.
  • Ensured all examples work with the updated Java 8 Developer Preview Release (build 1.8.0-ea-b124).

B6.0 - 13 January 2014

Indexing is complete.

B5.0 - 28 December 2013

Copyediting is complete. Indexing is next.

B4.0 - 16 December 2013

  • Updated code and related text to Java-8 Developer Preview Release (build 1.8.0-ea-b120)
  • Addressed suggestions/corrections from book forum and errata, and acknowledged the contributors.
  • Added a section on dealing with exceptions.
  • Provided more details on using Collectors and related operations.
  • Included an example of using flatMap().
  • Content-complete and heading to production.

B3.0 - 19 September 2013

  • Updated code and related text to Java-8 Developer Preview Release (build 1.8.0-ea-b106).
  • Updated select code examples to use newly added JDK methods.
  • Addressed suggestions/corrections from book forum, reviewers, and errata.

B2.0 - 19 July 2013

  • Updated code and related text to Java-8 pre-release build 99.
  • Addressed suggestions/corrections from book forum, reviewers, and errata, and acknowledged the contributors.
  • Fixed known typos and reworded a few sentences.

B1.0 - 06 March 2013

Initial beta release.

Saturday, January 26, 2013

What's new in Programming Groovy 2nd Edition

Time goes by quite fast. The first edition of Programming Groovy was released back in 2008, based on Groovy 1.5. Groovy has evolved in the mean time.

The feedback from some readers was quite resounding, they suggested that I write the 2nd edition of the book. After quite some effort and feedback from some wonderful technical reviewers, the 2nd edition of Programming Groovy is out.

If you're curious what's new in the 2nd edition of the book, here's the list of changes:

The first edition of this book covered version 1.5. Groovy has come a long way since then. This second edition of the book is up to date with Groovy 2.0 and heres how the significant additions and changes in this edition will help you:
  • Youll learn Groovy 2.0 features.
  • Youll learn about Groovy code generation transformations like @Delegate,
    @Immutable, ....
  • Youll learn the benefits of the new Groovy 2.0 static type checking and
    static compilation facilities.
  • Closures in Groovy are quite exceptional and, youll learn about their new support for tail-call optimization and memoization.
  • You learn how to integrate Java/Groovy quite effectively, pass Groovy Closures from Java, and even invoke dynamic Groovy methods from Java.
  • Youll find new examples to learn about the enhancements to metapro- gramming API.
  • Youll learn how to use Mixins and implement some elegant patterns with it.
  • In addition to runtime metaprogramming, you can also grasp compile- time metaprogramming and Abstract Syntax Tree (AST) transformations.
  • In the topic of builders, youll see the details for building and reading JSON data.
  • In addition to these, youll also learn the Groovy syntax that facilitates fluent creation of Domain Specific Languages (DSL).
To find out more, please click on the book cover image:

Wednesday, January 23, 2013

Functional Programming in Java is quite Approachable

Let's avoid Fear and Confusion

In the past few days number of tweets pointed to this blog: "Why Functional Programming in Java is Dangerous."  Several people have commented on it already, I'd like to present here a pure Java example that solves the problem discussed in that blog.

I would totally agree with the title of that blog if three words are removed from it: "Functional", "in", and "Java". The blog simply showed that programming can be dangerous, especially if we use the tools provided by a language for what it's not intended.

Disclaimer: I will admit, I am often critical of languages and have called out on things I find deficient. Java has been on the top of that list many times. At the same time, when I see a feature well done, I don't hesitate to speak in favor of it as well. I sincerely try not to carry any biases against languages, but try to be as objective as possible.

I have been playing with the lambda expressions facility in Java and have only nice things to say so far.

The blog mentioned above talks about functional programming, but the examples are really dealing with lazy collections and tail call optimization (which benefit from the functional paradigm), both of which are quite possible and elegant in Java 8. Let's get to the examples.

A Word of Caution

This blog is quite terse, I am not explaining much here, the intention is simply to show what's feasible.

How to run the code examples below

You'd need Java 8 with support for lambda expressions to compile and run the code below. Please download from http://jdk8.java.net/lambda/. The code below was compiled using build b-74.

Square of integers

Java 8 has an interesting interface called Stream which provides a lazy collection. Let's use that to build square of integers mentioned in that blog.

import java.util.stream.Streams;

public class Sample {
  
  public static void main(String[] args) throws Exception {
    Streams.iterate(1, number -> number + 1)
    .map(number -> number * number)
    .limit(25)
    .forEach(number -> System.out.print(number + " "));
  }
}
//output:
//1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400 441 484 529 576 625  

That's the complete code.
In the above code the iterate method of the Streams class is a higher order function that takes in a seed value (1) and a generator. The map method is lazily evaluated and is delayed until the call to limit method arrives. Each time the generator is called (and it's called 24 times in this example), it returns the next number in the series. Using this we created a series of numbers 1, 2, 3, 4, ... and then the map method simply creates a square of those numbers.

Tail call optimization

Tail call optimization is trivial once we get a hang of the lazy infinite collection. Rather than thinking about it as calling the function repeatedly while holding on to the stack, let's think of it as a collection of unknown number of function calls that we can lazily evaluate as many times as we like. Once we wrap our head around this problem as a lazy evaluation of an infinite collection, it simply fizzles down to minimum code.

Let's use the same example as in the other blog, tail recursion of squareAndPrint method. You can run the code below with as large an input as you like, 25000 for example, and will not get any StackOverflowError.

import java.util.stream.Streams;

@FunctionalInterface
interface TailCall {
  TailCall get();
  default boolean terminated() { return false; }
}

class TailCallTerminate implements TailCall {
  public TailCall get() { throw new Error("Don't call"); }
  public boolean terminated() { return true; }
}

public class Sample {  
  public static TailCall squareAndPrint(int number, int max) {
    System.out.println(number * number);
    if(max > number) {
      return () -> squareAndPrint(number + 1, max);
    } else {
      return new TailCallTerminate();
    }
  }
  
  public static void main(String[] args) throws Exception {
    int max = Integer.parseInt(args[0]);
    
    Streams.iterate(squareAndPrint(1, max), TailCall::get)
    .filter(TailCall::terminated)
    .findFirst();
  }
}

We're creating a functional interface called TailCall here. The squareAndPrint method returns either a next call (packaged into a TailCall implementer) or indicates the recursion is over by returning a TailCallTerminate instance. We can query the instance returned to know if we should continue or stop.

To begin with we have no clue how many tail calls exist. We turn this into a lazy infinite collection using the Streams' iterate method. We continue with the recursion, iteratively that is, until we reach the terminating call.

The above two examples shows what's feasible in Java. We could do this today with anonymous inner classes, but that would drive us insane. With lambda expressions just around the corner, we can write quite a bit of elegant code in Java.

Java is not a perfect language, it has quite a bit of ceremony, and we have heard several complains (including some from yours truly in the past). However, Java 8's functional style of programming is giving new hopes to millions of Java programmers who're putting it to good use each day. I see this to be a step in the right direction for Java, I am quite optimistic and will not hesitate to program with it, in functional style of course.

Sunday, November 25, 2012

Functional Style of programming in JavaScript—Part IV: Using Higher order functions and Lexical Scoping

In the previous part we learned about creating higher order functions. In this part we will put those concepts to use.

In the example we create here, we'll display your current location. If you're on a smart phone, you can see the location begin displayed on this page. If geolocation is not available on your device (or if you don't permit access), then an error will be displayed.

We'll use the geolocation API to get the current location. The API requires us to register two callback functions, one for success and one for error. These two functions will be called back by the API with either the position or an error code, respectively. In these callback functions we need to update the appropriate DOM element in this HTML page. This requires us to capture the DOM element information when we create the callbacks. Let's use higher order functions to achieve this.

Here's the code, stored in a file named displayLocation.js:

var displayLocation = function(elementToUpdate) {
  var displayLatLon = function(position) {
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;
    elementToUpdate.innerHTML = 
      "Lat: " + latitude + ", Lon: " + longitude;
  }

  var displayError = function(error) {
    var errorMessage = 
      ['', 'Permission denied', 
        'Position unavailable', 'timeout'];

    elementToUpdate.innerHTML = 
      "error - " + errorMessage[error.code];
  }

  elementToUpdate.innerHTML = '--';
  navigator.geolocation.getCurrentPosition(
    displayLatLon, displayError);
}

The displayLocation function takes an HTML DOM element as a parameter. In this function we create two functions, displayLatLon and displayError, which take as parameters the position and error, respectively. Within each of these functions we reach out to, in their lexical scope, the variable elementToUpdate to display the value of the position or the error, as appropriate. Finally, in the displayLocation function we access the navigator's geolocation property and invoke its getCurrentPosition higher-order function, sending it the two functions we created.

In the HTML file let's create a span tag to hold the location and give it the id locationInfo. Use the view source to take a look at this span tag below.

Location Info:

As the last step, let's bring in the javaScript into this document using the script tag, again view source to take a look at it.


When you visit this page, you should receive a request from the browser to share your location (we're not going to store or monitor you, so feel free to say yes if you like). If you allowed the location to be shared, you should see your latitude and longitude displayed above after the Location Info. We have used higher order functions to create the callbacks and register with the geolocation API in this example. We can see the lexical scoping used in this example as well.

Friday, November 16, 2012

Functional Style of programming in JavaScript—Part III: Creating and Returning Functions

In the previous part we squashed the little duplication that emerged in the example. We saved the function to determine if a price is greater than $35 into a variable and reused it. Let's continue with that example. Suppose we want to compute the total of all prices greater than $25 and also all prices greater than $10. Here's the code for it:

var prices = [10, 20, 25, 30, 35, 40, 45, 50];

var isPriceGreaterThan35 = function(price) {
  return price > 35;
}

var isPriceGreaterThan25 = function(price) {
  return price > 25;
}

var isPriceGreaterThan10 = function(price) {
  return price > 10;
}

totalSelectPrices(prices, isPriceGreaterThan35); //135

totalSelectPrices(prices, isPriceGreaterThan25); //200

totalSelectPrices(prices, isPriceGreaterThan10); //245

The calls are still quite concise, but some serious duplication has crept in when defining these little functions. The functions isPriceGreaterThan35, isPriceGreaterThan25, and isPriceGreaterThan10 are identical except for the value to be compared with, 35, 25, and 10, respectively.

We need to refactor these three methods so the value to compare the price with, let's call it a pivot, can be passed in as a parameter.

On first thought, we could write something like this:

//won't work
var isPriceGreaterThanPivot = function(price, pivot) {
  return price > pivot;
}

totalSelectPrices(prices, isPriceGreaterThanPivot); //0

That did not go well, we got an incorrect result of 0. Of course, we did not pass the pivot value, so this call is in trouble to begin with.

We're concerned with two parameters, the price and the pivot. We get the price values from within the totalSelectPrices function. We know the pivot at the time of call to totalSelectPrices function. Looks like this function isPriceGreaterThanPivot need two parameters, but these are available at different time in the call sequence, at different levels of the call stack. Oops.

We need a way to pick up one of the parameters when it's available and carry it along for use when the other parameter becomes available.

Let's evolve the code towards that capability, we'll take a series of small steps next.

var pivot = 35;
var isPriceGreaterThanPivot = function(price) {
  return price > pivot;
}

totalSelectPrices(prices, isPriceGreaterThanPivot); //135

pivot = 25;
totalSelectPrices(prices, isPriceGreaterThanPivot); //200

We first defined a variable pivot with an initial value of 35. This version of isPriceGreaterThanPivot takes only one parameter price. Within this function we use this parameter, but we also reach over and access the pivot variable defined outside of this function. The variable pivot binds to the variable defined in the context or scope of where this function, isPriceGreaterThanPivot, itself is defined. Then we pass this function to the totalSelectPrices function. Within the totalSelectPrices we invoke the given function with the price values and we get the expected result of 135 from this call. Next we change the value of the variable pivot (an act of mutability that's not quite desirable as we'll discuss in a future blog) and then invoke the totalSelectPrices again, sending it the isPriceGreaterThanPivot reference again. This time, since the value of pivot is 25, this call produces the appropriate result of 200.

We got the code working, but there are a few things we need to address. First let's discuss this variable binding. Next we will eliminate this "let's change this variable" approach and make the code self-contained.

We saw how the function reached out and grabbed (or bind) to a variable outside its scope. Let's take a closer look at this binding with an example:

var pivot = 35; //Def 1
var isPriceGreaterThanPivot = function(price) {
  return price > pivot;
}

var checkPrice = function(selector) {
  var pivot = 100; //Def 2
  return selector(50);
}

checkPrice(isPriceGreaterThanPivot); //true

We have a variable named pivot in the outer scope where the variable isPriceGreaterThanPivot is defined. We use this variable pivot within the function. In the function checkPrice we receive a function as a parameter, define another local variable named pivot and invoke the provided function. Finally, we call the checkPrice function.

Which of the two variables named pivot will be used within the isPriceGreaterThanPivot function—the Def 1 or Def 2?

Neither one of them is the universally correct answer. If the language chooses to bind to the variable in the scope of the function definition, the binding is called lexical scoping. On the other hand, if the language decide to bind to the closest definition on the runtime stack, it's called dynamic typing.

From the response of the checkPrice function we can see that JavaScript uses lexical scoping, that is the function bound to the definition marked as Def 1.

Binding to the variable pivot in the scope of the definition of the function partly helps us solve the problem on hand, but the approach we took to modify the variable between calls is not elegant and error prone. We can use the lexical scoping, with a level of indirection. Let's explore how:

var isPriceGreaterThanPivot = function(pivot) {
  return function(price) { return price > pivot; }
}

totalSelectPrices(prices, isPriceGreaterThanPivot(35)); //135

totalSelectPrices(prices, isPriceGreaterThanPivot(25)); //200

We removed the mutability of the variable pivot and turned it into a parameter of the isPriceGreaterThanPivot function. Within this function, in the spirit of higher order functions, we create another function. This inner anonymous function takes one parameter price and binds to the parameter pivot in its lexical scope. Finally, we return this inner anonymous function from the isPriceGreaterThanPivot function.

In the first call to totalSelectPrices function we first invoke the isPriceGreaterThanPivot passing it the pivot value of interest, 35. This returns a specialized function that caches the pivot value and takes price as a parameter. This generated function is passed to the totalSelectPrices function. Similarly, in the second call we create a function on the fly that takes on parameter and uses the cached value 25 for the pivot.

In this final version we saw how to create functions within functions and return it. We also saw how to pass functions to functions. These three are core capabilities of higher order functions. In the next part we'll look at a practical example where we'll use this.

Thursday, November 15, 2012

Functional Style of programming in JavaScript—Part II: Reusing Functions

In the previous part we created a higher order function named totalSelectPrices and called it a few times with different anonymous functions. Let's revisit one such call:

var prices = [10, 20, 25, 30, 35, 40, 45, 50];

totalSelectPrices(prices,
  function(price) { return price > 35; }); //135

It was quite easy to create the anonymous function that returned a boolean true or false depending on whether the given price was greater than $35 or not. Now, if we want to total prices in another list of prices, we could write:

var prices2 = [10, 20, 30, 40, 50, 60, 70, 80];

totalSelectPrices(prices2,
  function(price) { return price > 35; }); //300

The conciseness of this call is deceivingly simple, but we quietly duplicated that little anonymous function.

In our field, if there are two simple acts that each of us can do to improve code quality, those would be avoiding long functions and eliminating duplication. With anonymous methods and the desire to keep the code concise, we'd automatically lean towards shorter functions, however, they do make it easier to duplicate code and we gotta keep an eye on it.

Let's remove that duplication, instead of remaining anonymous, let's store the function into a variable and reuse it.

var isPriceGreaterThan35 = function(price) {
  return price > 35;
}

totalSelectPrices(prices, isPriceGreaterThan35); //135    

totalSelectPrices(prices2, isPriceGreaterThan35); //300

It's a good idea to save the functions into variables and pass the references to other functions. I'm sure you've seen your share of bad JavaScript that could benefit from that advice. Let's avoid code like:

someFunction(function(message) {
    //several lines of code here...
    //...
    //...
  }, function(error) {
    //handle error here...
    //...
    //...    
  });

This is hard to read, our eyes have to parse through quite a bit to realize there are multiple parameters to someFunction, and to figure out where they begin and end.

Instead, we can make the code easier to read, like so:

var successHandler = function(message) {
  //several lines of code here...
  //...
  //...
}

var errorHandler = function(error) {
  //handle error here...
  //...
  //...    
}

someFunction(successHandler, errorHandler);

There's a fine line between concise code and terse code. When writing code, we have to balance conciseness and easier to read/follow.

We eliminated the small duplication that emerged in the example. In the next part, we'll tackle the next level of duplication that's about to creep in.