posted on 2013-01-06 14:40:00
Is there anything more pointless than a new blog engine? Probably not. 4 months ago, I wouldn't have thought that I would be distracted from my Lisp 6502 emulator so long or that I'd have this much fun writing blogware. It is amazing, however, just how much you can do with a bit of time and ~600 lines of lisp.
Lately I've come to realize my favorite part of hobby programming is that I essentially treat it as creative writing. One of the reasons I love Lisp and find myself using it so much for hobby code is how easily it enables me to experiment with new coding styles. In Coleslaw's case, this has meant a stronger focus on CLOS and API design.
I like to think there's a clear stylistic shift in my projects, from the earlier and messy imperative of Paktahn, through the neat but overly macro-heavy cl-scrobbler, to the more balanced style of my present day code. It's no surprise that some of my favorite lisp luminaries, Peter Seibel and Luke Gorrie, talk a lot about code as literature and readable programs. Hopefully, I will continue to progress in that tradition.
Coleslaw 0.8 is hereby released. The biggest features are multi-site publishing and support for new content types. Here is an example bookmark or tweet-like content type that may ship in a future release, Shouts. See the NEWS for further details. It's time to get back to Memory Mappers for a bit and see if I can't get actual NES emulation going in pure Common Lisp. See you next time, Planet Lisp.
posted on 2012-12-13 21:12:00
It's late 2012. I'm writing this in a gaming bar watching hopefuls for the next National Street Fighter Tournament practice. The FBI have lost track of a modern political dissident, a hacker vagabond by the name of Commander X. Last night I attended an escapist lightshow of a concert, where kids burned their brains out "like neon novas". Drones police the New York skies. My online handle is more crucial to my professional career than my "True Name". I drive a veritable supercar knowing that once self-driving cars are commercialized, classical driving could be a luxury if not slowly phased out altogether. I was born in the sea of information and raised by the sound of dial tones. The cyberpunk aesthetics of the 90s are quietly, imperceptibly interleaved into modern life. But like Alan Kay, I believe the computer revolution hasn't happened yet. My 10 year old self has everything he ever dreamed of. Time to come up with bigger dreams and see what's next.
posted on 2012-10-16 18:10:15
I've been in India almost 10 days now and I'm still not really ready to say anything about it. I return October 20th. I am enjoying the trip immensely however. I've spent time trying to experience India, shopping and being a sightseeing tourist, reconnecting with old friends, and resolving a longstanding personal question. At some point there will be pictures but for now, since I'm having trouble finding my own words, here are some from my favorite writer:
"They are made of amorous dough. As soon as they turn twelve, love has begun to take them somewhere. They see its glowing torch from afar and follow it through the half-light of childhood..." - Carlo Gozzi, Memorie inutile
Elegy for Y.Z.
A year after your death, Y.Z.,
I flew from Houston to San Francisco
And remembered our meeting on Third Avenue
When we took such a liking to each other.
You told me then that as a child you had never seen a forest,
Only a brick wall outside a window,
And I felt sorry for you because
So much disinheritance is our portion.
If you were the king's daughter, you didn't know it.
No fatherland with a castle at the meeting of two rivers,
No procession in June in the blue smoke of incense.
You were humble and did not ask questoins.
You shrugged: who after all am I
To walk in splendor wearing a myrtle wreath?
Fleshly, woundable, pitiable, ironic,
You went with men casually, out of unconcern,
And smoked as if you were courting cancer.
I knew your dream: to have a home
With curtains and a flower to be watered in the morning.
That dream was to come true, to no avail.
And our past moment: the mating of birds
Without intent, reflection, nearly airborne
Over the splendor of autumn dogwoods and maples;
Even in our memory it left hardly a trace.
I am grateful, for I learned something from you,
Thought I haven't been able to capture it in words:
On this earth, where there is no palm and no scepter,
Under a sky that rolls up like a tent,
Some compassion for us people, some goodness
And, simply, tenderness, dear Y.Z.
posted on 2012-09-26 20:13:00
I have a bad feeling that I'm about to piss off a lot of people. Oh, well.
Bret Victor gave a very interesting talk at Strange Loop called "Visible Programming". From what I can tell, Bret is a very smart guy and an accomplished UI designer. I was surprised to find that while I agreed with many (all?) of his premises I disagreed with most of his argumentation. As I've received a question or two about it, I'll try to clarify my thoughts here.
I have three core points:
Ironically, I gave a talk on a different but overlapping topic a few weeks back. As mentioned in Chris Granger's talk, examples like the ones he and Bret Victor gave are much easier when working with a dynamic runtime. Unfortunately, dynamic is conventionally interpreted as a language with dynamic types and, put simply, we should try to change that. I argue that a dynamic language is one that allows you to inspect values and update function and class definitions while the program runs. This is formally known as reflection. What I believe dynamic language advocates care about is the ability to work with a "live" system, not the presence or lack of static type checking.
Being able to visualize program execution means having a snapshot of the program state during each step of execution. Setting aside the impractical size of such a thing for programs with arbitrarily large working data sets, this requires either A) annotating every line or function call with logging statements/function tracing, or B) instrumenting the language runtime in some fashion to retrieve values during execution. That's why these examples are much easier with a reflective language like Javascript where you can hook arbitrary behavior into the Object prototype.
Trying to get an editor to do this for all languages is a fool's errand without a nice reflective runtime and API to retrieve data from. It's hard enough with that stuff! And that means we need reflective compilers and interpreters before we can have an ideal editor.
Many of Bret's examples were highly domain specific. While it makes sense to have a simple interface for toying with values in a visualization/drawing program, it's harder to see how to usefully apply that to something like protein folding software or even RSS feed parsers. Having editor extensibility in addition to reflective systems enables arbitrary widgets or modes for dealing with a given problem domain or data visualization need. Plain and simple, there's no way to build-in useful visualizations that are universally applicable. I admit I am not a designer or gifted at visualization so I may have simply struggled here.
Bret essentially wants to make the experience of programming more tractable through interactivity and tangibility. He suggested 5 key requirements:
While philosophically well-formed, Bret seems to miss the fact that runtime support is required for a Visible Editing Experience to emerge. If the industry still doesn't understand that dynamism is about the runtime rather than types, clamoring for a magic editor will get us nowhere. I want to see a more interactive, tangible environment in the future as well but we cannot get there by arguing that IDE/editor writers need to step up their game. We need to make a concerted argument for the resurrection of highly reflective systems in both research and industry. Once systems with robust reflective capabilities are widespread, realizing a vision such as that described will be a week long hack rather than a decade-long million man-hour slog.
I'd also like to examine how far reflection can scale and a bit about making such a thing applicable to both novices and experts but I need more time to compose my thoughts so I'll save that for a future post. Any comments on this post or its mistakes, of course, are welcome.
posted on 2012-09-25 10:17:00
Lots of detail on anatomy and physiology. Use that to derive theories and test with software.
Neocortex is a predictive modeling system.
Grok, a predictive modeling product.
Future of AI.
Neocortex builds online models from streaming data. Think about it in terms of the senes.
Beware, vision is more than one sense. Retina is array of a million sensors. Auditory nerve is 30,000.
Brain has several million sensors changing firing in the 10s of milliseconds.
The brain invokes model building in response to novel sensory input. It can: make predictions, detect violations of predictions, generate actions.
The brain is more of a memory system than a computing system.
Neocortex is a hierarchy of projected systems. retina->cochlea->somatic nerve. But all one memory algorithm.
Primary memory is sequence memory. Playback of stored patterns. Stream processing!
Sparse distributed representations of data.
Traditional computing uses dense representation. ASCII is a perfect example. Individual bits have no meaning, programmer assigns meaning.
Brain uses sparse representation. Mostly 0 bits, maybe 2% 1s. Sparse IntMap? Bits that represent specific things. Top bit that means X.
SDR Properties:
Similarity: shared bits = semantic similarity. A similar bit vector has similar semantics.
Store and Compare: Store indices of active bits, don't traverse the whole thing. Subsampling is OK though!
Probability shows errors are very unusual even with subsampling. If you do make a mistake, it's a close/semantically similar one.
Union membership: Sets! Is this SDR (10..001) a member of this union of SDRs (00..001)? Very high correctness.
The key to machine intelligence is sparse distributed representation.
Sequence memory:
If pattern does not repeat, forget it. If it does, reinforce it.
Synapses are either connected or not. Represented via scalar, if it's above a threshold, it is connected.
Typical system: 1 region, 2,000 columns, 30 cells per column, 128 dendrite segments per cell, 40 connections per segment. 300M connections. No SPOF.
Predictive Analytics Today:
Future of Machine Intelligence:
35 years later...
Worked at Microsoft, got hired as a PM. PM on Visual Studio. Owned C#+VB in the IDE. Was asked "What is the future of editing?"
Well...how do users really work with it? NO end-to-end usability studies on Visual Studio. Only on specific features.
Richest feedback you'll ever get on a product is a usability study.
Expectation: Visual Studio is amazing tech! Actual: Too complicated, too noisy. Shock: No one actually vocalized problem.
If it's true that the key attribute of a good programmer is keeping the system in your head, its very sobering. How to teach memory?
Everyone just uses: Code navigatoin, Debugger, Editor. Basic workflow has not changed since Emacs.
Many innovations but never went mainstream: Smalltalk, Lisp Machines, etc. Time to re-imagine.
Tried many things, nothing like Light Table. What changed?
We're always dealing with abstraction. We are not recipe writers. We consume and subsequently create abstractions. We are synthesizing machines!
Need to ask questions about them. Poke at them. You don't understand code until you run it. Writing it is not enough.
Realization: Interactivity/REPLs were a big enabler at getting people into computing. Closer connection to what you're doing. YAFIYGI->WYSIWYG is similar.
What is an IDE for Abstractioners? Light Table. Initially a 6 day hack. Half a million people saw it in 2 days.
Raised 300k+ on kickstarter. Acknowledgement that we are in the dark ages of software dev. We're disconnected from our software!
Brief live demo...
git status
and update the git-state with it.(on files.save [] (update))
. We're live!defui
is a Light Table construct to make a DOM element and bind events to it.HA! We've been in a custom presentation mode.
Missed due to chatting with Chris Granger and other awesome folks.
Okay, I couldn't keep up and had you been there you wouldn't blame me.
But this was cool and analagous to the Byrd/Friedman running programs backwards and forward stuff from yestereday.
Also, Buyer Beware: Oleg's papers may be more clear than his presentation style. :P
In an age of shamanism when it comes to operating computers.
Talking about pressure as it relates to large scale distributed systems. Cliff's company, Boundary, does high-volume streaming.
One day they noticed IOPS starting to disappear. Kafka message queue, writes to disk. If IOPS start dropping...
Pressure rising on interior nodes, data kept coming in, not going out. Death spiral! Chained failures.
Like riding out a storm, just trying to keep systems up until traffic dies down.
There is no explicit flow control. But we need it! (We already have it.)
Only documentation of queue explosion problem + flow control in Erlang. ... Ulf Wiger mailing list post.
Create an end-to-end linkage of back pressure so edge nodes can know when there's a problem and react.
{active, true}
is an unfettered firehouse.{active, once}
provides explicit control over when delivery occurs. Overload then backs up to TCP receive queue. Slows down sender!MemoryAwareThreadPoolExecutor
Is this familiar? "SEDA: An Architecture for Highly Concurrent Server Applications"
What does this buy you? Back pressure gives you time to recover. Like System Dynamics, about getting a grip on non-linear behavior.
An aside: SCTP is a little better for this.
Aspects of Expressiveness:
Expressiveness over performance, every time! (in Ioke)
Types of Abstraction:
Macros!
Different kinds:
Modularity!
Static typing!
Generics!
Working with generic code over an unrestricted set of containers.
Most abstractions are leaky. See ORMs. Occasionally can't get underneath it to use raw SQL.
"Abstractions may be formed by reducing the information content of a concept, to retain information only relevant for a specific purpose." - What purpose?
Effective communication requires common experience/understanding. Referents in linguistics.
Lin-guis-tics:
Communicating indirectly with many audiences though. The machine, team members, ops, etc. Even business stakeholders! Totally unique to programming.
Syn-tax:
From a PLT perspective, doesn't matter. In day to day pragmatics, it does matter. Everyone knows this.
Can go too far in either direction, Salt or Saccharine.
Operator overloading. Probably not one right answer.
Don't support it.
Support overloading built-ins.
Don't have operators. Everything is a function.
Arbitrary operators to be defined or redefined. (haskell/ml)
Should built-ins look different than user defined stuff? (editors note: Hell no, let the editor show you/syntax highlighting).
Expressiveness is not always better. Many dimensions to optimize along. Language design is a balancing act. Find the right clustering of features for a given point in the design space.
Expressiveness and abstractions are relative.
5 Principles to aim for:
Examples of these principles in a hypothetical environment: (JS & Processing for this talk)
How does this scale to real-world programming? I have answers but I think it's better to question the question.
Asking how to scale to everyday programming is like asking how engines benefit horses. We have to work like this.
Argues against static runtimes. I agree but this was a weak treatment. There is tooling to work around this.
"There is no future in destroy-the-world programming. It's got to go." - Agreed.
Ten days in May 1995: Shipped Mocha.
September 1995: Livescript
December 1995: Javascript.
"Hey maybe we should fix equality?" "Nope, too late."
Adding very minimal classes.
Adding MODULES!!!! Fuck. Thank God. FINALLY. Not first-class but better than nothing.
Symbols (formerly names or private names). They're self-named objects that you can't forge from strings. Hygiene!
If you're using symbols, there ought to be a nice way to deference/get at them. How about @symbol?
Utilities for symbols, many interesting applications.
Default parameters. arguments is a hideous hack. We will kill the arguments object but Brendan will pay to see that movie. :)
&rest parameters. Guess what, MO LISPY! Prototyped in Spidermonkey right now.
... is spread, inverse of rest. I.e. the **kwargs\kwargs split. Splicing?
for-of, iterators and generators. Have to use of instead of in. Can finally iterate over values instead of keys.
Callback hell. What can we do? More problems than aesthetics, could capture too many outer variables.
Promises/futures still not here...but we will have coroutines from generators and use combinators to make things suck much less!
Array comprehensions. Lazy generator comprehensions too! When did they get feature-itis?
Sets too! Proxies for metaprogramming API. Think they got feature-itis when they thought about this audience. ;)
Can emulate NoSuchMethod/DoesNotUnderstand with proxies. Couldn't agree on standardization. Could add a default one to Object.Prototype.
Apparently all that was library and application improvements. What about code generators?
So bytecode...
JS might actually be better than bytecode and COMPRESS better.
Bytecode standardization simply won't happen. Need to be versioned, deters competitive race, don't have the bandwidth in companies.
"Versioning is an anti-pattern on the web. You want to fail soft."
No call/cc for you! Also, many humans still like writing JS.
Proper tail calls have been standardized. Thanks Dave Herman!
Just care about making the web better. Wound up adding Typed Arrays for WebGL. Big potential win for compilers there. See: emscripten.
"The reach of the web exceeds any other platform."
"To game developers, they're just excited about doing another port."
LLJS, low-level javascript is another experiment. C-like lang to typed arrays js to... Feel free to play with it.
ES4 collapsed when they tried to add something type-like. NOT adding types or contracts or whatever. Have typed arrays. Go away.
"People write Javascript in a latently well-typed way."
There is however a proposal for User-defined structs that are stored in typed arrays. Close enough, right?
The last missing JS feature is... MACROS. Not in ES6. Sweetjs.org though. It's on github, it works. It's a sound JS reader and hygienic macros.
"Worst thing I did out of Perl envy was to make regular expressions with slashes...means you have to parse (the whole thing) to lex!"
"Please help because if we can get this into ES7, we can get put ourselves out of business, and I can do something else."
Left with a general optimism on the continued future of Javascript.
I was going to have to miss the last keynote and two talks as well as all the camaraderie that would occur after. Delta had screwed up my flight and I didn't have a hotel room for the night. Thankfully, some Loopers came to my rescue though Delta still managed to extract $170 from me. Soulless corporations! It was totally worth it. I can't think of a more worthwhile or energizing way to spend 3 days. I'd like to thank everyone I was able to spend time drinking and chatting with especially Scott Vokes, Paul Snively, Andreas Fuchs. Brian Rice, and Jose Valim. Obviously, I never want to go home.
posted on 2012-09-24 10:46:00
Though I didn't take notes on these, or today's keynotes, I have seen quite good coverage of ELC and Strange Loop talks here.
Design Patterns: Are they a sign of weakness in your language?
Graph of known Monad tutorials. Skyrocketing. :P
Monads are a great abstraction to capture/describe patterns, NOT explain them.
Possibly the talk I'm most excited for today. DESTROY ALL SOFTWARE!
3 Confessions
They will not merge our kernel patches. How do we move forward? Our "Shipping Culture" is poisonous to infrastructure. We just accrete low level infrastructure. Programmer Archaeologists are we. INCREMENTAL DEVELOPMENT WILL NOT WORK FOR THIS.
"A Data Structure is just a stupid programming language." - Bill Gosper
Perhaps instead...
"A data structure is just a tiny virtual machine." - Scott Vokes
"The cheapest, fastest, and most reliable components are those that aren't there." - Gordon Bell
Good choice of data structure /subtracts/ code.
Data structures set the path of least resistance for interacting with your data.
You probably won't know the ideal DS up front. Don't paint yourself in a corner.
?- uses(prolog, Person).
no.All coming to a github near you soon.
Elided due to battery life.
posted on 2012-09-19 20:47:00
I haven't finished my headless NES emulator in time for Strange Loop. On the other hand, I have done some cool things that I didn't anticipate. Here's what's been going on in hackland lately:
The majority of my efforts have been related to my new blogging engine, Coleslaw. I've substantially cleaned up the rendering pass, added optional RSS feeds for specific tags, revamped the plugin architecture, and added a plugin for Disqus support. Jose Pereira also wrote a heroku buildpack for running Coleslaw so if you feel like having a simple managed install, problem solved!
While docs are still needed, here is a rough overview of the plugin architecture. I'll add a simple, hello-world-ish example to the README shortly.
Plugins are lisp files placed in coleslaw's plugins
directory.
Each plugin should define a package :coleslaw-$filename
where $filename is the name, excluding extension, of the plugin.
The package should export a function named enable
that can be called to activate the plugin.
enable
is mostly useful for adding Javascript to the page via add-injection
or passing initialization args elsewhere.
add-injection
takes a cons like (js-string predicate)
and a location (:head
or :tail
) to insert it.Plugins can also extend render-content
to support new post formats such as ReStructuredText or modify deploy
with :before
, :after
, or :around
methods to support deployment to S3, serving via Hunchentoot, etc.
enable
with no args whereas a plugin given as a list will call enable
with the args after the plugin's name.I am pleased to announce I've taken over as maintainer of colorize. It provides the syntax highlighting in Coleslaw's 3bmd markdown mode. I've backported patches from lisppaste to colorize for Haskell, Erlang, Python, and a number of other languages. I also added very rudimentary support for Clojure highlighting. While I'm interested in seeing further language support (particularly Clojure and Rust) I lack the time to work on further coloring modes myself. If you have any inclination to hack on colorize to add support for new languages or otherwise improve it please feel free to contact me. I'm more than happy to review and merge pull requests. :)
I delivered a final Lunch and Learn at CMGdigital on Dynamic Systems. I have a screencast of it like my last talk but I haven't uploaded it yet. I'm a bit more out of my depth this time and am still considering tweaking the content and rerecording. The slides are linked above though and I would welcome comments. I'm also working on a Magic the Gathering tutorial/unsession for Strange Loop and an Emacs Crash Course for my new coworkers at Primedia. Finally, I'm giving a talk on the internals of cl-6502 to the Atlanta Lisp User Group on October 1st.
Vladimir Sedach has been working on a C to Common Lisp compiler called Vacietis for a while now. It's become mature enough to generate Lisp executables for small C programs. However, dumping executables isn't a portable CL feature so I contributed a minor pull request to use trivial-dump-core to improve portability from ccl to clisp, sbcl, and ccl. I hope trivial-dump-core sees more use and gains support for more implementations as portable executable creation would be a nice thing to have.
posted on 2012-09-04 13:22:05
Now that the i's have been dotted and the t's crossed I'm pleased to announce I've accepted a new job. Starting September 17th, I'll be a Senior Developer working for Primedia. I'll be helping them migrate from ruby to clojure. I've been meaning to spend more time hacking Clojure as it is. I'm particularly delighted that I'll be in something of a teaching role and able to share my knowledge and experience with lisp with interested hackers.
CMGdigital has been a phenomenal place to work for the last year and I'll miss everyone there dearly. I wasn't looking for a new job but Primedia found me and this was in many ways the right opportunity at the right time.
I'm also very excited for the arrival of Leiningen 2.0 and happily running the latest preview. After using quicklisp, I disliked having to setup a mock project to experiment with arbitrary libraries in Clojure. Leiningen 2 uses a library called pomegranate under the covers which allows modifying the REPL classpath. Thus, dependencies can be easily added to a running REPL and experimented with!
In other lispy news, the dream of endless swank backends and SLIME on everything has died. Previously, I had coerced SLIME into running Clojure, Scheme, and Common Lisp simultaneously and knowing which filetypes to associate with which repls. It took a lot of fiddling. I actually had a rant against the proliferation of swank backends for other languages like Chicken Scheme and Clojure happening outside the main SLIME tree. Anyway, between Emacs 24 shipping package.el, marmalade, nrepl.el for Clojure, and Geiser for scheme, the situation has resolved itself even if the infinite SLIME dream is dead. And ultimately, that's better for hackers everywhere...so who am I to complain? :)
posted on 2012-08-28 20:14:15
I just saw this over on PLT Alain de Botton's twitter feed and couldn't resist collecting and reposting it here:
The Goldilocks Principle for Programming Languages:
Addendum: I was an idiot 5 minutes ago, and will be an elitist in 5 minutes. Where's my beautiful code gone?
What a charming, weird little enterprise hacking is.
PS: With any luck I've got a very cool announcement coming in the next few days. Also, blogging is a lot more fun using emacs+git. I may just start doing it more.
posted on 2012-08-26 12:42:00
So, Coleslaw is alive (you're looking at it) and I've done a clean reinstall on my server for the first time since 2008 or so. Thank GOD.
With any luck, I'll get back to hacking emulators now. :) But first... a test of some features! I should really overhaul the README for coleslaw too.
;; God do I love being able to write this post in emacs. And commit and push to publish.
(defun slug-char-p (char)
"Determine if CHAR is a valid slug (i.e. URL) character."
(or (char<= #\0 char #\9)
(char<= #\a char #\z)
(char<= #\A char #\Z)
(member char '(#\_ #\- #\.))))
(defun slugify (string)
"Return a version of STRING suitable for use as a URL."
(remove-if-not #'slug-char-p (substitute #\- #\Space string)))
$$ \lambda \scriptstyle{f}. (\lambda x. (\scriptstyle{f} (x x)) \lambda x. (\scriptstyle{f} (x x))) $$
This blog covers 2015, Books, Butler, C, Dad, Discrete Math, Displays, Education, Erlang, Essay, Gaming, Gapingvoid, HTDP, Hardware, IP Law, LISP, Lecture, Lessig, Linkpost, Linux, Lists, MPAA, Milosz, Music, Neruda, Open Source, Operating Systems, Personal, Pics, Poetry, Programming, Programming Languages, Project Euler, Quotes, Reddit, SICP, Self-Learning, Uncategorized, Webcomic, XKCD, Xmas, \"Real World\", adulthood, apple, career, careers, choices, clones, coleslaw, consumption, creation, emulation, fqa, games, goals, haltandcatchfire, heroes, injustice, ironyard, linux, lisp, lists, math, melee, metapost, milosz, music, pandemic, personal, poetry, productivity, professional, programming, ragequit, recreation, reflection, research, rip, strangeloop, vacation, work, year-in-review
View content from 2024-03, 2024-01, 2023-12, 2023-07, 2023-02, 2022-12, 2022-06, 2022-04, 2022-03, 2022-01, 2021-12, 2021-08, 2021-03, 2020-04, 2020-02, 2020-01, 2018-08, 2018-07, 2017-09, 2017-07, 2015-09, 2015-05, 2015-03, 2015-02, 2015-01, 2014-11, 2014-09, 2014-07, 2014-05, 2014-01, 2013-10, 2013-09, 2013-07, 2013-06, 2013-05, 2013-04, 2013-03, 2013-01, 2012-12, 2012-10, 2012-09, 2012-08, 2012-06, 2012-05, 2012-04, 2012-03, 2012-01, 2011-10, 2011-09, 2011-08, 2011-07, 2011-06, 2011-05, 2011-04, 2011-02, 2011-01, 2010-11, 2010-10, 2010-09, 2010-08, 2010-07, 2010-05, 2010-04, 2010-03, 2010-02, 2010-01, 2009-12, 2009-11, 2009-10, 2009-09, 2009-08, 2009-07, 2009-06, 2009-05, 2009-04, 2009-03, 2009-02, 2009-01, 2008-12, 2008-11, 2008-10, 2008-09, 2008-08, 2008-07, 2008-06, 2008-05, 2008-04, 2008-03, 2008-02, 2008-01, 2007-12, 2007-11, 2007-10, 2007-09, 2007-08, 2007-07, 2007-06, 2007-05