March 23, 2007
Daniel Keep wrote:
> 
> [...]
> Andrei posts at 4:32 PM, you post at 5:48 PM, Andrei replies at 5:02 PM,
> and then you reply to him at 6:46 PM.
> 
> It's currently 6:04 PM :)

Then I'm sure it's because I'm still running W2K *gasp*, which is an officially unsupported OS.  I still get "security" patches, but nothing as luxurious as a DST patch.  I could patch the registry myself, but why bother when the problem will fix itself in a week? ;>

Dave
March 23, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Kevin Bealer wrote:
>> Dan wrote:
>> ...
>>> What should then happen is this:  The compiler should recognize that we
>>  > only accept values such that x > y.  Knowing that, it should then verify
>>> that in all cases where this function can be called, that the input to the
>>  > function must have this condition.  In cases where this *can* fail, it
>>> should raise an error - such as variables that are affected by user input
>>  > or outside parameters that aren't already bounds checked or adjusted...
>>>
>>> Theoretically, one could take any given int (between int.min and int.max)
>>  > and adjust it such that x > y will be true for all cases.  This can be
>>  > proven and verified by a proof by induction.
>>>
>>> If you don't isolate the in/out tests from the body, a proof by induction
>>> couldn't know what needs to be proved to prove the code safe.
>>
>> I think there are very few cases where this kind of induction could reasonably be done, unless x and y are literals.  I suspect that in most cases where the compiler had enough info to do this kind of induction checking, the code for the function could nearly as easily be "constant folded" and optimized away entirely.  Prove me wrong, but I suspect that this kind of induction is too hard (and in the cases where it works, too slow) to be practical.
>>
>> If x and y are literals, though, you can do something like this now:
>>
>> Original source:
>>
>> int foo(int x, int y, int z)
>> {
>>     assert( x > y ); // runtime
>> ...
>> }
>>
>> int z = foo(10, 20, 30);
>>
>> Checking at compile time:
>>
>> int foo(int x, int y)(int z)
>> {
>>     static assert( x > y ); // compile time
>> ...
>> }
>>
>> int z = foo!(10, 20)(30);
>>
>> It's a very simple transformation --- take any compile-time known values and make them template parameters.  In this case, the calling syntax even looks nearly the same!
> 
> The need to cater for cases with partial statically-available
> information is seriously taken into consideration. The general scenario
> is called "partial evaluation": you call a function with a few
> statically-known values and a few runtime values. The current
> compile-time evaluation mechanism can't help with that. So a considered
> addition to D is to accommodate static parameters (pushed by yours truly
> and using a syntax suggested by Dave Held):
> 
> int foo(int x, int y, int z);
> int foo(static int x, int y, int z); // x is known during compilation
> int foo(int x, static int y, int z); // y is known during compilation
> int foo(static int x, static int y, int z); // x and y are... you know

I pushed for essentially the same thing, about six months ago:

http://lists.puremagic.com/pipermail/digitalmars-d/2006-October/008987.html

and the syntax I proposed was:

int foo(template int x, template int y, int z)
{
   static if (is(x: const) && is(y: const)) { ... }
   else return simple_foo(x);
}

I think the concept (in whichever form) is a killer feature; the potential for optimisation is incredible.
March 23, 2007
David B. Held wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> David B. Held wrote:
>>> Andrei Alexandrescu (See Website For Email) wrote:
>>>> [...]
>>>> int foo(int x, int y, int z);
>>>> int foo(static int x, int y, int z); // x is known during compilation
>>>> int foo(int x, static int y, int z); // y is known during compilation
>>>> int foo(static int x, static int y, int z); // x and y are... you know
>>>> [...]
>>>> final a = to!(int)(readln), b = to!(int)(readln);
>>>> foo(a, b, b);  // firsts overload
>>>> foo(1, a + b, b); // 2nd
>>>> foo(a + b, a - b, b);  // 3rd
>>>> foo(42, 7, b); // 4th
>>>> [...]
>>>
>>> Great sir, could you impart upon us mere mortals the wisdom by which you are able to ascertain, at compile time, the difference between two values known only at runtime (a la the "3rd" overload)?  We are in great need of such Oracle-like behavior.
>>
>> I also notice you're still posting from the future. You must make good money daytrading. Future postulae commotus est. :o)
> 
> Hmm...and I'm equally sure you're posting from the past.  My watch currently says 11:45 PM, my last post shows 10:48 PM (which I think is accurate), and your follow-up shows 10:02 PM (which was just a few impossibly short moments ago, by my reckoning).  The only way I can explain this discrepancy is that we have an extreme relative velocity (perhaps on the order of 0.99999998c?).  The other possibility is that your OS is not patched for DST.

It's a timezone thing. What's your OS timezone? Your posts show -0800 time shift, while other people's in the same timezone show -0700. I know you have nostalgia for your old place, but it's about time you move to Seattle entirely :o).

Andrei
March 23, 2007
> >>> Andrei Alexandrescu (See Website For Email) wrote:
> >>>> [...]
> >>>> int foo(int x, int y, int z);
> >>>> int foo(static int x, int y, int z); // x is known during compilation
> >>>> int foo(int x, static int y, int z); // y is known during compilation
> >>>> int foo(static int x, static int y, int z); // x and y are... you know
> >>>> [...]
> >>>> final a = to!(int)(readln), b = to!(int)(readln);
> >>>> foo(a, b, b);  // firsts overload
> >>>> foo(1, a + b, b); // 2nd
> >>>> foo(a + b, a - b, b);  // 3rd
> >>>> foo(42, 7, b); // 4th
> >>>> [...]
> >>>
> >>> Great sir, could you impart upon us mere mortals the wisdom by which you are able to ascertain, at compile time, the difference between two values known only at runtime (a la the "3rd" overload)?  We are in great need of such Oracle-like behavior.
> >>
> >> I also notice you're still posting from the future. You must make good money daytrading. Future postulae commotus est. :o)

Dear sirs, I have such wisdom.

Your example is absolutely packed with bugs.  First, you are reading an entire line into an int.  May I pass the pi?

I can tell you that the range of a uint is 0..4294967295. I also say with cofidence that int is -2147483648..2147483647.  Knowing that, good sirs, you are most likely unwittingly causing a bug by calling foo(a+b) where a and b are ints.

I say most likely because you may intend for the program to overflow if(a+b > int.max)

I can also say that if you add any two unbound integers and attempt to store them in another integer, you are likewise creating an opportunity for a bug.

So... let's bound them shall we?

void moveTo(Item it, int x, int y)
in {
   assert(x > 0);
   assert(y > 0 && y < SCREEN.MAXHEIGHT);
}
body {
  it.left = x;
  it.top = y;
}

... elsewhere...

void setLayout(int a, ubyte b)
{
   moveTo(a-350,b);
}

We now know that in this case, a had better be >= 350, or our assert ought to fail.  In fact, it's a bug, because it *could* be < 350.  We also know the upper bound is no longer 2147483647, but 2147483297 for x.

For y, we know that the possible bounds are in fact only 0-255, while the function will accept anything between 0 and SCREEN.MAXHEIGHT, whatever arbitrary number that ought to be.

So we do know something about it, and we can proveably demonstrate that the program will work for all cases, or it won't with variables being used.

Welcome to discrete mathematics 101.

March 23, 2007
Dan wrote:
>>>>> Andrei Alexandrescu (See Website For Email) wrote:
>>>>>> [...]
>>>>>> int foo(int x, int y, int z);
>>>>>> int foo(static int x, int y, int z); // x is known during compilation
>>>>>> int foo(int x, static int y, int z); // y is known during compilation
>>>>>> int foo(static int x, static int y, int z); // x and y are... you know
>>>>>> [...]
>>>>>> final a = to!(int)(readln), b = to!(int)(readln);
>>>>>> foo(a, b, b);  // firsts overload
>>>>>> foo(1, a + b, b); // 2nd
>>>>>> foo(a + b, a - b, b);  // 3rd
>>>>>> foo(42, 7, b); // 4th
>>>>>> [...]
>>>>> Great sir, could you impart upon us mere mortals the wisdom by which you are able to ascertain, at compile time, the difference between two values known only at runtime (a la the "3rd" overload)?  We are in great need of such Oracle-like behavior.
>>>> I also notice you're still posting from the future. You must make good money daytrading. Future postulae commotus est. :o)
> 
> Dear sirs, I have such wisdom.  
> 
> Your example is absolutely packed with bugs.  First, you are reading an entire line into an int.  May I pass the pi?

The point of using readln was to clarify that the symbols were dynamically bound.

Andrei
1 2 3 4 5 6
Next ›   Last »