24 July 2013

Python should have Haskell's $ operator

In Python, I often want to repeatedly say "apply some function to the remainder of the current statement". Think foo(bar(baz(qux, quux))). In my text editor, which mostly automatically handles the parenthesis correctly, this is a quick thing to type.

Within IPython, statements like that are tedious. IPython does have a limited version of this in its automatic parenthesis feature. Notice how many syntax error gotchas lurk in those examples.

Haskell's $ operator is pretty sweet. All of the following are equivalent in Haskell:

putStrLn (show (1 + 1))
putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1

Python should adopt Haskell's $ operator. That is, the following should be equivalent:

foo(bar(baz(qux, quux)))
foo $ bar $ baz(qux, quux)
foo $ bar $ baz $ qux, quux
Though odd looking, there's easy consistency for unary functions:
foo()
foo $

Haters of the new-ish print might find respite in print $ foo.

26 June 2013

Plus ça change.org

This past fall I spun up a change.org petition entitled 83rd Texas State Legislature: Reduce traffic congestion by legalizing lane-splitting for motorcycles. As of right now, 1,664 people signed the petition. Sadly, despite gathering this tome of names and much late-night letter writing to both newspapers and elected officials, the Texas legislature didn't introduce the desired bill.

But there may be hope for the 84th legislature in two years... Today I got an unexpected and very cool email from the office of Senator Kirk Watson. Watson said he'll try to get lane splitting formally studied between now and the next legislature. I'll redefine success to match this outcome and claim it. The full message follows.

19 April 2013

How to not land a job.

30 March 2013

Quick benchmark on the bounded_buffer<T> example from Boost Templated Circular Buffer

Boost's Templated Circular Buffer documentation claims that some modest Boost.Thread wrapping of a boost::circular_buffer<T> makes a bounded producer-consumer queue. Happily, they provide a benchmark. I believe 'em, of course, but I'd like to get an idea of the variability behind the claims.

Rusty Russell, of CCAN fame, put out a nice pipe-oriented processor for gathering statistics. This can directly be fed the output of the benchmark as a pretty cute one-liner:

gcc -Wall -O3 -pthread bounded_buffer_comparison.cpp -lboost_thread-mt
for i in `seq 1 100`; do ./a.out; done | ./stats

With a touch of reformatting and sorting the columns by increasing mean, here are the results on a circa-2007 T61 stinkpad of mine:

bounded_buffer<int>                         0.45 -- 0.98  (0.7588 +/- 0.17 ) s
bounded_buffer<std::string>                 0.58 -- 0.91  (0.7678 +/- 0.095) s
bounded_buffer_deque_based<std::string>     0.43 -- 0.94  (0.8291 +/- 0.095) s
bounded_buffer_deque_based<int>             0.48 -- 1.03  (0.8374 +/- 0.12 ) s
bounded_buffer_space_optimized<int>         0.55 -- 1.10  (0.8459 +/- 0.1  ) s
bounded_buffer_space_optimized<std::string> 0.46 -- 1.21  (0.8852 +/- 0.24 ) s
bounded_buffer_list_based<int>              2.84 -- 6.65  (4.2641 +/- 0.74 ) s
bounded_buffer_list_based<std::string>      2.22 -- 5.77  (4.2663 +/- 0.66 ) s
Building -O3 makes a big difference as you might expected and I've not bothered showing -O2. On average, the sample bounded_buffer<T> does slightly outperform the deque-based logic as the Boost Templated Circular Buffer documentation suggests. The variability is, uhhh, more variable than I'd expected.