Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Jacob Carlborg

On 2011-08-03 20:36, Andrej Mitrovic wrote:

On 8/3/11, Jacob Carlborg  wrote:

Why would you want to slow down framerate?


Because the examples were written in the 90s and CPUs and graphic
cards are so fast these days that the old code runs at an enormous
framerate.


I would say that the correct solution is to rewrite the examples to work 
with any CPU speed. But as you say, it's examples, may not be worth it.


--
/Jacob Carlborg


Re: NaCl stable ABI

2011-08-03 Thread Nick Sabalausky
"Andrej Mitrovic"  wrote in message 
news:mailman.2097.1312408853.14074.digitalmars-d-le...@puremagic.com...
>I liked QLive before they forced 30 second commercials on server joins
> for non-subscribers. :(
>
> It was cool being able to casually browse to other tabs, then going
> back to qlive and finding a game.
>
> UT for example had an integrated IRC client, but people preferred
> using mIRC and having a ut://123.123.123.123 protocol they can just
> click on to join a game. Don't forget having to minimize all the time
> to chat to someone on MSN while playing a game. So there are some
> benefits to having a browser based interface for a game, imo.

There is nothing you've mentioned that can't be (better) fixed without 
cramming everything into a browser. 




Re: NaCl stable ABI

2011-08-03 Thread Andrej Mitrovic
I liked QLive before they forced 30 second commercials on server joins
for non-subscribers. :(

It was cool being able to casually browse to other tabs, then going
back to qlive and finding a game.

UT for example had an integrated IRC client, but people preferred
using mIRC and having a ut://123.123.123.123 protocol they can just
click on to join a game. Don't forget having to minimize all the time
to chat to someone on MSN while playing a game. So there are some
benefits to having a browser based interface for a game, imo.


Re: NaCl stable ABI

2011-08-03 Thread Nick Sabalausky
"Nick Sabalausky"  wrote in message 
news:j1cb3a$2qe7$1...@digitalmars.com...
>
> I mean this is the stupid motherfuck industry that's spent the last ten 
> years completely ignoring who they're *supposed* to be (***VIDEOGAME*** 
> developers) and instead running around as a bunch of goddamn 
> graphics-whore, "storytime", Pixar/Hollywood wannabe, IP-fellatiatng, 
> fucking posers. Especially the absolutely disgraceful graphics-whore and 
> "Pixar/Hollywood wannabe" parts. Those two in particular can't be 
> over-emphasized.
>

Oh, and how could I forget the other major evidence of the industry's 
asinine mentality: Seriously, this indistry is holding onto DRM and 
closed-platforms about 10x harder than the *music* industry, for fuck's 
sake. And the long-hated music industry has never done region coding - 
another thing the so-called "videogame" industry (really the 
"hollywood-wannabe" industry, like I said) is keeping a deathgrip on.




Re: NaCl stable ABI

2011-08-03 Thread Nick Sabalausky
"Peter Alexander"  wrote in message 
news:j1asck$81d$1...@digitalmars.com...
>
> The games industry has been crying out for something like NaCl for a long 
> time. It is exactly what we want:
>
> - Ability to launch games within browser without a plugin download
> - Platform independent ABI
> - No f*cking Javascript (performance will never match C++)
> - Safe (no need for end users to worry)
>
>
> JavaScript for high-quality games is a non-starter. It's too slow.

Browser for "high-quality" games is a non-starter. What idiot would rather 
play a game inside a damn browser? You could have all the speed in the 
world, and the browser would still be completely unsuitable for anything 
beyond dinky little popcap-style shit. We've had Quake playable in the 
browser for awhile now: and who the hell actually plays it that way? And who 
actually wants to? It's nothing but a "Gee whiz, look what we can do in a 
browser!" dick-measuring contest.

The whole premise of games in a browser is idiotic. What is needed is 
0install and an OS-level security model that's actually good, or something 
along those lines. None of this Google-mentality "pretending the browser is 
a platform" bullshit.

The browser is a complete strawman here; cramming games into it is solving 
the wrong issue. It's exactly the old web-app trend all over again: People 
thought web-based stuff made deployment easier (in a few different ways: not 
all of which were actually true) and thought that it was safe/secure (which, 
frankly, has never really been true). So instead of *soving those issues* by 
putting their focus on improving deployment of *real* apps (via something 
like 0install) and pushing for improved OS security models (via something 
like selinux maybe? Seriously how much push is actualyl behind that? Not 
nearly enough), the morons started cramming apps into the browser (well, 
that and Valve's Steam abomination) and consequently fucked up computing 
while *still* not solving half the issues they thought they were solving 
anyway.

If the games industry is crying out for faster in-browser computing, then 
what they're asking for is a faster horse. But it figures: I mean this is 
the stupid motherfuck industry that's spent the last ten years completely 
ignoring who they're *supposed* to be (***VIDEOGAME*** developers) and 
instead running around as a bunch of goddamn graphics-whore, "storytime", 
Pixar/Hollywood wannabe, IP-fellatiatng, fucking posers. Especially the 
absolutely disgraceful graphics-whore and "Pixar/Hollywood wannabe" parts. 
Those two in particular can't be over-emphasized.




Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Andrej Mitrovic
On 8/3/11, Andrej Mitrovic  wrote:
> if ((t - t_prev).usecs > (1_000_000.0 / FPS))
> {
> t_prev = t;
> DrawGLScene();
> }
>
> SwapBuffers(hDC);

My mistake here, SwapBuffers belongs inside the if body, there's an
unrelated keyboard bug that made me push it there but I've found
what's causing it. Anyway this is offtopic.


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Dmitry Olshansky

On 03.08.2011 22:26, simendsjo wrote:

On 03.08.2011 19:15, Jonathan M Davis wrote:

On 03.08.2011 18:18, Jonathan M Davis wrote:

On Thursday 04 August 2011 00:27:12 Mike Parker wrote:

On 8/3/2011 11:23 PM, simendsjo wrote:

On 03.08.2011 15:49, bearophile wrote:

simendsjo:

void main() {
assert(is(typeof("") == typeof("".idup))); // both is
immutable(char)[]

assert("" !is null);
assert("".idup !is null); // fails - s is null. Why?
}


I think someone has even suggested to statically forbid "is 
null" on

strings :-)

Bye,
bearophile


How should I test for null if not with "is null"? There is a 
difference

between null and empty, and avoiding this is not necessarily easy or
even wanted.
I couldn't find anything in the specification stating this 
difference.

So... Is it a bug?


This is apparently a bug. Somehow, the idup is clobbering the 
pointer.

You can see it more clearly here:

void main()
{

assert("".ptr);

auto s = "".idup;
assert(s.ptr); // boom!

}


I don't know if it's a bug or not. The string _was_ duped. assert(s ==
"") passes. So, as far as equality goes, they're equal, and they don't
point to the same memory. Now, you'd think that the new string 
would be

just empty rather than null, but whether it's a bug or not depends
exactly on what dup and idup are supposed to do with regards to null.
It's probably just a side effect of how dup and idup are implemented
rather than it being planned one way or the other. I don't know if it
matters or not though. In general, I don't like the conflation of null
and empty, but is this particular case, you _do_ get a string which is
equal to the original and which doesn't point to the same memory. 
So, I
don't know whether this should be considered a bug or not. It 
depends on

what dup and idup are ultimately supposed to do.

- Jonathan M Davis


I would think it's a bug, but strings doesn't quite behave as regular
references anyway...
But why should dup/idup change the semantics of the array?

void main() {
// A null string or empty string works as expected
string s1;
assert(s1 is null);
assert(s1.ptr is null);
assert(s1 == ""); // We can check for empty even if it's
null, and it's equal to ""
assert(s1.length == 0); // ...and length even if it's null
s1 = "";
assert(s1 !is null);
assert(s1.ptr !is null);
assert(s1.length == 0);
assert(s1 == "");

// the same applies to null mutable arrays
char[] s2;
assert(s2 is null);
assert(s2.ptr is null);
assert(s2 == "");
assert(s2.length == 0);
// but with .dup/.idup things is different!
s2 = "".dup;
//assert(s2 !is null); // fails
//assert(s2.ptr !is null); // fails
assert(s2.length == 0); // but... s2 is null..?
assert(s2 == "");
assert(s2 == s1);
}


If you look at the spec ( 
http://d-programming-language.org/arrays.html ), it

says:

dup: Cre­ate a dy­namic array of the same size and copy the con­tents 
of the

array into it.

idup: Cre­ate a dy­namic array of the same size and copy the 
con­tents of the

array into it. The copy is typed as being im­mutable. D 2.0 only


This is _exactly_ what dup and idup are doing. You get a new array 
with the
exact same size and contents. null doesn't factor into it at all. So, 
per the
spec, there's no bug here at all. dup and idup promise _nothing_ with 
regards

to null.

It may be that it would be better if dup and idup returned an array 
which was
null if the original was null, and that would also be within the 
spec, but

what dup and idup do at the moment _does_ follow the spec.

So, feel free to file a bug report on it. Maybe it'll get changed, 
but the
current behavior follows the spec. And given how arrays don't 
generally treat
empty and null as being different, I wouldn't really expect an array 
to stay
null if you do _anything_ to it other than simply pass it around or 
check its
value. In this case, you're creating a new array, and D just doesn't 
generally
care about null vs empty when it comes to arrays. I wouldn't argue 
that that's
a good thing (because I don't really think that it is), but because 
of that,
you can't really expect much to treat null and empty as being 
different. And
in this particular case, it's not only debatable as to whether it 
matters, but

the current behavior is completely within the spec.

- Jonathan M Davis


Schveighoffer also states it is as designed.
But it really doesn't behave as one (at least I) would expect.
So in essence (as bearophile says), "is null" should not be used on 
arrays.


I was bitten by a bug because of this, and used "" intead of "".idup 
to avoid this, but given D doesn't distinguish between empty and null 
arrays, this doesn't feel very safe now..


In the code in question I have a lazy initialized string. The problem 
is that I would see if it has been initialized, but an empty string is 
also a valid value. Because I shouldn't check for null, I now have to 
add another field to the struct to see if the array has been 
initialized. This feels like a really suboptimal solution.


length works e

Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Steven Schveighoffer

On Wed, 03 Aug 2011 14:26:54 -0400, simendsjo  wrote:


Schveighoffer also states it is as designed.
But it really doesn't behave as one (at least I) would expect.
So in essence (as bearophile says), "is null" should not be used on  
arrays.


I was bitten by a bug because of this, and used "" intead of "".idup to  
avoid this, but given D doesn't distinguish between empty and null  
arrays, this doesn't feel very safe now..


I would recommend against depending on the difference between null and  
not-null-but-empty arrays.  But in any case, "".idup is mainly pointless,  
there is never a need to idup a string, since it's already immutable (and  
therefore can be passed wherever you need it).


In the code in question I have a lazy initialized string. The problem is  
that I would see if it has been initialized, but an empty string is also  
a valid value. Because I shouldn't check for null, I now have to add  
another field to the struct to see if the array has been initialized.  
This feels like a really suboptimal solution.


Where is it that you need to use idup?  I think you may be using that  
without need (or if you are using code that violates immutability, that  
code is incorrect), but I don't know what your code looks like so I might  
be wrong.


In any case, there may be a better way to do what you want, without the  
extra field.


At the very least, here is a function that can help you:

myIdup(string s)
{
   return s.length == 0 ? "" : s.idup;
}

Note that this kind of thing *ONLY* works for strings, because string  
literals are not null.  For normal arrays, I wouldn't expect this to work.


-Steve


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Jonathan M Davis
> On 03.08.2011 19:15, Jonathan M Davis wrote:
> >> On 03.08.2011 18:18, Jonathan M Davis wrote:
> >>> On Thursday 04 August 2011 00:27:12 Mike Parker wrote:
>  On 8/3/2011 11:23 PM, simendsjo wrote:
> > On 03.08.2011 15:49, bearophile wrote:
> >> simendsjo:
> >>> void main() {
> >>> assert(is(typeof("") == typeof("".idup))); // both is
> >>> immutable(char)[]
> >>> 
> >>> assert("" !is null);
> >>> assert("".idup !is null); // fails - s is null. Why?
> >>> }
> >> 
> >> I think someone has even suggested to statically forbid "is null" on
> >> strings :-)
> >> 
> >> Bye,
> >> bearophile
> > 
> > How should I test for null if not with "is null"? There is a
> > difference between null and empty, and avoiding this is not
> > necessarily easy or even wanted.
> > I couldn't find anything in the specification stating this
> > difference. So... Is it a bug?
>  
>  This is apparently a bug. Somehow, the idup is clobbering the pointer.
>  You can see it more clearly here:
>  
>  void main()
>  {
>  
>  assert("".ptr);
>  
>  auto s = "".idup;
>  assert(s.ptr); // boom!
>  
>  }
> >>> 
> >>> I don't know if it's a bug or not. The string _was_ duped. assert(s ==
> >>> "") passes. So, as far as equality goes, they're equal, and they don't
> >>> point to the same memory. Now, you'd think that the new string would be
> >>> just empty rather than null, but whether it's a bug or not depends
> >>> exactly on what dup and idup are supposed to do with regards to null.
> >>> It's probably just a side effect of how dup and idup are implemented
> >>> rather than it being planned one way or the other. I don't know if it
> >>> matters or not though. In general, I don't like the conflation of null
> >>> and empty, but is this particular case, you _do_ get a string which is
> >>> equal to the original and which doesn't point to the same memory. So, I
> >>> don't know whether this should be considered a bug or not. It depends
> >>> on what dup and idup are ultimately supposed to do.
> >>> 
> >>> - Jonathan M Davis
> >> 
> >> I would think it's a bug, but strings doesn't quite behave as regular
> >> references anyway...
> >> But why should dup/idup change the semantics of the array?
> >> 
> >> void main() {
> >> // A null string or empty string works as expected
> >> string s1;
> >> assert(s1 is null);
> >> assert(s1.ptr is null);
> >> assert(s1 == ""); // We can check for empty even if it's
> >> null, and it's equal to ""
> >> assert(s1.length == 0); // ...and length even if it's null
> >> s1 = "";
> >> assert(s1 !is null);
> >> assert(s1.ptr !is null);
> >> assert(s1.length == 0);
> >> assert(s1 == "");
> >> 
> >> // the same applies to null mutable arrays
> >> char[] s2;
> >> assert(s2 is null);
> >> assert(s2.ptr is null);
> >> assert(s2 == "");
> >> assert(s2.length == 0);
> >> // but with .dup/.idup things is different!
> >> s2 = "".dup;
> >> //assert(s2 !is null); // fails
> >> //assert(s2.ptr !is null); // fails
> >> assert(s2.length == 0); // but... s2 is null..?
> >> assert(s2 == "");
> >> assert(s2 == s1);
> >> }
> > 
> > If you look at the spec ( http://d-programming-language.org/arrays.html
> > ), it says:
> > 
> > dup: Cre­ate a dy­namic array of the same size and copy the con­tents of
> > the array into it.
> > 
> > idup: Cre­ate a dy­namic array of the same size and copy the con­tents of
> > the array into it. The copy is typed as being im­mutable. D 2.0 only
> > 
> > 
> > This is _exactly_ what dup and idup are doing. You get a new array with
> > the exact same size and contents. null doesn't factor into it at all.
> > So, per the spec, there's no bug here at all. dup and idup promise
> > _nothing_ with regards to null.
> > 
> > It may be that it would be better if dup and idup returned an array which
> > was null if the original was null, and that would also be within the
> > spec, but what dup and idup do at the moment _does_ follow the spec.
> > 
> > So, feel free to file a bug report on it. Maybe it'll get changed, but
> > the current behavior follows the spec. And given how arrays don't
> > generally treat empty and null as being different, I wouldn't really
> > expect an array to stay null if you do _anything_ to it other than
> > simply pass it around or check its value. In this case, you're creating
> > a new array, and D just doesn't generally care about null vs empty when
> > it comes to arrays. I wouldn't argue that that's a good thing (because I
> > don't really think that it is), but because of that, you can't really
> > expect much to treat null and empty as being different. And in this
> > particular case, it's not only debatable as to whether it matters, but
> > the current behavior is completely within the spec.
> > 
> > - Jonathan M Davis
> 
> Schveighoffer also states it is as designed.
> But it really doesn't behave as one (at least I) would expect.
> So in ess

Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Jonathan M Davis
> On Wed, 03 Aug 2011 06:35:08 -0400, simendsjo  wrote:
> > void main() {
> > 
> > assert(is(typeof("") == typeof("".idup))); // both is
> > 
> > immutable(char)[]
> > 
> > assert("" !is null);
> > assert("".idup !is null); // fails - s is null. Why?
> > 
> > }
> 
> An empty string manifest constant (i.e. string literal) still must have a
> valid pointer, because it's mandated that the string have a zero byte
> appended to it. This is so you can pass it to C functions which expect
> null-terminated strings.
> 
> So essentially, there is a '\0' in memory, and "" points to that character
> with a length of 0
> 
> However, idup calls a runtime function which *purposely* asks to make a
> copy. However, it's *NOT* required to copy the 'zero after the string'
> part.
> 
> The implementation, knowing that a null array is equivalent to an empty
> array, is going to return null to avoid the performance penalty of
> allocating a block that won't be used. If you append, it will simply
> allocate a block as needed.
> 
> I see no reason the runtime should waste cycles or a perfectly good
> 16-byte buffer to give you an empty array.
> 
> Definitely functions as designed, not a bug. If you would like different
> behavior, you are going to have to have a really really good use case to
> get this changed.

Given that if you really wanted the duped string to be empty instead of null, 
it wouldn't be very hard to write a wrapper function for dup which did that, 
I'd be _very_ surprised if you could find a use case where dup should allocate 
for an empty string.

I don't generally like the fact that D tends to conflate null and empty, but 
you're creating a new array here. It's not at all surprising if it ends up 
null if it has no elements in it. In general though, you need to be fairly 
careful about where you rely on the difference between empty and null. If any 
kind of memory allocation occurs to an array and its length is 0, it's pretty 
much free game as to whether it's empty or null.

- Jonathan M Davis


Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Steven Schveighoffer
On Wed, 03 Aug 2011 13:42:34 -0400, Andrej Mitrovic  
 wrote:



That could be the reason. I'm testing on Windows.


Windows only supports millisecond resolution.

A valid solution to this is probably to have anything > 0 and < 1 ms sleep  
for at least 1ms.  Or maybe it can round up to the next ms.


For now, you can simply sleep for 1ms.

-Steve


Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Andrej Mitrovic
On 8/3/11, Jacob Carlborg  wrote:
> Why would you want to slow down framerate?

Because the examples were written in the 90s and CPUs and graphic
cards are so fast these days that the old code runs at an enormous
framerate.

Anyway, after a bit of googling I've found a solution:

enum float FPS = 60.0;
auto t_prev = Clock.currSystemTick();
while (!done)
{
auto t = Clock.currSystemTick();

if ((t - t_prev).usecs > (1_000_000.0 / FPS))
{
t_prev = t;
DrawGLScene();
}

SwapBuffers(hDC);
}

I can also use currAppTick() which is similar.

I'm using "enum float" instead of just "enum FPS" because creeping
integer truncation bugs lurk into my code all the time. i.e. I end up
having an expression like "var1 / var" evaluate to an integer instead
of a float because a variable was declared as an integer.

Here's what I mean:
enum FPS = 60;

void main()
{
auto fraction = (1 / FPS);  // woops, actually returns 0
}

Using "enum float FPS = 60;" fixes this. It's a very subtle thing and
easily introducable as a bug.


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread simendsjo

On 03.08.2011 19:15, Jonathan M Davis wrote:

On 03.08.2011 18:18, Jonathan M Davis wrote:

On Thursday 04 August 2011 00:27:12 Mike Parker wrote:

On 8/3/2011 11:23 PM, simendsjo wrote:

On 03.08.2011 15:49, bearophile wrote:

simendsjo:

void main() {
assert(is(typeof("") == typeof("".idup))); // both is
immutable(char)[]

assert("" !is null);
assert("".idup !is null); // fails - s is null. Why?
}


I think someone has even suggested to statically forbid "is null" on
strings :-)

Bye,
bearophile


How should I test for null if not with "is null"? There is a difference
between null and empty, and avoiding this is not necessarily easy or
even wanted.
I couldn't find anything in the specification stating this difference.
So... Is it a bug?


This is apparently a bug. Somehow, the idup is clobbering the pointer.
You can see it more clearly here:

void main()
{

assert("".ptr);

auto s = "".idup;
assert(s.ptr); // boom!

}


I don't know if it's a bug or not. The string _was_ duped. assert(s ==
"") passes. So, as far as equality goes, they're equal, and they don't
point to the same memory. Now, you'd think that the new string would be
just empty rather than null, but whether it's a bug or not depends
exactly on what dup and idup are supposed to do with regards to null.
It's probably just a side effect of how dup and idup are implemented
rather than it being planned one way or the other. I don't know if it
matters or not though. In general, I don't like the conflation of null
and empty, but is this particular case, you _do_ get a string which is
equal to the original and which doesn't point to the same memory. So, I
don't know whether this should be considered a bug or not. It depends on
what dup and idup are ultimately supposed to do.

- Jonathan M Davis


I would think it's a bug, but strings doesn't quite behave as regular
references anyway...
But why should dup/idup change the semantics of the array?

void main() {
// A null string or empty string works as expected
string s1;
assert(s1 is null);
assert(s1.ptr is null);
assert(s1 == ""); // We can check for empty even if it's
null, and it's equal to ""
assert(s1.length == 0); // ...and length even if it's null
s1 = "";
assert(s1 !is null);
assert(s1.ptr !is null);
assert(s1.length == 0);
assert(s1 == "");

// the same applies to null mutable arrays
char[] s2;
assert(s2 is null);
assert(s2.ptr is null);
assert(s2 == "");
assert(s2.length == 0);
// but with .dup/.idup things is different!
s2 = "".dup;
//assert(s2 !is null); // fails
//assert(s2.ptr !is null); // fails
assert(s2.length == 0); // but... s2 is null..?
assert(s2 == "");
assert(s2 == s1);
}


If you look at the spec ( http://d-programming-language.org/arrays.html ), it
says:

dup: Cre­ate a dy­namic array of the same size and copy the con­tents of the
array into it.

idup: Cre­ate a dy­namic array of the same size and copy the con­tents of the
array into it. The copy is typed as being im­mutable. D 2.0 only


This is _exactly_ what dup and idup are doing. You get a new array with the
exact same size and contents. null doesn't factor into it at all. So, per the
spec, there's no bug here at all. dup and idup promise _nothing_ with regards
to null.

It may be that it would be better if dup and idup returned an array which was
null if the original was null, and that would also be within the spec, but
what dup and idup do at the moment _does_ follow the spec.

So, feel free to file a bug report on it. Maybe it'll get changed, but the
current behavior follows the spec. And given how arrays don't generally treat
empty and null as being different, I wouldn't really expect an array to stay
null if you do _anything_ to it other than simply pass it around or check its
value. In this case, you're creating a new array, and D just doesn't generally
care about null vs empty when it comes to arrays. I wouldn't argue that that's
a good thing (because I don't really think that it is), but because of that,
you can't really expect much to treat null and empty as being different. And
in this particular case, it's not only debatable as to whether it matters, but
the current behavior is completely within the spec.

- Jonathan M Davis


Schveighoffer also states it is as designed.
But it really doesn't behave as one (at least I) would expect.
So in essence (as bearophile says), "is null" should not be used on arrays.

I was bitten by a bug because of this, and used "" intead of "".idup to 
avoid this, but given D doesn't distinguish between empty and null 
arrays, this doesn't feel very safe now..


In the code in question I have a lazy initialized string. The problem is 
that I would see if it has been initialized, but an empty string is also 
a valid value. Because I shouldn't check for null, I now have to add 
another field to the struct to see if the array has been initialized. 
This feels like a really suboptimal solution.


Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Jacob Carlborg

On 2011-08-03 19:42, Andrej Mitrovic wrote:

That could be the reason. I'm testing on Windows.

I was using sleep() as a quick hack around slowing down the framerate
of an OpenGL display. There are better way to do this but I didn't
have time to find a proper solution yet.


Why would you want to slow down framerate?

--
/Jacob Carlborg


Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Andrej Mitrovic
That could be the reason. I'm testing on Windows.

I was using sleep() as a quick hack around slowing down the framerate
of an OpenGL display. There are better way to do this but I didn't
have time to find a proper solution yet.


Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Steven Schveighoffer
On Wed, 03 Aug 2011 13:14:50 -0400, Andrej Mitrovic  
 wrote:



Take a look at this:

import std.stdio;
import core.thread;

void main()
{
foreach (x; 0 .. 1000)
{
Thread.sleep(dur!("usecs")(999));
writeln(x);
}

foreach (x; 0 .. 1000)
{
Thread.sleep(dur!("usecs")(1000));
writeln(x);
}
}

Compile and run it. The first foreach loop ends in an instant, while
the second one takes much much longer to finish, which is puzzling
since I've only increased the sleep while for a single microsecond.
What's going on?


I can only imagine that the cause is the implementation is using an OS  
function that only supports millisecond sleep resolution.  So essentially  
it's like sleeping for 0 or 1 millisecond.  However, without knowing your  
OS, it's hard to say what's going on.  On my linux install, the timing  
seems equivalent.


-Steve


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Steven Schveighoffer

On Wed, 03 Aug 2011 06:35:08 -0400, simendsjo  wrote:


void main() {
 assert(is(typeof("") == typeof("".idup))); // both is  
immutable(char)[]


 assert(""  !is null);
 assert("".idup !is null); // fails - s is null. Why?
}


An empty string manifest constant (i.e. string literal) still must have a  
valid pointer, because it's mandated that the string have a zero byte  
appended to it.  This is so you can pass it to C functions which expect  
null-terminated strings.


So essentially, there is a '\0' in memory, and "" points to that character  
with a length of 0


However, idup calls a runtime function which *purposely* asks to make a  
copy.  However, it's *NOT* required to copy the 'zero after the string'  
part.


The implementation, knowing that a null array is equivalent to an empty  
array, is going to return null to avoid the performance penalty of  
allocating a block that won't be used.  If you append, it will simply  
allocate a block as needed.


I see no reason the runtime should waste cycles or a perfectly good  
16-byte buffer to give you an empty array.


Definitely functions as designed, not a bug.  If you would like different  
behavior, you are going to have to have a really really good use case to  
get this changed.


-Steve


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Jonathan M Davis
> On 03.08.2011 18:18, Jonathan M Davis wrote:
> > On Thursday 04 August 2011 00:27:12 Mike Parker wrote:
> >> On 8/3/2011 11:23 PM, simendsjo wrote:
> >>> On 03.08.2011 15:49, bearophile wrote:
>  simendsjo:
> > void main() {
> > assert(is(typeof("") == typeof("".idup))); // both is
> > immutable(char)[]
> > 
> > assert("" !is null);
> > assert("".idup !is null); // fails - s is null. Why?
> > }
>  
>  I think someone has even suggested to statically forbid "is null" on
>  strings :-)
>  
>  Bye,
>  bearophile
> >>> 
> >>> How should I test for null if not with "is null"? There is a difference
> >>> between null and empty, and avoiding this is not necessarily easy or
> >>> even wanted.
> >>> I couldn't find anything in the specification stating this difference.
> >>> So... Is it a bug?
> >> 
> >> This is apparently a bug. Somehow, the idup is clobbering the pointer.
> >> You can see it more clearly here:
> >> 
> >> void main()
> >> {
> >> 
> >> assert("".ptr);
> >> 
> >> auto s = "".idup;
> >> assert(s.ptr); // boom!
> >> 
> >> }
> > 
> > I don't know if it's a bug or not. The string _was_ duped. assert(s ==
> > "") passes. So, as far as equality goes, they're equal, and they don't
> > point to the same memory. Now, you'd think that the new string would be
> > just empty rather than null, but whether it's a bug or not depends
> > exactly on what dup and idup are supposed to do with regards to null.
> > It's probably just a side effect of how dup and idup are implemented
> > rather than it being planned one way or the other. I don't know if it
> > matters or not though. In general, I don't like the conflation of null
> > and empty, but is this particular case, you _do_ get a string which is
> > equal to the original and which doesn't point to the same memory. So, I
> > don't know whether this should be considered a bug or not. It depends on
> > what dup and idup are ultimately supposed to do.
> > 
> > - Jonathan M Davis
> 
> I would think it's a bug, but strings doesn't quite behave as regular
> references anyway...
> But why should dup/idup change the semantics of the array?
> 
> void main() {
> // A null string or empty string works as expected
> string s1;
> assert(s1 is null);
> assert(s1.ptr is null);
> assert(s1 == ""); // We can check for empty even if it's
> null, and it's equal to ""
> assert(s1.length == 0); // ...and length even if it's null
> s1 = "";
> assert(s1 !is null);
> assert(s1.ptr !is null);
> assert(s1.length == 0);
> assert(s1 == "");
> 
> // the same applies to null mutable arrays
> char[] s2;
> assert(s2 is null);
> assert(s2.ptr is null);
> assert(s2 == "");
> assert(s2.length == 0);
> // but with .dup/.idup things is different!
> s2 = "".dup;
> //assert(s2 !is null); // fails
> //assert(s2.ptr !is null); // fails
> assert(s2.length == 0); // but... s2 is null..?
> assert(s2 == "");
> assert(s2 == s1);
> }

If you look at the spec ( http://d-programming-language.org/arrays.html ), it 
says:

dup: Cre­ate a dy­namic array of the same size and copy the con­tents of the 
array into it.

idup: Cre­ate a dy­namic array of the same size and copy the con­tents of the 
array into it. The copy is typed as being im­mutable. D 2.0 only


This is _exactly_ what dup and idup are doing. You get a new array with the 
exact same size and contents. null doesn't factor into it at all. So, per the 
spec, there's no bug here at all. dup and idup promise _nothing_ with regards 
to null.

It may be that it would be better if dup and idup returned an array which was 
null if the original was null, and that would also be within the spec, but 
what dup and idup do at the moment _does_ follow the spec.

So, feel free to file a bug report on it. Maybe it'll get changed, but the 
current behavior follows the spec. And given how arrays don't generally treat 
empty and null as being different, I wouldn't really expect an array to stay 
null if you do _anything_ to it other than simply pass it around or check its 
value. In this case, you're creating a new array, and D just doesn't generally 
care about null vs empty when it comes to arrays. I wouldn't argue that that's 
a good thing (because I don't really think that it is), but because of that, 
you can't really expect much to treat null and empty as being different. And 
in this particular case, it's not only debatable as to whether it matters, but 
the current behavior is completely within the spec.

- Jonathan M Davis


Re: Weird timing issue with Thread.sleep

2011-08-03 Thread Andrej Mitrovic
s/sleep while/sleep value


Weird timing issue with Thread.sleep

2011-08-03 Thread Andrej Mitrovic
Take a look at this:

import std.stdio;
import core.thread;

void main()
{
foreach (x; 0 .. 1000)
{
Thread.sleep(dur!("usecs")(999));
writeln(x);
}

foreach (x; 0 .. 1000)
{
Thread.sleep(dur!("usecs")(1000));
writeln(x);
}
}

Compile and run it. The first foreach loop ends in an instant, while
the second one takes much much longer to finish, which is puzzling
since I've only increased the sleep while for a single microsecond.
What's going on?


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread simendsjo

On 03.08.2011 18:18, Jonathan M Davis wrote:

On Thursday 04 August 2011 00:27:12 Mike Parker wrote:

On 8/3/2011 11:23 PM, simendsjo wrote:

On 03.08.2011 15:49, bearophile wrote:

simendsjo:

void main() {
assert(is(typeof("") == typeof("".idup))); // both is
immutable(char)[]

assert("" !is null);
assert("".idup !is null); // fails - s is null. Why?
}


I think someone has even suggested to statically forbid "is null" on
strings :-)

Bye,
bearophile


How should I test for null if not with "is null"? There is a difference
between null and empty, and avoiding this is not necessarily easy or
even wanted.
I couldn't find anything in the specification stating this difference.
So... Is it a bug?


This is apparently a bug. Somehow, the idup is clobbering the pointer.
You can see it more clearly here:

void main()
{
assert("".ptr);

auto s = "".idup;
assert(s.ptr); // boom!
}


I don't know if it's a bug or not. The string _was_ duped. assert(s == "")
passes. So, as far as equality goes, they're equal, and they don't point to
the same memory. Now, you'd think that the new string would be just empty
rather than null, but whether it's a bug or not depends exactly on what dup
and idup are supposed to do with regards to null. It's probably just a side
effect of how dup and idup are implemented rather than it being planned one way
or the other. I don't know if it matters or not though. In general, I don't
like the conflation of null and empty, but is this particular case, you _do_
get a string which is equal to the original and which doesn't point to the
same memory. So, I don't know whether this should be considered a bug or not.
It depends on what dup and idup are ultimately supposed to do.

- Jonathan M Davis


I would think it's a bug, but strings doesn't quite behave as regular 
references anyway...

But why should dup/idup change the semantics of the array?

void main() {
// A null string or empty string works as expected
string s1;
assert(s1   is  null);
assert(s1.ptr   is  null);
assert(s1   ==  ""); // We can check for empty even if it's 
null, and it's equal to ""

assert(s1.length==  0);  // ...and length even if it's null
s1 = "";
assert(s1   !is null);
assert(s1.ptr   !is null);
assert(s1.length==  0);
assert(s1   ==  "");

// the same applies to null mutable arrays
char[] s2;
assert(s2   is  null);
assert(s2.ptr   is  null);
assert(s2   ==  "");
assert(s2.length==  0);
// but with .dup/.idup things is different!
s2 = "".dup;
//assert(s2   !is null); // fails
//assert(s2.ptr   !is null); // fails
assert(s2.length==  0); // but... s2 is null..?
assert(s2   ==  "");
assert(s2   ==  s1);
}


Re: Hexadecimal string to integer

2011-08-03 Thread Stijn Herreman

On 3/08/2011 2:32, Johann MacDonagh wrote:

On 8/2/2011 8:17 PM, Stijn Herreman wrote:

std.conv does not support conversion from a hexadecimal string to an
integer. Is there a technical reason for this limitation?

This is the best I could do, can it be improved still?
int i = to!int(parse!float("0x1ap0"));


parse!int("1a", 16);

I tried multiple combinations but not that one, thanks.


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Jonathan M Davis
On Thursday 04 August 2011 00:27:12 Mike Parker wrote:
> On 8/3/2011 11:23 PM, simendsjo wrote:
> > On 03.08.2011 15:49, bearophile wrote:
> >> simendsjo:
> >>> void main() {
> >>> assert(is(typeof("") == typeof("".idup))); // both is
> >>> immutable(char)[]
> >>> 
> >>> assert("" !is null);
> >>> assert("".idup !is null); // fails - s is null. Why?
> >>> }
> >> 
> >> I think someone has even suggested to statically forbid "is null" on
> >> strings :-)
> >> 
> >> Bye,
> >> bearophile
> > 
> > How should I test for null if not with "is null"? There is a difference
> > between null and empty, and avoiding this is not necessarily easy or
> > even wanted.
> > I couldn't find anything in the specification stating this difference.
> > So... Is it a bug?
> 
> This is apparently a bug. Somehow, the idup is clobbering the pointer.
> You can see it more clearly here:
> 
> void main()
> {
>   assert("".ptr);
> 
>   auto s = "".idup;
>   assert(s.ptr); // boom!
> }

I don't know if it's a bug or not. The string _was_ duped. assert(s == "") 
passes. So, as far as equality goes, they're equal, and they don't point to 
the same memory. Now, you'd think that the new string would be just empty 
rather than null, but whether it's a bug or not depends exactly on what dup 
and idup are supposed to do with regards to null. It's probably just a side 
effect of how dup and idup are implemented rather than it being planned one way 
or the other. I don't know if it matters or not though. In general, I don't 
like the conflation of null and empty, but is this particular case, you _do_ 
get a string which is equal to the original and which doesn't point to the 
same memory. So, I don't know whether this should be considered a bug or not. 
It depends on what dup and idup are ultimately supposed to do.

- Jonathan M Davis


Re: NaCl stable ABI

2011-08-03 Thread Adam Ruppe
Peter Alexander wrote:
> If D were usable in NaCl that would be a huge selling point for the
> language.

Well, let's set aside my personal things and see how this might be
done.

Based on what I've read so far, it actually sounds easy enough, codegen
wise.

It might be possible to drop gdc into their hacked up gcc backend and
have it work with minimal effort.

Or, changing dmd's backend to emit code for it might not be hard
either. It looks like it'd just have to align jumps, which should
be as simple as padding labels with some nops.


The bigger difficulty I suspect will be porting the runtime... but,
since it builds on C in a lot of places, that might be simple too.



I can't find more details on what's needed to happen to the compilers,
but I'm really thinking it won't be very difficult to make it happen.


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread Mike Parker

On 8/3/2011 11:23 PM, simendsjo wrote:

On 03.08.2011 15:49, bearophile wrote:

simendsjo:


void main() {
assert(is(typeof("") == typeof("".idup))); // both is immutable(char)[]

assert("" !is null);
assert("".idup !is null); // fails - s is null. Why?
}


I think someone has even suggested to statically forbid "is null" on
strings :-)

Bye,
bearophile


How should I test for null if not with "is null"? There is a difference
between null and empty, and avoiding this is not necessarily easy or
even wanted.
I couldn't find anything in the specification stating this difference.
So... Is it a bug?



This is apparently a bug. Somehow, the idup is clobbering the pointer. 
You can see it more clearly here:


void main()
{
assert("".ptr);

auto s = "".idup;
assert(s.ptr); // boom!
}


Re: GG bug? (OS X Lion, DMD 2.054)

2011-08-03 Thread David Nadlinger

On 8/3/11 4:07 PM, Magnus Lie Hetland wrote:

I upgraded from OS X Snow Leopard to Lion recently (on a 32-bit iMac),
and when I tried to run my D code afterward, I suddenly ran into all
kinds of interesting problems (lots of failed assertions in my tests,
and bus errors in my actual runs...).


This seems to be exactly same problem I reported to the NG some days 
ago. It is caused by ASLR being enabled for 32bit applications on Lion 
too, and kennytm is to be credited for tracking this down to a fixed 
stack bottom in the druntime code: 
https://github.com/D-Programming-Language/druntime/pull/43. The fix has 
already been merged into master, please use that for OS X development 
until the next DMD release.


David


Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread simendsjo

On 03.08.2011 15:49, bearophile wrote:

simendsjo:


void main() {
  assert(is(typeof("") == typeof("".idup))); // both is immutable(char)[]

  assert(""  !is null);
  assert("".idup !is null); // fails - s is null. Why?
}


I think someone has even suggested to statically forbid "is null" on strings :-)

Bye,
bearophile


How should I test for null if not with "is null"? There is a difference 
between null and empty, and avoiding this is not necessarily easy or 
even wanted.

I couldn't find anything in the specification stating this difference.
So... Is it a bug?



Re: GG bug? (OS X Lion, DMD 2.054)

2011-08-03 Thread Magnus Lie Hetland
Note that an explicit call to GC.collect isn't necessary. Whenever 
collection occurs, the collectors seems rather indiscriminate, 
collecting things it shouldn't, resulting in bus errors. When I disable 
the GC, my code runs just fine. (My production code, that is. There are 
still mysterious, probably Lion-related, bugs in my test suite...)


--
Magnus Lie Hetland
http://hetland.org



GG bug? (OS X Lion, DMD 2.054)

2011-08-03 Thread Magnus Lie Hetland
I upgraded from OS X Snow Leopard to Lion recently (on a 32-bit iMac), 
and when I tried to run my D code afterward, I suddenly ran into all 
kinds of interesting problems (lots of failed assertions in my tests, 
and bus errors in my actual runs...). Still cleaning stuff up, but I've 
isolated at least one thing that seems to be a bug, and that wasn't 
there before I upgraded.


Now, I upgraded from DMD 2.052 to 2.054 before doing any extensive 
debugging, so I'm not 100% sure this specific problem was there in 
2.052 as well, but I *think* so (i.e., making the switch to Lion the 
triggering factor).


Anyway, here's some code:

import std.exception, core.memory;

class Foo {
   bool bar;
}

void main() {
   auto f = new Foo;
   f.bar = true;
   //GC.collect();
   enforce(f.bar);
}

Works well, unless you uncomment the GC call, in which case a bus error 
occurs (at least for me). Seems the collector is a bit over-eager...?


--
Magnus Lie Hetland
http://hetland.org



Re: "" gives an empty string, while "".idup gives null

2011-08-03 Thread bearophile
simendsjo:

> void main() {
>  assert(is(typeof("") == typeof("".idup))); // both is immutable(char)[]
> 
>  assert(""  !is null);
>  assert("".idup !is null); // fails - s is null. Why?
> }

I think someone has even suggested to statically forbid "is null" on strings :-)

Bye,
bearophile


Re: Convert string to wchar.

2011-08-03 Thread Jacob Carlborg

On 2011-08-03 09:34, Pelle wrote:

On Wed, 03 Aug 2011 08:29:09 +0200, Jacob Carlborg  wrote:

Yes, convert the first code point to a wchar and then throw if there's
more the one character in the string.



Not tested, and I might be wrong, but 'to!' should work between dchar
and wchar, no?

wchar to_wchar(string s) {
auto c = s.front;
s.popFront();
assert (s.empty);
return to!wchar(c);
}


Ok, thanks.

--
/Jacob Carlborg


Re: Convert string to wchar.

2011-08-03 Thread Jacob Carlborg

On 2011-08-03 08:38, Jonathan M Davis wrote:

On Wednesday 03 August 2011 08:29:09 Jacob Carlborg wrote:

On 2011-08-02 19:51, Jonathan M Davis wrote:

I tried to convert a string into a wchar, but that didn't compile
because of this template constraint:

https://github.com/D-Programming-Language/phobos/blob/master/std/conv.
d#L17 70

Is there a way to convert a string into a wchar?


Does that even make sense? What do you want it to do, convert the first
code point to a wchar and throw if there's more than one character in
the string? That's like asking whether you can covert between a
container of ints and an int. I would never expect std.conv.to to
support that. Not to mention, you shouldn't normally be using char or
wchar by themselves, because they might not be valid code points.
Normally, only dchar should be used when representing an individual
character. If you want this, I'd suggest that you simply do something
like

cast(wchar)str.front

What you're asking for is inherently unsafe as far as unicode goes.

- Jonathan M Davis


I'm working on a serialization library and I intend to support as many
types as possible. So if someone serializes a single wchar I need to be
able to deserialize it. Since the serialized data is represented by a
string, in this case, I need to convert a string containing a single
character to a wchar when deserializing.

Yes, convert the first code point to a wchar and then throw if there's
more the one character in the string.


Well, while it's understandable that you have to cover pretty every possible
case of converting to and from a string with what you're doing, I don't think
that it's at all reasonable to have std.conv.to convert a string to any
character type, let alone one other than dchar. It's almost always a horrible
idea and should _not_ be encouraged. So, I'd advise you to just find a way to
deal with it appropriately in your own code. I think that it would be a very
bad idea for std.conv.to or anything else in Phobos to support such a
conversion.

- Jonathan M Davis


Ok, fair enough.

--
/Jacob Carlborg


"" gives an empty string, while "".idup gives null

2011-08-03 Thread simendsjo

void main() {
assert(is(typeof("") == typeof("".idup))); // both is immutable(char)[]

assert(""  !is null);
assert("".idup !is null); // fails - s is null. Why?
}


Re: Immutable member functions and private members

2011-08-03 Thread simendsjo

On 03.08.2011 12:01, Jonathan M Davis wrote:

On Wednesday 03 August 2011 11:44:27 simendsjo wrote:

On 03.08.2011 10:52, Jonathan M Davis wrote:

On Wednesday 03 August 2011 10:37:58 simendsjo wrote:

I have a struct with a private member that is only ever accessed
through
a single property method - even from within the struct.
As this property fills the value on the first access, it cannot be
immutable, and as such, none of the many methods accessing this
property
can be immutable methods.

This is according to specification, but I thought that since the
single
write to the property is done at one, and only one, access point, that
it would be safe?

I could fill this value in the constructor, but it's a bit slow, so
I'd
rather do it only if needed.

And is there any potential performance optimizations done by the
compiler, or is it "only" for safety?
Is there a way to hack around this, and more importantly, is it safe
to
do so, or will I open Pandora's box?


Small example:

int len(const char[] c) {

   return c.length;

}

struct S {

   private immutable(char)[] _v;
   @property immutable(char[]) v() { // Cannot be immutable
   method

   if(!_v)

   _v = "init"; /* or from external function
   */

   return _v;

   }

   @property int a() { // and so this cannot be immutable
   method

   return len(v); /* notice the property function v
   that might

modify _v */

   }

}

void main() {

   S s;
   s.a;

}


You're basically looking for logical const - albeit a subset which would
be much easier to implement were we to implement it (that is, a lazy
initialized const or immutable member variable). D has no support for
logical const. Even worse, you're looking for logical immutable (which
makes no sense at all beyond perhaps lazy initialization and probably
doesn't even make sense there).

The thing is that immutable methods are pointless unless you make the
struct immutable (if you want to be able to call them with both a
mutable and immutable instance of the struct, then you need the
functions to be const, not immutable). And if you make the struct
immutable, the compiler is free to put it in read-only memory if it so
chooses, at which point setting _anything_ in the struct after the
constructor has run is likely to blow up. So, even if you can get
around the issue via casts and get both lazy initialization and
immutable methods, there's a good chance that it'll blow up at some
point (as in segfault or worse).

If you were trying to do this with const, you might get away with it
(though you'd be stepping outside of the type lsystem by casting away
const and then altering anything - it's undefined behavior). But with
immutable, there's no way that this is a good idea.

Lazy initialization with const or immutable member variables just is
_not_ a good idea in D. D provides no type-safe way to do this. You
must break the type system by casting away const or immutable to even
attempt it. Convievably, in the case of const, the language could be
extended to allow for lazy initialization of member variables, but
there's no way that it could do that with immutable (because the
variable could conceivably be put in read- only memory), and even if it
were done, it would likely have to be a D3 feature. Syntactically, it
would probably be something like this:

lazy int v = initFunc();

and then when v was first accessed, initFunc would be called and v set
to that value. But that could be ugly and inefficient to implement even
if it's theoretically possible, so I wouldn't bet on anything like that
making it into the language. Regardless, it wouldn't be until D3. For
now, D doesn't support any kind of logical const.

http://stackoverflow.com/questions/4219600/logical-const-in-d

- Jonathan M Davis


Thanks!

I'm not really sure the compiler could put my struct in ROM.
My lazy parameter is immutable(char)[], so the compiler should see that
I have a non-immutable reference.

The entire struct is immutable without this lazy variable though.
It only has two handles for passing to external functions.
I really would like to always use it only as immutable s = S(123). It
makes no sense for it to be mutable at all.

Below is an exact example of what I want to do.
If I move the handle2 calculation to the ctor and use const methods, I
still cannot call the methods using a const variable though.. Bug?
const s = S(100);
s.a; // function t.S.a () immutable is not callable using argument type
It says immutable when it should say const..?

immutable s = S(100);
s.a; // works on both const and immutable


If a variable is const, you should only be able to call const functions on it.
If it's immutable, you can call either const or immutable functions. If it's
mutable, then you can call either const or non-const, non-immutable functions.
If it's complaining about being unable to call a function on an immutable
variable whe

Re: Immutable member functions and private members

2011-08-03 Thread Jonathan M Davis
On Wednesday 03 August 2011 12:00:18 simendsjo wrote:
> On 03.08.2011 11:44, simendsjo wrote:
> > On 03.08.2011 10:52, Jonathan M Davis wrote:
> >> On Wednesday 03 August 2011 10:37:58 simendsjo wrote:
> >>> I have a struct with a private member that is only ever accessed
> >>> through a single property method - even from within the struct.
> >>> As this property fills the value on the first access, it cannot be
> >>> immutable, and as such, none of the many methods accessing this
> >>> property can be immutable methods.
> >>> 
> >>> This is according to specification, but I thought that since the
> >>> single
> >>> write to the property is done at one, and only one, access point,
> >>> that
> >>> it would be safe?
> >>> 
> >>> I could fill this value in the constructor, but it's a bit slow, so
> >>> I'd
> >>> rather do it only if needed.
> >>> 
> >>> And is there any potential performance optimizations done by the
> >>> compiler, or is it "only" for safety?
> >>> Is there a way to hack around this, and more importantly, is it safe
> >>> to
> >>> do so, or will I open Pandora's box?
> >>> 
> >>> 
> >>> Small example:
> >>> 
> >>> int len(const char[] c) {
> >>> return c.length;
> >>> }
> >>> 
> >>> struct S {
> >>> private immutable(char)[] _v;
> >>> @property immutable(char[]) v() { // Cannot be immutable method
> >>> if(!_v)
> >>> _v = "init"; /* or from external function */
> >>> return _v;
> >>> }
> >>> 
> >>> @property int a() { // and so this cannot be immutable method
> >>> return len(v); /* notice the property function v that might
> >>> modify _v */
> >>> }
> >>> }
> >>> 
> >>> void main() {
> >>> S s;
> >>> s.a;
> >>> }
> >> 
> >> You're basically looking for logical const - albeit a subset which
> >> would be
> >> much easier to implement were we to implement it (that is, a lazy
> >> initialized
> >> const or immutable member variable). D has no support for logical
> >> const. Even
> >> worse, you're looking for logical immutable (which makes no sense at
> >> all
> >> beyond perhaps lazy initialization and probably doesn't even make
> >> sense
> >> there).
> >> 
> >> The thing is that immutable methods are pointless unless you make the
> >> struct
> >> immutable (if you want to be able to call them with both a mutable and
> >> immutable instance of the struct, then you need the functions to be
> >> const, not
> >> immutable). And if you make the struct immutable, the compiler is free
> >> to put
> >> it in read-only memory if it so chooses, at which point setting
> >> _anything_ in
> >> the struct after the constructor has run is likely to blow up. So,
> >> even if you
> >> can get around the issue via casts and get both lazy initialization
> >> and
> >> immutable methods, there's a good chance that it'll blow up at some
> >> point (as
> >> in segfault or worse).
> >> 
> >> If you were trying to do this with const, you might get away with it
> >> (though
> >> you'd be stepping outside of the type lsystem by casting away const
> >> and then
> >> altering anything - it's undefined behavior). But with immutable,
> >> there's no
> >> way that this is a good idea.
> >> 
> >> Lazy initialization with const or immutable member variables just is
> >> _not_ a
> >> good idea in D. D provides no type-safe way to do this. You must break
> >> the
> >> type system by casting away const or immutable to even attempt it.
> >> Convievably, in the case of const, the language could be extended to
> >> allow for
> >> lazy initialization of member variables, but there's no way that it
> >> could do
> >> that with immutable (because the variable could conceivably be put in
> >> read-
> >> only memory), and even if it were done, it would likely have to be a
> >> D3
> >> feature. Syntactically, it would probably be something like this:
> >> 
> >> lazy int v = initFunc();
> >> 
> >> and then when v was first accessed, initFunc would be called and v set
> >> to that
> >> value. But that could be ugly and inefficient to implement even if
> >> it's
> >> theoretically possible, so I wouldn't bet on anything like that making
> >> it into
> >> the language. Regardless, it wouldn't be until D3. For now, D doesn't
> >> support
> >> any kind of logical const.
> >> 
> >> http://stackoverflow.com/questions/4219600/logical-const-in-d
> >> 
> >> - Jonathan M Davis
> > 
> > Thanks!
> > 
> > I'm not really sure the compiler could put my struct in ROM.
> > My lazy parameter is immutable(char)[], so the compiler should see that
> > I have a non-immutable reference.
> > 
> > The entire struct is immutable without this lazy variable though.
> > It only has two handles for passing to external functions.
> > I really would like to always use it only as immutable s = S(123). It
> > makes no sense for it to be mutable at all.
> > 
> > Below is an exact example of what I want to do.
> > If I move the handle2 calculation to the ctor and use const methods, I
> > still cannot call the methods using a const variable though.. Bug?
> > const s = S(10

Re: Immutable member functions and private members

2011-08-03 Thread simendsjo

On 03.08.2011 11:44, simendsjo wrote:

On 03.08.2011 10:52, Jonathan M Davis wrote:

On Wednesday 03 August 2011 10:37:58 simendsjo wrote:

I have a struct with a private member that is only ever accessed through
a single property method - even from within the struct.
As this property fills the value on the first access, it cannot be
immutable, and as such, none of the many methods accessing this property
can be immutable methods.

This is according to specification, but I thought that since the single
write to the property is done at one, and only one, access point, that
it would be safe?

I could fill this value in the constructor, but it's a bit slow, so I'd
rather do it only if needed.

And is there any potential performance optimizations done by the
compiler, or is it "only" for safety?
Is there a way to hack around this, and more importantly, is it safe to
do so, or will I open Pandora's box?


Small example:

int len(const char[] c) {
return c.length;
}

struct S {
private immutable(char)[] _v;
@property immutable(char[]) v() { // Cannot be immutable method
if(!_v)
_v = "init"; /* or from external function */
return _v;
}

@property int a() { // and so this cannot be immutable method
return len(v); /* notice the property function v that might
modify _v */
}
}

void main() {
S s;
s.a;
}


You're basically looking for logical const - albeit a subset which
would be
much easier to implement were we to implement it (that is, a lazy
initialized
const or immutable member variable). D has no support for logical
const. Even
worse, you're looking for logical immutable (which makes no sense at all
beyond perhaps lazy initialization and probably doesn't even make sense
there).

The thing is that immutable methods are pointless unless you make the
struct
immutable (if you want to be able to call them with both a mutable and
immutable instance of the struct, then you need the functions to be
const, not
immutable). And if you make the struct immutable, the compiler is free
to put
it in read-only memory if it so chooses, at which point setting
_anything_ in
the struct after the constructor has run is likely to blow up. So,
even if you
can get around the issue via casts and get both lazy initialization and
immutable methods, there's a good chance that it'll blow up at some
point (as
in segfault or worse).

If you were trying to do this with const, you might get away with it
(though
you'd be stepping outside of the type lsystem by casting away const
and then
altering anything - it's undefined behavior). But with immutable,
there's no
way that this is a good idea.

Lazy initialization with const or immutable member variables just is
_not_ a
good idea in D. D provides no type-safe way to do this. You must break
the
type system by casting away const or immutable to even attempt it.
Convievably, in the case of const, the language could be extended to
allow for
lazy initialization of member variables, but there's no way that it
could do
that with immutable (because the variable could conceivably be put in
read-
only memory), and even if it were done, it would likely have to be a D3
feature. Syntactically, it would probably be something like this:

lazy int v = initFunc();

and then when v was first accessed, initFunc would be called and v set
to that
value. But that could be ugly and inefficient to implement even if it's
theoretically possible, so I wouldn't bet on anything like that making
it into
the language. Regardless, it wouldn't be until D3. For now, D doesn't
support
any kind of logical const.

http://stackoverflow.com/questions/4219600/logical-const-in-d

- Jonathan M Davis


Thanks!

I'm not really sure the compiler could put my struct in ROM.
My lazy parameter is immutable(char)[], so the compiler should see that
I have a non-immutable reference.

The entire struct is immutable without this lazy variable though.
It only has two handles for passing to external functions.
I really would like to always use it only as immutable s = S(123). It
makes no sense for it to be mutable at all.

Below is an exact example of what I want to do.
If I move the handle2 calculation to the ctor and use const methods, I
still cannot call the methods using a const variable though.. Bug?
const s = S(100);
s.a; // function t.S.a () immutable is not callable using argument type
It says immutable when it should say const..?

immutable s = S(100);
s.a; // works on both const and immutable



import std.conv, std.exception;

// external expensive function
extern(System) char[] getHandle2(const int handle) {
return to!(char[])(handle);
}

// other external functions taking string handle instead of int
extern(System) int extFunc1(string handle2) {
return to!int(handle2);
}

struct S {
immutable int handle;
private immutable(char)[] _handle2;

this(int handle) {
this.handle = handle;
}

@property immutable(char[]) handle2() {
if(!_handle2) {
auto buf = getHandle2(handle);
_handle2 = assumeUnique(buf);
}
return _handle2;
}

@property int

Re: Immutable member functions and private members

2011-08-03 Thread Jonathan M Davis
On Wednesday 03 August 2011 11:44:27 simendsjo wrote:
> On 03.08.2011 10:52, Jonathan M Davis wrote:
> > On Wednesday 03 August 2011 10:37:58 simendsjo wrote:
> >> I have a struct with a private member that is only ever accessed
> >> through
> >> a single property method - even from within the struct.
> >> As this property fills the value on the first access, it cannot be
> >> immutable, and as such, none of the many methods accessing this
> >> property
> >> can be immutable methods.
> >> 
> >> This is according to specification, but I thought that since the
> >> single
> >> write to the property is done at one, and only one, access point, that
> >> it would be safe?
> >> 
> >> I could fill this value in the constructor, but it's a bit slow, so
> >> I'd
> >> rather do it only if needed.
> >> 
> >> And is there any potential performance optimizations done by the
> >> compiler, or is it "only" for safety?
> >> Is there a way to hack around this, and more importantly, is it safe
> >> to
> >> do so, or will I open Pandora's box?
> >> 
> >> 
> >> Small example:
> >> 
> >> int len(const char[] c) {
> >> 
> >>   return c.length;
> >> 
> >> }
> >> 
> >> struct S {
> >> 
> >>   private immutable(char)[] _v;
> >>   @property immutable(char[]) v() { // Cannot be immutable
> >>   method
> >>   
> >>   if(!_v)
> >>   
> >>   _v = "init"; /* or from external function
> >>   */
> >>   
> >>   return _v;
> >>   
> >>   }
> >>   
> >>   @property int a() { // and so this cannot be immutable
> >>   method
> >>   
> >>   return len(v); /* notice the property function v
> >>   that might
> >> 
> >> modify _v */
> >> 
> >>   }
> >> 
> >> }
> >> 
> >> void main() {
> >> 
> >>   S s;
> >>   s.a;
> >> 
> >> }
> > 
> > You're basically looking for logical const - albeit a subset which would
> > be much easier to implement were we to implement it (that is, a lazy
> > initialized const or immutable member variable). D has no support for
> > logical const. Even worse, you're looking for logical immutable (which
> > makes no sense at all beyond perhaps lazy initialization and probably
> > doesn't even make sense there).
> > 
> > The thing is that immutable methods are pointless unless you make the
> > struct immutable (if you want to be able to call them with both a
> > mutable and immutable instance of the struct, then you need the
> > functions to be const, not immutable). And if you make the struct
> > immutable, the compiler is free to put it in read-only memory if it so
> > chooses, at which point setting _anything_ in the struct after the
> > constructor has run is likely to blow up. So, even if you can get
> > around the issue via casts and get both lazy initialization and
> > immutable methods, there's a good chance that it'll blow up at some
> > point (as in segfault or worse).
> > 
> > If you were trying to do this with const, you might get away with it
> > (though you'd be stepping outside of the type lsystem by casting away
> > const and then altering anything - it's undefined behavior). But with
> > immutable, there's no way that this is a good idea.
> > 
> > Lazy initialization with const or immutable member variables just is
> > _not_ a good idea in D. D provides no type-safe way to do this. You
> > must break the type system by casting away const or immutable to even
> > attempt it. Convievably, in the case of const, the language could be
> > extended to allow for lazy initialization of member variables, but
> > there's no way that it could do that with immutable (because the
> > variable could conceivably be put in read- only memory), and even if it
> > were done, it would likely have to be a D3 feature. Syntactically, it
> > would probably be something like this:
> > 
> > lazy int v = initFunc();
> > 
> > and then when v was first accessed, initFunc would be called and v set
> > to that value. But that could be ugly and inefficient to implement even
> > if it's theoretically possible, so I wouldn't bet on anything like that
> > making it into the language. Regardless, it wouldn't be until D3. For
> > now, D doesn't support any kind of logical const.
> > 
> > http://stackoverflow.com/questions/4219600/logical-const-in-d
> > 
> > - Jonathan M Davis
> 
> Thanks!
> 
> I'm not really sure the compiler could put my struct in ROM.
> My lazy parameter is immutable(char)[], so the compiler should see that
> I have a non-immutable reference.
> 
> The entire struct is immutable without this lazy variable though.
> It only has two handles for passing to external functions.
> I really would like to always use it only as immutable s = S(123). It
> makes no sense for it to be mutable at all.
> 
> Below is an exact example of what I want to do.
> If I move the handle2 calculation to the ctor and use const methods, I
> still cannot call the methods using a const variable though.. Bug?
>const s = S(100);

Re: Immutable member functions and private members

2011-08-03 Thread simendsjo

On 03.08.2011 10:52, Jonathan M Davis wrote:

On Wednesday 03 August 2011 10:37:58 simendsjo wrote:

I have a struct with a private member that is only ever accessed through
a single property method - even from within the struct.
As this property fills the value on the first access, it cannot be
immutable, and as such, none of the many methods accessing this property
can be immutable methods.

This is according to specification, but I thought that since the single
write to the property is done at one, and only one, access point, that
it would be safe?

I could fill this value in the constructor, but it's a bit slow, so I'd
rather do it only if needed.

And is there any potential performance optimizations done by the
compiler, or is it "only" for safety?
Is there a way to hack around this, and more importantly, is it safe to
do so, or will I open Pandora's box?


Small example:

int len(const char[] c) {
  return c.length;
}

struct S {
  private immutable(char)[] _v;
  @property immutable(char[]) v() { // Cannot be immutable method
  if(!_v)
  _v = "init"; /* or from external function */
  return _v;
  }

  @property int a() { // and so this cannot be immutable method
  return len(v); /* notice the property function v that might
modify _v */
  }
}

void main() {
  S s;
  s.a;
}


You're basically looking for logical const - albeit a subset which would be
much easier to implement were we to implement it (that is, a lazy initialized
const or immutable member variable). D has no support for logical const. Even
worse, you're looking for logical immutable (which makes no sense at all
beyond perhaps lazy initialization and probably doesn't even make sense
there).

The thing is that immutable methods are pointless unless you make the struct
immutable (if you want to be able to call them with both a mutable and
immutable instance of the struct, then you need the functions to be const, not
immutable). And if you make the struct immutable, the compiler is free to put
it in read-only memory if it so chooses, at which point setting _anything_ in
the struct after the constructor has run is likely to blow up. So, even if you
can get around the issue via casts and get both lazy initialization and
immutable methods, there's a good chance that it'll blow up at some point (as
in segfault or worse).

If you were trying to do this with const, you might get away with it (though
you'd be stepping outside of the type lsystem by casting away const and then
altering anything - it's undefined behavior). But with immutable, there's no
way that this is a good idea.

Lazy initialization with const or immutable member variables just is _not_ a
good idea in D. D provides no type-safe way to do this. You must break the
type system by casting away const or immutable to even attempt it.
Convievably, in the case of const, the language could be extended to allow for
lazy initialization of member variables, but there's no way that it could do
that with immutable (because the variable could conceivably be put in read-
only memory), and even if it were done, it would likely have to be a D3
feature. Syntactically, it would probably be something like this:

lazy int v = initFunc();

and then when v was first accessed, initFunc would be called and v set to that
value. But that could be ugly and inefficient to implement even if it's
theoretically possible, so I wouldn't bet on anything like that making it into
the language. Regardless, it wouldn't be until D3. For now, D doesn't support
any kind of logical const.

http://stackoverflow.com/questions/4219600/logical-const-in-d

- Jonathan M Davis


Thanks!

I'm not really sure the compiler could put my struct in ROM.
My lazy parameter is immutable(char)[], so the compiler should see that 
I have a non-immutable reference.


The entire struct is immutable without this lazy variable though.
It only has two handles for passing to external functions.
I really would like to always use it only as immutable s = S(123). It 
makes no sense for it to be mutable at all.


Below is an exact example of what I want to do.
If I move the handle2 calculation to the ctor and use const methods, I 
still cannot call the methods using a const variable though.. Bug?

  const s = S(100);
  s.a; // function t.S.a () immutable is not callable using argument type
It says immutable when it should say const..?

  immutable s = S(100);
  s.a; // works on both const and immutable



import std.conv, std.exception;

// external expensive function
extern(System) char[] getHandle2(const int handle) {
return to!(char[])(handle);
}

// other external functions taking string handle instead of int
extern(System) int extFunc1(string handle2) {
return to!int(handle2);
}

struct S {
immutable int handle;
private immutable(char)[] _handle2;

this(int handle) {
this.handle = handle;
}

@property immutable(char[]) handle2() {
i

Re: Immutable member functions and private members

2011-08-03 Thread Jonathan M Davis
On Wednesday 03 August 2011 10:37:58 simendsjo wrote:
> I have a struct with a private member that is only ever accessed through
> a single property method - even from within the struct.
> As this property fills the value on the first access, it cannot be
> immutable, and as such, none of the many methods accessing this property
> can be immutable methods.
> 
> This is according to specification, but I thought that since the single
> write to the property is done at one, and only one, access point, that
> it would be safe?
> 
> I could fill this value in the constructor, but it's a bit slow, so I'd
> rather do it only if needed.
> 
> And is there any potential performance optimizations done by the
> compiler, or is it "only" for safety?
> Is there a way to hack around this, and more importantly, is it safe to
> do so, or will I open Pandora's box?
> 
> 
> Small example:
> 
> int len(const char[] c) {
>  return c.length;
> }
> 
> struct S {
>  private immutable(char)[] _v;
>  @property immutable(char[]) v() { // Cannot be immutable method
>  if(!_v)
>  _v = "init"; /* or from external function */
>  return _v;
>  }
> 
>  @property int a() { // and so this cannot be immutable method
>  return len(v); /* notice the property function v that might
> modify _v */
>  }
> }
> 
> void main() {
>  S s;
>  s.a;
> }

You're basically looking for logical const - albeit a subset which would be 
much easier to implement were we to implement it (that is, a lazy initialized 
const or immutable member variable). D has no support for logical const. Even 
worse, you're looking for logical immutable (which makes no sense at all 
beyond perhaps lazy initialization and probably doesn't even make sense 
there).

The thing is that immutable methods are pointless unless you make the struct 
immutable (if you want to be able to call them with both a mutable and 
immutable instance of the struct, then you need the functions to be const, not 
immutable). And if you make the struct immutable, the compiler is free to put 
it in read-only memory if it so chooses, at which point setting _anything_ in 
the struct after the constructor has run is likely to blow up. So, even if you 
can get around the issue via casts and get both lazy initialization and 
immutable methods, there's a good chance that it'll blow up at some point (as 
in segfault or worse).

If you were trying to do this with const, you might get away with it (though 
you'd be stepping outside of the type lsystem by casting away const and then 
altering anything - it's undefined behavior). But with immutable, there's no 
way that this is a good idea.

Lazy initialization with const or immutable member variables just is _not_ a 
good idea in D. D provides no type-safe way to do this. You must break the 
type system by casting away const or immutable to even attempt it. 
Convievably, in the case of const, the language could be extended to allow for 
lazy initialization of member variables, but there's no way that it could do 
that with immutable (because the variable could conceivably be put in read-
only memory), and even if it were done, it would likely have to be a D3 
feature. Syntactically, it would probably be something like this:

lazy int v = initFunc();

and then when v was first accessed, initFunc would be called and v set to that 
value. But that could be ugly and inefficient to implement even if it's 
theoretically possible, so I wouldn't bet on anything like that making it into 
the language. Regardless, it wouldn't be until D3. For now, D doesn't support 
any kind of logical const.

http://stackoverflow.com/questions/4219600/logical-const-in-d

- Jonathan M Davis


Immutable member functions and private members

2011-08-03 Thread simendsjo
I have a struct with a private member that is only ever accessed through 
a single property method - even from within the struct.
As this property fills the value on the first access, it cannot be 
immutable, and as such, none of the many methods accessing this property 
can be immutable methods.


This is according to specification, but I thought that since the single 
write to the property is done at one, and only one, access point, that 
it would be safe?


I could fill this value in the constructor, but it's a bit slow, so I'd 
rather do it only if needed.


And is there any potential performance optimizations done by the 
compiler, or is it "only" for safety?
Is there a way to hack around this, and more importantly, is it safe to 
do so, or will I open Pandora's box?



Small example:

int len(const char[] c) {
return c.length;
}

struct S {
private immutable(char)[] _v;
@property immutable(char[]) v() { // Cannot be immutable method
if(!_v)
_v = "init"; /* or from external function */
return _v;
}

@property int a() { // and so this cannot be immutable method
return len(v); /* notice the property function v that might 
modify _v */

}
}

void main() {
S s;
s.a;
}


Re: Convert string to wchar.

2011-08-03 Thread Jonathan M Davis
On Wednesday 03 August 2011 01:02:02 Jonathan M Davis wrote:
> On Wednesday 03 August 2011 09:34:53 Pelle wrote:
> > On Wed, 03 Aug 2011 08:29:09 +0200, Jacob Carlborg  wrote:
> > > Yes, convert the first code point to a wchar and then throw if
> > > there's
> > > more the one character in the string.
> > 
> > Not tested, and I might be wrong, but 'to!' should work between dchar
> > and
> > wchar, no?
> > 
> > wchar to_wchar(string s) {
> > 
> >  auto c = s.front;
> >  s.popFront();
> >  assert (s.empty);
> >  return to!wchar(c);
> > 
> > }
> 
> It's debatable as to whether std.conv.to should be able to convert between
> code units like that (you _really_ shouldn't ever be using char or wchar
> outside of arrays or other ranges), but it does appear to compile, for
> better or worse.

It looks like the conversion works as long as the character in question will 
fit in the character type that you're converting to. If it doesn't fit, then it 
throws. So, it's as safe as such a conversion can be (though it still isn't 
generally a good idea to use individual chars or wchars in code).

- Jonathan M Davis


Re: Convert string to wchar.

2011-08-03 Thread Jonathan M Davis
On Wednesday 03 August 2011 09:34:53 Pelle wrote:
> On Wed, 03 Aug 2011 08:29:09 +0200, Jacob Carlborg  wrote:
> > Yes, convert the first code point to a wchar and then throw if there's
> > more the one character in the string.
> 
> Not tested, and I might be wrong, but 'to!' should work between dchar and
> wchar, no?
> 
> wchar to_wchar(string s) {
>  auto c = s.front;
>  s.popFront();
>  assert (s.empty);
>  return to!wchar(c);
> }

It's debatable as to whether std.conv.to should be able to convert between 
code units like that (you _really_ shouldn't ever be using char or wchar 
outside of arrays or other ranges), but it does appear to compile, for better 
or worse.

- Jonathan M Davis


Re: Convert string to wchar.

2011-08-03 Thread Pelle

On Wed, 03 Aug 2011 08:29:09 +0200, Jacob Carlborg  wrote:
Yes, convert the first code point to a wchar and then throw if there's  
more the one character in the string.




Not tested, and I might be wrong, but 'to!' should work between dchar and  
wchar, no?


wchar to_wchar(string s) {
auto c = s.front;
s.popFront();
assert (s.empty);
return to!wchar(c);
}


Re: NaCl stable ABI

2011-08-03 Thread Peter Alexander

On 2/08/11 2:24 AM, Adam Ruppe wrote:

 From what I can tell, it's Google's alternative to Flash; they want
to make crappy games on it.

Consider that the first thing they ported to it, again, just like
their javascript nonsense, was Quake. (I think Google loves
Javascript too much to let it go anyway.)

The API has a lot of graphics and audio stuff too which reinforces
this.


The games industry has been crying out for something like NaCl for a 
long time. It is exactly what we want:


- Ability to launch games within browser without a plugin download
- Platform independent ABI
- No f*cking Javascript (performance will never match C++)
- Safe (no need for end users to worry)


JavaScript for high-quality games is a non-starter. It's too slow. You 
simply cannot do high performance numeric code in Javascript 
(http://chadaustin.me/2011/01/digging-into-javascript-performance/).


Writing C++ code to run outside of the browser is a pain, and 
inconvenient for the user. First, you have to write your code to handle 
all the different platforms, which is a huge burden. Once you've done 
that, you need to convince users to download and install your game. It 
would be much more convenient to just have users go a website and be 
done with it.


If D were usable in NaCl that would be a huge selling point for the 
language.