News aggregator

manage effects in a DSL

haskell-cafe - Tue, 01/28/2014 - 1:03pm
Hi Haskell-Caféists! I have a small DSL for a game. Some instructions have effects (change the game state), some not. -> In short, my question is: how can I semantically separate instructions with effect from the others? i.e. how can I mark down and track those effects? Here is a simplified version of the DSL I use. First some boilerplate: This is the DSL: It can read and write to an account (belonging to the state of the game), set a victory condition, and trigger some event every minute. With that you can write: "victoryRule" sets the victory condition to be: "if there is more than 100 gold in the account, you win." This is the game state: The evaluation of "Exp" can be: If you evaluate "victoryRule", you change the Game state by setting the victory field. Then, each time you will evaluate the victory field, you will know if you won or not (depending on your account...). This is all well and good, but imagine if you write: Ho no! Now each time a player is refreshing his screen (on the web
Categories: Offsite Discussion

Munich Haskell Meeting

haskell-cafe - Tue, 01/28/2014 - 12:52pm
Dear all, I hope that you had good start into 2014. Munich's Haskell enthusiasts (or other declarative languages) meet for their first get-together in 2014 on Thu, 30th of January at 19h30 at Cafe Puck. If you plan to join, please go here and hit the button: http://www.haskell-munich.de/dates With my best wishes for this year, Heinrich
Categories: Offsite Discussion

To LLVM or not to LLVM...

haskell-cafe - Tue, 01/28/2014 - 12:10pm
A package I just released (arb-fft) gets about a 17% performance boost from using GHC's LLVM backend (on my machine at least). That seems a big enough gain that I put "-fllvm" into the ghc-options field in the Cabal file for the package. Unfortunately, that means the package won't install unless you have the LLVM tools installed. What's the best thing to do? Use the native code generator by default and add a Cabal flag to install using LLVM? Just take the "-fllvm" out and add a note to the Cabal file description to tell people to install using LLVM if they have it? A quick survey of packages on Hackage reveals only very few instances where the "-fllvm" flag appears in Cabal files, which makes me suspect that I'm doing it wrong.
Categories: Offsite Discussion

Manage effects in a DSL

Haskell on Reddit - Tue, 01/28/2014 - 6:08am

Hi Haskellers! I have a small DSL for a game. Some instructions have effects (change the game state), some not. -> In short, my question is: how can I semantically separate instructions with effect from the others? i.e. how can I mark down and track those effects?

Here is a simplified version of the DSL I use. First some boilerplate (this is literate Haskell):

> {-# LANGUAGE GADTs #-} > import Control.Monad > import Control.Monad.State > import Control.Monad.Free

This is the DSL:

> data Exp a where > ReadAccount :: Exp Int > WriteAccount :: Exp Int -> Exp () > SetVictory :: Exp Bool -> Exp () > OnTimer :: Exp () -> Exp () > Return :: a -> Exp a > Bind :: Exp a -> (a -> Exp b) -> Exp b

It can read and write to an account (belonging to the state of the game), set a victory condition, and trigger some event every minute.

> instance Monad Exp where > return = Return > (>>=) = Bind > instance Functor Exp where > fmap f e = Bind e $ Return . f

With that you can write:

> victoryRule :: Exp () > victoryRule = SetVictory $ do > m <- ReadAccount > return (m > 100)

"victoryRule" sets the victory condition to be: "if there is more than 100 gold in the account, you win."

This is the game state:

> data Game = Game { bankAccount :: Int, > victory :: Exp Bool, > timerEvent :: Exp ()}

The evaluation of "Exp" can be:

> eval :: Exp a -> State Game a > eval (SetVictory v) = modify (\g -> g{victory = v}) > eval ReadAccount = get >>= return . bankAccount > eval _ = undefined -- etc.

If you evaluate "victoryRule", you change the Game state by setting the victory field. Then, each time you will evaluate the victory field in Game, you will know if you won or not (depending on your account...). This is all well and good, but imagine if you write:

> victoryRule' :: Exp () > victoryRule' = SetVictory $ do > m <- ReadAccount > WriteAccount (return $ m + 1) > return (m > 100)

Ho no! Now each time a player is refreshing his screen (on the web interface), the victory condition is re-evaluated to be displayed again, and the bank account is increased by 1! This is not what we want. We should allow only effect-less (pure) instructions in the victory field, like readAccount, but not WriteAccount.

How would you do that?

I tried with the Free monad to delimit those effects. I re-write each primitives, marking them with the special type "Effect", when needed.

> type Effect = Free Exp > -- readAccount remain the same: it has no effect > readAccount :: Exp Int > readAccount = ReadAccount > --writeAccount is marked as having an effect > writeAccount :: Exp Int -> Effect (Exp ()) > writeAccount ei = Pure $ WriteAccount ei > --onTimer is able to trigger an effect every minute > onTimer :: Effect (Exp ()) -> Effect (Exp ()) > onTimer e = Pure $ OnTimer $ iter join e > --victoryRule can be re-written like this, note that effects are rejected now > victoryRule'' :: Effect (Exp ()) > victoryRule'' = Pure $ SetVictory $ do > m <- readAccount > --writeAccount (return $ m + 1) --will be rejected at compile time (good)! > return (m > 100) > --increase my bank account by 1 every minute > winMoney :: Effect (Exp ()) > winMoney = onTimer $ do > m <- lift readAccount > writeAccount (return $ m + 1)

I don't know if I got it right at all... How does it sound? It only bothers me that in this context "Pure" really means "Impure" :) Do you think of any other solution?

Cheers, Corentin

submitted by kaukau
[link] [16 comments]
Categories: Incoming News

Lecture notes and assignments

del.icio.us/haskell - Tue, 01/28/2014 - 3:07am
Categories: Offsite Blogs

Lecture notes and assignments

del.icio.us/haskell - Tue, 01/28/2014 - 3:07am
Categories: Offsite Blogs

Yesod Web Framework: Announcing: the Resource monad

Planet Haskell - Tue, 01/28/2014 - 2:40am

Back in June, Gabriel Gonzalez wrote a blog post on the Resource monad. At the time, I thought it was an interesting idea, but I didn't have a very good use case for it. However, while working on Persistent 2.0, I realized it was a great way to abstract the concept of acquiring a database connection, and allow both ResourceT and non-ResourceT access to Persistent.

So with Gabriel's permission to steal his idea, I added the Resource monad to the resourcet package. The internal representation is slightly different than the one presented in Gabriel's blog post. In order to provide proper async exception safety, the internal structure is:

data Allocated a = Allocated !a !(IO ()) newtype Resource a = Resource ((forall b. IO b -> IO b) -> IO (Allocated a)) instance Monad Resource where return a = Resource (\_ -> return (Allocated a (return ()))) Resource f >>= g' = Resource $ \restore -> do Allocated x free1 <- f restore let Resource g = g' x Allocated y free2 <- g restore `E.onException` free1 return $! Allocated y (free2 `E.finally` free1)

Allocated provides a value and its cleanup method. Resource is a function from mask's restore function to an action returning Allocated. By being set up in this way, we know that async exceptions are not thrown in the intermediate steps of monadic bind.

Usage of the API is pretty simple. We can create a file-opening resource:

openFileResource :: FilePath -> IOMode -> Resource Handle openFileResource fp mode = mkResource (openFile fp mode) hClose

Using the Applicative instance, we can then build this up into a Resource for allocating both a file reader and writer:

myHandles :: Resource (Handle, Handle) myHandles = (,) <$> openFileResource "input.txt" ReadMode <*> openFileResource "output.txt" WriteMode

And then we can allocate these Handles with either the bracket pattern:

bracketCopy :: IO () bracketCopy = with myHandles $ \(input, output) -> sourceHandle input $$ sinkHandle output

or using ResourceT itself:

resourcetCopy :: IO () resourcetCopy = runResourceT $ do (releaseKey, (input, output)) <- allocateResource myHandles sourceHandle input $$ sinkHandle output release releaseKey

Hopefully others will find this abstraction useful as well.

Categories: Offsite Blogs

Builder vs Builder

haskell-cafe - Tue, 01/28/2014 - 1:06am
Does anyone know whether blaze-builder is deprecated in favour of bytestring's new Builder module, or are they the same, or... I know Simon is the evil wizard cackling in his dank lair in both cases, and I do remember him saying he was trying to get his work "upstream" into bytestring, but I haven't heard anyone suggesting we should be using Data.ByteString.Lazy.Builder instead of Blaze.ByteString.Builder I can only imagine the integration with the allocation routines is much better now that it's in bytestring, but on the other hand it's hard to upgrade bytestring — it being so low in the stack — so perhaps the original blaze remains the right choice from a bugfix and stability perspective. Thoughts? AfC Sydney _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Just Testing

del.icio.us/haskell - Tue, 01/28/2014 - 12:33am
Categories: Offsite Blogs

Just Testing

del.icio.us/haskell - Tue, 01/28/2014 - 12:33am
Categories: Offsite Blogs

The Unlines

del.icio.us/haskell - Tue, 01/28/2014 - 12:33am
Categories: Offsite Blogs

The Unlines

del.icio.us/haskell - Tue, 01/28/2014 - 12:33am
Categories: Offsite Blogs

Announcement - HGamer3D release candidate 0.3.0

haskell-cafe - Mon, 01/27/2014 - 11:54pm
Dear All, I'm happy to announce HGamer3D, version 0.3.0 as a release candidate on Github. Please look here: http://www.hgamer3d.org and https://github.com/urs-of-the-backwoods/HGamer3D . The new version features: - Linux ! (in addition to Windows) - HBind tool to generate and administrate bindings Of course I would be largely interested in feedback for the final release of 0.3.0. Best regards Peter Althainz _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

mightybyte: Ember.js is driving me crazy

Planet Haskell - Mon, 01/27/2014 - 11:52pm

For the past few months I've been working on a project with a fairly complex interactive web interface. This required me to venture into the wild and unpredictable jungle of Javascript development. I was totally unprepared for what I would find. Soon after starting the project it became clear that just using JQuery would not be sufficient for my project. I needed a higher level Javascript framework. After a doing a little research I settled on Ember.js.

The Zombie Code Apocalypse

Ember was definitely a big improvement over straight JQuery, and allowed me to get some fairly complex UI behavior working very quickly. But recently I've run into some problems. The other day I had a UI widget defined like this:

App.FooController = Ember.ObjectController.extend({ // ... }); App.FooView = Ember.View.extend({ // ... });

It was used somewhere on the page, but at some point I decided that the widget was no longer needed, so I commented out the widget's markup. I wasn't sure whether we would ultimately keep the widget or not, so I opted to keep the above javascript code for the controller and view around for awhile so it would be easily available if I later decided to re-enable that UI element.

Everything seemed to work fine until a few days later when I noticed that another one of my controls, Bar, was not being populated with data. After spending hours trying to figure out the problem, I finally happened to comment out the unused code for the Foo widget and the problem went away. WTF?!? Why should this have anything to do with the functioning of a completely unrelated widget? This makes absolutely no sense to me, and it completely violates the natural assumption that the controller and view for two completely unrelated controls would have no impact on each other. I would have liked to know the underlying cause, but I didn't want to waste time with it, so I just removed the code and moved on.

Spontaneously Changing Values

Maybe a week later I ran into another problem. Some data was changing when I didn't expect it to. I looked everywhere I could think of that might affect the data, but couldn't find anything. Again, I spent the better part of a day trying to track down the source of this problem. After awhile I was getting desperate, so I started putting print statements all over the place. I discovered that the data was changing in one particular function. I examined it carefully but couldn't find any hint of this data being impacted. Eventually I isolated the problem to the following snippet:

console.log(this.get('foo')); this.set('bar', ...); console.log(this.get('foo'));

The first log line showed foo with a value of 25. The second log line showed foo with a value of 0. This is utter madness! I set one field, and a completely different one gets changed! In what world does this make any shred of sense? This time, even when I actually figured out where the problem was happening I still couldn't figure out how to solve it. At least the first time I could just comment out the offending innocuous lines. Here I narrowed down the exact line that's causing the problem, but still couldn't figure out how to fix it. Finally I got on the #emberjs IRC channel and learned that Ember's set function has special behavior for values in the content field, which foo was a part of. I was able to fix this problem by initializing the bar field to null. WAT?!?

I was in shock. This seemed like one of the most absurd behaviors I've encountered in all my years of programming. Back in the C days you could see some crazy things, but at least you knew that array updates and pointer arithmetic could be dangerous and possibly overwrite other parts of memory. Here there's no hint. No dynamic index that might overflow. Just what we thought was a straightforward getter and setter for a static field in a data type.

Blaming Systems, Not People

Before you start jumping all over me for all the things I did wrong, hear me out. I'm not blaming the Ember developers or trying to disparage Ember. Ember.js is an amazing library and my application wouldn't exist without it or something like it. I'm just a feeble-minded Haskell programmer and not well-versed in the ways of Javascript. I'm sure I was doing things that contributed to the problem. But that's not the point. I've been around long enough to realize that there are probably good justifications for why the above behaviors exist. The Ember developers are clearly way better Javascript programmers than I will ever be. There's got to be a better explanation.

Peter Senge, in his book The Fifth Discipline, talks about the beer distribution game. It's a game that has been played thousands of times with diverse groups of people in management classes all over the world. The vast majority of people who play it perform very poorly. Peter points out that we're too quick to attribute a bad outcome to individual people when it should instead be attributed to the structure of the system in which those people were operating. This situation is no different.

Like the beer distribution game, Javascript is a complex system. The above anecdotes demonstrate how localized well-intentioned decisions by different players resulted in a bad outcome. The root of the problem is the system we were operating in: an impure programming language with weak dynamic typing. In a different system, say the one we get with Haskell, I can conclusively say that I never would have had these problems. Haskell's purity and strong static type system provide a level of safety that is simply unavailable in Javascript (or any other mainstream programming language for that matter).

The Godlike Refactoring

In fact, this same project gave us another anecdote supporting this claim. The project's back end is several thousand lines of Haskell code. I wrote all of the back end code, and since we have a pretty aggressive roadmap with ambitious deadlines the code isn't exactly all that pretty. There are a couple places with some pretty hairy logic. A few weeks ago we needed to do a major refactoring of the back end to support a new feature. I was too busy with other important features, so another member of the team worked on the refactoring. He had not touched a single line of the back end code before that point, but thanks to Haskell's purity and strong static type system he was able to pull off the entire refactoring single-handedly in a just a couple hours. And once he got it compiling, the application worked the first time. We are both convinced that this feat would have been impossible without strong static types.

Conclusion

I think there are a couple of interesting points worth thinking about here. First of all, the API chosen by Ember only hid the complexity, it didn't reduce it. What seemed to be a simple get() method was actually a more complex system with some special cases. The system was more complex than the API indicated. It's useful to think about the true complexity of a problem compared to the complexity of the exposed API.

The second point is that having the ability to make categorical statements about API behavior is very important. We use this kind of reasoning all the time, and the more of it we can do, the fewer the number of assumptions we will have to question when something isn't behaving as we expect. In this case, I made the seemingly reasonable categorical assumption that unused class definitions would have no effect on my program. But for some reason that I still don't understand, it was violated. I also made the categorical assumption that Ember's get() and set() methods worked like they would work in a map. But that assumption didn't hold up either. I encounter assumptions that don't hold up all the time. Every programmer does. But rarely are they so deeply and universally held as these.

So what can we learn from this? In The Fifth Discipline, Senge goes on to talk about the importance of thinking with a systems perspective; about how we need to stop blaming people and focus more on the systems involved. I think it's telling how in my 5 or 6 years of Haskell programming I've never seen a bug as crazy as these two that I encountered after working only a few months on a significant Javascript project. Haskell with it's purity and strong static type system allows me to make significantly more confident categorical statements about what my code can and cannot do. That allows me to more easily build better abstractions that actually reduce complexity for the end user instead of just hiding it away in a less frequented area.

Categories: Offsite Blogs

ajg/yocto · GitHub

del.icio.us/haskell - Mon, 01/27/2014 - 7:46pm
Categories: Offsite Blogs

ajg/yocto · GitHub

del.icio.us/haskell - Mon, 01/27/2014 - 7:46pm
Categories: Offsite Blogs