August 05, 2009
Reply to bearophile,

> Jarrett Billingsley:
[...]
> ------------------
> Lars T. Kyllingstad:

Replying to two different post in the same post significantly reduces the changes that the second poster will see your reply.


August 06, 2009
Tue, 04 Aug 2009 19:57:19 -0400, bearophile wrote:

> D2 is now able to execute math functions (sin, cos, sqrt, etc) at compile time.
> 
> [snip]
> 
> But similar D2 program produces, with DMD v.2.031:
> test.d(12): Error: non-constant expression (V3(1,2,3)).norm()
> 
> // D2 code
> import std.math, std.c.stdio;
> 
> struct V3 {
>     double x, y, z;
>     V3 opMul(double d) { return V3(x * d, y * d, z * d); }
>     V3 norm() { return this * (1.0 / sqrt(this.magsqr())); }
>     double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; }
>     double magsqr() { return dot(this); }
> }
> 
> const V3 v = V3(1.0, 2.0, 3.0).norm();
> 
> int main() {
>     printf("%f %f %f\n", v.x, v.y, v.z);
>     return 0;
> }

You can't call methods at compile time, and you can't pass temporary by reference.  This works:

import std.math, std.c.stdio;

struct V3 {
    double x, y, z;
    V3 opMul(double d) { return V3(x * d, y * d, z * d); }
    V3 norm() { return this * (1.0 / sqrt(this.magsqr())); }
    double dot(ref V3 v) { return x * v.x+y * v.y + z * v.z; }
    double magsqr() { return dot(this); }
}

V3 mul(ref V3 v, double d) {
    return V3(v.x*d, v.y*d, v.z*d);
}

V3 norm(V3 v) {
    return mul(v, 1.0 / sqrt(magsqr(v)));
}

double dot(ref V3 a, ref V3 b) {
    return a.x*b.x + a.y*b.y + a.z*b.z;
}

double magsqr(ref V3 v) {
    return dot(v, v);
}

const V3 v = norm(V3(1.0, 2.0, 3.0));

int main() {
    printf("%f %f %f\n", v.x, v.y, v.z);
    return 0;
}
August 06, 2009
Jarrett Billingsley wrote:
> *On Wed, Aug 5, 2009 at 7:23 AM, Ary Borenszweig<ary@esperanto.org.ar> wrote:
>> bearophile escribió:
>>> Jarrett Billingsley:
>>>> C++ has static initialization that occurs before main() too.  It's just..
>>>> hidden.<
>>> I see. I have to learn more about C++. Thank you.
>>>
>>> ------------------
>>> Lars T. Kyllingstad:
>>>
>>>> This is good news! The restrictions you are referring to, are they any of
>>>> the ones documented here:
>>>> http://www.digitalmars.com/d/2.0/function.html#interpretation <
>>> That list has a point regarding what I was trying to do:
>>>> 4. the function may not be a non-static member, i.e. it may not have a
>>>> this pointer<
>>> It's true regarding stucts used as values too, and not just classes...
>> It would be nice if the compiler could say so: "I can't evaluate it because
>> you are using a this pointer". With other words, but much more useful than
>> "non-constant expression".
> 
> Yes, oh my God, this is the main reason I don't use CTFE: debugging
> them is virtually impossible, and the compiler does nothing to help
> there.

Nice error messages for CTFE assignment statements are in the next release. That's probably 50% of the instances of "non-constant expression".
August 21, 2009
Lars T. Kyllingstad wrote:
> Don wrote:
>> Jarrett Billingsley wrote:
>>> I don't think you can call struct methods at compile-time.  Kind of
>>> lame, I know.  Try making norm a free function.
>>>
>>>> Can the D2 compiler modified/improved to allow this?
>>>
>>> It sure would be nice.
>>
>> In fact the D1 compiler should support it too.
>> BTW a few of the restrictions on CTFE will be removed in the next release.
> 
> 
> This is good news! The restrictions you are referring to, are they any of the ones documented here:
> 
>     http://www.digitalmars.com/d/2.0/function.html#interpretation
> 
> or are they "undocumented" restrictions, i.e. bugs?
> 
> -Lars

Both. Using CTFE will be a completely different experience after the next release.
August 21, 2009
Don wrote:
> Lars T. Kyllingstad wrote:
>> Don wrote:
>>> Jarrett Billingsley wrote:
>>>> I don't think you can call struct methods at compile-time.  Kind of
>>>> lame, I know.  Try making norm a free function.
>>>>
>>>>> Can the D2 compiler modified/improved to allow this?
>>>>
>>>> It sure would be nice.
>>>
>>> In fact the D1 compiler should support it too.
>>> BTW a few of the restrictions on CTFE will be removed in the next release.
>>
>>
>> This is good news! The restrictions you are referring to, are they any of the ones documented here:
>>
>>     http://www.digitalmars.com/d/2.0/function.html#interpretation
>>
>> or are they "undocumented" restrictions, i.e. bugs?
>>
>> -Lars
> 
> Both. Using CTFE will be a completely different experience after the next release.


I can't wait. :)

-Lars
August 22, 2009
Don:
>Using CTFE will be a completely different experience after the next release.<

What kind of limits do you want to lift? :-)

I think now LDC uses a compile-time garbage collector (beside the second one in the D runtime and the third one used by LLVM), so using CTFE&templates is better already with LDC.

I like to use CTFE is to create 1D arrays at compile-time. This is a small test, it has the problem of being "fragile": if you change this code just a bit, it doesn't compile anymore. The other problem (with DMD) is that it uses a lot of RAM, even for modern standards of memory.

import std.stdio: writefln;

bool isPrime(int n) {
    if (n < 2)
        return false;
    for (int i = 2; i < n; i++)
        if (n % i == 0)
            return false;
    return true;
}

int[] genPrimes(int n) {
    int[] result;
    for (; n > 1; --n)
        if (isPrime(n))
            result = n ~ result;
    return result;
}

static const auto primes = cast(int[900])genPrimes(7000);

void main() {
    writefln(primes);
}


Currently to do such things I use templat: http://www.fantascienza.net/leonardo/so/templat.html

With code like this, that's fast and uses small resources, but forces to use two languages:

import std.stdio: writefln;

{{
import textwrap

def find_primes(n):
    if n < 2:
        return []
    primes = [2]
    for i in xrange(2, n+1):
        for j in primes:
            if i % j == 0:
                break
        else:
            primes.append(i)
    return primes

p = find_primes(7000)
out = "const int primes[%d] = %s;" % (len(p), p)
print "\n".join(textwrap.wrap(out, 80, subsequent_indent=" "*4))
}}

void main() {
    writefln(primes);
}

Bye,
bearophile
August 24, 2009
bearophile wrote:
> Don:
>> Using CTFE will be a completely different experience after the next release.<
> 
> What kind of limits do you want to lift? :-)

The unpredictability, mainly. Currently, it's really easy to write code that you'd expect would work in CTFE, but doesn't. Sometimes because of bugs, sometimes because of the official restrictions in the list, which are more restrictive than you'd expect.

All kinds of crazy stuff is now working in my patched version of DMD.

There's no improvements to the memory situation, though. That requires significant changes to several parts of the compiler. So the two most important CTFE bugs (1330 and 1382) won't be fixed in this release.
1 2
Next ›   Last »