Yes, really, in 2012. See here, it’s on GitHub.
Why, in the name of all that is 8-bit?
For one, it’s fun. The core protocol is well defined by the RFCs. In the web development world you don’t often get to program to specifications like that; it’s a nice change of pace. There’s no need for any front-end work either. I get to write Python, which I haven’t done for a while. And finally, it’s my own free time, nowgetoffmydamnlawn.
TL;DR No, it doesn’t work (as of 2012. April 28). This post is just to save you some time. But I’ll buy you a beer if you manage to get it to work, and tell me how.
NetPincér is an online food ordering service in Hungary. The website has quite a few problems, but one of the most annoying ones is that there’s no way to filter the menu of a restaurant based on what’s in the food. Even though most of the restaurants list some ingredients as the description of the course.
Solution: a user script that adds whitelist and blacklist filtering. It looks like this:
It works in both Chrome as a user script and as a Gresemonkey script in Firefox. You can get it from userscripts.org:
We just had a national holiday, which meant a longish weekend with my parents. We played some board games, and as a result I hacked up a Mastermind game in CoffeeScript that runs entirely in the browser. It took about six-eight hours, and it was actually quite fun.
The model was done in an hour or so, but without any tests. I decided to do only manual testing, which added some time at the end, but whatever. The UI took a bit longer, and it doesn’t look as good as it could. It’s also not optimal, but it’s good enough. It’d be great if someone could spend some time polishing it… nudge-nudge, wink-wink
Anyway, here’s the game: http://mastermind.abesto.net
And the GitHub repo: https://github.com/abesto/mastermind
It was time to try it out. Here’s the result – 67 lines of Clojure code for an RPN calculator with the basic operators. Also, Seesaw (GUI lib for Clojure) rocks.
(ns net.abesto.calc_clj.core (:gen-class) (:use seesaw.core)) (native!) (def stack-size 4) (def stack (ref )) (def gui-stack (ref )) (defn push [x] (dosync (ref-set stack (concat (next (deref stack)) [x])))) (defn popn [n] (dosync (let [ret (take-last n (deref stack))] (ref-set stack (take stack-size (concat (repeat n 0) (deref stack)))) ret))) (defn sync-gui  (dorun (map value! (deref gui-stack) (map str (deref stack))))) (defn number [n] (action :handler (fn [e] (dosync (push ( n (* 10 (first (popn 1)))))) (sync-gui)) :name (str n) )) (defn operator [label operator operand-count] (action :handler (fn [e] (let [operands (popn operand-count)] (push (apply operator operands))) (sync-gui)) :name label)) (defn -main [& args] (invoke-later (dosync (ref-set gui-stack (take stack-size (repeatedly #(text :editable? false)))) (ref-set stack (repeat stack-size 0))) (sync-gui) (-> (frame :title "Hello", :content (vertical-panel :items [ (vertical-panel :items (deref gui-stack)) (horizontal-panel :items [ (action :name "Enter" :handler (fn [e] (push 0) (sync-gui))) (operator " /-" - 1) ]) (grid-panel :rows 4 :columns 4 :items [(number 7) (number 8) (number 9) (operator " " 2) (number 4) (number 5) (number 6) (operator "-" - 2) (number 1) (number 2) (number 3) (operator "*" * 2) (number 0) "" "" (operator "/" / 2) ]) ]) :on-close :exit) pack! show!) ))