web-developer, serious schemer
I really hate having another blog on the web that explains how to make a blog but I do think mine is a little unique. My entire site is written in PLT-Scheme. I'm a really big fan of scheme especially for web development and I thought it would be hypocritical to write about how great scheme is for web development and have it hosted on wordpress.
Unfortunately this was probably the least lean product I've ever had to create. I had to implement and search index, and MVC framework to keep it organized and I really wanted s-expression based css so I implemented a css compiler as well. I also had to deal with a major lack of documentation/examples. The PLT-Scheme website is great but there is a lack of bloggers/external sources talking about scheme web development. Try understand anything non-trivial without using google, it's really hard and we've become way to dependent on it.
So onto the meat, why scheme? There are a lot of reasons but it comes down to two major concepts Pattern Matching and Hygienic Macros. Show me any other languages that provide those two features and I would probably switch. Another big one is s-expression html templating.
S-expression syntax is a method of display tree structured data that has been around since the 1950s. XML (and HTML) also attempted to solve this problem. A lot of web programmers claim they follow the "don't repeat yourself" principle but XML is designed in a way that causes programmers to constantly repeat themselves e.g. closing tags. I do understand the argument for readability of closing tags but a lot of people want a more concise syntax. [1, 2, 3]
S-expression are used in scheme for both language syntax (cause programs are tree) and structured data (lists/trees). Here is HTML markup in scheme:
Fairly concise and includes both expressions; anything in a list that starts with a comma ,(get-post-body id) and literals; anything in the list that is not unquoted. Here's the same example in php:
Okay not bad, s-expressions manage to cut some of the fat but we still have a lot of repeating code. For example, our script tags have a repeating pattern. We can solve this problem with a function call (as we can in other languages): <?= script("foo.js", "bar.js") ?> which is fine but I think scheme provides a better solution via Pattern Matching.
Pattern matching is a the act of checking for the presence of a pattern. Most languages provide some form of pattern matching (eg. regular expressions). Scheme has pattern matching for not just strings but for tree structured data. The pattern matching is fairly similar to context free grammar. The main function I use is called match-lambda. match-lambda is a function that takes pairs of (pattern,result) and returns a function that takes one parameter. When you call the returned function it tries to match the argument to the one of the patterns. When it finds a match, it returns the corresponding result. Here's a simple example:
Note: The ... notation in the pattern describes match one or more
So how does this apply to html and our script example? We'll we can write a pattern that removes repetition and will expand into valid html.
I really don't want to write: script (blah blah blah (src filename))) (script (blah (src otherfile)) ...
I would prefer (js filename otherfile ...)
So let's code the ideal and then write a program that rewrites it in a syntax that the browser understands. I'm going to use a library created by Gary Baumgartner called rewrite. Rewrite uses Rewrite Systems to abstract away from recursion when rewriting trees. The main function he provides is called rewrite which takes to parameters, a unary function which either "rewrites" it's input or returns it unmodified, and the thing we need rewritten. The rewrite function then iteratively applies the rewrite rules until nothing changes, meaning there is nothing else to rewrite. First we have our rewrite rules:
Then we just simple write html as we want and call rewrite on it
We can take this even further if we want. html is riddled with repetition, view the source of any website and you'll see it. If you use clearing divs wouldn't something like (clear) be nicer? or if one day you decide to change the path all images files in a large repo, wouldn't it be nice if you could just write a 3 line program do it for you?...
Not only did I use match/rewrite on all of my html, but I used it to convert an s-expression syntax css into standard css. It was about 5 lines of code and I could probably implement the features included in SASS within a couple hours.
You can find a lot more examples of Pattern Matching on the PLT-Scheme siteThe final thing worth mentioning is Hygienic Macros, if you though match was kinda cool you're gonna love this.
Hygienic macros are macros that guarantee that their expansion will not collide with any existing symbol definition. Here's a simple C example (un-hygienic macro):
Here's the output:
Expected:a=2, b=1 Actual:a=2, b=1 Expected:a=10, _c=2 Actual:a=2, _c=10
Obviously someone is being a jerk but we can stop jerks with hygiene, here's the same example in scheme:
Here's the output:
Expected:a=2, b=1 Actual:a=2, b=1 Expected:a=10, c=2 Actual:a=10, c=2
Let's try an example:
Okay fine, but I've had people claim they can do this in any language, just define functions plus_plus and ternary:
It doesn't work. Think about why. What if I use both of those functions together?
PHP outputs 1 because it evaluated plus_plus before calling ternary. This might seem incredibly obvious, but a number of people haven't understood it when I attempt to explain.
So where do we go from here? We make languages libraries, allow syntax/semantics to be imported into a project. Have some AI program you wrote in Prolog? Implement the semantics and write a program to convert your prolog program into s-expressions. Nicole Allard and Gary Baumgartner managed to do this exact thing in about three weeks. Throw it on the scheme webserver and boom Prolog to the browser.
That's about it, that's why I actually use scheme it allows me to express more then any other language and if I can't find a feature in the language I add it. Check out the PLT-scheme website and comment if you have any questions.