Re: D equivalent of C++ reinterpret cast?

2010-09-20 Thread Kagamin
Juanjo Alvarez Wrote:

> Unions are not allowed in SafeD, so I guess they are considered 
> unsafe in D.

They're safer in this particular case. Note how original poster forgot about 
taking and address.


Re: Copying a delegate

2010-09-20 Thread Kagamin
Jonathan M Davis Wrote:

> delegate by definition has context which is not going to be copied. So, any 
> functon pointer or delegate that you have must refer to a function which is 
> logically pure, otherwise any algorithm that relies on save is not going to 
> work 
> correctly.

If phobos causes subtle bugs, it's a bug worth filing.


Re: Copying a delegate

2010-09-20 Thread Jonathan M Davis
On Monday 20 September 2010 01:08:25 Kagamin wrote:
> Jonathan M Davis Wrote:
> > delegate by definition has context which is not going to be copied. So,
> > any functon pointer or delegate that you have must refer to a function
> > which is logically pure, otherwise any algorithm that relies on save is
> > not going to work correctly.
> 
> If phobos causes subtle bugs, it's a bug worth filing.

Except that it's not really phobos' fault. The problem is that once part of the 
state of a struct or class is a delegate, you *can't* copy it. As far as I 
know, 
there is no way in the language to do it. A forward range's save property is 
supposed to give you a copy of the range which copies the state specific to 
iterating the range such that you can iterate the copy to your heart's content 
without affecting the original's ability to iterate. But if a delegate is part 
of 
the iteration state of a range, and that delegate isn't logically pure, the 
copy 
is going to use that delegate and alter the state of the original range, 
because 
they share that delegate. I don't think that there's anything Phobos can do 
about it. It's a limitation of delegates.

- Jonathan M Davis


Re: Purity with references and pointers

2010-09-20 Thread Don

Simen kjaeraas wrote:

Jonathan M Davis  wrote:


Except that since when is anything implictly convertable to immutable?
Implicitly converted to const, yes. That happens often enough, but 
immutable?


Anything that does not contain pointers or references to non-immutable
data is implicitly convertible to immutable, if passed by value.


And you definitely don't have to use immutable references with pure 
functions.


That sounds like a bug. Unless you mean things like immutable(char)[],
which is implicitly convertible to immutable, according to the above rules.


I have gotten some const-related errors when using pure on member 
functions, so
I get the impression that using pure on a member function implicitly 
makes it

const, but I'm not sure if that's enough.


The 'this' pointer is also a parameter to a function, so also needs to
be immutable.


But that's impossible, except for trivial, useless classes.


Re: Copying a delegate

2010-09-20 Thread Kagamin
Jonathan M Davis Wrote:

> I don't think that there's anything Phobos can do 
> about it. It's a limitation of delegates.

If the range doesn't support copying, it shouldn't pretend to support it, and 
algorithms relying on copy won't compile.


Re: Error: cannot implicitly convert expression (this) of type const(S) to S

2010-09-20 Thread Steven Schveighoffer
On Sat, 18 Sep 2010 17:20:31 -0400, Jonathan M Davis   
wrote:



On Saturday 18 September 2010 09:58:15 Steven Schveighoffer wrote:


In reality, you cannot make save const, unless you want to do a deep  
copy

(but I recommend against that, save should be a quick operation).


Well, I was trying to make a deep copy (that's what it does if it  
doesn't have
an array in it anyway). I suppose whether it really needs to be const or  
not
depends on what you're trying to do with it. I'm definitely trying to  
create a
range here, and if save() is supposed to make a copy of the range,  
whether that
needs to be a shallow copy or a deep copy depends on what the  
std.algorithm stuff
does with it. When I think copy, I usually think deep copy, but that's  
not
necessarily the case. I will have to enquire as to the intent of save().  
For
value types, shallow copy and deep copy are the same, so it's not an  
issue. But
for class ranges or struct ranges with references, it does become an  
issue.


You don't want a deep copy of a range.  All you want to copy is the  
iteration state, not the data.


save is definitely supposed to be shallow.  I.e. you should copy the range  
itself, not what the range points to.


-Steve


Re: D equivalent of C++ reinterpret cast?

2010-09-20 Thread Steven Schveighoffer
On Sun, 19 Sep 2010 13:39:38 -0400, Bradley Mitchell  
 wrote:



Hello,

I'm trying to implement the Quake 3 fast inverse square root algorithm  
which
requires casting from int to float without modifying the stored bits. A  
C++
reinterpret cast seems to accomplish this just fine but so far I have  
had no
success in D after trying quite a few different things. Here is the C++  
I've

written that currently works:

#include 

float fastInvSqrt( float x )
{
const int INV_SQRT_N = 1597292357;
const float MULT = 1.000363245811462f;

float const mx = 0.5f * MULT * x;
int xi = *reinterpret_cast( &x );


Note the use of pointers and address above?


xi = INV_SQRT_N - (xi >> 1);
x = *reinterpret_cast( &xi );
return x * (1.5f * MULT - mx * x * x);
}

int main()
{
float a = fastInvSqrt( 9.0f );
std::cout << a << std::endl;
}

And here is my D code that doesn't work yet:

module test;

import std.stdio;

float fastInvSqrt( float x )
{
const int INV_SQRT_N = 1597292357;
const float MULT = 1.000363245811462f;

float mx = 0.5f * MULT * x;
int xi = cast(int)cast(void*)x;


You forgot that here...

int xi = *cast(int *)(&x);

rule of thumb -- if you want to do a reinterpret cast, you usually must  
take the address first.  The compiler never tries anything tricky on  
pointer casts.


-Steve


Re: Purity with references and pointers

2010-09-20 Thread Kagamin
Jonathan M Davis Wrote:

> If a pure function takes a reference/pointer, does that state that the result 
> of 
> the function will be the same on two calls to it if the reference/pointer 
> points 
> to the same data in both cases or if the data itself is unchanged?
> 
> If it's a matter of pointing to the same data, then that could be horribly 
> broken. That would mean that as long as I pased in the same reference, the 
> compiler could cache the result but that the actual result of the function 
> could 
> have and should have been different for each call because the object pointed 
> to 
> was altered.

You can search for bug report about purity of stdc string functions. Don 
proposed two flavors of purity. When you pass const data to pure function, the 
call effectively becomes impure.


Re: Where is module dstats.all for dflplot?

2010-09-20 Thread Lars T. Kyllingstad
On Sat, 18 Sep 2010 07:15:35 -0400, Sam Hu wrote:

> Greetings!
> 
> I want to have a try on dflplot.But I don't find module dstats.all which
> is used by dflplot.d,could anybody let me where it is?
> 
> Thank you.


Hi!

David Simcha (the dflplot author) has changed the name of the library to 
Plot2Kill, so if you're still using dflplot, it's an old version.  Check 
out the Plot2Kill project for the latest version:

  http://www.dsource.org/projects/plot2kill

As far as I know, dstats is not required to use Plot2Kill, it's only used 
for the demo/test application.  Anyway, if you need it, you can find it 
here:

  http://www.dsource.org/projects/dstats


-Lars


Re: Error: cannot implicitly convert expression (this) of type const(S) to S

2010-09-20 Thread Jonathan M Davis
On Monday, September 20, 2010 04:11:05 Steven Schveighoffer wrote:
> You don't want a deep copy of a range.  All you want to copy is the
> iteration state, not the data.
> 
> save is definitely supposed to be shallow.  I.e. you should copy the range
> itself, not what the range points to.

That makes sense, but whenever I see copy, I pretty much always think deep 
copy, 
though obviously a copy isn't always a deep copy or you wouldn't need the word 
deep.

- Jonathan M Davis


Re: Copying a delegate

2010-09-20 Thread Jonathan M Davis
On Monday, September 20, 2010 04:08:11 Kagamin wrote:
> Jonathan M Davis Wrote:
> > I don't think that there's anything Phobos can do
> > about it. It's a limitation of delegates.
> 
> If the range doesn't support copying, it shouldn't pretend to support it,
> and algorithms relying on copy won't compile.

Except that you don't know what is in a delegate, or it wouldn't be a delegate. 
Many delegates can be reused just fine and thus "copied" because they are 
logically pure. Others can't be. If you have a range based on a delegate, 
unless 
you know every single function that could be used as the delegate, you have no 
way of knowing whether the delegate is logically pure. And even then, you'd 
only 
know it because you knew what the functions did; the compiler couldn't enforce 
it.

So, you can have a range which properly supports copying as long as its 
delegate 
is logically pure, but you can't use the compiler to enforce that the delegate 
be logically pure. There's no way for Phobos to avoid the problem. The only way 
to completely avoid the problem is not to have ranges which are generated with 
delegates, but that would eliminate a lot of useful ranges.

- Jonathan M Davis


Re: Applying a tuple to a function (and more)

2010-09-20 Thread Philippe Sigaud
On Sun, Sep 19, 2010 at 18:33, Juanjo Alvarez  wrote:

> Philippe Sigaud wrote:
>
> > What languages are you used to? You seem to do quite well with genericity
> > :)
>
> What I've done profesionally and personally in the last year would be 90%
> Python, 5% Java and 5% C++. So yes, since Python is like a D with an
> uberauto and everything being runtime templates the real problem I have is
> with generic declarations :)
>

OK, that's why you're using tuples for everything :)
Python's tuples are cool. I think I *learnt* what tuples were while dabbling
in Python a few years ago. (Haskell's ones are great too).

Note that the 'real' D tuples are expression tuples (instantiated
typetuples). The "T..." thingies in templates, once instantiated with  T t;
They know their length, are indexable, slicable, iterable, etc. In a way
they are random-access range with a length, only with heterogeneous types.
But I don't think they were conceived as tuples in other languages, not at
first. I'd guess that, for Walter, they were just a natural
extension/cleaning for templates, based on C++. But they are like Python's
tuples! Except for one blatant limitation: they cannot be returned from a
function :(
But you can return a templated struct. So the basic idea is to wrap them in
Tuple(T...) to be able to return them. Then std.typecons.tuple does its best
to offer a interesting access to the underlying expression tuple. But it's
not a first-class citizen in D: you cannot iterate them nor slice them...
For now, because the situation has improved.

What many people coming from C++/Java do is putting their stuff in
structs/classes. They tend not to use tuples that much.



This is much better, no doubt. I've changued that part too (I'm really
> learning a lot with your posts, you should think about writing a book about
> D too).
>

What I should do is moving my a** and have some code reviewed for Phobos.
But it seems I can't find the time. When I've half an hour, I try to help
here instead :)




> Now I've two new roadblocks:
>
> Roadblock1:
>
> If the tuple is defined in the same file as the code expanding it (with the
> template function in another file), it works. But if I move the tuple
> definition to another file (urls.d) the compiler gives me the error:
>
> Error: Unions with overlapping fields are not yet supported in CTFE
> urls.d(9): Error: cannot evaluate tuple("^/home/$",& index,42,3.14) at
> compile time
> urls.d(9): Error: cannot evaluate tuple("^/home/$",& index,42,3.14) at
> compile time
>
> That is, this works:
>
> // file: bindselector.d
> import std.typecons;
> import views;
>
> void main() {
> // tuple defined here
> auto selector_data = tuple( "^/home/$", &(views.index!(int, double)),
> 42, 3.14 );
> auto sel_regex_var  = selector_data.field[0];
> auto sel_view_var = selector_data.field[1];
> sel_view_var(sel_regex_var, selector_data.expand[2..$]);
> }
>
>
> But moving the declaration of "selector_data" to a file urls.d and then
> importing that file from bindselector.d gives me that error... bug?
>

What do you mean, you moved the declaration of selector_data ? You declared
it outside main() in another module? I don't know why, I never declare date
outside functions/objects.

Maybe if you declare it in the 'root scope' of the module (I don't know how
to call that: the basic scope of a module, the one where the module name;
is), it's initialized at compile time. And at compile time, I'm not sure
things like addresses &(...) have a sense.

Did you try to make selector_data a function?

auto selector_data() { return tuple("^/home/$", &(views.index!(int,
double)),42, 3.14 );}



> Roadblock2:
> The next step is to define multiple tuples in urls.d inside some iterable
> data structure, so bindselector.d can import that and do its thing inside a
> foreach.
>
> The problem here is related again with my limitations declaring generics.
> Since every tuple will have a different type signature, I tought that the
> logical structure to group them would be... yes, another tuple :) Then I
> would foreach on that structure and bind the params, etc.
>
> First try (Fail-1):
>
> // 
> auto selector_data_tuples = tuple(
>   tuple( "^/home/$", &(views.index!(int,
> double)), 42, 3.14 )
> );
>
> foreach(selector_data; selector_data_tuples) {
> auto sel_regex_var  = selector_data.field[0];
> auto sel_view_var = selector_data.field[1];
> sel_view_var(sel_regex_var, selector_data.expand[2..$]);
> }
> // 
>
> Compile error: Error: cannot infer type for selector_data
>
> Logical, since the type of the iterated element in the foreach is fixed,
> and
> I'm iterating over tuples of different types.
>

Oh, but you can iterate on an expression tuple alright, even when all its
elements have different types. I don't know why bearophile doesn't like
that.
It's just, as

Re: pure member functions

2010-09-20 Thread Don

bearophile wrote:

Jonathan M Davis:

I assume that if you declare a member function as pure, then all of its 
parameters - including the invisible this - are included in that. That is, if 
all of them - including the invisible this - have the same value, then the 
result will be the same.


This D2 program runs with no errors, and here there isn't a D language/compiler 
bug:

struct Foo {
int x;
this (int xx) { this.x = xx; }
pure int bar() { return x; }
}
void main() {
Foo f = Foo(1);
assert(f.bar() == 1);
f.x *= 2;
assert(f.bar() == 2);
}

Bye,
bearophile


You do need to be careful about concluding how 'pure' works based on the 
current behaviour of the compiler.
There's a trap here. What if you use a hypothetical startTimer() 
function which executes a delegate every few clock ticks?


void main() {
Foo f = Foo(1);
startTimer( () { f.x++; });
scope(exit)
killTimer();

assert(f.bar() == 1); // may fail!
f.x *= 2;
assert(f.bar() == 2);
}

I actually think that 'pure' on a member function can only mean, it's 
cacheably pure if and only if 'this' can be cast to immutable. Which 
includes the important case where the call is made from a pure function 
(this implies that the 'this' pointer is either a local variable of a 
pure function, or an immutable object).
Since pure functions cannot call impure functions, they can't do any of 
this nasty asynchronous stuff.


In fact I think in general, that's how pure should work: once you're 
inside 'pure', you should be able to pass even mutable objects into pure 
functions. This is possible because although it's mutable, the entire 
code that modifies it is confined to a single function. So the compiler 
can determine if it is cacheably pure without performing any kind of 
whole program analysis.


But this is just my opinion. I don't know if it will eventually work 
that way.


Re: pure member functions

2010-09-20 Thread Steven Schveighoffer

On Mon, 20 Sep 2010 15:45:10 -0400, Don  wrote:


bearophile wrote:

Jonathan M Davis:

I assume that if you declare a member function as pure, then all of  
its parameters - including the invisible this - are included in that.  
That is, if all of them - including the invisible this - have the same  
value, then the result will be the same.
 This D2 program runs with no errors, and here there isn't a D  
language/compiler bug:

 struct Foo {
int x;
this (int xx) { this.x = xx; }
pure int bar() { return x; }
}
void main() {
Foo f = Foo(1);
assert(f.bar() == 1);
f.x *= 2;
assert(f.bar() == 2);
}
 Bye,
bearophile


You do need to be careful about concluding how 'pure' works based on the  
current behaviour of the compiler.
There's a trap here. What if you use a hypothetical startTimer()  
function which executes a delegate every few clock ticks?


void main() {
 Foo f = Foo(1);
 startTimer( () { f.x++; });
 scope(exit)
killTimer();

 assert(f.bar() == 1); // may fail!
 f.x *= 2;
 assert(f.bar() == 2);
}


Wouldn't f have to be shared for this to be asynchronous?

I actually think that 'pure' on a member function can only mean, it's  
cacheably pure if and only if 'this' can be cast to immutable. Which  
includes the important case where the call is made from a pure function  
(this implies that the 'this' pointer is either a local variable of a  
pure function, or an immutable object).
Since pure functions cannot call impure functions, they can't do any of  
this nasty asynchronous stuff.


I think it's ok for a function to be pure if all the arguments are  
unshared, regardless of immutability.  However, in order to cache the  
return value, the reference itself must not be used as the key, but the  
entire data of the reference.  Even if it's immutable, wouldn't you not  
want to cache the return values between two identical immutable objects?


-Steve


Re: pure member functions

2010-09-20 Thread Don

Steven Schveighoffer wrote:

On Mon, 20 Sep 2010 15:45:10 -0400, Don  wrote:


bearophile wrote:

Jonathan M Davis:

I assume that if you declare a member function as pure, then all of 
its parameters - including the invisible this - are included in 
that. That is, if all of them - including the invisible this - have 
the same value, then the result will be the same.
 This D2 program runs with no errors, and here there isn't a D 
language/compiler bug:

 struct Foo {
int x;
this (int xx) { this.x = xx; }
pure int bar() { return x; }
}
void main() {
Foo f = Foo(1);
assert(f.bar() == 1);
f.x *= 2;
assert(f.bar() == 2);
}
 Bye,
bearophile


You do need to be careful about concluding how 'pure' works based on 
the current behaviour of the compiler.
There's a trap here. What if you use a hypothetical startTimer() 
function which executes a delegate every few clock ticks?


void main() {
 Foo f = Foo(1);
 startTimer( () { f.x++; });
 scope(exit)
killTimer();

 assert(f.bar() == 1); // may fail!
 f.x *= 2;
 assert(f.bar() == 2);
}


Wouldn't f have to be shared for this to be asynchronous?


That's an excellent point. 'pure' was put into the language long before 
'shared' and '__gshared'. It could now just mean, "doesn't use static, 
globals, shared, or __gshared".


And then cachable pure is just: pure, + all reference parameters are 
immutable.


If this becomes the rule, it seems likely that pure functions would 
become far more common than impure ones.


I actually think that 'pure' on a member function can only mean, it's 
cacheably pure if and only if 'this' can be cast to immutable. Which 
includes the important case where the call is made from a pure 
function (this implies that the 'this' pointer is either a local 
variable of a pure function, or an immutable object).
Since pure functions cannot call impure functions, they can't do any 
of this nasty asynchronous stuff.


I think it's ok for a function to be pure if all the arguments are 
unshared, regardless of immutability.  However, in order to cache the 
return value, the reference itself must not be used as the key, but the 
entire data of the reference.  Even if it's immutable, wouldn't you not 
want to cache the return values between two identical immutable objects?


Possibly, but my guess is that it would take too long to check.


Re: Applying a tuple to a function (and more)

2010-09-20 Thread bearophile
Philippe Sigaud:
> Oh, but you can iterate on an expression tuple alright, even when all its
> elements have different types. I don't know why bearophile doesn't like that.

I like the iteration on typetuples (the nomenclature here is a mess, see bug 
4113), but you have to use such iteration with care because it's a static 
foreach, your code may become very long (this is why in bug 4085 I have asked 
to require a "static foreach" to iterate on typetuples, to help the programmer 
see the difference better).

Bye,
bearophile


Re: D equivalent of C++ reinterpret cast?

2010-09-20 Thread bearophile
Ali Çehreli:
> I remember being a part of a discussion where D'is unions were told to 
> be exactly the same as C's. That means, results of using a union is only 
> specified when it's used through one its members. Writing to one member 
> and reading from another is unspecified. It is clear that endianness and 
> padding should complicate matters.

I have just written a post about this topic:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=117675

Bye and thank you,
bearophile