Saturday, August 20, 2011

Beer Part Two

So since my first post I've actually had occasion to try a couple of other beers. My buddy Ryan brought over a can of Labatt Blue Light Lime. I'm not sure I enjoy the addition of lime flavor to beer.

That same evening, I split a bottle of Blue Moon Summer Honey Wheat with him. That I did enjoy. Wheat beers comprise the majority of what I've had so far, and I must say they are growing on me. I don't think honey can help but improve most things. Beer turned out to be no exception.

Finally, since Ryan is leaving for Germany, another friend and I took him to the RIT-local bar: MacGregors. The selection for the three of us that evening was a pint each of Great Lakes Holy Moses (another wheat beer, with orange and coriander). Though it seemed a bit stronger than the Blue Moon, (the time separation is enough that direct comparison isn't possible) it was quite enjoyable alongside a burger on wheat bread.

That puts me up to date blogging about beer.

Saturday, August 13, 2011

Granola

I've been tweaking this through a few batches and this is what seems to work.

  • 3 cups rolled oats
  • 1/2 cup brown sugar
  • 1/2 cup butter
  • 1/3 cup honey

Combine oats and brown sugar. Melt butter, stir in honey. Combine with dry ingredients and stir until oats are coated. Spread evenly on a cookie sheet with foil. Bake at 325F for 13-20 minutes (until just lighter than golden brown), stirring every 5-7 minutes.

Friday, August 5, 2011

Beer

My wonderful Aunt was in town, and since my 21st (legal age for alcohol possession in the US) birthday was a couple of weeks ago, she bought some beer for me. So I now have several to try, and I'll be blogging about what I've discovered.

Initial Inventory

  • Sam Adams Blackberry Witbier x6
  • Sam Adams Boston Lager x1
  • Blue Moon Summer Ale x2
  • Ellicotville Blueberry Wheat Beer x2
  • Ithaca Nut Brown x1
  • Saranac Adirondack Lager x1

Tonight I had a friend over for dinner, and we each had a Blackberry Witbier. The blackberry flavor was there, but barely detectable. The beer overall was slightly bitter but very enjoyable.

I'll continue to post my brief thoughts on the beers as I try them. Next up is most likely the Summer Ale.

Monday, July 18, 2011

From Chesterton's "Orthodoxy"

But remember that this text is too lightly interpreted. It is constantly assured, especially in our Tolstoyan tendencies, that when the lion lies down with the lamb the lion becomes lamb-like. But that is brutal annexation and imperialism on the part of the lamb. That is simply the lamb absorbing the lion instead of the lion eating the lamb. The real problem is—Can the lion lie down with the lamb and still retain his royal ferocity? THAT is the problem the Church attempted; THAT is the miracle she achieved.

Wednesday, July 13, 2011

Garlic Fries Success!

On my second attempt at making garlic fries, I was successful, modulo a few undercooked fries which can be attributed to a college apartment stove and cheap pan with very uneven heat distribution. Rather than follow the recipe which called for a two-step process of baking the oil-coated fries and then frying them in garlic butter, I went straight to the frying. I also decided to substitute cheddar for parmesan and chives for parsley.

Ingredients

3 cu. inches (approx) sharp white cheddar cheese
4 cloves of garlic
2 chives
4 tablespoons butter 1 large baking potato

Procedure

Slice potato into 1/4in by 1/4in strips. Melt butter over low-to-medium heat. Begin frying the potato strips in the butter. Increase heat to medium. Crumble cheddar cheese. Finely chop garlic. Chop chives. Combine these ingredients. Turn potato strips as they cook. When strips are golden brown on all sides, add cheese, garlic, and chives, stir with spatula. Place fries on plate covered with paper towel to drain excess butter. Serve immediately.

Tuesday, July 12, 2011

Abstract of Research in Transactional Events

I'll be revising my abstract in this post. Comments appreciated.

Revision 1 (Initial Revision)

Revision 1 (Initial Revision)

Transactional Events is an abstraction (a well-defined concept hiding implementation details) for communication between concurrent processes (multiple programs running at once). The current implementation of Transactional Events provides only the guarantee that a communication will happen if one is possible.

A particularly attractive possible guarantee is that of "fairness," which guarantees that for a concurrent thread which is repeatedly capable of communicating, there is no point after which it never communicates.

In each of our attempts to enforce this property in the implementation, we have been able to construct counterexamples which either prevent the system from making progress or escape the enforcement of the fairness guarantee. This leads us to suspect that enforcing fairness requires the solution of an undecidable problem.

To prove that enforcing fairness requires this solution we are attempting to demonstrate that an implementation which enforces fairness would permit the solution of such an undecidable problem. Such a demonstration would prove the impossibility of enforcing the fairness condition.

Finally, we are exploring if a condition similar to fairness but weak enough to enforce would still be useful.

Saturday, June 4, 2011

Summer Research: Transactional Events (and other summer stuff)

I'm in Rochester for the summer, primarily to do research with Matthew Fluet on Transactional Events. I'll be working on Dr. Fluet's implementation of Transactional Events (TxEvents) in Haskell.

I'll also be working with Intervarsity Christian Fellowship over the summer. I'm hoping to perhaps lead a "GIG" ("Group Investigating God") this summer, certainly in the fall. I'll also be working with the IV staff to explore our resources for outreach.

Hopefully I'll get to go to a baseball game in or two this summer. I'd like to make a trip to Cincinnati to finally see my Reds play at home, but who knows.

Friday, May 20, 2011

A Survey of Functional Reactive Programming [Link PDF]

I just completed a survey paper of the literature on Functional Reactive Programming for an independent study. I'm posting it in the hope that it is useful to someone investigating FRP. http://www.cs.rit.edu/~eca7215/frp-independent-study/Survey.pdf

Monday, May 2, 2011

Project Ideas for the summer

I'll be here over the summer working 30 hours/week on research, so I should have time to do other productive things. I plan on editing this list whenever I get more ideas. I've listed these in order of decreasing overall difficulty.

Ridiculous

  • Dalvik code generator for GHC
  • Bindings to Android libraries to go along with the above

Hard

  • Haskell bindings for the Cocoa API
  • Comms app for Android

Medium

  • Driving app for Android
  • FRP optimization benchmarking

Easy

Sunday, April 3, 2011

Howto: Install GHC 7.0.3 on OS X 64-bit with shared library support

I have JackOSX installed on my computer, which provides the JACK client libraries only as a dynamic library. I want to build Sonke Hahn and Henning Theilmann's Haskell bindings to the JACK library, but GHC doesn't come build with dynamic library support for OS X x86_64 in the Haskell Platform. I grabbed the GHC 7.0.3 sources and discovered the following steps to get a GHC install with dynamic library support. (You must have a working 64-bit GHC installed, I used 7.0.2 from HP 2011.2.)

  1. Install libgmp (I used Homebrew). Though the GHC sources include libgmp, it doesn't build libgmp as a shared library, which causes problems linking integer-gmp later on. Installing libgmp through homebrew or macports will build libgmp as a shared library.
  2. In the build tree, copy "mk/build.mk.sample" to "mk/build.mk".
  3. Edit the "mk/config.mk" file, and find the line that says "PlatformSupportsSharedLibs = ..."
  4. In the platform list on this line, add "x86_64-apple-darwin"
  5. Run the configure script, making sure to use "--with-gmp-includes" and "--with-gmp-libraries" to tell configure where to find your preinstalled libgmp headers and libraries.
  6. make && sudo make install

Disclaimer: I take no responsibility for any damage caused by following these instructions. Building OS X 64 bit shared library code is obviously not officially supported by GHC, and I'm not sure it works for anything other than the simplest programs.

Edit: Don Stewart commented that a release of the Haskell Platform with support for dynamic libraries on OS X is due in early April 2011.

Tuesday, March 22, 2011

Demonstrating a Time Leak in Arrowized FRP

One of the motivations for expressing FRP (Functional Reactive Programming) as signal functions is to avoid time leaks [1].

A time leak is a situation in which a value is dependent on past values for an arbitrary time interval, and they are not evaluated as they are produced, thus, suddenly forcing a value may take an arbitrary amount of time. This occurs in the following pathological example in Haskell with Yampa, but should be true in the general case for continuation-based signal function implementations in non-strict languages:

{-# LANGUAGE Arrows #-} 
module Main where 
 
import Data.Time.Clock
import Data.IORef
import FRP.Yampa
import System.Random
 
alt :: SF a b -> SF a b -> SF a (Event ()) -> SF a b
alt sf1 sf2 sfEv = proc inp -> do 
  outPair <- sf1 &&& sf2 -< inp
  evt <- sfEv -< inp
  swappedEvt <- accum (arr fst) -< evt `tag` (arr swap >>>) 
  rSwitch (arr fst) -< (outPair, swappedEvt) 
  
average = proc inp -> do 
  inpIntegral <- integral -< inp
  t <- time -< inp
  returnA -< inpIntegral / t
  
leak = (time &&& after 30 ()) >>> alt (constant 0) (arr fst >>> average) (arr snd) 
              
         
main = do 
  t <- getCurrentTime
  timeRef <- newIORef t 
  let init = return ()
      sense = (\_ -> do 
                  t' <- getCurrentTime
                  t <- readIORef timeRef 
                  let dt = realToFrac (t' `diffUTCTime` t) 
                  writeIORef timeRef t'
                  return (dt, Nothing) 
              ) 
      actuate = (\_ x -> do 
                    print x
                    return $ snd x > 60 
                ) 
  reactimate init sense actuate (leak &&& time) 

Since the integral (within the average function) is dependent on all past values, and the average function is part of the network from the beginning, but its output is not required until 30 seconds into evaluation, it builds up an extremely long sequence of thunks. On my machine, one can observe the behavior as at the 30 second mark the program pauses for a short time and then trips a stack overflow, caused by running out of stack space for the chain of evaluations.

  1. "Functional Reactive Programming, continued" Nilsson, Henrik and Courtney, Antony and Peterson, John, Haskell '02

Edited for forgotten citation

Wednesday, January 19, 2011

Corrected Instances for the MonadAttempt class

In my previous post, I outlined the MonadAttempt class that I had created to solve a problem with code generation using a state monad in Haskell. This morning, with a much clearer mind, I was able to create much cleaner instances for the StateT and ErrorT monads:
instance (Monad m, MonadAttempt m) => MonadAttempt (StateT s m) where
  attempt a m = do s <- get
                   lift $ attempt a $ do (x, _) <- runStateT m s
                                         return x
 
instance (Error e, Monad m, MonadAttempt m) => MonadAttempt (ErrorT e m) where
  attempt a m = lift $ attempt a $ do e <- runErrorT m
                                      case e of
                                        Left _ -> return a
                                        Right x -> return x


  

Tuesday, January 18, 2011

The MonadAttempt Class

While working on the code generator for my compiler construction class, I ran across a rather somewhat sticky issue. I am using a state monad to store code as it is generated. This allows me to very quickly build up sequences generated from an AST. However, for conditional instructions, I needed a jump location, which depends on the length of code generated *after* the conditional. There are several ways I could do this, but the solution I invented allows me to generate the code and then 'rewind', knowing the length of the code, and generating the jump instruction. I'm only going to demonstrate instances that I used in my code generator here, as I have not taken the time to write any others. I also haven't spent a lot of time verifying correctness or elegance, so I'd love to hear about any mistakes in the comments.

class Monad m => MonadAttempt m where
  attempt :: a -> m a -> m a
  
The MonadAttempt class defines 'attempt', which takes a default value and monadic action, and returns the result of the monadic action without its side effects, or the monadic action returning the default value if the input action fails.

instance MonadAttempt Identity where
  attempt _ m = m
 
The instance for the Identity monad is trivial. There are no side effects, so we can simply produce the action.
 
instance (Monad m, MonadAttempt m) => MonadAttempt (StateT s m) where
  attempt a m = do s <- get
                   (x, _) <- lift $ attempt (a, s) $ runStateT m s
                   return x
I suppose a more elegant solution would be a do block to extract just the return value from runStateT, but this worked for what I needed. runStateT is used to isolate the side effects, the transformed monad is recursively attempted with a new default value, and the the result is then lifted. But since lift is pure in the transformer (not necessarily the transformed) monad, the state is not updated, and we can extract just the value. (Note that we explicitly get the state and then use it to run the monad.)
 
 
instance (Error e, Monad m, MonadAttempt m) => MonadAttempt (ErrorT e m) where
  attempt a m = do e <- lift $ attempt (Right a) $ runErrorT m
                   case e of
                     Left _ -> return a
                     Right x -> return x
  
  
  
For ErrorT, we attempt the computation, return its result if we can, and if not, return the default value. Again, a do block for extracting the value is probably in order.

I will try to rewrite the StateT and ErrorT instances tomorrow such that they pass the same value to the recursive attempt calls (down the monad transformer stack). If I'm successful I'll post it here.

Update: I've posted corrected instances.

Saturday, November 6, 2010

The Library

I got a chance to do something that I have not done all quarter. I relaxed and read some stuff that I really enjoyed. Even when I've had spare time, sitting in my apartment, I wasn't able to do that. Something about the view from the fourth floor of the library, combined with the excitement of discovery (always available in a library) combined as God's gift of relaxation for me. Perhaps I will visit more often now.