Month: December 2014

Upgrade to Bash 4 on Mac OSX

I came across some article regarding dictionary array for bash 4. I wanted to try it out but I am currently running bash 3.2 in Mac OSX Maverick. I came across this article on how to use homebrew to upgrade to bash 4 and ran into a few problems.

First, after I run

brew install bash

I got an error saying there is a permission error for /usr/local/share/info. I changed the owner of the folder to me and rerun the linking process.

sudo chown $(whoami) /usr/local/share/info
brew link bash

Everything seems to be working. Now I following the article and add /usr/local/bin/bash to /etc/shells and run chsh -s /usr/local/bin/bash (see link below). So I check my bash version to see what happen.

bash --version
GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin13)
Copyright (C) 2007 Free Software Foundation, Inc.

Ok. What is going on? I went and changed the Terminal Preference in Shells open with: Command (complete path) to /usr/local/bin/bash under Startup and still have the old version. Here I suspect that when I run the version check, I am not checking what the version open by the terminal but the /bin/bash version. Finally, I found out that there is an environment variable BASH_VERSION that I can check for the current bash environment that I am running.

echo $BASH_VERSION
4.3.18(1)-release

Bingo. It works. I changed my preference back to Default login shell and still give me the update version.

Additional References:

JMH : Java Microbenchmarking Harness

I attended PJUG last night and they had a talk about microbenchmarking in Java. The talk started with what might be the most important things to keep in mind for any benchmarking code.

  • avoid dead code elimination by always return output or use blackhole
    • An example is that if the code you are benchmarking doesn’t do anything, the optimizer might interpret it as dead code and never translate that into bytecode at all. However, if the result in the dead code is being return, then optimizer won’t be able to eliminate the code away.
  • avoid constant folding by reading input from state objects
    • If at some point inside the code for benchmarking where a function is taking a constant as argument and return the same value every time , then the optimizer again will interpret the return value as a constant as well even though you might be benchmarking the execution of the function. In this case, move the constant out and make it into a field in your class so that the function argument becomes a variable.

Other interesting topic were monomorphic, bimorphic and megamorphic, and concurrency issue with jmh. The full presentation slides is here.

Additional References:

Problem 25

99 Haskell Problems

Problem 25

Generate a random permutation of the elements of a list.

Example:

* (rnd-permu '(a b c d e f))
(B A D C E F)

Example in Haskell:

Prelude System.Random>rnd_permu "abcdef"
Prelude System.Random>"badcef"

Solution:

Using the nub solution from Problem 23 again,

rnd_permu xs = rnd_select xs (length xs)

With rnd_select as:

rnd_select :: [a] -> Int -> [a]
rnd_select x n = map (x!!) is
 where is = take n . nub $ randomRs (0, length x - 1) (mkStdGen 100)

Additional References:

Problem 24

99 Haskell Problems

Problem 24

Lotto: Draw N different random numbers from the set 1..M.

Example:

* (rnd-select 6 49)
(23 1 17 33 21 37)

Example in Haskell:

Prelude System.Random>diff_select 6 49
Prelude System.Random>[23,1,17,33,21,37]

Solution:

Using the nub solution from Problem 23 to remove any duplicates, this become very easy.

diff_select n m = rnd_select [1..m] n

With rnd_select as:

rnd_select :: [a] -> Int -> [a]
rnd_select x n = map (x!!) is
 where is = take n . nub $ randomRs (0, length x - 1) (mkStdGen 100)

Additional References:

Problem 23

99 Haskell Problems

Problem 23

Extract a given number of randomly selected elements from a list.

Example:

* (rnd-select '(a b c d e f g h) 3)
(E D A)

Example in Haskell:

Prelude System.Random>rnd_select "abcdefgh" 3 >>= putStrLn
eda

Solution:

Random number seems to be a departure from what I have learn about functional language as it is suppose to be referential transparent. Since I have not deal with random number in Haskell, some reading was needed. In particular, I learn a new notation call do block that helps initialize my random generator g.

rnd_select xs n = do
 g <- newStdGen
 print $ rndS xs n g

rndS [] _ _ = []
rndS xs n g
 | n == 0 = []
 | otherwise = (xs !! r) : rndS xs (n-1) gen
 where (r, gen) = randomR (0, ((length xs) - 1)) g

Using randomR in rndS function, I can pick a number from 0 upto length of the list minus 1 and use that number to pick the element. The most interesting part are the type for rndS and rnd_select:

rnd_select :: (Eq a1, Num a1, Show a) => [a] -> a1 -> IO ()
rndS :: (Eq a1, Num a1, RandomGen t) => [a] -> a1 -> t -> [a]

rndS is expected. However, rnd_select using do block, the output become IO() instead of [a]. A more elegant result from the solution is to use list comprehension:

rnd_select xs n = do
 g <- newStdGen
 return $ take n [ xs !! x | x <- randomRs (0, (length xs) - 1) g]

However, this still using IO[a] instead of [a] as the result. The solution was to use nub in yet another result from the solution section but now if you run the function in consecutive times, the result will be the same.

rnd_select :: [a] -> Int -> [a]
rnd_select x n = map (x!!) is
 where is = take n . nub $ randomRs (0, length x - 1) (mkStdGen 100)

Additional References:

Problem 22

99 Haskell Problems

Problem 22

Create a list containing all integers within a given range.

Example:

* (range 4 9)
(4 5 6 7 8 9)

Example in Haskell:

Prelude> range 4 9
[4,5,6,7,8,9]

Solution:

range :: Int -> Int -> [Int]
range start end
    | start > end = []
    | start == end = [end]
    | otherwise = start:(range (start+1) end)

Avoid exception by having a check return empty list if start is greater than end. However, the language provided range function as

range start end = [start..end]

Problem 21

99 Haskell Problems

Problem 21

Insert an element at a given position into a list.

Example:

* (insert-at 'alfa '(a b c d) 2)
(A ALFA B C D)

Example in Haskell:

P21> insertAt 'X' "abcd" 2
"aXbcd"

Solution:

insertAt :: a -> [a] -> Int -> [a]
insertAt x [] _ = [x]
insertAt x (y:ys) n
 | n > length(y:ys) = (y:ys) ++ [x]
 | n <= 1 = x:(y:ys)
 | otherwise = y:(insertAt x ys (n-1))

Any n less than or equal to 1 will assume the element will insert at the head and any n greater than the length of the list will be at the tail.