Posted on 12/31/2007 6:53:13 PM by Justin Etheredge
I was working on my Linq To SimpleDB provider today and I received this error message:
"Modifying a 'operator' which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled."
Talk about feature interaction! So, if we are in an operator, that has a lambda expression, and we are debugging, with "Edit and Continue" enabled, then this error will appear. My head just hurts thinking about all of the code that must be in there to catch these little edge cases like this. What about if my method starts with "A" and I am drinking a diet soda? Do they have checks in there for that?
It really makes you wonder how long can we continue like this. I wrote a blog post recently which touched on the issue of feature laden software and how as we add more and more features to software we are heading down a road where the interactions are going to become so complex that we will have an almost impossible time managing them. There are certain companies out there that are going the simple software route, and a few are quite successful with it. But will this tactic work for all software? Probably not. Will we need a fundamental shift in how we design software in order to deal with this growing complexity? I don't know. What I do know is that something will have to change. Software teams cannot keep expanding in order to try to keep up with software's growing complexity.
Also, with the shadow of massive parallelism looming on the horizon, things could get more complicated really quickly. If we can barely deal with the complexity that we have now, how are we going to move forward?
Posted on 12/31/2007 3:45:56 AM by Justin Etheredge
I am currently in the middle of writing a Linq to Amazon SimpleDB provider since I have yet to really dive deep into Linq and I wanted to figure out exactly how it all works. I have already made some decent headway into the query part of it (I have yet to deal with inserts, updates, or deletes) but I am running into some issues with the way that Amazon SimpleDB handles numbers. According to Amazon all numbers must be zero padded to the length of the maximum number size that you will use. So, if I wanted to use decimals then I would need to pad to 29 digits!
The issue here is that Amazon treats all data as text, so in order to get proper comparisons we have to pad it all out. So, if I compare '6' and '12' then '6' will come out as larger since '6' is larger than '1'. But if I pad '6' out as '06' then '12' will come out larger since we will now compare '0' to '1' and '12' will win out.
On top of that, you also shouldn't use negative numbers with Amazon SimpleDB since this will also keep you from doing proper comparisons. So, if you are going to use negative numbers, then you need to add the opposite of the smallest negative number that you are going to use. So, if the smallest number I am going to use is '-500', then I can add '500' to this and '-500' becomes '0' and '0' becomes '500'. This way all of our comparisons in the database still come out correct, and when we pull the data out of the db we just subtract this number from our value and we end up with our proper number. A bit of a pain if you ask me, but still doable nonetheless.
The problem I am running into is that I don't know how large or small any of these fields are going to be. And since each domain (basically a table) in SimpleDB can hold any number of attributes and different items can have different attributes, then we don't know what attributes are available for a domain. If we don't know what attributes are available then we can't really ask the user for values for them. Well, we can get values for them, but we have no real way to check them. This would have to be configured in some way for each application, and if you got these values wrong, then you could really shoot yourself in the foot later on if you needed a larger (or smaller) number.
So, what would you do? I am leaning toward going the simple route and just making every number in the db large enough to hold the maximum and minimum Decimal type value. I don't really know what the performance implications will be on the Amazon side, but I will see what I can find out. Most likely I will just need to run some tests and see if I can get some numbers on this.
Also, SimpleDB is still in limited beta, and so I am writing the provider using the query specs provided by Amazon. I also have access to the WSDL for the web service so I can see what the calls are going to look like. I do not have an account to test any of this though, so if anyone out there knows someone who can get me hooked up with an account on SimpleDB please let me know!
Posted on 12/26/2007 1:04:26 PM by Justin Etheredge
In the previous post in this series we discussed currying and partial application with examples in two variables. We saw that with two variables partial application and currying look very similar. Currying just appears to have an extra step of creating the method that generates our partially applied methods, but this is actually somewhat deceptive. When going beyond two parameters we will start to see the differences in currying and partial application a little more clearly.
So, lets use a multiply method with a third parameter:
public static int Multiply(int a, int b, int c)
{
return a * b * c;
}
So, lets first look at an implementation of a Curry function with three arguments:
public static Func<TArg1, Func<TArg2, Func<TArg3, TResult>>>
Curry<TArg1, TArg2, TArg3, TResult>
(this Func<TArg1, TArg2, TArg3, TResult> func)
{
return argument1 => argument2 => argument3 =>
func(argument1, argument2, argument3);
}
You may already be seeing the differences here. With the currying method we are chaining these arguments together so that we build up new methods by passing in single arguments at a time. Here is how this would look when we used it:
Func<int, int, int, int> method = Multiply;
var curriedMultiply = method.Curry();
var multiplyByTwo = curriedMultiply(2);
var multiplyByTwoThenFive = multiplyByTwo(5);
var multiplyByTwoThenSix = multiplyByTwo(6);
int result1 = multiplyByTwoThenFive(10);
int result2 = multiplyByTwoThenSix(10);
You see what we are doing here? We have curried the method, then we build up our methods by calling our curried methods over and over but always with only one parameter! You can shorten it with a bit of somewhat confusing syntax:
Func<int, int, int, int> method = Multiply;
var curriedMultiply = method.Curry();
var multiplyByTwoThenFive = curriedMultiply(2)(5);
var multiplyByTwoThenSix = curriedMultiply(2)(6);
int result1 = multiplyByTwoThenFive(10);
int result2 = multiplyByTwoThenSix(10);
You may or may not find it hard to read, but we are just skipping the intermediate step by passing two parameters with the second one being passed to the return type. In this instance though you are bypassing the advantages of currying, which is the ability to slowly build up methods, and you might as well be using partial application. You'll see why in a second.
So, before we look at an implementation of a three parameter "PartiallyApply" method let me just say that there is more than one. When you think about it that makes sense. With two parameters "partially applied" can mean only one thing, that we have passed in one parameter. Otherwise it would be "unapplied" or "fully applied". :-) With three parameters though we can have one parameter pre-applied or two. So, here is our three parameter "PartiallyApply" methods:
public static Func<TArg2, TArg3, TResult>
PartiallyApply<TArg1, TArg2, TArg3, TResult>
(this Func<TArg1, TArg2, TArg3, TResult> func, TArg1 argument1)
{
return (argument2, argument3) =>
func(argument1, argument2, argument3);
}
public static Func<TArg3, TResult>
PartiallyApply<TArg1, TArg2, TArg3, TResult>
(this Func<TArg1, TArg2, TArg3, TResult> func,
TArg1 argument1, TArg2 argument2)
{
return argument3 => func(argument1, argument2, argument3);
}
There you have it, a three parameter "PartiallyApply" method that has been partially applied in two different ways. Here you can see how we use them:
Func<int, int, int, int> method = Multiply;
var needTwoMoreParams = method.PartiallyApply(2);
var needOneMoreParam = method.PartiallyApply(2, 5);
int result1 = needTwoMoreParams(5, 3);
int result2 = needOneMoreParam(3);
So easy! So, now you see how currying and partial application are actually quite different concepts. Currying is useful if you need to slowly build up your function over several different iterations while partial application is useful if you just need to set a few parameters on a function and the rest will be filled in later. While you will probably be able to find a few places where partial application may be useful, currying will probably be a bit harder to find a real world use for. If you have any good examples of using these in the real world, please leave a comment!
Posted on 12/26/2007 2:44:50 AM by Justin Etheredge
I put up some generic CPM ads on my pages to make a few pennies to help pay for bandwidth. But I loaded up my page and I believe that one of the ads made noise without me doing anything. Ooooooooooooh, that is bad. It may have been another tab in my browser, but if one of my ads makes a noise without you doing anything please put a comment on this post and I will remove them immediately. Man nothing is worse than ads that make noise. If they are making noise by themselves, then I sincerely apologize to everyone that this happened to.