29 May 2013

Functional language for a java developer

Why should you learn it? IMHO, very important and underestimated argument is: it makes you a better programmer. What is more, you are probably already using it (javascript) and clojure and scala get more and more attention so it may be a good investment. But there is another, less obvious reason: it will help get a java job. A lot of interview questions are short algorithmic tasks. You can find one at almost every interview. Just pick the task, say that it would be easier to write it in a functional language and do it. Let's see a few examples. I asked google for 'programming interview questions' and I landed here. You can easily pick some tasks:

Create all permutations of a string. Here, haskell version is really impressive
permutation [] = [[]]
permutation xs = [x:ys | x <- nub (xs), ys <- permutation (delete x xs)]
In an array 1-100 numbers are stored, one number is missing how do you find it?
missing = succ . length . takeWhile id . zipWith (==) [1..] . sort
In an array 1-100 exactly one number is duplicate how do you find it?
duplicated = length . takeWhile id . zipWith (==) [1..] . sort
or after removing duplication:
increasingPrefixLength = length . takeWhile id . zipWith (==) [1..] . sort
missing = succ . increasingPrefixLength
duplicated = increasingPrefixLength
just for clarification, let's see how it works:
missing [1,3,2,5,6]
-- 4
duplicated [3,2,1,2,4]
-- 2
From other source: sum of digits of decimal expansion of 100!
(apply + (map #(Integer/parseInt (str %)) (str (apply *' (range 1 101)))))
number of zeros in decimal expansion of 100!
(count (filter #(= \0 %) (str (apply *' (range 1 101)))))
and the same in haskell (with currying and compact syntax for function composition)
sum . map digitToInt . show $ product [1..100]
length . filter (== '0') . show $ product [1..100]
Why functional style is useful? Often it's simpler because it has less edge cases (yes, you have to know the language and understand the FP). Of course above tasks aren't much more difficult in procedural approach and still, during the interview, you will probably have to solve them also in java. But I guarantee you: after such an answer you are a few points ahead of your competitors.

26 May 2013

Everything is a nail

How many times have you rejected someone's idea to use new tool in a (new) project? How many times have you done it without knowing the pros and cons of the tool? Just because you wasn't familiar with it? Why do you use the language / framework / library you use? Because it's best? Sufficient? If you really believe it, read the famous Beating the Averages (or at least the paragraph about The Blub Paradox).

Quiz


Before you expand code snippets, think for a while how would you solve the problem. Just try to estimate the complexity.

Question 1

What's the name of the following method? You know this method. If you don't, you should
public static boolean xxx(String str) {
    int strLen;
    if (str == null || (strLen = str.length()) == 0) {
      return true;
    }
    for (int i = 0; i < strLen; i++) {
      if ((Character.isWhitespace(str.charAt(i)) == false)) {
        return false;
      }
    }
    return true;
  }
How much time did you need to read and understand one of the most common functions?

Question 2

Can you do it better? Can you make this code more readable? Pick any tool you want.
isBlank = all isSpace

Question 3

Search all subdirectories and find all mp3 files greater than 9mb.
find -iname "*.mp3" -size +9M
Tiny academic examples? Maybe. Let's try something bigger and more complex.

Question 4

Write sudoku solver. The following solution is from Manuel Rotter's blog.
:- use_module(library(clpfd)). 

sudoku(Rows) :- 
  append(Rows, Vs), Vs ins 1..9,
  maplist(all_distinct, Rows),
  transpose(Rows, Columns),    
  maplist(all_distinct, Columns),    
  Rows = [A,B,C,D,E,F,G,H,I],    
  blocks(A, B, C), blocks(D, E, F), blocks(G, H, I),    
  maplist(label, Rows).     
 
blocks([], [], []).      
blocks([A,B,C|Bs1], [D,E,F|Bs2], [G,H,I|Bs3]) :-    
  all_distinct([A,B,C,D,E,F,G,H,I]),     
  blocks(Bs1, Bs2, Bs3)
Not a real life examples? No company would ever use such strange languages to make money? Well... they and they do.

Question 5

Something from corpo world. Typical security for web application. Only users with admin role (based on company's ldap) can access the application and only via https. Secondary log in of the same user should terminate his previous session. Each login should create new session id to prevent session fixation attack. Css files should not be protected because of performance.
<ldap-server url="ldap://mycompany.com:389/dc=mycompany,dc=com" />
<ldap-authentication-provider 
                         user-dn-pattern="uid={0},ou=people"
                         group-search-base="ou=groups" />

<http pattern="/css/**" security="none"/>
<http auto-config='true'>
    <form-login login-page='/login.jsp'/>
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" 
                                         requires-channel="https"/>
    <intercept-url pattern="/**" access="ROLE_ADMIN" requires-channel="https"/>

    <session-management>
        <concurrency-control max-sessions="1" />
   </session-management>
</http>
End of quiz. If you have other examples of a language/tool perfectly suited for a specific task, send them to me! Disclosure: prolog and spring examples haven't been tested.

Of course, you can't freely mix languages. Cost of integrating different languages, not designed for it, is rather high. Complicated build process, nonexchangeable data types, different runtimes, bad IDE support and so on. So, before each project, choose your language wisely. Will it cover most of requirements? Will it cover the most time-consuming ones? Then you won't add another language just to write isBlank but at some point it may be worth it. Will you recognize it when you reach that point? Cause when all you have is a hammer...