Tag Archives: f#

F#, Mono, Agile, Architecture, DevOps

Several people have asked online lately, “Can you really write production code in F# and mono?”, “How are you doing architecture now that you’ve switched completely to F#”, and “Aren’t you doing some kind of weird thing now that doesn’t work with interactive websites?”

I usually don’t do coding blogs, because, frankly, after a while it all gets pretty boring. Same old bytes, just new bells and whistles on top. But my approach to architecture has changed in a major way over the last five years. Might as well document it.

Description of Problem Domain. For our sample project, let’s take Newspaper23. It’s a production system with a small number of users that’s been running for a few years and has evolved through my change in philosophy.

Newspaper 23 exists for one reason: I have a very short attention span. Websites are always trying to get me to hang around, click on related stories, sign-up for things, and so on. I find this very distracting. It’s very easy for me to spend a lot of time online that’s unproductive. So a few years ago I had an idea: since the news I consume is all from a dozen or two sites, why don’t I just harvest the titles and links from those sites and put them in a big list? Then I’m choosing what content to consume based on the site brand and the title of the article, not social cues or any other nonsense.

So I got out my credit card, went over to Amazon AWS, and fired up the site.

The Old, Old Way of doing things. The first time through, I did this in a “classic” manner. I sketched out a domain model, I elaborated a bit on a database model, I built a database model in MySQL, and I created a new C# app in Visual Studio and wrote a program to do everything that was needed — get some links, save the data about them, create a page with the links, do some “other stuff”.

The problem was, I was never really clear what the program should do. Should I collect the votes the article had from reddit? Don’t know, so I’ll throw that in there and save it. Might need it later. Should I provide the ability to comment, or vote? Don’t know. I’ll add space — after all, space is cheap — and if I need it, it’s there. Should there be some kind of authentication? Beats me. (Decided to skip that one)

Don’t get me wrong; none of this was a heavyweight or Big Design Up Front process. I’m only talking about an hour or two of doodling around with things. And the beauty of modern tools is that it really doesn’t matter whether your table has 5 fields or 10. Unless you’re writing the code to do something with the data, it’s just “out there”.

It did make the “link sucking” process a little more complicated, because with different sites I had to get different pieces of data. Fair enough.

What happened. After a couple of weeks of off-and-on coding, I got the program up and running, along with a unique system for identifying data on a web page to harvest. (It was a recursive RegEx language. Please, no “but you can’t use Regex on html!” It looked good.) The code base consisted of a data tier, some controller logic on top, and it seemed to work fine.

For a while.

But over a period of just a few days or weeks, it seemed like there were always these weird edge cases, both in the sites, and more disturbingly, in the tool version, setup, and configuration. Site X would change their format, and I’d be in the code changing the way I received links. Yes, I had hard-coded in the parameters for each site, but how difficult was it to change some hard-coded values once or twice a year? Except the more source code there was, and the more I touched the code, the more errors I got. And it seemed like for one reason or the other with this way of programming there was a boatload of code to wade through and I was always horsing around with it. [insert discussion here about TDD]

By using a MVC paradigm, I had written one piece of software that I could easily lay a bunch of different controllers down on. In fact, as we all know, I could develop a “controller library” over time that would take the data and do all sorts of wondrous and amazing things. That’s the beauty of a good model — it facilitates many different solutions.

I still think this might be the way to go, assuming 1) you use good testing practices, and 2) you’re going to constantly be under the hood in the code for a long time. But it introduced all kinds of problems related to having everything pass through one executable and code base. Did I really want to horse around with the code that grabbed links, for instance, simply because I was fixing the code that wrote the web page? Why was I putting all of my eggs in one basket? OOP is a great way of doing things, but it introduces a freaking huge amount of hidden interdependencies. Some times I wonder if 90% of the problems development teams have with programming is based on the fact that in the developer’s mind there is separation of model and controller, but that in the wiring itself, things can be all hooked together in completely insane ways, usually for what seemed like good reasons at the time. The black box of OOP has a lot of very sharp edges.

The Old Way of doing things. The first thing I did was ditch C#. It’s a great language, a better Java than Java, but it was the wrong paradigm for me. The second thing I did was start to build the app from the ground-up. Programming functionally required me to write functions that did things. This sounds blazingly obvious, but it’s actually a much different way of looking at things from creating a model and adding controllers on top. I still used the MySQL datastore — had to put stuff somewhere — but my code was a LOT smaller.

It also needed much less tweaking. Remember: this is personal programming. Instead of sitting on top of a model that could do many things and having to choose what to implement, which might cover calls all over the place, my code did a few things, and there was a clear path to the data for the things it did.

What happened. There was still that problem with everything running through one spot. If I wanted to tweak anything, anywhere, I’m opening up the entire codebase to make a change.

Interestingly, since this was revision 2, the code ran for much longer without needing tweaking. This meant that when I did get around to tweaking it, I had forgotten the build setup! So I’d have a 2-line change that would require screwing around with re-remembering the build-deploy environment. That might take several hours. Plus the sites were still hard-coded. The output was hard-coded. As much as I loved data-driven programming, why was everything so coupled?

Along this time I built HN Books, a social book site for hackers. It was all static. I found I could do a lot with static web pages and JSON files. Much more than most web programmers would believe.

Hmm. Fuctional programming. Static pages. Hmmm.

The way I do things now.

So now I have a new philosophy:

  • Third time through, I decided I write small programs. As small as I can. Instead of one big honking system, my system has four programs: GetLinks, UpdateArticleLibrary, CreateSelectedArticleList, and FormatSelectedArticleList. There’s a bonus utility, CheckXPath, which lets me check out XPath strings against websites to make sure they work (in case the site layout changes). I use as few external libraries, tools, or frameworks as possible. Over the years, I’ve found that every tool I picked up had 40 tons of features, of which I only needed 3. That meant that whenever I needed to do something simple that I had never done before, I had to wade through all sorts of forums, hearing about all sorts of arcane switches and other stuff. Screw that. I do not need to buy and operate a nuclear attack sub to go fishing from the pier. So — no Visual Studio, no MySQL, no complex dependencies at all. (Having said that, I actually dumped my custom link-sucking system and went with HtmlAgilityPack. I mean heck, once it’s installed, it’s just XPath. Time spent learning XPath is not as completely sunk as time spent learning WhizBang 7). Simplify.

  • My files read and write data on the local storage. I’m not doing transactions, therefore I don’t need a transactional datastore. It’s functional coding. Things come in, things go out. The O/S already has a wonderful tool for storing things. It’s called a file system, and unless I’m going to be moving around tens of thousands of these things, it’ll work just fine, thank you. Simplify.

  • I use the O/S to schedule when the programs run and to move things around. Instead of having one program that runs once a day, split the work up into a “pipeline” and have the O/S manage the pipeline. It’s already good at managing processes — it has all kinds of tools for it. Use them. Simplify.

  • I don’t “interact”. I process things at certain times. In the old days, I’d have an instance of my program spun up in Apache, waiting around in fastCGI for a client to come and connect. Then the program would do all sorts of things depending on which client it was, what the request was, and so on.

    After many, many years of coding like this, I had to ask myself: why? Why the hell am I doing it this way? 9 times out of ten I’m delivering the same content. 9 times out of ten the client is just reading stuff. 9 times out of 10 I’m creating database connections, cursors, and all sorts of other cruft — just to send the same stuff back down the wire as I sent 2 seconds ago. For the huge majority of the use cases I can imagine, even for interactive sites, there’s no difference at all to the user between a program that sits waiting for connections and a series of programs that updates data every few seconds. This is stupid. Don’t do this any more. Decouple. Simplify.


  • I write simple queries to monitor how things are moving through the pipeline. Quite frankly, the system is running so well I don’t need to monitor it, but if I did, I’d simply monitor how things flow through the pipeline. I could even make a nice html page with graphs. Don’t need to, but it’s an easy option. In fact, I’d argue that the only things interesting to me as a owner/maintainer would be things visible at a system level, not a programming level. Huge win here: no programming skill required to look at CLR innards, just O/S skills. Simplify.

  • Nothing exists as hard-coded data. It’s all either config files or command-line parameters. Right now as I bring up the page, I can see that Hacker News isn’t returning any data. If I wanted, I could probably figure out what the problem was and fix it (assuming it was fixable on my end) in about 10 minutes. No programming required. All I need is a shell. I AM re-coding the system, kinda. I decided that since I have 10-15 functions that are the same across each executable, it would make sense to create one Visual Studio solution and share a couple of library source files. Welcome back to the days of shared C header files! I’m also making the logging more robust. Right now I log everything. (I don’t read the logs, but they are there.) This is using up too much disc space. Every few months I have to clean it out. So a more fine-tuned logging system would be nice. Maybe. Maybe not. Simplify.

  • TDD? TDD? We don’t need no stinking TDD. With purely functional programming, there are only 3 mistakes I can make: Failure to break down transforms into understandable atomic units, failure to describe the transform correctly, and failure to validate the data. If I do all three of those correctly? There’s nothing to test. It’s like trying to test an SQL select statement. The idea doesn’t make sense. Simplify.

It’s very nice. Here’s the main function for the first program in the chain, GetLinks, that gets links from sites (duh):

Code Snippet
  1. [<EntryPoint>]
  2. let main argv =
  3.     try
  4.         let opts = parseCommandLineArgs (Array.toList argv)
  5.         if opts.verbose >= Verbosity.Normal then
  6.             printfn "Options Selected:"
  7.             printfn "%A" opts
  8.             printfn ""
  9.         let config = getConfigData opts
  10.         let outputDataHolder = {
  11.             outputSections = new System.Collections.Generic.Dictionary<string, outputSection>()}
  12.         let outputData = ripLinks opts config outputDataHolder
  13.         printfn "Processing Complete for %A" opts.siteUrl
  14.         let numberOfDataPointsMatchMessage =
  15.             if outputData.outputSections.Count>0
  16.             then
  17.                 let max = outputData.outputSections |> Seq.maxBy(fun x->x.Value.outputList.Count)
  18.                 let maxCount = max.Value.outputList.Count
  19.                 let min = outputData.outputSections |> Seq.minBy(fun x->x.Value.outputList.Count)
  20.                 let minCount = min.Value.outputList.Count
  21.                 if maxCount = minCount
  22.                 then
  23.                       maxCount.ToString() + " links with " + (outputData.outputSections.Count-1).ToString() + " pieces of additional information about each link gathered."
  24.                 else "Number of links, titles, and other Data DOES NOT MATCH.\r\n" + max.Key + "  has " + maxCount.ToString() + "entries while " + min.Key + " has " + minCount.ToString() + ".\r\nCheck your configuration file or run this program with the verbose option set /V"
  25.             else
  26.                 "\r\n\r\nTHERE WERE NO SECTIONS OUTPUT.\r\nPlease check your configuration file.\r\nTry running this program with the /V option"
  27.         System.Console.WriteLine(numberOfDataPointsMatchMessage)
  28.         0 // return an integer exit code
  29.     with
  30.         | :? UserNeedsHelp as hex ->
  31.             System.Console.WriteLine("You'd like help")
  32.             System.Console.WriteLine("Good luck with that")
  33.             System.Console.WriteLine("/V for verbose output")
  34.             System.Console.WriteLine("/S:<url> to set the target site url")
  35.             System.Console.WriteLine("/C:<filename> to set the config file used. Config file is expected to have Windows line returns \r\n")
  36.             System.Console.WriteLine("/O:<filename> to set the output file created/overwritten")
  37.             System.Console.WriteLine("/N:<integer> number of links desired")
  38.             System.Console.WriteLine("")
  39.             0


This is 50 lines of code. But it’s really only 4, lines 204-207. It gets the configs passed in. It creates a new container to hold the output data, it processes the link, and then it saves the data (which happens in the ripLink function. Should be down in this one. Ugh.) The rest of it is logging and help system stuff.

I could show you ripLinks, but it’s the same deal: 50 lines of code which are really about 10. It gets the links from the page using the “ripLinksOnAPage” function (clever naming, eh?), then it processes the links according to the config file.

Let’s look at how it breaks up.

wtf-blog-getLinks-fd

As you can see, there are really only 5 functions, ripLinks, http, loadHtml, recBuildLinksUp, writeLinksOut, and ripLinksOnAPage. The rest is either library calls or a few small helper functions. Take out the logging and some of the other broilerplate, and there’s maybe 50 lines of “real code” here.

We’ve done something simple, easily describable, and concrete. We took stuff from the file system, read a webpage, wrote stuff to the file system. Logged as we went along. That’s it. No need to solve world hunger. It has value.

This code has been running for more than a year with no modifications. I expect it to continue running forever. I’m done. Isn’t that nice?

Common objections.

It’s re-inventing the wheel. In most cases, I don’t need a wheel. I need a lug nut. Yes, I know what the wheel looks like, but the cognitive load of buying a big stack of wheels and carrying them around when I just need a couple of lug nuts? Tell you what. If I start thinking about round things to fit on cars, I’ll get a wheel. Otherwise I’m fine.

It’ll never scale. The funny part about this objection is the opposite is true: the more complex your stack, the more difficult and nuanced it is to scale. I can take this app and scale it out as far as I like. Heck, copy it to a CDN. We’re done. And for those of you thinking interactivity, think long and hard whether you need immediate feedback for the user or just something that changes every few seconds or once a minute. You could be spending a huge number of processor cycles worrying about concurrent clients when you really don’t need it.

It’s poorly-thought-out. My datastore? Line-delimited text files. Code complexity? Nothing more than a few hundred lines of code. Is there anything it can’t do? Not really. But (and this would be the objection I would have made several years ago) what if you want it to do something that required the data to change? Wouldn’t you have to re-jigger every piece of code in the pipeline?

Not really. First, because I’m using name-value pairs, I can always add data and not use it. So really, what would happen if I wanted some cool new feature would be 1) I’d change the data representation where it was created, 2) I’d add the code to store it, and 3) I’d add the code to use it. If you’ve worked in a functional environment, this is the way you make changes anyway. Nothing new here.

It’s not as cool as X. Probably not.

The deployment process is brittle. Actually, although I’m not continuously deploying what I write — there’s no need to automate it when it’s just me — I’m integrating DevOps directly into the solution. There’s no one part of this solution that’s “programming” and another part that’s “deployment”. It’s all integrated together. Instead of good coupling and cohesion at the function level, I have good coupling and cohesion at both the function and the executable level. Very cool stuff.

Continuing to add features. The very next thing I’m going to do is add/adjust the logging. Having to clean out the logs once every 3 or 4 months is a chore. Next up in my quest to eliminate distractions, I’ll probably go to the target site and rip the plain text and store it here. I’ve thought about adding voting and commenting, but it’s a personal site.

None of this will require a major change or a re-think of how the architecture works. Mostly the system just works and I don’t have to mess with it. O/S updates handle updating security and scaling problems. I worked a bit to make the solution, and now the solution works for me. And isn’t that the entire idea?

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.

Programming is for Stupid People

I had to give a presentation on F# last week at Code Camp and boy, was I afraid.

You see, I have been learning F# — and functional programming — for the last year or so, and it’s different. I mean way different from “normal” C# programming. Don’t get me wrong, I love it, but I had a hard time getting my head around it. Unlike C# and OOP, it seemed that no matter how much I learned, there was always some next level that I hadn’t reached.

I find that immensely rewarding. But I also find it pretty scary when I’m giving a presentation called “F# Ninja” Folks are going to be expecting a master of space and time, uber-lord of F#. Instead, they get me.

The day came, and I went out there and started my presentation. On the very first example, a guy raised his hand in the audience.

You know, you can do what you’re doing simply by using library X, he said.

I managed to get by the question — after all, the point wasn’t whether there was a library that could do something, the point was showing how the language worked — but the guy seemed to enjoy pointing out my “mistake”

It was an awkward moment.

Afterwards, several participants approached and asked questions. A couple even said it was the best presentation they had seen at Code Camp that day (I was last). But my friend was there too, and he had a whole bunch of questions about F#.

I was happy to answer. He had heard a few things about the language that were not true. He also pointed out how there were many other methods in many other libraries that do the same thing that you can do in F#. After all, all of Microsoft’s programming languages run on the same CLR, so it makes sense that if you can do it in one .NET language you can do it in another.

I got one of those feelings — it seemed to me that this guy had some attachment to justifying his not learning F#. Perhaps I misread him — but then again perhaps not. Either way, that’s fine. I’ve worked with really smart guys, and he seemed top of the pack. Amazing recall of various libraries and such.

Finally, out of exasperation, I said something like “Yes, I know you can do it like that, but you know what? I am an old and simple-minded programmer. If I don’t have to remember 4000 libraries — if, instead, I only need to remember the few dozen functions I’ve written — it’s easier on my mind”

That seemed to pacify him, and it also hit me as accidentally touching on a really deep truth:

Programming is for stupid people.

Continue reading

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.

My Master Plan to Destroy the Internet as we know it

What’s the minimum amount of interface that you need to do the most work?

I’m not talking web interface. I’m talking interface period. Picture a black box. What kinds of buttons, lights, or displays would you need to do, say, 80% of the work you do online?

I think the answer is very surprising: not very much. In fact, I’d argue with a few buttons that double as lights, and a mostly-plain display, you can do much of whatever you do right now. No keyboard, no web browser, no flash, no iPad.

Another way to phrase this question: What are the limits of a universal Minimum Viable Product?

It’s a magic box. A box where you push a simple button to get a category of information you are interested in, not a specific set of information from a specific site. Interested in technology news? Push the technology news button. Up pops a list of technology news gather from, well, anywhere/ Where it comes from doesn’t matter. Strangest 500-pound gorilla in the room ever — we go to this branded sites and participate in sign-ups, voting, games, and other “sticky” and “engagement” activities not because we particularly like them, but because they use human psychology against us in an attempt to own an entire category of material.

Want to chat with your friends? Push a button and say something. It goes to your friends (or “followers” as Twitter calls them). Send a person a message? Click on their name and speak the message. Want to review your financial status? Push a button to see your net worth. Another one to track recent activity.

Want to know why most people use Google? It’s not because of the quality. Most people use Google because after thousands of searches, they’ve trained themselves to think of “search” and the Google logo. I know — I’ve been using Duck, Duck, Go for the last 2 weeks and it has been painful. It’s a better search engine, yet in my mind the Google branding that I’ve subjected myself to over the years still draws me back to Google.

This is stupid. It doesn’t matter where all this information comes from. You want to send a message to a friend, do you care if she updated her personal email on LinkedIn? Does it matter? You just want to send her a message. We live in a wonderful age of computers. Why are we getting so wrapped up in channels, walled-gardens, brands, and all sorts of implementation details that have nothing to do with what’s important in our lives?

Such a device is known as a “magic box”. My current working title is “magic brick”, since the goal is to make the thing as plain, unattractive, and simple as possible. You can see an early prototype reading tech news from several different sites in the video below if you like. I’m building it in F# on a .NET stack, but the idea is to run it on mono on a stand-alone device

Of course this kind of detachment from the inner workings of the web not only brings freedom, it also threatens millions of established business models. Why build a freemium service if nobody comes to see your engagement material, nobody “plays” your site enough to become a paying member? How can you sell advertising if nobody ever reads the ads?

I love saying this next phrase because it has such a mad scientist feel to it (picture Dr. Evil with his pinky in his mouth) This will destroy the internet as we know it!

I have no idea where this project would lead, but I know the underlying technology is sound, I have a working prototype, and I know exactly how it’s all going to come together. If you’d like to be a henchman or a minion, we’re now taking applications. We’re also looking for places to build our secret lair. A death ray would be awesome, but perhaps that’s a bit much for now.

Technology has become an amusement park you have to drive to and pay to get in, even if “paying” only means putting up with ads and branding, and not like the human-empowering super-tool it was supposed to be. Let’s fix that.

UPDATE: Nice darker look at the situation from my reading today

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.

Functional TDD: Codd is my Copilot

Let’s play a little game.

You work for the IRS. Your job today is to select a list of people with large bank balances so that you can do some kind of indescribably-complex tax-stuff to them. Your boss would like a list of these guys on his desk by noon.

SELECT FirstName, LastName, SSN FROM RICHGUYS WHERE Wealth > 250000

Now before you start in with the exceptions, this extremely tiny program provides business value. It’s something your customer is going to use over and over again. Over time, it is planned to become part of a larger program which chases down tax cheats overseas and posts their personal information on Facebook. This is just the first increment.

According to some, you shouldn’t write a lick of code without writing a test first. I think Bob Martin said to code without testing first is something a “caveman” would do. But how would you do that with a SELECT statement? I guess you could create some mock data, then run the select and test against the results, but that makes no sense. Plus if you test that way, you’re only testing the database engine at that point, not the code. In fact, the only thing to test here is whether or not you understood what the requirement is — is the data being returned and transformed the way the customer wanted or not? The only real test is a business test, not a programming test.

TDD doesn’t work with SQL. Most people develop this code by, well, just typing it in and running it, probably on a development copy of the database. Either it works or it doesn’t. Once it works, it works. You can move on to other stuff. The test and the business acceptance are really the same thing.

Ok, so perhaps simple SELECT statements are really silly to test. Let’s move up a notch in complexity. Over time, you build up a library of SELECT, UPDATE, and transform statements. None of them have a cursor and all of them are atomic transforms — data comes in one way and goes out another. Each of them do what they are supposed to do. None of them have been tested, at least not in the TDD sense.

A funny little secret comes into play here that is going to change programming forever.

Continue reading

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.

Google Chrome and .NET – Almost, But Not Quite

I’ve been working on a browser for people who are easily-distracted. My theory is that most of html, instead of providing user value, is actually put in to drive “engagement” or “site stickiness”, which are just fancy words for me spending too much time doing things that serve little practical value, like clicking up or down voting buttons, playing a flash game, signing up for some subscription, or engaging in a conversation with somebody else who is wrong on the internet.

The working name is “Magic Brick”, and basically it works like one of those old-fashioned Star Trek tablets. Big lights, simple screen, plain text. Nothing else.

Over the last two weeks, however, I’ve realized that plain text has its limitations. You can’t put a table easily into plain text, for instance. As my oldest son pointed out, some articles center around a central picture — a infographic, an unusual photo, or a movie. While I could custom-code up all of that, it seemed like reinventing the wheel. Why not just create html that looks mostly like plain text and display it in a browser? That way if I just have to have 3-D models, I can easily send it out to the browser and let it handle it.

Ah so, but not so simple, grasshopper.

First up, IE is a huge pig. Love you Microsoft guys, but it has been time for a refactor/re-inventing of that code for a long, long time. I’m really not tying my project to something that is big, unwieldy, slow, and so far behind everybody else. It’s going to have to be the most HTML5 compliant browser I can find.

So I started googling around. Can I use Google Chrome as a browser control? I have some pretty good Google-Fu, but searching for this — embedding Chrome in a .NET winforms application — was like trying to find the body of Jimmy Hoffa (look it up kids). It just wasn’t happening. Google don’t want you putting Chrome in .NET apps. After all, that defeats their entire business model! They want us to be the Borg. They store all of our data, provide it on demand, and tell us what to do. The Queen Borg, as it were. If we had full creative capability over what to do what our browser we might start doing stupid and crazy things, like keeping our data locally, using the same algorithms they use but keeping our personal life to ourself, skipping ads, or telling ourselves what to do. All sorts of nonsense. Can’t have that.

But there was a ray of hope! Turns out Google created Chrome Frame, an Active-X control that sits inside of IE and basically turns it into some kind of it-came-from-hell hybrid of Chrome and IE. Part of the world domination plan, yes, but a part I can use.

So the new strategy — much as I didn’t like it — was to embed IE (webbrowser control) in a form, then use Chrome Frame to display the html.

That didn’t work.

Problem is, I’m using Microsoft’s cool new whiz-bang functional language, F#. So I’m doing all the cool functional stuff — immutable data, threading, asynchronous callbacks, currying and hurrying. IE don’t play nice in that world. IE’s threading model is STA, which, to make it short and sweet, means it doesn’t play ball with the big kids. It just kind of sits over on the sideline and whines a lot.

That sucks.

So no IE, no Chrome. But wait! Isn’t Chrome built on the open-source webkit engine? Perhaps I can use Chrome without really using Chrome.

Sure enough, I found a guy who is writing a C# wrapper around webkit. A few minutes of clicking and downloading, and I had a beautiful C# project on my desktop. A project which didn’t work, either.

Something about COM interfaces. For those of you who have not experienced the joys of COM programming, to get an idea of the pain involved just pinch your bottom lip real hard. Now pull your lip over your head.

Never fear! I am not giving up this easily. Programming is an odd mix of skills — it’s part chessmaster, part puzzlemaster, and part stubborn jackass.

As much as I’ve slammed Microsoft over the years, you have to hand it to .NET and the CLR, I honestly think it’s the best thing they’ve done in the last decade. I brought up the source code (in C#, not F#), then ran my f# project while it tried to use the control. A little bit of looking around and there — some new COM interfaces that the original programmer had not implemented. Pretty cool to program in one language and debug in another.

At first, I just commented out everything that broke. Open source is awesome! Having problems? Find the offending lines and comment them out. Suddenly no more problems! Function failing and needs to return a string? Make it the return value “weasel”. I’m sure some code somewhere will know what to do with it.

So after commenting out about five errors, the control ran well. Only it didn’t do anything except display an empty box. In the business this is technically known as “sub-optimal performance”

But there’s a method to the madness. By doing my hacking exercise, I realized that the scope of the problem is around 5 methods. This allowed me to make the decision whether or not to actually fix the problem or continue searching for answers. I decided to fix the problem.

A couple hours later, and voila, webkit running as a threaded control inside a F# project. All the html5 goodness I could want.

But it gets better. With the initial wrapper code in place, I could easily start getting the nightly builds of webkit and just updating the wrapper code in my project. As such, I’d always have the latest html5 deployment, even ahead of Google Chrome.

But that’s heading down another road entirely, and for the easily-distracted, probably worth putting off until another day.

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.

Structuring Larger F# Functional Projects

Everybody that’s interested in F# has played around with some code, and it’s amazing how much stuff you can put into a small space with the language, but at some point, you’re probably going to get into a situation where you have more than one source file, yet you’d still like to stay functional.

So here’s a suggested structure outline for those larger functional projects

Continue reading

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.

Feb 2010 New F# Compiler Bugs

I have been playing around with F# for over a year now, and I really love it. I *think* I have most of it mastered, except maybe active patterns and workflows — but I’m getting close to groking those. Recursion still makes me scratch my head for a bit, but I can recurse with the best of them once I get going.

What sucks is running into bugs — not mine, but the compiler’s. Here are two I ran into last week that’s caused a lot of pain (and information about a possible third one)

Continue reading

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.

Answering PG’S Arc Challenge: On the Road to a DSL

I’m building a new startup — it allows people to collect and share quotes from books and web articles. As you add each quote, you tag it. When people vote up or down your quote (or comment on it), the system trains itself to learn which tags each user likes. I may like quotes from American History. You may never want to see any quotes about politics. Over time, the system learns this and acts accordingly. That way you can have a broad range of subjects with a large user base and the app still has the feel of a private forum.

A while back, Paul Graham wrote a language called Arc. After he wrote it, he challenged other languages to create a simple set of web pages in as few tokens as possible. In Paul’s philosophy, the fewer tokens a language has (or needs) the more robust it is. Therefore the more likely it is to last a hundred years

I’ve been thinking about Paul’s assertion for over a year now. I’ve programmed in lots of languages — to me they’re just tools. Old friends. I can’t say I am crazy about one language or another, no matter how many tokens it has.

As I and others pointed out, you can make a computer language do almost anything in as few tokens as you like as long as you’ve set up a DSL (Domain-Specific Language) for the problem domain.

Since I’m building my product almost from scratch, I thought I would take you through a quick tour of how you end up with powerful “languages” that have maximum expressiveness and minimum tokens, no matter what tools you are using. For this discussion, we’ll stick to a (mostly) .NET stack, with some major modifications, but the stack is really not important.

Continue reading

Share
If you've read this far and you're interested in Agile, you should take my No-frills Agile Tune-up Email Course, and follow me on Twitter.