« Angry Yet?| Main | What's a Startup, Anyway? »

Programming is for Stupid People

| | Comments (31)

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.

What is one of the main the purposes of OO (Object Oriented X)?

I know it provides a wonderful way to organize large projects, and OO provides the best analysis and design tools around, hands-down, but the real beauty of OO is that I don't have to think that much. Aside from small refactoring, and the incremental update and refactoring of the design as necessary, most of the "normal" work of OO is tightly encapsulated around just a few concepts. I have an object, a method, an interface. Inside the method I'm working with another object, method, or interface. As long as I keep my names so that they represent real-world things, I have very few new symbols to keep in my head. It's all just "common sense"

In that sense, OO systems are very relaxing, you design some, you code some, then you design some more. You're always dealing with things from the problem domain and you're always working in small pieces. Most of the time, by the time I'm 20% of the way into an OO program I kinda know mostly how it's all going to turn out.

Functional programming -- at least how I understand it -- makes my brain hurt. I told a friend of mine that FP made me become the linker. I felt as if I had to carry around these data structures, variable names, and function signatures in my head at all times. After all, FP gave me the ability to radically reshape the code in the middle of writing it. In the OO world this would be the equivalent of renaming half your objects with just one line of code. It's enough to give a body a headache.

So at the micro-level, at the level of each individual project, OO is a winner for stupid people like me.

But the situation changes at the macro level.

What I've found, working with several projects, is that I started building up a library of functions that I can reuse. Microsoft's .NET comes with so many libraries and features that it's a full-time job just keeping up with all of it. And Microsoft is always adding more each month.

FP, however, allows me to "cross-cut" -- pull pieces of things from here and there and make little functions that are useful to me. Things I probably am going to reuse in other projects.

Here's the kicker -- for most people's jobs, there are only about 30-70 types of things you do in writing code. You create a window. You process a message loop. You sort some stuff. Some of this is generic, but some of it is highly specific to your work -- you take a stream of characters from a serial interface and translate it, or you poll a device to see what state it is in.

FP says that you don't have to have 20 thousand libraries. Or rather, you're welcome to have as many libraries as you want, but you develop those 30-70 functions that you use most often in your job and re-use them Instead of learning a new problem domain for each project and then working inside of it little piece by little piece, you're creating you own minimal set of symbols that work on all of your projects, thereby making each new project more and more trivial.

OO code, on the other hand, is rarely reused. By the time you've written your Customer object, it's so dependent on the framework it is in and the way that it is used that every object you make is basically a one-of for that particular project. Sure, you can wrap potentially reusable code into objects of your own, but I've been doing this over 20 years and I can tell you that true code reuse between projects in the OO world is mostly a pipe dream. That's why so many good OO guys end up being toolsmiths and writing frameworks -- out of a desperate desire to create true reusable pieces of code for common problems.

In contrast, FP offers true reuse -- you ferret out what you need from all the noise of the libraries and then put it in your personal set of code.

I then thought about my new friend -- and the thousands more like him. Spending countless hours every year learning yet another version of WhizBang, getting certified, trying to teach some concepts, learning some more. How many versions of database access has Microsoft offered over the years? He had an amazing ability to remember small details from hundreds of places. We usually call such ability to recall being "smart"

But how much of real programming is about remembering thousands of different symbols? Programming is making some technical solution happen for somebody. As a programmer, I should be in the business of quickly making solutions for folks, not becoming a finalist on "Jeopardy! "

I could have written some generic database code in 1995 and still be reusing it. As long as it isn't broken, what's wrong with that? In fact, isn't the whole idea of programming to keep working at a higher and higher level of abstraction? Instead we reward people for being smart -- for learning more and more details about trivial libraries that will be deprecated in ten years' time. Something is wrong with that. It smells like the game Quicken plays. Intuit stopped actually doing anything new about balancing checkbooks 15 years ago but continues to release "new and improved" programs each year -- with a hefty price tag attached.

Sometimes I think you can be too smart for this stuff.

Yep, programming is for stupid people. I think I'm in the right spot.

APPEND: Don't know if you've read this or not, but there was a great book about this philosophy of simplicity, at least how it pertains to UI design. But the same is true for what happens behind the scenes. It's amazing how important simplicity is, yet we talk about it without actually doing much of it.


Try Scheme or Haskell. I grew weary of being a "coder" (someone who stitches together pre-made libraries of code with other pre-made libraries of code) and was searching for something that stimulated my intellect.

My first affair was with Erlang where I also first encountered Emacs. Erlang is a functional language - instead of objects with methods you have modules with functions. Instead of assignment you have pattern matching (which is assignment but not the same as saying var = "some value").

Erlang is interesting because it does have a large ecosystem of libraries already made for it - only catch is, they were made for things most programmers outside the telecom industry would rarely/never need to use (XML parsing/writing in Erlang? Coming from Python's ElementTree, it made me cringe hard).

After learning Erlang I moved onto LISP - I read a lot about its "grandfather" status and many of the interesting ideas in the language; I selected my dialect, CL (Common Lisp, or just "Lisp" note camel case not caps) and pounded away. I quickly got the feeling that Common Lisp was trying to be too much for everyone and the libraries were out-dated. I also learned that Common Lisp isn't a "true" functional language.

After that romp I decided upon a dialect of LISP that was functional - Scheme. Picked up the Little Schemer series and downloaded PLT (amazing) and went to town. Scheme is packed with so much and yet leaves you, the programmer (not "coder"), with the facilities to create - programming in Scheme is like classical figurative painting. You have a rich set of tools, but nothing on the canvas is pre-done for you, it's up to you to mix your paints, and select the brush, etc...

Presently, I'm a full-time Python programmer (having come from PHP...) and a hobby Scheme/Erlang/Haskell programmer; the technology I built my company on is powerful and I'm hoping the next company I build will be built on top of Scheme or Haskell.

I've always thought that the best software is written by the most creative people, not the smartest. Being smart doesn't hurt (in fact it helps most of the time) but I'd favor a creative mind over an uncreative one.

To me, it seems that you're talking mostly about procedural programming instead of functional programming. You somehow touched the subject of FP, but not quite much I'd say, and the reason is that you didn't mention anything about combinators, or immutable state. I'm not saying that you didn't understand the essence of FP, just that maybe you didn't express it quite the way it is (personal opinion again :)).

When I'm saying combinators I'm referring to those abstract functions that take functions as arguments (and maybe return other functions). They provide little pieces of reusable code that is open for extension by means of higher-order functions. This is possible in OO too, using abstract classes with something like the template method pattern. It's just that it's cumbersome to write all that stuff in a language like Java.

These are the real building blocks that make FP so tempting. Being armed with these combinators, it's usually just a matter of wrapping a few lines of highly condensed combinators into a function with an appropriate name for the domain you're modeling.

Mutable state is another strong point of most FP languages because they ease our reasoning about our programs. Not having to keep up with all the symbols and state, that you already mentioned actually, is far less easier. A function starts here and ends here. Almost no contact with the outside world is possible. You can do that in OO, but again, it would be cumbersome. There are though some hybrid languages that try to alleviate this issue, because at some point, the differences between OO and FP are not that big. Sometimes is just a matter of syntax.

Lately it's been bugging me that there's so much boilerplate everywhere and that I might just have to deal with it, but recently I've encountered Haskel at functional programming course at university - it seemed like a light at the end of the tunnel, but it also seemed to me that it's just a new concept without practical application. Your comment (and this article) is encouraging and releaving for me to hear that it's not just exercise for the mind, and I'll give it even more attention now :)

Thanks for the good article. I like this and I share this my facebook profile. My friends like this also..

Really Thanks..

The best programmers are lazy people. But not mere ordinary lazy people who take the path of least resistance. Rather, programmers are people who seek sustained, long-term laziness. Paradoxically, this leads them to work harder on a day-to-day basis, seeking the code that will require the least effort in maintenance, be the most re-useable, etc.

I disagree with "stupid people", programming is really hard, Dijkstra
knew it and said something about this matter:

(The Humble Programmer)
"We shall do a much better programming job, provided that we approach
the task with a full appreciation of its tremendous difficulty,
provided that we stick to modest and elegant programming languages,
provided that we respect the intrinsic limitations of the human mind
and approach the task as Very Humble Programmers."


It's not about being stupid or lazy or clever.
It's about coping with the limits of human intellect.
Software is among the most complex of human endeavors.

A human can only keep a few things in short term memory. Much of programming involves doing everything you can to manage extreme complexity with what little we are capable of.


Thanks for the comment!

You managed to put my entire blog entry into just a couple sentences.

I think I need to call you next time I want to write an article :)

Now if you'd just understand that I was being facetious -- of course people are not stupid or lazy or whatever, it's a matter of working with the wetware we have -- then I would have scored 100.

But I'm happy that you got it, even if it didn't come from me.

Also, this wasn't supposed to necessarily be a commentary on OO or FP, aside from noting that both ways of looking at code involve minimizing the number of symbols, just in different ways.

My highschool math teacher told me that he often found that the laziest smart kids did best at math. He figured that they worked out the quickest way to meet workload expectations without worrying about what they were learning so much. I think the same thing applies to programming.

I am an 'old' programmer now, and though I still enjoy learning about new tech and languages, I rarely use them to earn my income.

I remember a time when there were no libraries available for micro-computers. Wasn't a particularly good selection of languages either. So you did the obvious--- built your own. Even later when this began to change (first libs I remember were for math chips and such) you typically ran into the problem of 'someone else's idea of a good time' when it came to fitting your code to their library. To give an indication of an industry blind spot, it all of the years that I've been coding, I only remember one book on the craft of writing a library for someone else to use. All of this by way of saying your comments resonate with my beliefs and experience--- good work!


As for the guy:
I know the guy you are speaking of as I was in your class. I thought it was a great class and I agree that he was missing the point of the demo. However, I can tell you two things. First, he is extraordinarily bright which evidenced by his extensive contributions to MONO. Second, he is regularly the heckler in the crowd. In his case though, it isn't by malicious intention. He just takes things very literally. So much so in fact that he sees any perceived misstatement or misinterpretation as an invitation to assist by contributing from his experience.

As for the post:
I agree that OO and system libraries take a lot of the art out of the programming. There are days where I feel more like an assembly line than an engineer. F#, and other languages, bring modern development in closer touch to its engineering origins. For those of us in the industry that can appreciate such tools, this is a wonderful thing.

What I'd like to hear your opinions on is this: If you with 20, or I with 15, years of experience struggle with the intellectual agility required by F#, how is the average line programmer going to keep up? At the end of the day, Bank of XYZ cares about the delivery and maintainability of its application. So doesn't that dictate that the most widely understood techniques be used?

Obviously there will be times when functional programming is the best solution, but there will be a far larger number of times when it is only one of many solutions. How can we justify using F# when C# can do the job and there are far more programmers to support C#?

This is ultimately the question I struggle with, as I love F# but I've yet to be faced with a problem best solved with Functional Programming. Thus, I've yet to be in the position of advocating it to the client.

I heard that Einstein said he never memorized things, that is what books are for, they would remember so he didn't have to. He just had to look them up.

That has always stuck with me. And while I might memorize tools just by using/reusing them so much, typing a search term into Google and looking up something for reference is a standard thing that I do.

Yes, some people are of the mindset that you have to memorize everything. But these days so much reference is at our fingertips it makes more sense to look it up.

You've sparked my interest in F# and functional programming. I hope to learn what you are talking about here first hand.

Great article. I really like the concept that "whole idea of programming to keep working at a higher and higher level of abstraction".

If I solve a problem elegantly and efficiently, I should never have to solve that problem again, it should become part of my arsenal against new problems.

That said, I was eagerly reading through the comments hoping that "the guy" would post a response...(fingers crossed)

Programming is really tough. You have to be smart, creative to do well in programming.No matter how much you have learnt there is still something new everyday.


Thanks for the comments! I was wondering if anybody from the class would stop by. That's awesome.

Whoever the guy is, I'd like to thank him. Our conversation led me to piece together several things I had been mulling over for weeks.

You are entirely correct about "why move to F# when we're already in C# and F# programmers are so hard to find"

What I did -- unintentionally, of course, is switch definitions of "programming" around.

If you're talking "programming", the ability for me to sit in front of a computer and make things happen, then I'd vote for FP -- as long as it was exploratory in nature.

If you're talking "programming", the ability to form a team of coders and work on a large-ish predefined business solution, then I'd vote C#/imperative.

There's programming the art, programming the business, and programming in large teams. All of these topics are very different.

Over time, I think that we're all headed towards some version of FP. This is the reason I took so much time with it. I might be wrong, but usually I'm a pretty good technology guesser. Of course, it could all end up as FP-ish extensions to some kind of OOP, but I doubt it. (I just don't know).

However with F#/OCAML you get your cake and eat it too -- you can do objects or "true" FP depending on what your needs are. In fact, if you watch Don Syme, you'll find him saying over and over again to use F# in the functional and interactive modes to explore and solve the heart of problems, then move up to some kind of OOP structure as the solution matures. How much of that is just Microsoft-political-speech and how much of that is practical? Also beyond me. I think a little of each.

Great comments. Glad you liked the presentation.

Daniel, I think I know why functional programming will eventually win over both OOP and procedural programming : it yield simpler programs. A good deal of this simplicity can be felt by just avoiding to use of the assignment statement¹.

Adam, the only reason F# requires a significant intellectual agility is because it's different. I barely know .net, but knowing a bit of Java and a good deal of Ocaml, I'm almost certain that F# is simpler than C# in every respect. I agree that it still makes sense to choose C# over F# in the short term. But in the long run, C# will die a COBOL death.

[1]: http://www.loup-vaillant.fr/articles/assignment

Couldn't agree more. Now quit exposing me for the charlatan that I am. :)

It's all about level of abstraction.
In assembly, you think in terms of moving integers among registers and directly addressed memories.
In C, you think about variables, pointers, functions, and memory management.
In modern OO (Java, C#), you think in objects with states and methods.
FP is supposed to provide some abstraction above objects.

I mostly agree with your post... except for 1 thing.

To be able to remember 100s of libraries is to have good memory. To be able to use them to solve a new problem that is not in any of them, that is being smart. To be able to grow into the latter, we need to study how the existing concepts (not libraries) are put together. The fact that there is a library that already does it does not excuse the need to study. I believe that your student confused being smart with being a wise pants.

A similar transition happens when we go from procedural to OO programming. The difference is that OO is more forgiving in the bad habits carried from PP(Procedural Programming). Even after creating classes, the program can end up with highly co-dependent objects. Pure OO is hard. Really hard. Wrapping procedural code with public class xxx { } is not OO.

The problem that we are facing is that pure FP is hard, really hard. F# easy the situation by allowing a mix of paradigms. But then again, we can end up with an F# program that is more OO than FP.

Is programming for stupid people? An excel macro, yes, but as soon as complexity goes up, then the smartness needed goes up too. Anybody can put a band aid, that does not mean that everybody is a heart surgeon. The fact that you can go to Walmart to buy antibiotics does not excuse your doctor from knowing what they are and how they work.

General people have very short cycles of effort-reward, long term projects require much more than this. General people get easily tired if the problem at hand has more than 3 or 4 variables. Professional software development require juggling many more.

Like in any other profession anybody can get their feet wet, but smart people is the one that will end up excelling at it.

Great article. As someone who regularly speaks on F#, I can totally relate to the people in the room you are talking about. There's always one nit-picker and always at least one "get off my lawn" type.

The nit-picker either doesn't know that you are trying to hide information in order to avoid overwhelming the audience or is just looking for an excuse to derail your presentation and gain some personal attention. These I dislike the most.

I can relate to the "get off my lawn" types though. Who wants to learn another Microsoft framework-of-the-year just to have it replaced with something marginally better a short few years down the road? I think many see F# in this light, as if it was a framework itself. You make a great point about it really being something here to save us from framework madness.

I don't really agree with your use of the word stupid though. I just don't think "smart" vs "stupid" is about how much you can remember. Instead, I think it means "being able to do the least amount of work to get the thing you need done". As you talk about, this is where FP really shines :).

There's a good reason all of those mathy folks out there love matlab. There's no need to build or learn crazy abstractions. You only need a few key functions to get your job done.

It's all about the end product.


Thanks for the comment! Good to hear from other folks giving F# presentations.

As for the title, what can I say? I'm a corny-title junkie. I have been mulling Code Camp and what to write about it for a few days -- the gist was that the purpose of languages and frameworks is to minimize the amount of symbols a person has to juggle at any one time -- but the words just wouldn't come. When I got up yesterday morning, it occurred to me that saying that folks couldn't handle all the complexity of modern frameworks and languages? To some that would be like saying people are stupid. And that's not what I meant at all. But the phrase "programmers are stupid" stuck in my head, and I knew I had an article.

One of the main points one of the other presenters on F# made was this: F# is not just another language or framework. It's not OLEDB version 7, or WCF-to-the-max. It's a whole new ballgame. And when used properly and understood, it actually makes all that other stuff a lot more immediately practical and worthwhile.

I'm still uncomfortable speaking about F# -- so many things that are new to folks. Heck, I could do a couple of hours just on pattern-matching: very cool stuff in there. So it's always difficult to decide on what to say and what to leave out.


I'm always looking for videos and experience reports of others who speak on F#. It's helps to find grounding and interesting new ways to present ideas.

Along these lines, you might be interested in some of the many recorded New England F# User Group talks. We've been running for well over a year now and have a lot of material on our site.

In fact, if you'd be interested in speaking we'd love to have you (even via live meeting).

It's all over at http://fsug.org under the "Previous Speakers" tab. Just a warning though, there's a strong focus on ideas over fancy slides :).



Thanks a bunch man. This is EXACTLY the way I feel about it. I couldn't have said it better myself!

I sometimes refer to myself as "Ye Olde Country Programmer". I try to stay with the technology but I'm still fairly "simple-minded" in how I go about my work. Glad to see that I'm not alone in this way of thinking!


Very good read. Interesting perspective. I remember doing functional programming in college and really struggling with its terse yet powerful nature. It requires a great deal more abstract thought than OO for sure.

Also, I agree with your perspective regarding how we "reward smart people". I have some opinions on that too but I'll reserve those for a verbal discussion!

Object-oriented programming DOES promote reuse.

Every time you use an MFC class derived from CWnd, you're reusing thousands of lines of code.

Every time you derive a new class, you're reusing the code from your base classes.

Object-oriented programming allows the use of design patterns, which reuse design strategies worked out by other people.


Great comments. I was just trying to think this morning of a good OO reuse example, and Cwnd/Form/Control was the first thing that popped in my mind. They are immensely useful and reused all the time.

Of course, MFC is a *framework*, and as I point out, the reason so many good OO guys end up either being toolsmiths or framework creators is their desire to make something truly reusable. This has left us with thousands of tools and frameworks, but an embarrassment of riches is a good thing.

To your other point about design patterns. I grok what you're saying, but I would be extremely careful about your use of design patterns in an ad-hoc manner. I've ran into many a mess created by design pattern enthusiasts run amok.

It's a great idea to learn these patterns and when to spot them, and it increases your vocabulary of solutions immensely, but the problem here is that too often we rely on design patterns to skip over analysis. Sometimes (most times) the analysis shows that the pattern is not as fully formed as the textbook version, and we are much better off using the stripped down version.

I think C++ ( and I love C++) is probably the poster child for patterns and frameworks gone crazy. It is an immensely powerful power tool, a chainsaw of solution-building -- but it will cut your leg off as easily as it will cut down a tree. Probably easier, really.

That is one of my pet peeves - when people ask a 'question' that is not a question.

Have you ever noticed this 'well meaning soul' that interupts a presentation before the Q & A not only derails the instructor's train of thought, but often derails the entire audience.

Been there...seen that...wish I had a paintball gun sometimes.

Sorry you had to face that. I wish I'd been there for the presentation as I'm getting curious about F# too.

Michael in Calgary

Daniel, where's all that ego gone? No, really.
How much rewarding can it be to write a new web browser for your next POS system?
Instead, you could use an existing browser, and easier language (javascript than C/C++) and focus on the real features.
Programming isn't for stupid people. You may be lucky to have a lot of devs around you, making development seem like pie, but other people ain't that lucky.
I remember the thrill of telling a computer what to do when the user types "Q", in the ages-old QBasic....while the rest of my friends wasted their time trying to impress each other in the playground outside.


Thanks for the comment.

Here's the thing: libraries are like phonebooks: they are great tools to have to do lots of stuff, but if you have ADD (or like little shiny things), they can also be needlessly distracting. What you need is the phone numbers of your five best friends.

Most folks don't spend hours and hours studying the phonebook in preparation for a phone call, but we encourage this exact behaviour when it comes to libraries. Why? I suspect it's to sell more libraries, but maybe I'm cynical.

FP doesn't make you have to reinvent the browser. Heck, that's crazy. What it allows you to do is to pick up pieces of libraries and such from all across hundreds of toolsets and libraries and put them all in one file with just a few dozen symbols that you assign. This limits the cognitive load on the programmer and focuses on the important thing -- getting stuff done -- instead of the coolness of Browser 7.9

Hope that made more sense.

And where's the ego? (grin) You have to remember that sincerity and humility is the key to human interactions. If you can fake those, you pretty much got it made. :)

Leave a comment

Comment Policy: I really, really, really enjoy comments, but if all you have to offer is general platitudes like how happy you are to have found my site and what a wonderful place it is, I will delete your comment and report your comment as spam. Please try to either tell me I am wrong, sympathize with my point, expand on what I'm saying, or offer your own experiences or opinions. If you just want a link your best bet is to just ask for one. Probably won't work, but at least be honest about it. No name-calling and please keep the profanity as low as possible. If your grandma can't read it or you wouldn't say it in person, don't write it here. Thanks.

About this Entry

This page contains a single entry by DanielBMarkham published on October 18, 2010 10:06 AM.

Angry Yet? was the previous entry in this blog.

What's a Startup, Anyway? is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Share Bookmark this on Delicious

Recent Comments

  • DanielBMarkham: Christian, Thanks for the comment. Here's the thing: libraries are read more
  • Christian Sciberras: Daniel, where's all that ego gone? No, really. How much read more
  • Michael McLaughlin (Calgary, AB): Have you ever noticed this 'well meaning soul' that interupts read more
  • Liam McLennan: That is one of my pet peeves - when people read more
  • DanielBMarkham: Alan, Great comments. I was just trying to think this read more
  • Alan Balkany: Object-oriented programming DOES promote reuse. Every time you use an read more
  • Brian Lanham: Very good read. Interesting perspective. I remember doing functional programming read more
  • Bruce Roeser: Dan, Thanks a bunch man. This is EXACTLY the way read more
  • Rick Minerich: Daniel, I'm always looking for videos and experience reports of read more
  • DanielBMarkham: Rick, Thanks for the comment! Good to hear from other read more

Information you might find handy
(other sites I have worked on)

Recently I created a list of books that hackers recommend to each other -- what are the books super hackers use to help guide them form their own startups and make millions? hn-books might be a site you'd like to check out.
On the low-end of the spectrum, I realized that a lot of people have problems logging into Facebook, of all things. So I created a micro-site to help folks learn how to log-in correctly, and to share various funny pictures and such that folks might like to share with their friends. It's called (appropriately enough) facebook login help