- Bill de Hora responds to a few of my Durable and RESTful ideas. He points out that relying on a client-generated ID can be troublesome, and recommends using multiple identifiers – one created by the sender, one by the receiver and one representing the message exchange itself. However, the sender ID is vulnerable to client bugs & tampering as Bill points out, and neither the receiver ID nor the exchange ID can be used to determine if a given message is a duplicate. If you don’t trust the sender, is it even possible to determine if a given message is a duplicate?
- Pablo Castro confirms that there are “practical limits” to what ADO.NET Data Services can do with respect to idempotence. Nothing in his post was surprising, though I hope it will be more explicitly called out in the final docs. Developers used to the comforting protection of a transaction may be in for a rude awakening.
- Dare Obasanjo has a great post comparing the new features in C# 3.0 to dynamic languages like IronPython. I believe many of the productivity aspects of dynamic languages have little to do with being dynamic.
- Pat Helland noodles on durability and messaging, two topics near and dear to my heart (probably from working with him for a couple of years). I’m not sure where he’s going with this – his conclusion that “Basically, big, complex, and distributed system are big, complex, and distributed” isn’t exactly ground-breaking. But his point that “durable” isn’t a binary concept is worth more consideration. Also, his description of IMS only looking at the effects of a committed transaction is very similar to how web sites work, though obviously HTTP isn’t durable so you can’t make event horizon optimizations like IMS did.
- Tangentially related, Werner Vogels discusses the idea of eventually consistent distributed databases. Today, that’s a problem mostly only Internet-scale sites like Amazon deal with. In the near future of continued data explosion + manycore, we’ll all have to deal with it.
- Nick Malik argues that categorizing enterprise applications by lifecycle is much less useful than categorization based on organizational impact. He might also need a new chair.
- Jesus Rodriguez digs into one of SSB’s new features in SQL 2008: conversation priorities.
- Arnon Rotem-Gal-Oz and Sam Gentile are mixing it up over the definition of SOA. Sam thinks SOA has to include business drivers and Arnon doesn’t. I’m with Sam on this, defining “SOA” independently from “Applying SOA” seems pointless. Then again, rigorously defining SOA – much less arguing about said definition – seems like a waste of time in the first place IMHO.
- Wow, this guy Zed is mad at the Ruby community.
- Andrew Baron has 8 Reasons Why The TV Studios Will Die. Personally, I think reason #2 – Expendable Middle-Person – is the most important. If content producers can reach consumers directly, what value-add will the networks provide? (via United Hollywood)
Morning Coffee 134
Morning Coffee 133
- I’ve been off for two weeks, so getting back into “the swing” of things will probably take a day or two – both at work and on my blog. Hope everyone had a happy holiday season.
- I ended the year with 245 blog posts, which wasn’t quite as many as either of my first two years blogging, but was much more than I had been writing for the last two years.
- It was a Zune Xmas in the Pierson house. I got a pink Zune for my wife, and my mother and father got Zunes for each other. I got to load them all up with content for Xmas morning. Maybe I’m just used to WMP, but I’m not a huge fan of the Zune software. Yes, it’s very pretty but it’s missing some fairly basic features like automatic down-sampling lossless music. On the other hand, the on-device experience rocks and my wife is using her Zune regularly. I’ve got a trip to England coming up in April, and I’m thinking about getting one of the new 80GB ones for the trip.
- They lost any chance of playing for the national championship, but USC sure looked like a champion yesterday. Seems appropriate for this crazy college football season that if Ohio State doesn’t win big, pretty much all the other BCS bowl winners with a legitimate argument to be #1.
- The Caps beat the eastern-conference leading Senators yesterday for the third time this season and the second time in four days. They have 13 points in the last ten games and 10-5-4 since Boudreau took over as coach. If they keep that pace up, they would likely make the playoffs – that would be quite a feat given their horrific start.
- Speaking of hockey, I watched most of the Winter Classic yesterday, including the game-winning shootout goal by the Anointed One. It was really strange but cool to watch a hockey game between snowflakes. I agree with Scott Burnside’s take that these outdoor games are good for the league, but shouldn’t be a regular part of the season.
- I finished Portal yesterday – that’s a fantastic game. I also got Mass Effect, so now I need to decide which to take on first: that or Half-Life 2.
- A few months ago, I was thinking about using HomePlug for home networking but decided to upgrade my wireless network instead. But recently I’ve started streaming movies from my loft computer to my Xbox, and the wireless network isn’t always up to the task. I could run CAT5, but there’s already an unused coax cable running up to the loft and I wondered if I could just use that? I discovered the Multimedia over Coax Alliance, but none of their certified products appear to be available. Those products have to share the home coax network with the cable company, but I can dedicate my coax cable. Anyone know a way to use coax to bridge CAT5 networks? Even something DIY?
Morning Eggnog 132
- My parents are coming into town tomorrow so I’m off for the remaining week or so of the year. Blogging will likely be non-existent, unless I blog something I come up with while geeking out with my dad.
- Juergen van Gael
demonstrates how to use
TPL
from F#. He wrote this once
before
using F#’s async workflows feature. I like the TPL version, though
the
new Action<int>(RowTask)
is a little wordy. I’m guessing the eventual F# syntax will probably become something compact likeaction RowTask
. (via Don Syme) - Andrew Peter ported RoR’s Haml view engine to ASP.NET MVC, calling the result NHaml. I haven’t played around with the new MVC stuff much, but I’m guessing ASP.NET’s control-based approach doesn’t work well when you separate out the controller code. If I’m manually authoring view templates, I’d much rather type NHaml’s syntax than the standard ASP.NET <% …%> syntax. On the other hand, there aren’t any design tools out there today handle the NHaml syntax. Also, I wonder if Andrew is working on a Sass port. (via DNK)
F# PEG Parser Next Steps
There are still a couple of posts to go in my Practical Parsing in F# series. But with Christmas and my parents on their way, I’m taking the rest of the year off.
I’ve stuck the code as it currently stands up on my SkyDrive. Conveniently enough, xUnit.net released their RC1 build yesterday, which includes supports for static test methods. I’ve included the RC1 build in the zip file on SkyDrive, as well as simple batch file so you can run the tests yourself.
Taking a break from this project will give me a good opportunity to figure out where to take it next. As the code stands, it’s not very useful – it simply builds a PEG AST from a PEG grammar. That’s just the first phase of a typical compiler. Without those other phases (you know, like “generate binary code”) this is just an interesting sample.
Since I’m in the “future pondering” phase, now’s the time to make your opinion known. What do you, dear reader, think I should do with this code? Bonus points for wanting to get involved.
Practical F# Parsing: Semantic Productions (2)
Now that I’ve explained the AST, there are several more semantic productions to go. I’m not going to describe them all in detail, just hit a few important highlights.
Many of the semantic productions return lists of other productions. Class returns a list of Ranges, Literal and Identifier returns lists of characters, etc. As you would expect, these multiples are encoded in the grammar. For example, here’s the implementation of Literal:
///Literal <- ['] (!['] Char)* ['] Spacing /// / ["] (!["] Char)* ["] Spacing let (|Literal|_|) input = let rec (|LitChars|_|) delimiter chars input = match input with | TOKEN delimiter (_) -> Some(L2S chars, input) | Char (c, input) -> (|LitChars|_|) delimiter (chars @ [c]) input | _ -> None match input with | TOKEN "'" (LitChars "'" [] (lit, TOKEN "'" (Spacing(input)))) -> Some(lit, input) | TOKEN """ (LitChars """ [] (lit, TOKEN """ (Spacing(input)))) -> Some(lit, input) | _ -> None
I’m using a local recursive function LitChars to retrieve the characters
between the quote delimiters. The quote parameter – i.e. single or
double quote – is passed in as a parameter. I also pass in an empty list
of chars as a parameter. Remember that functional programs keep their
data on the stack, a list parameter is a common way to keep state in a
recursive function. When I match a single non-delimiter character, I add
it to the list with the chars @ [c]
expression. [c] converts a single
value c into a list of one element while the @ operator concatenates to
lists. I’m not sure adding the value to he end like that is a good idea
perf wise. Programming
Erlang recommends only adding
items to the head then reversing the list when you’re done matching. But
F# isn’t Erlang, so I’m not sure what the guidance is here.
Another thing you find in productions is the backtracking syntactic predicates. We saw an example of them in the implementation of Comment. Often, their used to indicate the end of a list of other productions, such as Literal, above. However, sometimes, they’re used to ensure the correct production is matched. For example, a Primary can be an Identifier, as long as it’s not followed by a left arrow. An identifier followed by a left arrow indicates a Definition.
///Primary <- Identifier !LEFTARROW /// / OPEN Expression CLOSE /// / Literal / Class / DOT let rec (|Primary|_|) input = let (|NotLEFTARROW|_|) input = match input with | LEFTARROW (_) -> None | _ -> Some(input) match input with | Identifier (id, NotLEFTARROW (input)) -> Some(Primary.Identifier(id), input) | OPEN ( Expression (exp, CLOSE (input))) -> Some(Primary.Expression(exp), input) | Literal (lit, input) -> Some(Primary.Literal(lit), input) | Class (cls, input) -> Some(Primary.Class(cls), input) | DOT (input) -> Some(Primary.Dot, input) | _ -> None
Here, I need a way to match the absence of LEFTARROW, so I’ve build a simple local function called NotLEFTARROW. This isn’t very clean IMO – I’d rather have a used a custom operator like !!! and &&& for my backtracking predicates. But I haven’t figured out how to use custom operators as Active Patterns. I was able to write a standard non-operator AP function, but then I have to use the full AP function name. Here’s a version of Primary written that way:
///Backtracking failure predicate let (|NotPred|_|) f input = match f input with | Some (_) -> None | _ -> Some(input) let rec (|Primary|_|) input = match input with | Identifier (id, NotPred (|LEFTARROW|_|) (input)) -> Some(Primary.Identifier(id), input) //Other matches omited
Frankly, I don’t think that’s very readable, so I didn’t implement it that way. If I can figure out how to use custom operators and pass around AP functions without using their full ugly name, I’ll change it.
Finally, there are a few things about F#’s scoping rules that you need to understand. F# uses linear scoping, which is to say there’s no way to use a type or function that hasn’t been declared, sort of like C/C++. The difference is that while C/C++ have a way to declare a type or function separately from its implementation, F# has no such capacity. This becomes an issue when you have circular references. For example, Primary can be an Expression, which is a list of SequenceItems, each of which is a Primary with an optional prefix and suffix. In order to declare those in F#, you have to use a special “and” syntax to link the types/functions together.
//ToString and Exp2Str omitted for clarity type Primary = | Identifier of string | Expression of Expression | Literal of string | Class of Range list | Dot //ToString omitted for clarity and SequenceItem = { primaryItem: Primary; itemPrefix: Prefix option; itemSuffix: Suffix option; } and Sequence = SequenceItem list and Expression = Sequence list
Likewise, the AP functions to recognize Primary, SequenceItem, Sequence and Expression are anded together. For me, this is one of the hardest things to get used to about F#. But as you can see from the expressiveness of the code, it’s well worth the trouble