Monday, October 31, 2005

Why Are Continuations So Confusing, and What Do They Really Do?

I recently watched a video trying to explain, in simple terms, what continuations are. The quick answer was "Continuations are just the remaining work to be done." WTF?! I had been wondering what the heck continuations were, but this answer gave me absolutely no clue. Oh! Of course! The remaining work to be done! It makes complete sense now. Unfortunately, this is one of those explanations that only makes sense if you already understand what is being explained. Kind of like 'a Java classpath is just the set of paths where all your classes are'. Completely useless to you if you don't already get it. Even the examples in the video confused me. I sort of got it, but not really. So I started digging into Ruby to see if I could figure it out, given the sparse clues I already had, and you know what ... continuations are so freaking simple that it boggles my mind why it was so difficult to understand them. Correction: It doesn't boggle my mind; I know exactly why continuations are confusing. And so, I hope to once and for all cut through all the confusion and explain what continuations are, and how to use them, in actual simple terms.

What are continuations?
That's actually the wrong question to ask. The answer will probably confuse you more than necessary. The better question to start with is:

Why are continuations so confusing?
The answer is quite simple: Wrong metaphor. The word 'continuation' provides no clue as to what it does. In fact, it describes its implementation rather than its purpose. So, it is necessary for you to understand the implementation before you can understand the purpose. But for someone new to continuations, this is completely backwards! We want to understand what continuations are for before we understand how the implementation works. Could you imagine if a class' methods were called 'virtual table entries'? Or if floating point numbers were called 'exponentiated mantissas'? Of course, the implementation is important to understand to become an expert, but I shouldn't need to know exactly how an internal combustion engine works just to drive a car.

What do they really do?
You know, I'm not even going to bother calling them continuations anymore, as that's a complete red herring. I'm going to explain to you a brand-spanking-new concept called 'execution sites'. Execution sites allow you to specify (or mark) a point of execution in your code, and store a representation of that site in a variable so that you can return to the original site later. Not only that, but it allows you to pass information back to the original site, so that it evaluates to a different value. I'll explain how this works with some simple Ruby code. (Note that the code below will not work in plain old Ruby. It requires some simple definitions which I'll provide at the end of the article. You can, for now, pretend that this is 'wishful' Ruby, or Ruby-as-I-would-like-it. I'll also use some redundant syntax to make the code more natural to non-Rubyists.)

I need to be able to mark my execution site and store it in a variable, like this:
theSite = mark();
'mark' is a special keyword (again, not in real Ruby, but in wishful-Ruby) that captures the site of execution, wraps it in an object, and returns it. 'theSite' is simply a local variable where we store the site. Later on, we can return to the site by using the 'return' method of the site object, like this:
theSite.return();
Here's a 'hello world' type of program that uses execution site marking:
theSite = mark();
puts "Hello, World!"
theSite.return();
This code performs an infinite loop, outputting "Hello, World!" over and over. You may be familiar with labels and gotos from other languages, which allow you to do something very similar to this. Here's a simple script to demonstrate how gotos and labels work:
:theSite
echo Hello
goto theSite
"So, an execution site is like a goto label?" Sort of, but actually more powerful. First, you can store an execution site in a variable, array, object field, or whatever, so it is more like an object than a label. Second, labels typically are limited in scope, depending on the language. For example, you usually can't goto from one method/function to another. With execution sites, you can return from deep inside some arbitrary code, back to wherever the site was marked:
# Method definitions
def startloop
startloopSite = mark();
puts "Inside startloop";
return startloopSite;
end

def endloop(startloopSite)
puts "Inside endloop";
startloopSite.return();
end

# Main execution path
theSite = startloop();
puts "Middle of the loop";
endloop(theSite);
This code will output "Inside startloop", "Middle of the loop", and "Inside endloop" over and over again. Notice that the main code execution path goes into startloop, marks the execution site, outputs "Inside startloop", and then returns the execution site. So, later, when endloop calls 'return' on the execution site, code execution goes right back inside startloop and outputs "Inside startloop" again. The site always returns to where it was marked, no matter where that is. Simple, but potentially much more powerful than a plain goto label.

The third major difference between labels and execution sites is that execution sites remember everything about where they were marked, whereas goto labels are more 'global' in this aspect. A label only knows where it is declared, but when you mark an execution site, it remembers how the execution path got there (such as the method call stack) and also what local variables have been declared up to that point. In essence, it stores the complete execution state in a little object so that you can return to that same state at any point in the future. Here's an example:
def remember(aValue)
theSite = mark();
puts "The value is " + aValue.to_s();
return theSite;
end

siteToReturnTo = 2;

# Remember the values and execution state
firstSite = remember(1234); # Line A
secondSite = remember("ABCD"); # Line B

puts siteToReturnTo;

# First go back to secondSite, then back to firstSite, then quit
if (siteToReturnTo == 2) then
siteToReturnTo = 1;
secondSite.return();
elsif (siteToReturnTo == 1) then
siteToReturnTo = -1;
firstSite.return();
end
This code outputs the following:

The value is 1234
The value is ABCD
2
The value is ABCD
1
The value is 1234
The value is ABCD
-1

The first two lines of output come from the first time the 'remember' lines were executed. Inside the 'remember' method, the parameter 'aValue' takes on different values depending on what was passed. Note that the execution site is marked inside the 'remember' method, so the site will remember the value assigned to the 'aValue' parameter, as each call to the method essentially creates a separate variable called 'aValue'. So, essentially, 'firstSite' remembers that 'aValue' is 1234, and 'secondSite' remembers that it is "ABCD". Not only that, but firstSite remembers that the 'remember' method call should return to Line A, and secondSite remembers that it should return to Line B. So local variables, the state of the call stack, and even the exact location in the code are all remembered when an execution site is marked.

When secondSite.return() is called, execution jumps inside the 'remember' method, where 'aValue' has the value "ABCD", and the 'remember' method will return to Line B. Hence, we get the fourth line of output, "The value is ABCD". By this time, our switch variable, 'siteToReturnTo' has been updated to cause firstSite.return() to be called. When this happens, execution jumps again into the 'remember' method, but this time 'aValue' has its original value of 1234, and the method call will return to Line A. (Note that firstSite and secondSite do not remember that 'siteToReturnTo' was initially given the value of 2. Sites remember the variables themselves not the values of the variables. The fact that 'aValue' exists as a local parameter inside the 'remember' method makes it act like two distinct variables, one for each method call, which happen to have the same name. It's a subtle distinction, and important to keep in mind. Those familiar with closures and code blocks in Ruby should have no trouble with this.)

Now, this is all fine and dandy, but doesn't this make execution sites seem like glorified gotos? In essence, that is very much what they are. Dijkstra's advice should be heeded: Goto Considered Harmful. Marking execution sites for the purposes of using them like gotos sounds to me like a recipe for spaghetti. I like spaghetti for a good meal, but not in my code! I really believe that execution sites have the potential to royally mess up your code, so I don't recommend using them without a very good reason. I would say that it is unlikely that most programmers will code directly with execution sites. Instead, it is more likely that they would be useful for specialized frameworks and services to give concise ways to express complex solutions to problems. However, that shouldn't stop you from playing around with them to get a solid feel for what they do. Hey, maybe you'll be the one writing that cool framework or service that uses execution sites.

What's the big deal?
There is one last capability of execution sites which I've been holding up my sleeve. I think this is what makes them truly powerful and useful, and worthy of taking the time to understand them. I'll be honest and admit that I personally can not think of very many practical uses for execution sites, although some very practical examples exist. I imagine that I'll start to see practical uses as my understanding improves and my imagination catches up with me (as happened to me with closures and macros). In any case, the final capability:

So far, you've seen that execution sites can mark a place in code execution that can be returned to at some later time. Wouldn't it be great if they could also return some useful information back to the original site? Then they could be used as a way to 'hold' a calculation until future information is available that can allow the calculation to 'continue' (Hmm, there's that word 'continue'.... I wonder if there's a connection to continuations? Patience, please. :-)

Maybe, in wishful-Ruby, it could look like this:
tryForBetter = true;
theSite = nil;
theCalculation = mark() { |site|
theSite = site;
# Do some work to get an initial value for the calculation
initialCalculation = 3;
theSite.return(initialCalculation); # Line A
}

puts "The calculation is " + theCalculation.to_s();

if (tryForBetter) then
tryForBetter = false;
# We discover a better value for the calculation
betterValue = 3.1415;
theSite.return(betterValue); # Line B
end
This usage of 'mark' is significantly different than the simple usage of 'mark'. In the simple usage, 'mark' returns the execution site itself:
theSite = mark();
In the new version, 'mark' returns a value, and the execution site is provided as a parameter to the accompanying code block. This syntax structure allows us to return different values in the future. The execution site is merely a book-keeping tool that we use to provide this capability.

The first time through the code, 'mark' captures the execution site, and then executes the code block. The code block is given the site object as a parameter, called 'site' in this example. We store the site object in the local variable 'theSite' so we can use it later. Then we return an initial value. This initial value becomes the value of the 'mark' expression. Note that the code block is only executed once, when the 'mark' expression is first evaluated. You can think of the code block as the initializer which performs book-keeping (storing the execution site object for future use), as well as producing an initial value for the 'mark' expression.

Thus, the initial value of 'theCalculation' is 3, because that's the value determined by the block, specifically by the expression theSite.return(initialCalculation) on Line A. So the first line of output is "The calculation is 3".

Since the site object is stored in 'theSite', we can essentially go back and change the value of 'theCalculation' by passing in a different value to return on Line B. Now 'theCalculation' gets the value 3.1415, and the second line of output is "The calculation is 3.1415". If we wanted to, we could keep using the site object to return successively better approximations of pi. This is admittedly a trivial example, but hopefully it will give you a spark to let your imagination consider the possibilities.

Summary

So that's it. An execution site provides three things: A way to mark a specific point in execution, including all the important context; an object which represents the execution site so you can store it, use it, abuse it, or what have you; and a mechanism to return back to the site mark, optionally returning some useful information.

"Wait a second, you've just told me about 'execution sites'. You just made that crap up. I want to know what continuations are, you jerk!"

Whoah, whoah, no need to be upset. It's very simple, really. A 'continuation' is an 'execution site'. You create continuations using a special command named 'callcc', which works exactly like the value-returning version of the 'mark' command, and you can return to the location of the 'callcc' by invoking the 'call' method on the continuation object. All I've really done is give better names to the concepts, 'callcc' becomes 'mark', 'continuation' becomes 'execution site', and the 'call' method becomes 'return'. Oh, and I also provide a simplified way to mark sites where you don't care about the return value and only want to capture a continuation (oops, I mean execution site). In fact, it's so simple there are only a few lines of Ruby code which will transform Ruby into wishful-Ruby:
class Continuation
alias_method :return, :call
end

def mark &block
if block != nil then return callcc(&block) end
theSite = nil
callcc{|s| theSite = s}
return theSite
end
So, wishful-Ruby code that looks like this:
theSite = nil;
aValue = mark { | site |
theSite = site;
}
...
site.return(someValue)
Looks like this in normal Ruby:
theContinuation = nil;
aValue = callcc { | cc |
theContinuation = cc;
}
...
cc.call(someValue)
In other words, continuations are cryptic and nearly incomprehensible. Still not satisfied? Okay. Fine. A continuation is just a reification of execution context. Or, in 'simple terms', a continuation is just the remaining work to be done. But you already know that now, don't you?

Now if someone could just explain to me what monads are....

78 Comments:

Anonymous Cameron said...

I got kicked in the monads once .. it really hurts ;-)

November 01, 2005 4:51 AM  
Anonymous Marius Gheorghe said...

Very very nice. Thanks a lot for the explanations. Do you happen to know a static typed language which supports continuations or this is dynamic language only thingie ?

November 01, 2005 3:06 PM  
Blogger Patrick said...

There are Java implementations of continuations. RIFE has a RIFE/Continuations sub-project that WebWork takes advantage of for continuation support. See the docs here

November 01, 2005 8:29 PM  
Anonymous Jeff Heon said...

Very informative article. You could post it to the Artima developer community and see what you stir up there
(http://www.artima.com)

Proposal link
(http://www.artima.com/write.html)

November 01, 2005 9:51 PM  
Blogger acoach2 said...

Great blog here! I'll be back. I also have a site devoted tonewsletter swing trading.
It covers many interesting ideas related to newsletter swing trading. Stop by if you get time and get a free 3 week free subscription.

November 02, 2005 12:07 AM  
Blogger acoach2 said...

You have a great blog. I'm going to book mark this one! I have a site onswing trading.
It also has a lot of usefull information about swing trading. Stop by if you have time.

November 02, 2005 8:24 AM  
Blogger The Computer Guys said...

Hey, you have a great blog here! I'm definitely going to bookmark you!
I have a speed up my pc 2.0speed up my pc 2.0 site/blog. It pretty much covers speed up my pc 2.0 Problems with your Windows Xp Computing !
Come and check it out if you get time :-)

November 03, 2005 1:10 AM  
Anonymous luc said...

An "execution site", n'est-ce pas? A "site"? Hmmm, let's see what Dictionary (you are on Mac OS X, right?) says about that:

site |sīt| noun an area of ground on which a town, building, or monument is constructed : the proposed site of a hydroelectric dam. • a place where a particular event or activity is occurring or has occurred : the site of the Battle of Antietam | materials for repairs are always on site. • short for building site . • short for Web site.

How about "point"? Would that cover it: "execution point"?

All fun aside, I think I'm beginning to grasp continuations... Thanks!

November 04, 2005 4:01 PM  
Anonymous Anonymous said...

Get your website seen use our web site promotion software tool tools to get the word out and take the work out of promotion. Resale rights available. Starting at only $6.99 get 1000's of links to your website http://www.BLGen.net

November 05, 2005 12:12 AM  
Blogger The Computer Guys said...

Yo, you have a Terrific blog here! Lots of content means more readers, more readers means more Sales!
I'm definitely going to bookmark you!
I have a computer speed boostercomputer speed booster site/blog. It pretty much covers computer speed booster Problems with your Windows Xp Computing !
Come and check it out if you get time We are just a Click Away ! :-)

November 05, 2005 5:34 PM  
Anonymous Anonymous said...

Want to register better domains with better keywords? Want to host the sites better as well? Check out register domain name australia!

November 09, 2005 7:42 AM  
Anonymous Anonymous said...

I have been following a site now for almost 2 years and I have found it to be both
reliable and profitable. They post daily and their stock trades have been beating
the indexes easily.

Take a look at Wallstreetwinnersonline.com

RickJ

December 13, 2005 6:16 PM  
Blogger Paul88888 said...

You have generated a lot of interest in your blog. It does contain a great deal of information and discussion. If you have some spare time, do feel free to visite the following web domain registration site as it offers much of all the web domain registration related services.

January 18, 2006 4:36 AM  
Anonymous Phil said...

Hi Rob,

Thanks for that excellent explanation. Would you please do closures next?

Thanks,
Phil

February 17, 2006 6:53 PM  
Anonymous Anonymous said...

Why are you using semi-colons? Just don't use them. Same with doing

"if (statement) then
...
end"

Drop the parentheses and the 'then'.

March 07, 2006 11:58 PM  
Anonymous Anonymous said...

Oh, and please don't use camelCase in Ruby. It is standard convention to use whatever_this_is_called.

March 08, 2006 12:01 AM  
Anonymous Anonymous said...

(Boy you got a lot of comment spam on this.)

Nice explanation! You might check out Nickle, which provides continuations as just setjmp()/longjmp() without the restrictions. :-)

There's also a nice example there of what continuations are for: namely, extending the language. Like any other language extension tool, they should definitely be used with caution. But it's very occasionally nice to be able to create new control flows in the same way you can create new datatypes.

March 08, 2006 12:06 AM  
Anonymous Richard said...

Well, that was a pretty bad attempt at a 'simple' explanation. But at least you were trying. setjmp/lngjmp? I shudder.

If I understand continuations then continuations are just lambdas with better syntax, and a different way to create them.

The only difference between a lambda and a continuation is that instead of creating the lambda and executing it being two seperate steps, a Call/CC does both steps at once.

So the way to emulate a continuation using lambdas is to store the lambda in a method variable and then execute the lambda. If the lambda references itself in any way, which is probably typical for continuations, then this is officially Very Ugly Code.

So a lambda is executed 0 or more times, whereas a continuation is executed 1 or more times.

And voila, those are continuations. Syntactic sugar for lambdas.

Or at least, that's what I've got from your explanation so you know who to blame if it's wrong.

March 08, 2006 8:25 AM  
Blogger Laurie Cheers said...

I think you've hit on the reason why so many people find functional language concepts hard - their terminology and syntax get chosen by mathematicians.

By the way, instead of "site.return()", perhaps "site.goto()" or "site.resume()" would be more appropriate?

March 08, 2006 1:48 PM  
Blogger Laurie Cheers said...

This post has been removed by a blog administrator.

March 08, 2006 4:28 PM  
Blogger Laurie Cheers said...

If you're interested in rephrasing monads in a similar way, then Monads for the Working Haskell Programmer explains them fairly well from a programmer's standpoint.
(that's in stark contrast to most "tutorials" on monads - for instance The Haskell Programmer's Guide to the IO Monad)

March 08, 2006 4:30 PM  
Blogger Chris Parker said...

Paul Graham has a great description of Continuations in his book On Lisp if you are a Lisper.

Really, really great article.

March 08, 2006 5:01 PM  
Anonymous Anonymous said...

Continuations are more general than lambda's?

You can easily build lambdas with continuations, but not the other way around. Or am I wrong now?

Lambdas/functions have 2 jump steps:

f = function(a)
{
print(a);
return();
}

f(1);

The first step is from f(); to the start of the function, when the function gets called. The second step is the return from the function to the place where it was called.

Now the same example using continuations (somewhat Io style, a continuations based programming language):

f = continuation(a, return)
{
print(a);
return();
}

f(1, mark());

The continuation has two parameters here: the value to be printed, and the place to return to. The place to return to is created by mark. This value is stored in the parameter "return" of the continuation. We call that continuation: return();

So what happens if we don't call return?

f = continuation(a, return)
{
print(a);
}

f(1, mark());

Then the execution terminates. There is no continuation to continue with.

So actually, continuations are more general that lambdas.

March 08, 2006 6:23 PM  
Anonymous Anonymous said...

In an environment that supports threads, how is this different than threads? the ability to return something?

March 08, 2006 7:38 PM  
Anonymous Levi said...

lambdas are more fundamental than continuations. Any program can be transformed to what is called 'continuation-passing style', where the point execution should continue at next is always explicitly passed as an argument.

If you transformed a program in a language that doesn't support first-class continuations, such as C, into continuation-passing style, you would essentially be passing the function return address explicitly as a parameter to every function call, and the end of every function would be calling that return address with the value to return.

This transformation makes the continuation explicit, and easily understood, but the programs themselves become much harder to follow. So, languages like Ruby and Scheme give you access to the implicit continuation that lies under the covers, so to speak, so you get the ability to do things with it aside from the standard return from a function call, but you also get the readability benefits of having your standard continuation be implicit.

Guy Steele wrote about this in his paper entitled: "Debunking the 'Expensive Procedure Call' Myth, or, Procedure Call Implementations Considered Harmful, or, Lambda: The Ultimate GOTO", which you can find at http://library.readscheme.org/page1.html

Another correction I'd like to make is this; the continuation does not, in fact, contain a record of the history of the computation. It seems like it does, because invoking a continuation 'rewinds' the program to a past state, but it only remembers the state left at that point needed to finish the computation. Much of the history of the execution may have been discarded at that point; only the frames left on the stack (which contain the rest of the computation to perform) are retained.

If that's unclear, Dave Herman said it better at http://calculist.blogspot.com/2006/03/call-stack-is-not-history.html/

Anyway, thanks for the intro to continuations! They're nifty, and helping more people understand them is definitely a laudable goal. :)

March 08, 2006 9:39 PM  
Blogger Joe Berenguer said...

I just came across your blog and wanted to
drop you a note telling you, Friend, how impressed I was with it.
I give you my best wishes for your future endeavors.
If you have a moment, please visit my site:
credit center
It covers credit center related contents.
All the best!

March 11, 2006 4:25 AM  
Blogger Joe Berenguer said...

Hi Blogger!I like your blog! Keep up the
good work, you are providing a great resource on the Internet here!
If you have a moment, please take a look at my site:
credit center
It pretty much covers credit center related issues.
Best regards!

March 11, 2006 4:39 AM  
Anonymous superq said...

Thanks for the introduction.

The word 'continuation' has already got an entry in Wikipedia: http://en.wikipedia.org/wiki/Continuation

Maybe you can add a link to your blog entry in the wiki page.

March 13, 2006 3:06 AM  
Blogger Paul88888 said...

A lot of interest for your blog and a great deal of discussion. Great sites to surf home based business, domain name, domain reseller, au domain, free website, online business, home based business, electric scooter, xbox360!

March 15, 2006 3:14 AM  
Anonymous Anonymous said...

As for Monads, some Ruby folk are dabbling with these - check out

Monads, Ruby and OO
http://cwilliams.textdriven.com/articles/2005/11/07/monads-ruby-and-oo

for a nice and quite readable expose...

March 28, 2006 7:44 AM  
Blogger Scott A. Edwards said...

As a special token of my appreciation for all your kind help and the wonderful business you have sent my way---I want to give you a free gift.
It is called the "$25000.00 Idea". It will help you in all your endeavors.
Click here: FREE GIFT

April 05, 2006 10:23 PM  
Anonymous Scott Arthur Edwards said...

NOW, check this out for FREE...

There is a new, fully automated traffic-generation system that can send 1000's of targeted prospects to your website, for FREE! It only takes 5 minutes to set up to set your FREE account!

To find out more visit: homebusiness site. It successfully exposes FREE information covering Traffic and homebusiness related stuff.

April 06, 2006 12:07 AM  
Anonymous Anonymous said...

web design company - I had a nice read on this site. I will return again with more comments

April 11, 2006 5:33 PM  
Anonymous Anonymous said...

Such interesting and informative comments on your site.

If you require some best web design company info come to my site at http://www.small-business-web-design.ssr.be

April 11, 2006 8:06 PM  
Blogger Scott A. Edwards said...

Hi my friends! I'm writing to you because I just came across a business that I think has great potential. It lets you save money on almost everything. Make money from almost everything, Including home loans- plus... help lower your taxes--best of all--it requires absolutely no investment. I thought you might be interested and like to check it out...

Here I have a how to start making money online site/blog. It successfully covers how to start making money online related stuff and almost everything else!

Come and check it out if you get time, Scott.

April 13, 2006 2:49 AM  
Blogger Scott A. Edwards said...

Here it is... FREE advertising, FREE download. No cost to you! Get your FREE download NOW! Make money and get FREE advertising! This is a great program for you to take advantage of... Check this out now for FREE!

To find out more visit: how to get rich online site. It successfully exposes FREE information covering traffic and how to get rich online related stuff. Don't forget, FREE, FREE, FREE!!!

April 13, 2006 4:02 AM  
Anonymous Scott Arthur Edwards said...

NOW, check this out for FREE...

There is a new, fully automated traffic-generation system that can send 1000's of targeted prospects to your website, for FREE! It only takes 5 minutes to set up to set your FREE account!

To find out more visit: internet secret to making money site. It successfully exposes FREE information covering Traffic and internet secret to making money related stuff.

April 13, 2006 4:39 AM  
Blogger Joe Berenguer said...

I was searching blogs,and I found your site.Please,
accept my congratulations for your excellent work!
If you have a moment, please visit my site:
domain names center
It pretty much covers domain names center related issues.
Have a good day!

May 05, 2006 7:56 PM  
Blogger James Baker said...

I just came across your blog and wanted to
drop you a note telling you, Friend, how impressed I was with it.
I give you my best wishes for your future endeavors.
If you have a moment, please visit my site:
domain names center
It covers domain names center related contents.
All the best!

May 09, 2006 10:31 AM  
Blogger Paul Adams said...

Hi Friend! You have a great blog over here!
Please accept my compliments and wishes for your happiness and success!
If you have a moment, please take a look at my site:
domain names center
It covers domain names center related subjects.
Have a great day!

May 19, 2006 7:25 AM  
Blogger Paul Adams said...

I just came across your blog and wanted to
drop you a note telling you, Friend, how impressed I was with it.
I give you my best wishes for your future endeavors.
If you have a moment, please visit my site:
domain names center
It covers domain names center related contents.
All the best!

May 19, 2006 4:13 PM  
Blogger James Baker said...

Hey Fellow, you have a great blog here! I have a web
site & blog about domain names center.
Yours is top-notch!
If you have a moment, please visit my site
domain names center
I wish you all the best!

May 25, 2006 7:56 AM  
Blogger Paul Adams said...

Hi Friend! You have a great blog over here!
Please accept my compliments and wishes for your happiness and success!
If you have a moment, please take a look at my site:
domain names center
It covers domain names center related subjects.
Have a great day!

May 25, 2006 2:00 PM  
Blogger Joe Berenguer said...

Hey Fellow, you have a great blog here! I have a web
site & blog about domain names center.
Yours is top-notch!
If you have a moment, please visit my site
domain names center
I wish you all the best!

May 25, 2006 8:21 PM  
Blogger James Baker said...

I was searching blogs,and I found your site.Please,
accept my congratulations for your excellent work!
If you have a moment, please visit my site:
domain names center
It pretty much covers domain names center related issues.
Have a good day!

May 26, 2006 5:44 AM  
Anonymous Temecula construction said...

Some people believe that to create is great but build is like changing the past forever... If you want to create a beautiful home Visit Temecula construction and you can see what a little change can create..

May 30, 2006 1:55 AM  
Anonymous Anonymous said...

Hi, Thank you for having this info on the web. I enjoyed your post. If you may have any interest in
debt consolidation
then I know where you may get your solution. For your comfort, I have enclosed the link, so if needed you can visit the site. Thanks again for your lovely blog. credit

June 04, 2006 3:44 PM  
Blogger Paul Adams said...

I just came across your blog and wanted to
drop you, Blogger, a note telling you how impressed I was with
the information you have posted here.
If you have a moment, please visit my site:
make money
It covers make money related contents.
I send you warm regards and wish you continued success.

June 14, 2006 3:27 PM  
Blogger Joe Berenguer said...

I just came across your blog and wanted to
drop you, Blogger, a note telling you how impressed I was with
the information you have posted here.
If you have a moment, please visit my site:
make money
It covers make money related contents.
I send you warm regards and wish you continued success.

June 14, 2006 9:55 PM  
Blogger Joe Berenguer said...

Congratulations Friend for your excellent blog on make money!Keep up the good work!
If you have a moment, please visit my site:
make money
I send you my warm regards and wish you continued success.
Have a nice day! :-)

June 15, 2006 4:24 AM  
Blogger Paul Adams said...

I was just searching blogs,and I found your site, Friend! I like it!
Please accept my compliments and wishes for your happiness and success.
If you have a moment, please take a look at my site:
make money
It pretty much covers make money related issues.
All the best!

June 15, 2006 9:35 AM  
Blogger Paul Adams said...

Hi Fellow! I was just searching blogs,and I found your site! I like it!
If you have a moment, please visit my site:
make money
It covers make money related contents.
All the best!

June 22, 2006 12:18 AM  
Blogger Paul Adams said...

Hi Friend! You have a great blog over here!
Please accept my compliments and wishes for your happiness and success!
If you have a moment, please take a look at my site:
domain names
It covers domain names related subjects.
Have a great day!

June 23, 2006 1:46 PM  
Anonymous Anonymous said...

Debt Help
Debt Consolidation can help you reduce your interest burden by charging an interest rate lower than the rate on your existing loans. Debt consolidation loan can also allow you to make small monthly payments by extending the loan period

June 24, 2006 6:00 AM  
Anonymous opportunity to make money online said...

A fantastic blog yours. Keep it up.
If you have a moment, please visit my opportunity to make money online site.
I send you warm regards and wish you continued success.

July 03, 2006 12:01 PM  
Anonymous online business from home said...

This is an excellent blog. Keep it going.You are providing
a great resource on the Internet here!
If you have a moment, please take a look at my online business from home site.
Have a great week!

July 05, 2006 2:54 PM  
Anonymous Anonymous said...

What If...Visit Our Web Site at http://buildhomes4u.com If You are Looking forr advice on build house.

July 08, 2006 8:00 AM  
Anonymous money making home business opportunity said...

Hey Fellow, you have a top-notch blog here!
If you have a moment, please have a look at my money making home business opportunity site.
Good luck!

July 08, 2006 8:20 PM  
Anonymous make money with your said...

Your blog I found to be very interesting!
I just came across your blog and wanted to
drop you a note telling you how impressed I was with
the information you have posted here.
I have a make money with your
site.
Come and check it out if you get time :-)
Best regards!

July 15, 2006 8:02 PM  
Anonymous make money working online said...

This is an excellent blog. Keep it going.You are providing
a great resource on the Internet here!
If you have a moment, please take a look at my make money working online site.
Have a great week!

July 16, 2006 12:29 PM  
Anonymous make money with no experience said...

This is an excellent blog. Keep it going.You are providing
a great resource on the Internet here!
If you have a moment, please take a look at my make money with no experience site.
Have a great week!

July 18, 2006 12:06 PM  
Anonymous make money using web said...

Hey, you have a great blog here! I'm definitely going to bookmark you!
I have a make money using web site.
Come and check it out if you get time :-)
Greetings.

July 21, 2006 10:27 AM  
Anonymous make money using said...

I was searching blogs,and I found yours.Please,
accept my congratulations for your excellent work!
If you have a moment, please visit my make money using site.
Have a good day!

July 22, 2006 2:10 PM  
Anonymous make money top ways said...

Your blog I found to be very interesting!
I just came across your blog and wanted to
drop you a note telling you how impressed I was with
the information you have posted here.
I have a make money top ways
site.
Come and check it out if you get time :-)
Best regards!

August 08, 2006 10:23 PM  
Anonymous .m3u internet address said...

I am here because of search results for blogs with a related topic to mine.
Please,accept my congratulations for your excellent work!
I have a .m3u internet address site.
Come and check it out if you get time :-)
Best regards!

August 10, 2006 8:49 PM  
Anonymous .m3u internet address said...

A fantastic blog yours. Keep it up.
If you have a moment, please visit my .m3u internet address site.
I send you warm regards and wish you continued success.

August 11, 2006 6:30 AM  
Anonymous .in domain names said...

Your blog I found to be very interesting!
I just came across your blog and wanted to
drop you a note telling you how impressed I was with
the information you have posted here.
I have a .in domain names
site.
Come and check it out if you get time :-)
Best regards!

August 11, 2006 2:28 PM  
Anonymous $3 domain names said...

Hello Friend! I just came across your blog and wanted to
drop you a note telling you how impressed I was with
the information you have posted here.
Keep up the great work, you are providing a great resource on the Internet here!
If you have a moment, please make a visit to my $3 domain names site.
Good luck in your endeavors!

August 11, 2006 6:48 PM  
Anonymous Anonymous said...

Debt
Debt can help you reduce your interest burden by charging an interest rate lower than the rate on your existing loans. Debt consolidation loan can also allow you to make small monthly payments by extending the loan period
http://www.debt-consolidation.com

August 11, 2006 10:49 PM  
Blogger Meg Taylor said...

A fantastic blog yours. Keep it up.
If you have a moment, please visit my about domain names site.
I send you warm regards and wish you continued success.

August 15, 2006 10:06 AM  
Blogger search engine secrets said...

I’ve use up all my search engine sick days, so I’m calling in dead.
search engine ranking

August 17, 2006 9:11 AM  
Blogger Emini Day Trader said...

Great blog. Nice job you've done here.

Sincerely,
Daytrader
day trading stock pick
http://www.daytradingcourse.com

August 23, 2006 3:25 PM  
Blogger Emini Day Trader said...

Nice blog. Keep up the good work.

Regards,
Emini Daytrader
tickquest neoticker
http://www.daytradingcourse.com

August 23, 2006 7:24 PM  
Anonymous dan said...

great post

August 24, 2006 10:15 PM  
Anonymous Scott Arthur Edwards said...

Check this out for FREE...

This opportunity says:

"Your Ad" Will Be Instantly Displayed on Thousands of Websites and Read By Over 10 Million People Per Week For FREE, and It Only Takes 60 Seconds To Get Started!

To find out more visit: network marketing site. It successfully exposes FREE information covering Traffic and network marketing related stuff.

August 26, 2006 9:47 PM  
Blogger TradingCourses said...

A good read. Thaks for all the good info.

Regards,
Mini-DOW Futures Day Trader
intuitive day trading
http://www.daytradingcourse.com

September 01, 2006 4:14 PM  
Anonymous Anonymous said...

I like your blog page with all the unique topics you talk about.I will surely bookmark this blog for future reference.Keep the Great Work you are doing on this blog going.

Since last month it seems a little wierd when you type a particular keyword phrase in you get a totally different return for your search.Basically I was looking for free home based business and your blog popped up.So this is really cool for your blog when you recieve free search engine traffic.Me personally I would love this type of unique visitors.So if you ever around my neck of the woods and need more free traffic exposure for your web blogs or web site.Please remember this link for all your free traffic needs.
http://www.home-business-offer.com/

September 07, 2006 1:30 PM  
Anonymous Online Degree said...

One of the questions that are now most keenly agitating the minds of the investing public and of financiers who cater for its wants, and also of employers and organisers of industry who are trying to see their way into after-the-war conditions, is that of the supply of capital. Don't waste the capital of your mind. It is now easier than ever to study for an online college degree. You can get more information at the online college degree course website

September 19, 2006 2:04 AM  

Post a Comment

<< Home