Wednesday, June 22, 2016

Lazy Evaluation make infinite streams possible

In the previous post we saw how lazy evaluation may make the code expressive without losing on performance. Here we'll see yet another benefit of lazy evaluations—Infinite Streams.

Streams may be unbounded or unrestricted in size. Let's look at a snippet of code first:

Stream.iterate(1, e -> e + 1)

We're calling the iterate() method of the java.util.stream.Stream interface, passing a value 1 and a lambda expression as arguments. This code snippet creates an infinite stream—it starts with the value 1, and may further yield a series of values 2, 3, 4, 5, 6, 7,...

The stream is infinite in length. "Infinite?" you say, "then where would you store it?" On the cloud of course.

It would not make sense to eagerly create an infinite stream, after all. We would run out of time, patience, memory,... and much more. The infinite streams simply say "I can produce an infinite amount of data and I dare you to ask for all of them."

Infinite stream are highly practical—they rely on the fact that we will only ask for finite amount of data and they produce the data just-in-time, on demand, lazily.

Let's expand the code snippet just a bit:

System.out.println(
  Stream.iterate(1, e -> e + 1)
        .filter(e -> e > 1000)
        .findFirst()
        .orElse(0));

This code gets an infinite stream that yields values starting with 1 and filters out any values from the stream that are less than or equal to 1000. The result of the filter operation is another infinite stream. Remember from the previous post that the filter method is an intermediate operation and it will not evaluate right away. In this example, the evaluation of both the lambda expression presented to iterate and the one passed to filter are lazy. It's the call to the terminal function findFirst that triggers the computation of both of these lambda expressions, but only just enough times for the terminal function to be satisfied.

The result of this code is a value of 1001.

Infinite streams will not be possible without the capability to perform lazy evaluations. It is our responsibility, however, to make sure that the number of evaluations are actually finite. For example, while it makes sense to query a bounded or finite stream for its size—using the count method—it would not make sense to call that method on an infinite stream. For example:

System.out.println(Arrays.asList(1, 2, 3).stream().count()); // prints 3

System.out.println(Stream.iterate(1, e -> e + 1).count());  // ...eternity

We took a peek at what makes infinite streams possible. In the next post we will look at an example of how infinite streams can make code highly expressive and remove some accidental complexities.

Wednesday, June 15, 2016

Lazy Evaluation: may make code more expressive without losing on efficiency: Part II

In the Part I we converted an imperative code to a more expressive functional code and ended with a question about efficiency. Let's pick up this blog from where we left.

Here's the imperative version of the code, again:

public static Integer computeImperative(List<Integer> numbers) {
    Integer result = null;
    
    for(int e : numbers) {
      if(e > 3 && e % 2 == 0) {
        result = e * 2;
        break;
      }
    }
    
    return result;
  } 

Let's see the number of operations this code will perform if the given list has the values (1, 2, 3, 5, 4, 6, 7, 8, 9, 10), in that order. The check > 3 will fail for the first three values and so the even check will not be done for those. That's 3 computations so far. For 5, it will perform both the checks in the if condition, so that's two more operations. For 4 it will perform the two checks and then the multiplication. That's 3 more computations and the code will hit the break right after that. That's 3 + 2 + 3, a total of 8 operations.

We implemented a functional version of this code in the previous blog. It was expressive and elegant, easier to read and understand. But, we were curious about its performance. Would it perform more operations, spend more time and effort to compute the result.

The short answer is, it could, but it does not have to. Let's see how.

We will first implement the functional style code using Ruby---which supports both imperative and functional style of programming.

def is_greater_than_3?(number)
  puts "is_greater_than_3 called for #{number}"
  number > 3
end

def is_even?(number)
  puts "is_even? called for #{number}"
  number % 2 == 0
end

def double_value(number)
  puts "double_value called for #{number}"
  number * 2
end

def compute(numbers)
  numbers.find_all { |e| is_greater_than_3?(e) }
         .find_all { |e| is_even?(e) }
         .map { |e| double_value(e) }
         .first
end

numbers = [1, 2, 3, 5, 4, 6, 7, 8, 9, 10]

puts compute(numbers)

We created small functions for each of the operations—the two checks and for the multiplication. In each of the functions we have a print statement, puts, for illustration purpose. In the compute function we use function composition. find_all is equivalent to the filter function.

To run the code, use the command ruby sample.rb where sample.rb is the file which contains the code.

This example does not show Ruby in it's best light, but that's not the intention. I like Ruby and use it quite extensively. It's great for many things. It's also a language that makes code concise and highly expressive. But, this example shows one of the drawbacks as well.

Here's the output from a run of the code:

is_greater_than_3 called for 1
is_greater_than_3 called for 2
is_greater_than_3 called for 3
is_greater_than_3 called for 5
is_greater_than_3 called for 4
is_greater_than_3 called for 6
is_greater_than_3 called for 7
is_greater_than_3 called for 8
is_greater_than_3 called for 9
is_greater_than_3 called for 10
is_even? called for 5
is_even? called for 4
is_even? called for 6
is_even? called for 7
is_even? called for 8
is_even? called for 9
is_even? called for 10
double_value called for 4
double_value called for 6
double_value called for 8
double_value called for 10
8

While Ruby supports functional style, it does not readily perform lazy evaluations. As a result, it performs redundant computations for the given example list. The first use of find_all function created a new list from the given list. We can see the is_greater_than_3 is called 10 times, once for each element. Then, the second use of find_all works with a list of seven elements to create a third list with only even numbers. The double_value is called for each element on this resulting list to create yet another list of values doubled. The final call to first returns only the first value in the final collection and discards the remaining values. We expended a total of 21 operations. In contrast, the imperative style only performed 8 operations for the same list of values.

If we add more elements to this list, the imperative style will not perform any extra operations. The Ruby functional style will, however.

For large collections, this may appear to be cost prohibitive. Are we forced to compromise on performance for elegance then?

Thankfully, not all languages that offer functional style exhibit the same behavior. A good number of languages, including Java, provide lazy evaluation in addition to function composition.

Let's reimplement the Ruby version in Java. A key strength of Java's Stream API is lazy evaluation. We'll see that in action here:

import java.util.*;

public class Sample {
  public static boolean isGreaterThan3(int number) {
    System.out.println("isGreaterThan3 called for " + number);
    return number > 3;
  }

  public static boolean isEven(int number) {
    System.out.println("isEven called for " + number);
    return number % 2 == 0;
  }

  public static int doubleValue(int number) {
    System.out.println("doubleValue called for " + number);
    return number * 2;
  }

  public static Optional<Integer> compute(List numbers) {
    return numbers.stream()
                  .filter(Sample::isGreaterThan3)
                  .filter(Sample::isEven)
                  .map(Sample::doubleValue)
                  .findFirst();
  }

  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
    
    System.out.println(
      compute(numbers).map(Object::toString)
                      .orElse("No value"));
  }
}

Each of the small methods in this version do the same thing as their Ruby counterpart. In the compute method we've used function composition to first filter the values greater than 3, then even numbers, then doubled the resulting values, and in the end obtained the first value from the final collection. These steps in Java are just the same as the steps we used in the Ruby version. However, there's a significant semantical difference between how Ruby evaluates the expressions in its function composition versus how the expressions in Java Stream's function composition are evaluated. The Stream is inherently lazy.

The behavior of the Stream is much like my teen age children—they don't act on things when they're told.

Here's a scenario from an evening at my home. My ever-so-patient wife to my teen:

"Please turn off the TV"

It's like no words were spoken; nothing happened.

"Clean up around you."

Chirp, chirp, nothing happened.

"Do your homework."

...sound of silence here...

"I'm calling your dad."

Suddenly the TV gets turned off and things start moving...

On occasions, it's me replacing my wife's callingDaddy() with IWillTellMomAboutThis().

The Stream is just like that. You call filter, nothing really happened, no filtering, no conversion of given collection to an intermediate collection. Same with the next call to filter and the subsequent call to the map function. They might as well have renamed the findFirst function as callAParent—it's the call to these terminal functions that trigger the evaluation, lazily.

When findFirst is called, the execution of the function chain is triggered. However, the sequence of evaluation is quite different from what appears to our eyes. Instead of the entire collection going through the first filter operation, the sequence of functions in the chain is applied to one element at a time, but only until the terminal operation is satisfied.

In the given example, the first element in the collection, 1 is passed through the first filter operation. Since it's not greater than 3, the next value in the collection is taken up. Since all the first three values are not greater than 3, after evaluating the isGreaterThan3 function on each one of them, the value 5 is next considered. This value goes successfully through the first filter operation but fails the second operation of isEven. That's a total of five operations so far. Next, the value 4 from the collection is taken up. It successfully goes through both the filters and reaches the findFirst operation. Since that satisfies the terminal method, the evaluation of this function composition terminates at this point, after a total of 8 operations. Here's the output from the execution of the Java version:

isGreaterThan3 called for 1
isGreaterThan3 called for 2
isGreaterThan3 called for 3
isGreaterThan3 called for 5
isEven called for 5
isGreaterThan3 called for 4
isEven called for 4
doubleValue called for 4
8

The functional style version in Java took the same number of steps during execution as the imperative version did, thanks to the execution being lazy.

We did not have to compromise on performance in order to benefit from the expressive power of functional style in Java. Languages and/or libraries in Java, C#, Scala, Haskell, F#,... and many more offer lazy evaluation. While embracing functional style of programming we have to take the time to explore if lazy evaluation is possible. Laziness has a great impact on the semantics and also on efficiency.

When used in the context of functional programming, the words lazy may be pronounced as efficient.

In the next blog we will see how lazy evaluation may lead to infinite streams.

Wednesday, June 8, 2016

Lazy Evaluation: may make code more expressive without losing on efficiency: Part I

In a previous blog we discussed how pure functions may enjoy lazy evaluations and mentioned a few benefits of being lazy. In this blog we discuss the first benefit: expressive code without losing on efficiency.

Let's first take a look at an example code:

import java.util.*;

public class Sample {
  public static Integer computeImperative(List<Integer> numbers) {
    Integer result = null;
    
    for(int e : numbers) {
      if(e > 3 && e % 2 == 0) {
        result = e * 2;
        break;
      }
    }
    
    return result;
  } 

  //...
}

The computeImperative method takes a list of Integer values and returns an Integer. But what does it really do?

By examining the loop and the if statement, we can figure out that it returns the double of the first even number greater than 3 from the given list. If the list were empty or if no number makes the cut, then null is returned. Also, the loop will terminate as soon as it finds a candidate element.

Let's take a look at the main method that uses the computeImperative method.

  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
               
    int doubleOfFirstEvenGreaterThan3 = computeImperative(numbers);
    System.out.println(doubleOfFirstEvenGreaterThan3);
  }

In main we call the computeImperative method and stored the result in an int variable. But, this is trouble waiting to happen. If the result of the method call were null, then this code will face a misserable NullPointerException at runtime.

The code is imperative in style and carries with it all the smells of that style of programming. Let's implement a functional style version of this method.

  public static Optional<Integer> computeFunctional(List<Integer> numbers) {
    return numbers.stream()
                  .filter(e -> e > 3)
                  .filter(e -> e % 2 == 0)
                  .map(e -> e * 2)
                  .findFirst();
  }

This version is a lot easier to read and understand than the imperative version. We can, in one sweep from top to the bottom, read out the task performed by this method: Given a collection of numbers, filter the numbers greater than 3, then filter numbers that are even, double the values, and finally return just the first element in the result.

The code is not only expressive, it's much safer to use as well. The result of findFirst is an Optional. An Optional may contain a value, of parameterized type T, or may be empty. We can't directly assign an Optional to a variable of type T. This prevents accidental NullPointerException at runtime. Instead, we have to program deliberately, and extract the value out of the Optional and along the way handle the possibility of the value not being present.

Let's change the main method to use the functional style computeFunctional:

  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
               
    Optional<Integer> doubleOfFirstEvenGreaterThan3 =
      computeFunctional(numbers);
      
    System.out.println(
      doubleOfFirstEvenGreaterThan3.map(Object::toString)
                                   .orElse("No result"));
  }

In main we call computeFunctional, convert the value, if present, in the resulting Optional to a String. We print that converted value or else, that is, if the value were not present, print a message "No result."

The code is expressive compared to the imperative version. It's functional in style and uses function composition. However, there's a deep rooted concern in this code. How much more work does this code do when compared to the imperative version? Are we trading a greater inefficiency for greater expressiveness.

We'll answer that question of efficiency in the next blog.

Wednesday, June 1, 2016

Benefits of Pure Functions: Can be Lazy

In a previous related blog we discussed how pure functions are easier to parallelize. In this blog, we discuss another benefit from this list: pure functions can be lazy.

Lazy evaluation is where a program may postpone evaluating an expression until just-in-time when it's value is needed. If the value is never needed during the execution of the program, the evaluation of the expression may be totally skipped.

Languages like Haskell perform lazy evaluations more naturally. In C# and Scala we can mark some variable bindings as lazy. In other languages, we have to work just a little harder to make variable bindings lazy.

Let's take a look at a short Scala example:

def compute(number: Int) = {
  //assume this is time consuming
  Thread.sleep(5000)
  number
}              

val start = System.nanoTime

if(Math.random() > 0.5 && compute(5) > 0)
  System.out.println("computed");
else
  System.out.println("skipped");
  
val end = System.nanoTime

println(s"Time taken: ${(end - start)/1e9}")

We'll assume that the compute function is a time consuming function—we better not call it unless it's result is really needed. When the program is run, depending on the value returned by the random() method, the function is either evaluated or skipped. Lets run the program a couple of time and see the output:

> scala sample.scala 
computed
Time taken: 5.003096089
> scala sample.scala 
skipped
Time taken: 1.75862E-4
> 

If the value returned by random() is less than or equal to 0.5, then the evaluation of the compute() function is skipped. The executions where the call is skipped will take far less time than in which the call is evaluated.

We know the concept we just saw as short-circuit evalution. Short-circuit evaluation is performed in most mainstream languages in use today.

Let's change the example a tad, by introducing a temporary variable, like so:

val temp = compute(5)

if(Math.random() > 0.5 && temp > 0)
  System.out.println("computed");
else
  System.out.println("skipped");

The result of the evaluation of compute() is now first stored in the variable temp, before the evaluation of the condition in if. Multiple runs of the code will take about the same time as we see in the output:

> scala sample.scala 
computed
Time taken: 5.004494657
> scala sample.scala 
skipped
Time taken: 5.002012277
> 

Even if the value of temp is not used, we incur the overhead of determining a value for it, due to eager evaluation of the compute() function.

We can tell Scala to be lazy about calling the compute() function. Let's change the code once more:

lazy val temp = compute(5)

We added the word lazy in front of the declaration of the variable temp. Scala now postponed binding the variable to its value until we're ready to use the variable. Let's run the code a couple of time and view the results:

> scala sample.scala 
skipped
Time taken: 1.84514E-4
> scala sample.scala 
computed
Time taken: 5.004431085
> 

Even though we called compute() before we entered the evaluation of the condition in if, the actual execution of the function was postponed until its value was actually used. If the value was not used, the execution was skipped.

Before we can rejoice about laziness of evaluations, there's one thing we have to be very careful about. Lazy evaluation makes sense only if the functions, whose evaluation are being postponed, are pure.

Let's take a look at yet another example to illustrate this point.

def increment(number: Int) = number + 1
                        
var x = 5
val result = increment(x)

if(Math.random() > 0.5) {
  println("changed")
  x = 77
} else {
  println("unchanged")
}

println(result)

No matter how many times we run this code, the value printed out by the last line will be exactly the same:

> scala sample.scala 
changed
6
> scala sample.scala 
unchanged
6
> 

Converting the binding of the variable result from an eager evaluation to a lazy evaluation will not make sense:

lazy val result = increment(x)

After this change, we can't quite predict the value of the result variable:

> scala sample.scala 
unchanged
6
> scala sample.scala 
changed
78
> 

The expression that's presented for lazy evaluation is not pure—it depends on a mutable variable. This variable may change at any time, in the current thread or in other threads. It may change before the evaluation of the function slated for lazy evaluation. And, it may change after. Or while the function is being evaluated—oops.

If a function is pure, you may evaluate it now or safely evaluate it later. Furthermore, you can save the value of evaluation and reuse it since it will have the same result no matter how many times we evaluate it. Also, if a function has no side-effect, the only way anyone will know if the function was evaluated or not is by looking at the result. So, the execution can be safely postponed as desired.

Pure functions can be lazily evaluated.

We saw an example in Scala in this blog. We'll take a look at some lazy evaluation examples in Java in the following blogs related to this topic.

In this series of blogs, we've looked at six benefits of pure functions. The last benefit we saw—pure functions can be lazy—leads to more benefits of its own.

Lazy evaluations:

  • may make code more expressive without losing on efficiency
  • make infinite streams possible
  • We will discuss these benefits of lazy evaluation in the future blogs.

    Wednesday, May 25, 2016

    Benefits of Pure Functions: Easier to Parallelize

    In a previous related blog we discussed how pure functions are memoizable. In this blog, we discuss another benefit from this list: pure functions are easier to parallelize.

    Functional style of programming makes code more expressive and concise. As we get more comfortable with functional style, where it makes sense, we can lean more towards functional style instead of the imperative style. However, we have to be careful to avoid impure lambda expressions. Let's discuss with an example.

    Here's a piece of code that computes the sum of square root of prime numbers from 2 to a given number:

    import java.util.*;
    import java.util.stream.IntStream;
    
    public class Sample {
      private static double sumOfSqrtsOfPrimes = 0.0;
    
      public static boolean isPrime(int number) {
        return number > 1 && 
          IntStream.range(2, number)
                   .noneMatch(i -> number % i == 0);
      }
      
      public static void main(String[] args) {
        int number = 500000;
        long start = System.nanoTime();
                             
        for(int i = 1; i <= number; i++) {
          if(isPrime(i))
           sumOfSqrtsOfPrimes += Math.sqrt(i);
        }
                               
        long end = System.nanoTime();
        
        System.out.printf("Time Taken: %g sec\n", (end - start)/1e9);
        System.out.println(sumOfSqrtsOfPrimes);
      }
    }
    

    The code within the main() function is imperative in style. It sequentially iterates through each number from 1 to the given number. It computes the square root of each prime number it finds in that range and adds the value to the sumOfSqrtsOfPrimes variable.

    Let's run the code to see how long this code takes to run.

    Time Taken: 64.6315 sec
    1.896851199544097E7
    

    It took a little over a minute to run. Let's now change the code in main() from imperative to functional style, but rather naively.

      public static void main(String[] args) {
        int number = 500000;
        long start = System.nanoTime();
    
        IntStream.rangeClosed(1, number)
                 .boxed()
                 .filter(Sample::isPrime)
                 .map(Math::sqrt)
                 .forEach(value -> sumOfSqrtsOfPrimes += value); //This is bad
                               
        long end = System.nanoTime();
        
        System.out.printf("Time Taken: %g sec\n", (end - start)/1e9);
        System.out.println(sumOfSqrtsOfPrimes);
      }
    

    First, we get a range of values using the rangeClosed method of IntStream, convert that to a Stream<Integer> using the boxed() function. Then we filter the Stream<Integer> to get only prime numbers, then compute the square root of those values. All is well so far in the code. In the final step, however, we provide to forEach a lambda expression that's impure. It mutates the variable sumOfSqrtsOfPrimes. We'll discuss the consequence of this shortly, but first let's run the code and check on the result and performance.

    Time Taken: 45.8868 sec
    1.896851199544097E7
    

    The result of the computation is exactly the same. The time is better as well, but this solution is sequential much like the imperative solution.

    Compared to the imperative solution, the functional solution is much easier to parallelize. In order to parallelize the imperative solution we have to manage a pool of threads and schedule the execution on different threads. In the functional solution, we can simply ask for the execution to be parallelized. That fits well with the spirit of functional style—tell what we want without getting into the details of how to do that.

    Unfortunately, there's a catch as we'll see soon.

    Let's parallelize the execution of this code first.

    IntStream.rangeClosed(1, number)
             .boxed()
             .parallel()
             .filter(Sample::isPrime)
             .map(Math::sqrt)
             .forEach(value -> sumOfSqrtsOfPrimes += value); //This is bad
    

    We only had to make a small change—inserted a call to parallel() right before calling the filter() operation. Now, instead of sequentially working on each of the number in the range, the operations will be performed in parallel. The number of threads on which the operations will be scheduled, by default, depends on the number of cores on the system. The program should run faster. Let's take a look at the result of the run.

    Time Taken: 11.6477 sec
    1.896639027717821E7
    

    It certainly took a lot less time. Before we go out to celebrate, let's compare the sum of the square root of the primes computed by the different versions. Hmm, we got 1.896639027717821E7 while the previous two versions printed 1.896851199544097E7.

    No point running really fast to produce the wrong result.

    The culprit is shared mutability. The lambda expression we passed to the forEach method is not a pure-function. When called from multiple threads, the lambdas ran into a race condition while updating the shared mutable variable. Trying to synchronize this access is a wrong solution—we get dragged into the complexity and details we can easily avoid by avoiding explicit mutability.

    Even though the functional style is highly capable of parallelization, purity of lambda expressions is vital.

    Using impure functions with functional style is like having indigestion when there's surplus gourmet food on the table.

    Let's fix the ill-written function composition, to do the right things—avoid mutation, make the lambda expression pure. We'll first create a sequential version.

    double sumOfSqrtsOfPrimes = 
      IntStream.rangeClosed(1, number)
               .boxed()
               .filter(Sample::isPrime)
               .map(Math::sqrt)
               .reduce(0.0, Double::sum);
    

    Doing the right things was not hard. We avoided any explicit mutation in the code. The function function sum of Double is a pure function. We defined a local variable sumOfSqrtsOfPrimes and set it to the result from the function composition. All the functions we used in the function composition are guaranteed by the JDK to be thread-safe.

    Let's take a look at how this version performs.

    Time Taken: 46.3244 sec
    1.896851199544097E7
    

    First, the result is consistent with the previous sequential versions. The time the code took was similar to the previous ill-written functional style. But, this version is not only easier to parallelize, it's safe as well. Let's do that.

    double sumOfSqrtsOfPrimes = 
      IntStream.rangeClosed(1, number)
               .boxed()               
               .parallel()
               .filter(Sample::isPrime)
               .map(Math::sqrt)
               .reduce(0.0, Double::sum);
    

    We parallelized this version much like we tried with the earlier version. But, now we're in the right direction. The lambdas given to the filter and the map functions are run concurrently. In addition, the lambda given to the reduce function is also run concurrently, but the reduce function will perform a divide-and-conquer operation and merge the partial results of computations in a thread-safe manner. The result of this computation will not only be faster than the sequential version, but the result be correct as well:

    Time Taken: 10.8499 sec
    1.8968511995440975E7
    

    As we get more comfortable and familiar with functional style, we have to remember to keep the lambda expressions pure. In particular, we should avoid shared mutability. I've received emails from programmers asking why their code fails to produce proper result when they add parallel. Often times the problem has been shared mutability from lambda expressions. Let's be careful not to fall into such trap.

    In this series of blogs, we've looked at five benefits so far. In the next blog we'll look at another benefit: pure functions can be lazy.

    Thursday, March 31, 2016

    A Foolish Sale at agilelearner.com

    Interested in subscribing to agilelearner.com?

    How about one month subscription for a ridiculously low price of $1.98.

    Use coupon code ALFS-APRI-LONE-2016 at https://www.agilelearner.com/subscription.

    The coupon expires April 1st, 2016 at 11:59PM GMT.


    Monday, March 14, 2016

    Thoughts through Tweets

    This is a collection of some thoughts expressed by Venkat Subramaniam 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.

    You won't pick dentist based on their "money back guarantee." Don't pick a vendor based on strong SLA, but on reputation & relationship.

    You doing the right things today is a good way to earn a sincere 'thanks' from the future you.

    It's amazing how technology has evolved. We've gone from calling the wrong person to texting the wrong person.

    You don't need anyone's permission to be professional.

    When that urge to comment strikes, see how to express that thought in code instead of comment.

    People often are not as convinced about things as they think they are.

    If only we could compare the cost of quality with the cost of not having it...

    Poor quality is like crime, there will always be someone willing to commit it. But, we can hope & nurture, so more of us have better values.

    Speed without discipline is the fastest way to wreckage.

    Tools or techniques used blindly do not create good design, programmers being conscious, making good decisions, applying right tools, do.

    Some organizations try to breed programmers in captivity; they can't survive outside of their frameworks or IDEs.

    Treating someone nice is not an act of respect but of self-respect.

    Most programmers seems to be bothered by syntax; get past that soon, the real scare is in the semantics.

    There are two kinds of people we run into each day: those we work with and those we work around.

    indirection is the ultimate sophistication in programming.

    The four uses of frameworks: reuse, confuse, misuse, and overuse.

    Somewhere in the transition from childhood to adulthood, quite a few humans go from "I don't know" to "I don't care to know."

    A sentence with "I don't like..." should not end in period, but continue to suggest why and offer some constructive alternatives.

    I know for certain that the rest of my day can only be better, for I am starting by writing a regular expression.

    It's little things that make a big difference in the hearts.

    Geeks complaining about technology is far more pleasant to hear than folks complaining about people.

    The lessons from history are filled with wonders, from what the heck was wrong with people, to awe about small group's heresies & tenacity.

    After traveling thru much of this world I've discovered there are only four major religions: cricket, soccer, football, and hockey.

    After roaming several parts of this world I conclude there's actually a universal form of expression. It's called graffiti.

    Confusion may arise in the presence of complexity but it also appears in the case of unfamiliarity.

    I've taken a few decades to acquire great wealth that's in the form of friendship with some beautiful minds.

    Coding in dream is fun.

    We are but victims of poor designs.

    The net effect of complexities and ceremonies is multiplicative, not additive.

    A true appreciation/understanding of a language emerges when we dig into its semantics, not just its syntax

    We can't make legacy code better by writing more of the same way; it needs change in behavior and practice.

    The biggest impediment to learning is the reluctance to interact. Good work cultures break such barriers, making it safe to communicate.

    When I was young, I was told there's heaven and hell. As I got older, I learned that to be true and both coexist here on earth.

    When learning new constructs I wish more developers ask "how do we test it" instead of asking "how do we debug this"?

    aspiration without perspiration --> unfulfilled dreams.

    Often questions seem more interesting than answers.

    t seems like writing the introduction is the hardest part of writing a book. Coming up with a good subtitle, the second hardest.

    automated tests are but one of many means to an end—rapid useful feedback. If there are better easier ways in a context, go for it.

    Until we've fully immersed in both an exceptionally static typed & a superb dynamic typed lang, we have no rights for opinions on typing.

    what makes both writing and coding so interesting and challenging, at the same time, is there's simply no one way to express.

    sometimes it takes years to realize how suckish some practices are.

    When did presentation get attached to slides instead of communication?

    If employees are reluctant to express their view, and discuss issues, an organization has a bigger problem to tackle first.

    Better feedback comes, not from demos, but active use of an application while being developed.

    It's important to learn from mistakes quickly, so we can move on to make new ones.

    Writing code is a lot of fun, but throwing out code is pure bliss.

    I'm shocked that they'd actually number a flight 404, don't complain if no geeks board.

    When selecting a language, library, or a framework, it's vital to evaluate the ability to automate tests at various levels.

    A field improves, not from corporate mandates, but when its practitioners grow up to act professionally.

    Nothing exposes ones ignorance of a topic than an attempt to teach it.

    Java came late to the party, but they brought great desserts

    Life's too short to be complaining about things we can't also help improve.

    I really like the sense of humor my friends have. They endorsed me on Linkedin for XML.

    I like going to foreign lands so I can learn first hand how ridiculously I've been pronouncing their town names.

    A poor performing unreadable code is hard to cure on both fronts.

    What a teacher teaches is far less important that what a student learns and how it's applied.

    There's humor in life, wherever we look.

    Let not the current employment restrict professional and personal interest, growth, and freedom of expression outside of work.

    Don't turn your problems into your customers' problems.

    The true pleasures of meeting someone is hearing their stories of life and their perspectives.

    Every day is bright, as I find someone random, who's better than me in some way, and quietly helps me improve myself.

    Both in coding and writing, experience takes us from the anxious state of trying to figure out "what to write" to "what to remove."

    Frequent travelers are never in jet lag, they're only in denial.

    A programmer though "I could solve this problem using a monad," now has a sequence of problems.

    When we focus on what we don't really need, it takes away time, money, effort, and focus from where it's really needed.

    When we compromise quality for speed, we end up losing both.

    I feel like all my code is like Benjamin Button, from the way it's created to how it turns with each refactoring.

    By nature we're wired to mistake familiar as simple and the unfamiliar as complex.

    A bright day will come when software developers treat errors as normal instead of as exceptions.

    Nothing helps make things fall in place better than an approaching deadline.

    I call on restaurants to reduce serving size. You will help reduce waste and waist.

    "temp" is the name of a variable that's crying for its dignity and recognition.

    There comes a point in time when it's more prudent to deprecate a language than deprecating some of it's features.

    Experience is developing the courage to realize we were wrong so many time over the years.

    I've come to realize the struggle to write automated tests come from lack of understanding & poor design than lack of tools.

    Poor quality code is a reflection of lack of respect we carry for what we do, often with out realizing it.

    self-realization is the best realization.

    The easiest way to learn a new language quickly is to keep learning new languages. It raises our bar so unfamiliar turn to similarities.

    What we say is a reflection of the subject, how we say it is a reflection of us.

    Life, love, and time - can't think of anything more precious than that.

    I have a feeling that each task I strike off on my todo list gives birth to a few more tasks.

    A good code invites the reader.

    If we're in a course, conference, or a workshop and we stare at our own monitors, that's called being at the wrong place at the wrong time.

    It's hard to effect change when the key participants do not truly understand its impacts and benefits.

    A good professional places quality over quantity.

    It's through struggles and failures that real learning happens.

    The hardest things to explain are the ones we've not understood well.

    Mind, the tricks you play!

    Family: A small group sent to planet earth to be brutally honest about you.

    Nothing brings comforting smile out of a C++ programmer as an unhealthy dose of type coercion.

    A sense of urgency should help us create relevant things with better quality, not lot of things with poor quality.

    when nothing else works…. reboot

    No timeboxed activity that improves our learning and influences steps forward can be a waste of time. It's a necessary investment.

    When I hear someone say "hi baby" I wonder if the subject is addressed that way for possible cuteness or probable behavior.

    Three levels of programming competency: "it's all magic" -> "here's how it works" -> "here's how it should work"

    Programming with locks is not concurrent programming, it should be called congestion programming.

    Concise vs terse: short enough, transparent, easy to read -vs- short, opaque, hard to understand. Let's favor concise, not terse code.

    Ah, caught myself creating a Rube Goldberg machine, thankfully sanity kicked in.

    Perseverance is not the determination to stick with the current plan of action but the will to adapt so we can reach our goals.

    I'd rather hear a "no" than a "yes" followed by inaction.

    It's not just about speed, agility is also about heading in the right direction.

    If we mostly follow what the masses do, we will mostly get only the results that everyone gets.

    When young, we figure out it's a struggle to change the world, but as we get older we realize the real struggle is in changing ourselves.

    Test code now or detest it later.

    big change, big fail

    make it work, then make it better real soon.

    Let the tools make us productive but not ignorant.

    Love them bugs that teach a lesson and set me straight.

    Weigh in the potential productivity gain from an external dependency with the probable cost to maintain it along.

    Exercising is a practice that turns from aversion to addiction.

    In a world that seems to honor complexity & clutter, shredding the shame of simplicity is the first step to creating better design.

    Feedback empowers those willing to listen.

    Some organizations practice what I'd like to call "agile by convenience."

    We're victims of our own complexities.

    Writing gets better, with each writing, and each review.

    A good design is not the one that correctly predicts the future, it's one that makes adapting to the future affordable.

    After traveling to many parts of the world, I've discovered there is one common language. It's called giggles.

    big wins are built from small successes.

    Career is like a vehicle you operate, not hard to get it moving, but you still have to start, accelerate, steer, and decide where to go.

    That desire, to solve problems without understanding them.

    Q: "What to do if our designers create detailed design, insist we code it?" A: Start by confiscating their cassette players & floppy disks.

    Comments that tell us what the code means is not a form of documentation but a cry for refactoring.

    The more time-sensitive or mission critical a project is the shorter should be the feedback loop.

    Experience does not teach us to write different code, it teaches us to write it differently.

    Life's easier if, instead of the attitude of drivers, we've the agility of bicyclists who get around blocks than being stuck complaining.

    Our field has turned good ideas of OOP into unnecessary pollution & excessive mutation of state. Often don't need as many object nor state.

    Coming from the OO background, I feel that lazy evaluation is the polymorphism of FP, equally exciting and all the more powerful.

    Rewrote a piece of code three times in flight. Now that I closed the laptop, a much better implementation comes to mind!

    A well written code deals with failure. A poorly written code is a failure.

    The true value's not in the different, but in the difference; not in how different you are, but in how you make a difference.

    Anyone who thinks they have a sense of humor has never tried to be funny around their teenagers.

    I don't really give tech talks, I simply drag my able body to the podium, then the languages and tools take over to do the rest.

    I have a feeling that the current times will be referred to, not too distant in the future, as the stagecoach days of programming.

    It's that feeling all over again, when the answers are waiting for you to ask the right questions.

    If there's just one thing programming has taught me, it's the value of perseverance.

    Most projects would be dead if there were no deadlines.

    We all suck when we start something new. The easiest way to address that—suck soon, suck often.

    Running a code to prove its thread-safe is like proving that someone is not guilty by asking them if they are.

    Refactoring is not only about transforming code, it's equally about how it transforms the coder.

    The difficulty to solve a problem increases with our level of stress.

    Easy to write is important, but not more than easy to test and to maintain.

    Learning good practices can help turn teams 180 degrees, but they have to practice to avoid turning another 180 degrees.

    We can't fix punctuality issues by starting late. Everyone has reasons for their delays. Value and respect those who show up on time.

    The best moments, however short, are when an adult reveals the child in them.

    I know of only one way to write readable code—ask a colleague to read it.

    Learn for school, you're a student. Learn for a living, you're a professional. But learn to share & enlighten, you become a great teacher.

    Talent is a gift that comes wrapped in hard work.

    With Java 8 we don't do any thing different than before, but we do it differently, for the better.

    Don't let other's behavior define your character.

    If you mostly talk to me negative about others in their absence, I've to assume you do the same about me in my absence.

    Professionals don't compete to show who's better; they collaborate to make the world around them better for everyone.

    Exercise does the mind good, it's effect on the body is a bonus.

    Programmer: one who can name their children quite easily but has a hard time naming their variables.

    learning is empowering.

    Coding beats any other form of inflight entertainment, hands down.

    Being a programmer is like a kid in a candy store, every single day.

    Clear head and dirty shoes; the effect of getting out into nature.

    When a test fails the programmer succeeds in learning a bit more.

    A smile is worth a thousand words.

    Things are often not as complex as we make them to be.

    we often perform poorly when trying to anticipate and identify performance problems.

    Sentences with 'always', 'never', and/or 'only' are most often wrong.

    Don't let programmers watch movies w hacking. While the audience go "how cool," the geek's like "eh, wrong options, missed a -r. sigh."

    Code quality is the professional responsibility of the technically savvy—the onus is not on who lacks the knowledge, details, or skills.

    It's OK to create unmaintainable code, that's if you work with people you hate.

    If you don't test the software you create someone else will, with a negative impact on both cost and reputation.

    Lambda expressions should be glue code. Two lines may be too many.

    People don't fear failure. They fear being seen as a failure.

    documenting is so much easier than self-documenting, but not as effective.

    No need to carry along that bag of hate through the journey of life, travel light, especially if you like to reach some heights.

    Learning is a process by which a curious mind transforms a set of unknowns to knowns in a way that it exposes an abyss of unknowns.

    Developers are often taught to write code, but not how to write code.

    Think more, type less. Aim for minimalism, fewer states, less mutability, and just enough code for the known, relevant parts of the problem.

    Functional is declarative, but declarative is not necessarily functional.

    It's the struggles that make us stronger.

    Typed "code is composable" and got autocorrected to compostable; love it when autocorrect knows about the state and quality of my code.

    "I've set the wedding date. I've not asked her out yet."---how software projects are managed.

    Whatever it is the you want to do, put your heart and soul into it. Not because it deserves better, it's because you do.

    Software field has evolved. Decades ago some programmers wrote bad code. Now they most copy and paste it.

    A passive teacher focuses on teaching the students. An active teacher focuses on learning with the students.

    The quality of code is inversely proportional to the effort it takes to understand it.

    The toughest part of testing JavaScript is shaking the belief that it is impossible or unmanageably hard.

    If current dir path has space in its name, Karma does not auto run tests on file change. Proves that space in file names is bad karma.

    The main problem with most products is not their capability, but one of imposed complexity beyond reasonable need.

    desire improvement than perfection.

    True freedom can be cherished when what a human can do, out of their own good will, isn't judged and restricted by the biases of another.

    Eating is good, eating a lot in one sitting, not so much. Same with coding.

    Best time to change what we do is when things are going well. Let go of what's working, with confidence, to reach for a greater good.

    Get very uncomfortable when things begin to feel quite comfortable.

    A very pleasing moment is when I hear good things about people I know, especially friends, from total strangers.

    If you're right, you learned it well. If you're wrong, you're learning it now. Either way you come out winning.

    Both in life and in writing, would be nice to favor more discussions and fewer bullets.

    Programmers: A group of people who create puzzles, they call code, for each other to solve.

    Just realized that typing the word "intimidating" is in itself intimidating.

    It is so much fun to start something and see it quickly take shape in ways never imagined. A humbling experience.

    Some of our weaknesses, when cautiously channelled, can turn into a strength.

    put the effort to get the result.

    There is so much we can give, each one of us, way more than we realize or will.

    Much like how quality of code varies, quality of automated tests vary too. Don't assume all is well if tests are being written.

    What's separable is more easily testable. That's another reason cohesion and modularity matter.

    significant whitespace is a feature some languages provide as a way to mess with developers' sanity.

    Don't measure someones capability based on your ability.

    Time's wasted when we argue and correct every fool that comes along. Wise to focus on helping those who genuinely desire to improve.

    Quick fixes may appear as short cuts in the near term but we end up cutting short in the long run.

    Programming is an act of rewriting our assumptions.

    The sad part of middle age is watching the people you looked up to when young fade away into history.

    Either lead or follow, don't stay put.

    "What do I want to improve today?" is a great thought to start the day.

    Good habits and practices, like success, is not for everyone.

    Software development: a profession where people get paid to write poor quality code and get paid more later to cleanup the mess.

    Those who can't design are condemned to document.

    Automation is easier if we aspire to automate, but equally loathe manual efforts.

    Happiness: moment when what you enjoy meets what you do.

    Software development involves both innovation and productization. Our practices need to facilitate both.

    Never cease an opportunity to influence a young mind.

    We seem to be driven largely by the fear of short term gains than the pleasure of long term wins.

    There seems to be nothing so greatly motivating than a fast approaching deadline.

    There are good times and then there are interesting times.

    Development mindset in the last few decades has been CRUD. It seems to be shifting to streams… we're at the cusp of newer abstractions.

    The ease of testing a function is inversely proportional to the number of levels of abstraction it deals with.

    The first step in becoming a better programmer is to let go of the conviction that we can code it once and get it right on the first write.

    The answers are all around us, waiting for us to simply pop the questions right.

    Willingness to adapt and deal with the situation on hand is not agile, it's called attitude.

    I dare software products to change their "Accept the Terms and Conditions" to "tl;dr"

    There's one student I really care to teach everyday, it's the one within. The fact others learn along is a nice side-effect.

    I'm shocked. I accidentally looked up & saw a man, walking with head straight up, facing forward, with no device on hand, like it's 2005.

    The best way to kill a great idea is to ask for the permissions to implement it.

    Forget cholesterol levels, doctors have found a new measure of people's health. It's called CPM or complains per minute?

    Look but take time to see, hear but be keen to listen, touch but the heart, speak but as wise, and laugh but not at others.

    The more we taken on the less we're able to deliver and the quality suffers too. Manage time & task wisely.

    Quick to judge, slow to understand - we can do better than that.

    A better person is not the one with fewer faults, but one who finds fewer faults in others.

    We can't call our times modern, no way, while humans constantly provoke & fight each other rather than joining hands for a better world.

    quick or quality—choose one.

    Design is problem solving. Solving one problem often exposes other problems. Need desire, perseverance, and focus to forge ahead.

    Good music does the mind good.

    Those who sacrifice quality to get performance may end up getting neither.

    Funny we complain software's not extensible, yet we're comfortable dining in restaurants that can't deviate the slightest from their menus.

    The biggest impediment to FP is lack of familiarity. Code with that style in anger and it begins to get easier in no time.

    fp != cryptic code — languages should promote meaningful syntax, programmers should choose sensible parameter names.

    When will humans learn, imposing your ideology, however great you may perceive it to be, on others is a terrible act.

    Everyone's emotional, but we express it differently. It's that difference that makes life enjoyable.

    When our own money and personal reputation is involved in what we create, we think differently.

    Automated testing slows us down when we code, speeds us up when we refactor.

    We should take as much care about how we present as to what we present.

    Don't bother testing software, if it does not work your users will tweet about it.

    Software development is no longer a game of hobbyists. It affects humans in many ways. High time we improve our practices and discipline.

    Open and timely communication is a reflection of mutual respect.

    Nature has wired us to thrive on feedback, right from our first moments. Make active use of it in every form possible.

    I hated Haskell's static typing until I realized it infers the type and I don't really have to mess with that detail for most part.

    No success ever emerged from staying comfortable.

    Lack of professional discipline is an sign of occupational stupidity.

    Of all the journeys, the one from confusion to clarity is the most enjoyable.

    Writing is addictive.

    Programming is a wonderful act of continuous discoveries.

    Writing is like the morning fog, rewriting is like the Sunshine that follows.

    Writing does not consume time, it consumes you.

    Improving oneself each day is the most enlightening part of living.

    The toughest part of writing is mustering courage to delete an entire chapter and start over. The best part is the result.

    Success is important. But, an organization's desire to succeed at all cost, by sacrificing their employees' living, is morally wrong.

    After all it really takes PHD to succeed, no not a degree, but Perseverance, Hard work & Determination.

    After all it really takes PHD to succeed, no not a degree, but Perseverance, Hard work & Determination.

    JavaScript is like an infant. It's cute to play with, but you have no clue why when it begins to cry.

    The reason we call something a common curtesy is to remind ourselves that it's common and expected.

    Automate the heck out of the world around you.

    It's not about how long, but how much practice one has had.

    resolve(n): the state of mind to leave a box of donuts untouched.

    Two words that make children happy and, at the same time, make parents sad: “snow day”

    Write, rewrite, and again, until no words can be removed to convey the meaning.

    Remember, there's always a human at the other end.

    With almost anything in life: what matters is not what we have, but what we do with it

    I've had one hell of a programming career. From DLL hell to Jar hell through assembly hell down to the npm hell. What's next?

    Three things for a programmer to exercise daily: mind, body, and code.

    Nothing seems more profound than David Wheeler's words "All problems in computer science can be solved by another level of indirection.”

    A vigilant programmer should design to manage inherent complexities but work hard to remove accidental complexities.

    I suspect when programmers have trouble sleeping they don't count sheep. They're busy deciding if it should be an int, long, BigInteger,...

    TIL that some developers do Test Dreaming Development.

    To love someone we must be first willing to accept them instead of changing them.

    Deliver excellence, not excuses.

    Cruelest person in the history: inventor of the alarm.

    Mostly all we leave behind are memories. Let's make them good.

    So often we work hard to find correct solutions to the wrong problems, without ever realizing it.

    It's often not easy to make things easy.

    Thinking of friends, though their smartness grabbed my attention at first it's their humbleness & kindness that locked in the friendship.

    I have a strong suspicion that the autocorrect feature was designed to ruin relationships.

    agile is not about finishing fast. It’s about sensibly adapting based on the realities as they emerge.

    There is a circus that comes to stage every four years in the US. This time around it picked up more clowns than usual.

    Messing with state is the root of many problems, both in software and in politics.

    An enriching experience is not the amount of time or the number of years, but the amount of absorption and realization.

    Refracturing: "the act of refactoring code without any tests or quick feedback loops."

    Have we created a culture that our colleagues are so reluctant to ask for help?

    Of all my wants, what I ask myself each day is for more patience and humility.

    May be I'm old school, but I'm used to hearing words like "could you please?" and "thank you" in questions and conversations.

    Realizing ones own weaknesses is the greatest strength one could have.

    Coding for work, brings money. Coding for community, brings satisfaction. Coding something up the family wants, now that's true bliss.

    mixing mutability with lambdas/closures is dysfunctional programming.

    The trainings we're given teach how to write code, a lot of it. The coaching we really need is how to write a lot less with better quality.

    Can't improve our coding style without explicitly observing & making efforts to change our coding habits. Habits & style == cause & effect.

    Perseverance is one of the most important virtues of a programmer.

    Minutes turn into hours, hours into days, days into months, and those into years. Let not turn "I have a dream" to "I once had a dream."

    Hearing there is only one approach or way is not a sign of wisdom but a poor reflection of zeal.

    A good code makes us feel less stupid.

    Help, not hinder.

    Sometimes have to step close to a problem to see the solution. But then, sometimes farther away. The challenge's in deciding which is right.

    Every experience is a learning experience.

    So many of us take so many things for granted. Need more empathy.

    To teach someone what you know you have to start from what they know.

    Knowledge, wealth, and happiness: they are ephemeral and, at any time, there's always someone out there with more of each that we do.

    There's nothing more satisfying than hearing one’s friends being praised.

    A great day starts with a set of unknowns and ends with a new pile of unknowns.

    separation of concern is everyones concern.

    Mother's love is special. It's just love at first, turns into tough love when needed, and eventually becomes unconditional love.

    The more one codes well with one particular language the less they bode well with yet another language.

    It does not matter how awesome and slick a piece of code looks, it's not good if it's hard to test.

    If you wanna nail it be willing to first fail it, several times.

    We're too eager to teach programming to kids, but let's not lose sight of teaching the critical problem solving skills.

    There is no better time to get better.

    Learning's a lot like mountain hiking. It's up hill, exhausting, we lose the way at times, but the view from the summit makes it all worth.

    If being a startup means writing unmaintainable code, many organizations are in startup mode even decades later.

    The issue is not one of lack of principles or values, but of insistence that everyone should have the same.

    Relationships are reflections of attitudes.

    No developer should be expected or required to defend the use of any technology, library, or framework that helps deliver value.

    Technology infatuation is as bad as tech stagnation. Decisions have to be for the right reasons, not because it's the next cool thing.

    If your app/org stores password in an easily decryptable to human readable form, exercise 1 of 2 options: please fix it or blow the whistle.

    Family(n): Individuals huddled under one roof, each staring intently at their own devices.

    It does not matter what one does. What matters is that they enjoy it, it results in good, and they work hard to do it super well.

    Weeks to get response to some emails? I suspect some servers may be printing & delivering to destination servers using the postal dept.

    Nothing wrong in waiting for opportunity to knock, but when it does one still has to get up to respond timely.

    The most fundamental respect for someone should arise from the fact that they are a fellow human, everything else is secondary.