Who's data is it anyways?
Whenever you post a comment in a blog, news article or your favorite social network, there is always a question of who owns the data and who creates value. Clearly on sites like Facebook and Twitter, YOU create most of the value, with comment on NYTimes, you create partial value. However you run the risk of losing YOUR data if the company goes under or it gets bought by Google and is discontinued. That's where disqus comes in and at least tries to solve the problem. If the website you're on supports disqus, then you have some control over your data. However this only solves the problem partially since for all the sites that don't support disqus comments, the problem still persists.
The solution:
A browser extension that records whatever you type on a textbox. ( Of course you have to authorize it to do so). That way all your comments are safe. It could also provide an option to save it on a server somewhere so you have some kind of a stream/blog kinda thing that belongs to you.
I hope somebody builds this. I'd use it.
Flush Internals
Most games need to manage the current state of a game, be it chess positions or number of cards played or the size of the pot. One could always use an global variable like turn and then set the variable to the next player., However, another approach could be to use functional programing idioms and let the state flow from one player to the next without having to create any such variable.Suppose there is a list of players, then we could recursively work on the list and get to the next player.For example:
(define (play players)
(if (null? players) ‘end
(begin
(do-sth (car players))
(play (cdr players))))Here we recurse on the list players and call do-sth on the first player in the list.Here we have completely removed the use for a turn variable. However, in this simplistic example there is no state management. In the game of flush, there are a couple of variables we need to manage, viz. the current size of the pot, the current minimum allowable bet amount and the amount of money each player has and info on whether a player has passed or not. Lets add the first two variable into our example. Also we change do-sth to play? which looks at the cards of the current player and decides whether it wants to play or not. (define (play players pot minbet)
(if (null? players) ‘end
(if (play? (car players)
(play (cdr players) (+ pot minibet) minibet)
(play (cdr players) pot minibet)
Now , when a player plays, the size of the pot increases and this information is passed on to the next player .( Note that we don’t have the functionality right now to increase the minibet yet.)But a coulple of information are missing like the amount of money player1 has and the pass state of a player. If a player has already passed, it will simply pass all the information to the next player. (define (play players pot minibet ms ps)
(if (null? players) ‘end
(if (and (car ps) (play? (car players) minibet pot (car ms))
(play (cdr players) (+ pot minibet) minibet (cdr ms) (cdr ps))
(play (cdr players) pot minibet (cdr ms) (cdr ps)))))
Ok, now we’ve made a couple of changes. First we added the list ms (money ) and ps (pass status) for each player. The (car ps) is set to true if a player is still playing, so we’ve also added that in the if statement. Also we’ve added more parameters to the play? function since you need the information on how big the pot is, how much money you have and what the minimum bet is to make your decision. Still a couple of things are missing here. First when you run out of players, it just stops. We’ll worry about that later. Another thing that’s missing is the new state of money and the pass state. While we have information on the amount of money you have right now, we have no way to record the amount of money you have after you decide to play, Also, if you decide not to play this turn, there is no way to record that info.Lets digress here to talk about some of the idioms of functional programming. Here’s a common way to recursively calculate length of a list. (define (length lst)
(if (null? lst) 0 (+ 1 (length (cdr lst))))The problem with this is that scheme has to keep track of the recursion and what is left to do. For eg. if you calculate length of a list (1 2 3) it recurs three times, and comes back up three times adding 1 for each recursive call. This problem is usually solved using accumulators. (define (length-helper lst value)
(if (null? lst)
value
(length-helper (cdr lst) (+ value 1)))) (define (length lst)(length-helper lst 0))
You can see here that length calls length-helper with an initial value of 0. The length-helper recurs till it exhausts itself of the list and returns the the variable value. One advantage of this approach is that there is no work left to do. In fact, scheme implementations are guaranteed to optimize the use of accumulators so that you get the speed of an iterative approach even though you’re actually recursing through a list. Ok, so back to our problem. Well, the solution is simple, you just add new accumulators for the new values of money and pass state. (define (play players pot minibet ms ps new-ms new-ps )
(if (null? players) ‘end
(if (and (car ps) (play? (car players) minibet pot (car ms))
(play (cdr players)
(+ pot minibet)
minibet
(cdr ms)
(cdr ps)
(cons (- (car ms) minibet) new-ms)
(cons #t new-ps))
pot
minibet
(cdr ms)
(cdr ps)
(cons (car ms) new-ms)
(cons #f new-ps)))))So now we are building up a new money and pass state list while consuming the previous version. Of course, the lists are being built in opposite order so you would need to reverse each list when you start a new round.
(define orig-players (list of players))
(define orig-money (list of money))
(define orig-pass (list of pass))
(define (play players pot minibet ms ps new-ms new-ps )
(if (null? players)
(play orig-players pot minibet (reverse new-ms) (reverse new-ps) ‘() ‘())
(if (and (car ps) (play? (car players) minibet pot (car ms))(play (cdr players)
(+ pot minibet)
minibet
(cdr ms)
(cdr ps)
(cons (- (car ms) minibet) new-ms)
(cons #t new-ps))
(play (cdr players)pot
minibet
(cdr ms)
(cdr ps)
(cons (car ms) new-ms)
(cons #f new-ps)))))
(define (game)
(play orig-players 0 20 orig-money orig-pass ‘() ‘()))
So there you go, we’ve managed state in a flush game without using one set! or using a global variable. Of course, this program above goes into an infinite loop but we’ll fix that later.....To recap what we’ve accomplished here is
1. we never had to keep track of a turn variable.
2. We managed to keep track of the current pot and minimum bet by passing it as a functional argument to the next player.
3. We used accumulators to generate new state for money and pass state while consuming an older version.
4. No use of set! or mutations at all!!I hope you enjoyed this article and you can check out the code the the flush game on github at http://github.com/alokthapa/flush
Some updates
Some updates on the callbreak and satori applications. I have finally gotten around to setting up my ec2 server and now callbreak (Seaside version ) and the Satori (github.com/alokthapa/satori) are both available online.
Link to callbreak : bit.ly/playcallbreak
Link to satori: http://bit.ly/f5BIrk (although this seems to be broken right now... :( )
Also, I've been working on a scheme implementation for flush (or sth like that), which is played using 3 cards. It's available here at github.com/alokthapa/flush so download it and check it out. You will need Racket 5.1 to play the game.
Enjoy.
A web-based teaching application
I was inspired by the way "The Little Schemer" was used to teach scheme, with question on the left and answers on the right. I wondered how hard it would be to build a web app that could teach you in such an interactive way. Not so hard as I later found out, it needed less than 70 lines of code to build a prototype. Not only is the code small, but all you need to do is create a "nodes" datatype to create your own custom book!
The application first starts with a list of nodes. Each node contains a question to ask and possible responses. Each response can either do nothing (i.e. you move on to the next node in the list), jump you to another named node or have their own child nodes that only they can visit. Each node may or may not have a label, so we can only use them when we need to jump.
Here's a small example that tries to teach you French.
Output:
This is the first page after you run the application. It shows the question of the first node. Since its response does not contain any action, it simply creates a link to the next node.
This page for the second node. There are two possible responses, either you say "I don't care" which takes you back to the "home" node while clicking on "you're welcome" takes you to the next node.
Let's skip the next node as it only has one response. Now the fourth node contains two responses each of which sends you to a different node.
If you click on "umm I don't know..." , you get to this page.
and if you click on "I guess it means good" link, you get to this page.
Since, none of the responses above do anything more clicking any of the two link above takes you to the page for the next node.
Enjoy.












