Optional braces

2011-08-19 Thread Jacob Carlborg
This might sound like a crazy idea. I don't expect everyone to drop what 
they're doing and start to implement this, it's just an idea.


In Java (C, C++ and others) braces are optional for statements like if, 
while, for and so on, containing only one expression. In D this is true 
as well, but compared with Java, D also allow try, catch and finally 
statements to have optional braces.


What about extending this to allow optional braces everywhere, where the 
braces contain a single expression? I'm thinking this will be most 
useful for functions/methods, templates and delegates. Specially for 
methods acting as properties that just forwards a value.


Examples:

class Foo
{
private int a_;
int a () return a_;
int a (int a) return a_ = a;
}

template Bar (T) alias T FooBar;

auto foo = delegate () return 3;
auto bar = return 3; // don't if this would be possible

--
/Jacob Carlborg


Re: Is std.log ready for review?

2011-08-19 Thread Jose Armando Garcia
Sorry guys for disappearing. I'll put some time into this...

On Wed, Aug 10, 2011 at 12:52 AM, Jonathan M Davis jmdavisp...@gmx.com wrote:
 Jose, are you ready for std.log to be reviewed? I believe that it's the item
 which has been in the review queue the longest at this point. So, if you're
 ready, then it should be reviewed. If you're not ready, then it sounds like
 the curl wrapper _is_ ready, and we'll probably move on with reviewing that.
 So, the question is: are you ready for std.log to be reviewed?

 - Jonathan M Davis



Re: CURL review request

2011-08-19 Thread Timon Gehr

On 08/19/2011 01:50 AM, Jonathan M Davis wrote:

On Thursday, August 18, 2011 16:00 Timon Gehr wrote:

On 08/19/2011 12:35 AM, Jonathan M Davis wrote:

On Thursday, August 18, 2011 14:33 jdrewsen wrote:

Den 17-08-2011 18:21, Timon Gehr skrev:

On 08/17/2011 05:58 PM, Jonathan M Davis wrote:

On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote:

On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com

wrote:

Den 17-08-2011 15:51, Steven Schveighoffer skrev:

On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen
jdrew...@nospam.com

wrote:

On 17/08/11 00.21, Jonathan M Davis wrote:

On Tuesday, August 16, 2011 12:32 Martin Nowak wrote:

On Tue, 16 Aug 2011 20:48:51 +0200,
jdrewsenjdrew...@nospam.com

wrote:

Den 16-08-2011 18:55, Martin Nowak skrev:

On Tue, 16 Aug 2011 15:13:40 +0200,
dsimchadsim...@yahoo.com

wrote:

On 8/16/2011 7:48 AM, Jonas Drewsen wrote:

Hi all,

This is a review request for the curl wrapper. Please
read the
known
issues in the top of the source file and if possible
suggest a
solution.

We also need somebody for running the review process.
Anyone?

Code:
https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl
.d
Docs:
http://freeze.steamwinter.com/D/web/phobos/etc_curl.html

Demolish!

/Jonas


 From a quick look, this looks very well thought out. I'll

review
it
more thoroughly when I have more time. A few
questions/comments
from a
quick look at the docs:

Does the async stuff use D threads, or does Curl have its
own
async
API?

In your examples for postData, you have onReceive a
ubyte[] and
write
it out to console. Did you mean to cast this to some kind
of
string?

For onReceive, what's the purpose of the return value?

If/when this module makes it into Phobos, are we going to
start
including a libcurl binary with DMD distributions so that
std.curl
feels truly **standard** and requires zero extra
configuration?


I was also wondering about the async handling. In the
long-term
I'd like
to see a bigger picture for async handling in phobos
(offering
some kind
of futures, maybe event-loops etc.).
Though this is not a requirement for the curl wrapper now.
std.parallelism also has some kind of this stuff and file
reading
would
benefit from it too.


This has been discussed before and I also think this is very
important.
But before that I think some kind of package management should
be
prioritized (A DIP11 implementaion or a more traditional
solution).


One thing I spotted at a quick glance, sending to be filled
buffers to
another thread should not be done by casting to shared not
immutable.


I'm not entirely sure what you mean. There is no use of shared
buffers
in the wrapper. I do cast the buffer between mutable/immutable
because
only immutable or by value data can be passed using
std.concurrency.
Since the buffers are only used by the thread that currently
has the
buffer this is safe. I've previously asked for a non-cast
solution
(ie.
some kind of move between threads semantic for
std.concurrency) but
was
advised that this was the way to do it.


martin


Pardon the typo. What I meant is that AFAIK casting from
immutable to
mutable has undefined behavior.
The intended method for sending a uint[] buffer to another
thread is
to
cast that
buffer to shared (cast(shared(uint[])) and casting away the
shared
on the
receiving side.
It is allowed to send shared data using std.concurrency.


Casting away immutability and then altering data is undefined.
Actually
casting it away is defined. So, if you have data in one thread
that
you know
is unique, you can cast it to immutable (or
std.exception.assumeUnique to do
it) and then send it to another thread. On that thread, you can
then
cast it
to mutable and alter it.

However, you're circumventing the type system when you do this.
So,
you have
to be very careful. You're throwing away the guarantees that the
compiler
makes with regards to const and immutable. It _is_ guaranteed to
work
though.
And I'm not sure that there's really any difference between
casting
to shared
and back and casting to immutable and back. In both cases, you're
circumventing the type system. The main difference would be that
if
you
screwed up with immutable and cast away immutable on something
that
really was
immutable rather than something that you cast to immutable just
to send it to
another thread, then you could a segfault when you tried to alter
it,
since it
could be in ROM.

- Jonathan M Davis


Yeah I know you have to be careful when doing these kind of
things. I
ran into the problem of sending buffers between threads (using
std.concurrency) so that they could be reused. There isn't any
move ownership support in place so Andrei suggested I could do
it by casting immutable.

If anyone knows of a cleaner way to do this please tell.


casting to shared and back. Passing shared data should be supported
by std.concurrency, and casting away shared is defined as long as
you know
only one thread owns the data after casting.

-Steve


Why is this 

Re: Optional braces

2011-08-19 Thread Timon Gehr

On 08/19/2011 08:50 AM, Jacob Carlborg wrote:

This might sound like a crazy idea. I don't expect everyone to drop what
they're doing and start to implement this, it's just an idea.

In Java (C, C++ and others) braces are optional for statements like if,
while, for and so on, containing only one expression. In D this is true
as well, but compared with Java, D also allow try, catch and finally
statements to have optional braces.

What about extending this to allow optional braces everywhere, where the
braces contain a single expression? I'm thinking this will be most
useful for functions/methods, templates and delegates. Specially for
methods acting as properties that just forwards a value.

Examples:

class Foo
{
private int a_;
int a () return a_;
int a (int a) return a_ = a;
}



I think this makes code harder to read for no obvious benefit.
I don't think this is any better than

class Foo{
private int a_;
int a(){return a_;}
int a(int a){return a_ = a;}
}



template Bar (T) alias T FooBar;


This one I'd probably use.



auto foo = delegate () return 3;
auto bar = return 3; // don't if this would be possible

{return 3;} is better than both of them imo.







Re: Why do struct literals count as lvalues?

2011-08-19 Thread Steven Schveighoffer
On Thu, 18 Aug 2011 18:56:01 -0400, bearophile bearophileh...@lycos.com  
wrote:



Jonathan M Davis:


I see _zero_ reason to
treat a newly constructed object as any different from one which is  
returned

from a function.


I have not followed fully this thread, so I am not sure what you are  
talking about, so sorry if I am misunderstanding the whole topic.


I assume you want to disallow code like:

struct Vect {
float[4] data = 0.0;
// lot of operator overloading here, all arguments are by ref
}
void foo(ref Vect f) {}
void main() {
foo(Vect([1,2,3,4]));
}

Such code is common. In foo() and in all the Vect operators ref is  
required for performance. This code is quite handy. Forcing me to define  
and assign a Vect to a temporary variable in main is not handy.


Think about writing expressions that use Vects with operator  
overloading, that use ref everywhere. If you can't pass and give Vects  
defined inside the expressions the code becomes quite more hairy.


I believe auto ref is slated to fix this problem.

-Steve


Re: Optional braces

2011-08-19 Thread Trass3r

Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr timon.g...@gmx.ch:

I think this makes code harder to read for no obvious benefit.
I don't think this is any better than

class Foo{
 private int a_;
 int a(){return a_;}
 int a(int a){return a_ = a;}
}


+1

Optional braces should be limited to statements.


Re: Clang with SAFECode

2011-08-19 Thread Walter Bright

bearophile wrote:

I'd like some optional functionality like SAFECode in the D compiler too.


Very little code in a D program needs to be @system, so I see little 
need for this.


Re: Why do struct literals count as lvalues?

2011-08-19 Thread Timon Gehr

On 08/19/2011 02:16 PM, Steven Schveighoffer wrote:

On Thu, 18 Aug 2011 18:56:01 -0400, bearophile
bearophileh...@lycos.com wrote:


Jonathan M Davis:


I see _zero_ reason to
treat a newly constructed object as any different from one which is
returned
from a function.


I have not followed fully this thread, so I am not sure what you are
talking about, so sorry if I am misunderstanding the whole topic.

I assume you want to disallow code like:

struct Vect {
float[4] data = 0.0;
// lot of operator overloading here, all arguments are by ref
}
void foo(ref Vect f) {}
void main() {
foo(Vect([1,2,3,4]));
}

Such code is common. In foo() and in all the Vect operators ref is
required for performance. This code is quite handy. Forcing me to
define and assign a Vect to a temporary variable in main is not handy.

Think about writing expressions that use Vects with operator
overloading, that use ref everywhere. If you can't pass and give Vects
defined inside the expressions the code becomes quite more hairy.


I believe auto ref is slated to fix this problem.

-Steve


auto ref currently treats struct literals as lvalues too. (therefore, as 
ref). And passing by value would be considerably less efficient for 
large structs.


As I understand it, the only issue with allowing literals and function 
results as lvalues is that generic code cannot detect if it is working 
with a temporary or not. I don't know if this would be useful in D though.


each code segment of the form:

void foo(ref S);
...
foo(S(...));

is equivalent to one explicitly declaring the temporary:

{auto __temp=S(...); foo(__temp);}

The difference is that the first is more pleasant to write. If 
temporaries would become rvalues everyone would always have to write the 
second form manually. So imho it is just a syntax sugar issue.


I'd actually argue that ref-passing should work for arbitrary function 
results too.
















Re: Why do struct literals count as lvalues?

2011-08-19 Thread kenji hara
2011/8/19 Timon Gehr timon.g...@gmx.ch:
 On 08/19/2011 02:16 PM, Steven Schveighoffer wrote:

 On Thu, 18 Aug 2011 18:56:01 -0400, bearophile
 bearophileh...@lycos.com wrote:

 Jonathan M Davis:

 I see _zero_ reason to
 treat a newly constructed object as any different from one which is
 returned
 from a function.

 I have not followed fully this thread, so I am not sure what you are
 talking about, so sorry if I am misunderstanding the whole topic.

 I assume you want to disallow code like:

 struct Vect {
 float[4] data = 0.0;
 // lot of operator overloading here, all arguments are by ref
 }
 void foo(ref Vect f) {}
 void main() {
 foo(Vect([1,2,3,4]));
 }

 Such code is common. In foo() and in all the Vect operators ref is
 required for performance. This code is quite handy. Forcing me to
 define and assign a Vect to a temporary variable in main is not handy.

 Think about writing expressions that use Vects with operator
 overloading, that use ref everywhere. If you can't pass and give Vects
 defined inside the expressions the code becomes quite more hairy.

 I believe auto ref is slated to fix this problem.

 -Steve

 auto ref currently treats struct literals as lvalues too. (therefore, as
 ref). And passing by value would be considerably less efficient for large
 structs.

 As I understand it, the only issue with allowing literals and function
 results as lvalues is that generic code cannot detect if it is working with
 a temporary or not. I don't know if this would be useful in D though.

 each code segment of the form:

 void foo(ref S);
 ...
 foo(S(...));

 is equivalent to one explicitly declaring the temporary:

 {auto __temp=S(...); foo(__temp);}

 The difference is that the first is more pleasant to write. If temporaries
 would become rvalues everyone would always have to write the second form
 manually. So imho it is just a syntax sugar issue.

 I'd actually argue that ref-passing should work for arbitrary function
 results too.

As far as I know, Andrei's original 'auto ref' means always receive
argument *by reference* either it is lvalue or rvalue, and it works
with non template function.

But, unfortunately, it doesn't exist in current D.

Kenji Hara


Re: Why do struct literals count as lvalues?

2011-08-19 Thread Timon Gehr

On 08/19/2011 03:04 PM, kenji hara wrote:

2011/8/19 Timon Gehrtimon.g...@gmx.ch:

On 08/19/2011 02:16 PM, Steven Schveighoffer wrote:


On Thu, 18 Aug 2011 18:56:01 -0400, bearophile
bearophileh...@lycos.com  wrote:


Jonathan M Davis:


I see _zero_ reason to
treat a newly constructed object as any different from one which is
returned
from a function.


I have not followed fully this thread, so I am not sure what you are
talking about, so sorry if I am misunderstanding the whole topic.

I assume you want to disallow code like:

struct Vect {
float[4] data = 0.0;
// lot of operator overloading here, all arguments are by ref
}
void foo(ref Vect f) {}
void main() {
foo(Vect([1,2,3,4]));
}

Such code is common. In foo() and in all the Vect operators ref is
required for performance. This code is quite handy. Forcing me to
define and assign a Vect to a temporary variable in main is not handy.

Think about writing expressions that use Vects with operator
overloading, that use ref everywhere. If you can't pass and give Vects
defined inside the expressions the code becomes quite more hairy.


I believe auto ref is slated to fix this problem.

-Steve


auto ref currently treats struct literals as lvalues too. (therefore, as
ref). And passing by value would be considerably less efficient for large
structs.

As I understand it, the only issue with allowing literals and function
results as lvalues is that generic code cannot detect if it is working with
a temporary or not. I don't know if this would be useful in D though.

each code segment of the form:

void foo(ref S);
...
foo(S(...));

is equivalent to one explicitly declaring the temporary:

{auto __temp=S(...); foo(__temp);}

The difference is that the first is more pleasant to write. If temporaries
would become rvalues everyone would always have to write the second form
manually. So imho it is just a syntax sugar issue.

I'd actually argue that ref-passing should work for arbitrary function
results too.


As far as I know, Andrei's original 'auto ref' means always receive
argument *by reference* either it is lvalue or rvalue, and it works
with non template function.

But, unfortunately, it doesn't exist in current D.

Kenji Hara


Oh, interesting. So why were they implemented with different semantics 
then? Also, how would they work in a non-templated function? Would they 
just be conservatively treated as rvalues in the function body?





newsgroup availability

2011-08-19 Thread Steven Schveighoffer
Has there been some strange issue with the newsgroup lately?  Frequently,  
I'm getting load errors (I assume this means the NG load is too large to  
deal with my communication).


It seems to be happening daily...

-Steve


Re: Why do struct literals count as lvalues?

2011-08-19 Thread kennytm
Timon Gehr timon.g...@gmx.ch wrote:

 auto ref currently treats struct literals as lvalues too. (therefore, as
 ref). And passing by value would be considerably less efficient for large 
 structs.
 
 As I understand it, the only issue with allowing literals and function
 results as lvalues is that generic code cannot detect if it is working
 with a temporary or not. I don't know if this would be useful in D though.
 
 each code segment of the form:
 
 void foo(ref S);
 ...
 foo(S(...));
 
 is equivalent to one explicitly declaring the temporary:
 
 {auto __temp=S(...); foo(__temp);}
 
 The difference is that the first is more pleasant to write. If
 temporaries would become rvalues everyone would always have to write the
 second form manually. So imho it is just a syntax sugar issue.
 
 I'd actually argue that ref-passing should work for arbitrary function 
 results too.

Here I propose that we go a step further and abolish the notion of rvalue
and lvalue entirely, and let the compiler insert necessary temporary
variable when needed, so that we can finally write things like

uint w;
memcpy(w, 5.0f, w.sizeof);
13u = w;

/joking


Re: newsgroup availability

2011-08-19 Thread Timon Gehr

On 08/19/2011 03:44 PM, Steven Schveighoffer wrote:

Has there been some strange issue with the newsgroup lately? Frequently,
I'm getting load errors (I assume this means the NG load is too large to
deal with my communication).

It seems to be happening daily...

-Steve


It has been the same for me.


Re: Why do struct literals count as lvalues?

2011-08-19 Thread Timon Gehr

On 08/19/2011 03:46 PM, kennytm wrote:

Timon Gehrtimon.g...@gmx.ch  wrote:


auto ref currently treats struct literals as lvalues too. (therefore, as
ref). And passing by value would be considerably less efficient for large 
structs.

As I understand it, the only issue with allowing literals and function
results as lvalues is that generic code cannot detect if it is working
with a temporary or not. I don't know if this would be useful in D though.

each code segment of the form:

void foo(ref S);
...
foo(S(...));

is equivalent to one explicitly declaring the temporary:

{auto __temp=S(...); foo(__temp);}

The difference is that the first is more pleasant to write. If
temporaries would become rvalues everyone would always have to write the
second form manually. So imho it is just a syntax sugar issue.

I'd actually argue that ref-passing should work for arbitrary function results 
too.


Here I propose that we go a step further and abolish the notion of rvalue
and lvalue entirely, and let the compiler insert necessary temporary
variable when needed, so that we can finally write things like

 uint w;
 memcpy(w,5.0f, w.sizeof);
 13u = w;

/joking


And then of course you could do:

5=6;
assert(5==6);

It hasn't been working since the good ol' days of fortran =(.


Re: Why do struct literals count as lvalues?

2011-08-19 Thread kenji hara
2011/8/19 Timon Gehr timon.g...@gmx.ch:
 Oh, interesting. So why were they implemented with different semantics then?

I don't know the background, sorry.

 Also, how would they work in a non-templated function?
In my opinion, that might work like C++ const T, that allows
receiving a rvalue argument.

 Would they just be conservatively treated as rvalues in the function body?
Maybe it doesn't. In D, a variable is always treated as lvalue, even
if it is a parameter.

The follows are my opinion: D might be designed as which ref parameter
receives only lvalue, and non-ref parameter receives only rvalue.
Today ref storage class also means that the parameter binds
corresponding argument by reference, but it is not a language design,
but that is performance decision. It seems to me that ref storage
class is designed for automatic move semantics.

According to my think, struct literal should be rvalue. That is
temporary, and we want to move it automatically.

Kenji Hara


Re: Optional braces

2011-08-19 Thread Ulrik Mikaelsson
There is one case where it might make sense. I've brought up a
variation of this before, but basically;

Object getMeSome() try {
  // Really try
} catch (SpecificFailure e) {
  return null;
}

vs.

Object getMeSome() {
  try {
// Really try
  } catch (SpecificFailure e) {
return null;
  }
}

Of course, every optional feature needs good judgement for appropriate
usage, for example the ternary statement vs. if/else.

2011/8/19 Trass3r u...@known.com:
 Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr timon.g...@gmx.ch:

 I think this makes code harder to read for no obvious benefit.
 I don't think this is any better than

 class Foo{
     private int a_;
     int a(){return a_;}
     int a(int a){return a_ = a;}
 }

 +1

 Optional braces should be limited to statements.



Re: newsgroup availability

2011-08-19 Thread Jesse Phillips
On Fri, 19 Aug 2011 15:52:40 +0200, Timon Gehr wrote:

 On 08/19/2011 03:44 PM, Steven Schveighoffer wrote:
 Has there been some strange issue with the newsgroup lately?
 Frequently, I'm getting load errors (I assume this means the NG load is
 too large to deal with my communication).

 It seems to be happening daily...

 -Steve
 
 It has been the same for me.

Yep, I get it all the time.


Re: newsgroup availability

2011-08-19 Thread kennytm
Timon Gehr timon.g...@gmx.ch wrote:
 On 08/19/2011 03:44 PM, Steven Schveighoffer wrote:
 Has there been some strange issue with the newsgroup lately? Frequently,
 I'm getting load errors (I assume this means the NG load is too large to
 deal with my communication).
 
 It seems to be happening daily...
 
 -Steve
 
 It has been the same for me.

It's the same for everyone because it's a problem of the newsgroup server,
not the client. I guess the server(s) needs more CPU running in parallel to
reduce load.


Re: Why do struct literals count as lvalues?

2011-08-19 Thread kennytm
Timon Gehr timon.g...@gmx.ch wrote:
 On 08/19/2011 03:46 PM, kennytm wrote:
 Timon Gehrtimon.g...@gmx.ch  wrote:
 
 auto ref currently treats struct literals as lvalues too. (therefore, as
 ref). And passing by value would be considerably less efficient for large 
 structs.
 
 As I understand it, the only issue with allowing literals and function
 results as lvalues is that generic code cannot detect if it is working
 with a temporary or not. I don't know if this would be useful in D though.
 
 each code segment of the form:
 
 void foo(ref S);
 ...
 foo(S(...));
 
 is equivalent to one explicitly declaring the temporary:
 
 {auto __temp=S(...); foo(__temp);}
 
 The difference is that the first is more pleasant to write. If
 temporaries would become rvalues everyone would always have to write the
 second form manually. So imho it is just a syntax sugar issue.
 
 I'd actually argue that ref-passing should work for arbitrary function 
 results too.
 
 Here I propose that we go a step further and abolish the notion of rvalue
 and lvalue entirely, and let the compiler insert necessary temporary
 variable when needed, so that we can finally write things like
 
  uint w;
  memcpy(w,5.0f, w.sizeof);
  13u = w;
 
 /joking
 
 And then of course you could do:
 
 5=6;
 assert(5==6);
 
 It hasn't been working since the good ol' days of fortran =(.

Actually that assignment would just become an expensive no-op because it
will be rewritten into

(int __lvalue1243 = 5, __lvalue1243) = 6;

So the assert would still assert.


Re: Optional braces

2011-08-19 Thread kennytm
Trass3r u...@known.com wrote:
 Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr timon.g...@gmx.ch:
 I think this makes code harder to read for no obvious benefit.
 I don't think this is any better than
 
 class Foo{
  private int a_;
  int a(){return a_;}
  int a(int a){return a_ = a;}
 }
 
 +1
 
 Optional braces should be limited to statements.

I agree. Besides, a minor problem is that 'if' statements may be mistaken
as template conditions:

void f1(T)(T x)   if (isFoo!T) { x ++; } 
void f2(T)(T x) { if (isFoo!T) { x ++; } }


Re: Why do struct literals count as lvalues?

2011-08-19 Thread Timon Gehr

On 08/19/2011 04:33 PM, kennytm wrote:

Timon Gehrtimon.g...@gmx.ch  wrote:

On 08/19/2011 03:46 PM, kennytm wrote:

Timon Gehrtimon.g...@gmx.ch   wrote:


auto ref currently treats struct literals as lvalues too. (therefore, as
ref). And passing by value would be considerably less efficient for large 
structs.

As I understand it, the only issue with allowing literals and function
results as lvalues is that generic code cannot detect if it is working
with a temporary or not. I don't know if this would be useful in D though.

each code segment of the form:

void foo(ref S);
...
foo(S(...));

is equivalent to one explicitly declaring the temporary:

{auto __temp=S(...); foo(__temp);}

The difference is that the first is more pleasant to write. If
temporaries would become rvalues everyone would always have to write the
second form manually. So imho it is just a syntax sugar issue.

I'd actually argue that ref-passing should work for arbitrary function results 
too.


Here I propose that we go a step further and abolish the notion of rvalue
and lvalue entirely, and let the compiler insert necessary temporary
variable when needed, so that we can finally write things like

  uint w;
  memcpy(w,5.0f, w.sizeof);
  13u = w;

/joking


And then of course you could do:

5=6;
assert(5==6);

It hasn't been working since the good ol' days of fortran =(.


Actually that assignment would just become an expensive no-op because it
will be rewritten into

 (int __lvalue1243 = 5, __lvalue1243) = 6;

So the assert would still assert.


Nah, no-ops should be a compile error :o).


More name hiding

2011-08-19 Thread bearophile
After translating some buggy C code (full of gotos and global variables) to D 
and going hunting for bugs for some time, I have grown a desire to write this 
post.

Variable name hiding is a source of bugs. A typical example:


int x;
void foo() {
int x = 5;
// lot of code code here
x++;
}


The local name 'x' hides the global variable name 'x'. Sometimes the programmer 
thinks she is using a global variable, when instead she is using the local one, 
of vice versa. Coding guidelines suggest to rename such local variable x to 
avoid possible future troubles, and I agree with this advice.

Some ways to face this problem:

1) Do nothing.
2) Give optional explicit information about the source of all variable names 
used in a function, using the optional @outer() I have proposed elsewhere.
3) Statically disallow (gives an error) local variables from shadowing global 
ones.
4) Produce a warning when a local variable shadows a global ones, in a smart 
way.
5) As the leading dot to denote global variables, require the use of another 
leading symbol (or some other mean) to denote local variable, when there is 
ambiguity.

--

Regarding option 1, in D global variables are uncommon if you follow modern 
programming practices, and if you keep functions short it's easy to see if they 
are shadowing an outer name.
But the situation is sometimes different if you are porting legacy C code to D, 
or if you have bad D programmers :-)

--

Option 3 is not so bad, D language already contains some examples of this:

struct Foo { int j; }
void main() {
foreach (i; 0 .. 10)
foreach (i; 0 .. 10) {} // error
Foo f;
int j;
with (f) {
j++; // error
}
}

--

Option 4 too is not bad, especially if some care is given to avoid producing 
warnings where they are not needed:


int x, y, z;
void main() {
  int x;
  .x++; // no warning, the scope is known
  x++; // warning
  string y;
  y = foo; // no warning, .y y have incompatible types
  int z;
  float z;
  z++; // warning, int is implicitly convertible to float
}

--

Option 5 means requiring explicit scope information when there there is a 
collision:

int x;
void main() {
  int x;
  .x++; // no error, the scope is known
  main.x++; // no error, the scope is known
}

--

I have discussed about hiding global variables from local ones, but D allows 
nesting of functions, so this discussion applies to such variables too:


void main() {
int x;
void foo() {
int x;
// code here
x++;
}
}

Bye,
bearophile


Re: Optional braces

2011-08-19 Thread Andrei Alexandrescu

On 8/19/11 1:50 AM, Jacob Carlborg wrote:

This might sound like a crazy idea. I don't expect everyone to drop what
they're doing and start to implement this, it's just an idea.

In Java (C, C++ and others) braces are optional for statements like if,
while, for and so on, containing only one expression. In D this is true
as well, but compared with Java, D also allow try, catch and finally
statements to have optional braces.

What about extending this to allow optional braces everywhere, where the
braces contain a single expression? I'm thinking this will be most
useful for functions/methods, templates and delegates. Specially for
methods acting as properties that just forwards a value.

Examples:

class Foo
{
private int a_;
int a () return a_;
int a (int a) return a_ = a;
}

template Bar (T) alias T FooBar;

auto foo = delegate () return 3;
auto bar = return 3; // don't if this would be possible


One thing I'd subjectively like is to require braces on both branches of 
if/else if at least one has braces.


Andrei



Re: More name hiding

2011-08-19 Thread Andrej Mitrovic
It's not just globals. It's hiding fields as well:

class A
{
int x;
this()
{
 int x; // - hides this.x
}
}

I've had this happen during a cut/paste session, which happens when
I'm refactoring my code.


Re: newsgroup availability

2011-08-19 Thread Stijn Herreman

On 19/08/2011 16:18, kennytm wrote:

Timon Gehrtimon.g...@gmx.ch  wrote:

On 08/19/2011 03:44 PM, Steven Schveighoffer wrote:

Has there been some strange issue with the newsgroup lately? Frequently,
I'm getting load errors (I assume this means the NG load is too large to
deal with my communication).

It seems to be happening daily...

-Steve


It has been the same for me.


It's the same for everyone because it's a problem of the newsgroup server,
not the client. I guess the server(s) needs more CPU running in parallel to
reduce load.


Could it be the cause of frequent Thunderbird freezes? I can't tell 
because I only started using it for the newsgroup a few weeks ago.


Re: Should unreachable code be considered an error?

2011-08-19 Thread maarten van damme
Why not a warning but when compiling using the -release flag throw an error?
Sounds logical to me as unreachable code can be there because of
debugging,etc but any released executable should not contain unreachable
code.

2011/8/18 Don nos...@nospam.com

 Timon Gehr wrote:

 On 08/18/2011 02:38 PM, Bernard Helyer wrote:

 Faramir on the Ars forums makes an excellent point:

 With the c preprocessor, both theoretically and as it is used in
 practice, you can easily get dead code in certain compile paths that is
 live in others.

 I think template mixins can achieve the same sort of shenanigans. I think
 warning it is.


 You mean string mixins?
 As string mixins are so much more expressive than C macros, one should
 actually almost never get trivial dead code in well designed string mixins.


 Yes, the equivalent to the C preprocessor is version statements.
 Obviously anything wrapped in a version(none) block shouldn't generate an
 unreachable code error...



Re: Optional braces

2011-08-19 Thread Timon Gehr

On 08/19/2011 05:12 PM, Andrei Alexandrescu wrote:

On 8/19/11 1:50 AM, Jacob Carlborg wrote:

This might sound like a crazy idea. I don't expect everyone to drop what
they're doing and start to implement this, it's just an idea.

In Java (C, C++ and others) braces are optional for statements like if,
while, for and so on, containing only one expression. In D this is true
as well, but compared with Java, D also allow try, catch and finally
statements to have optional braces.

What about extending this to allow optional braces everywhere, where the
braces contain a single expression? I'm thinking this will be most
useful for functions/methods, templates and delegates. Specially for
methods acting as properties that just forwards a value.

Examples:

class Foo
{
private int a_;
int a () return a_;
int a (int a) return a_ = a;
}

template Bar (T) alias T FooBar;

auto foo = delegate () return 3;
auto bar = return 3; // don't if this would be possible


One thing I'd subjectively like is to require braces on both branches of
if/else if at least one has braces.

Andrei



if(condition){
...;
}();else ...;

if(condition) ...;
else{
...
}();


:o)






Re: Why do struct literals count as lvalues?

2011-08-19 Thread Trass3r

Am 19.08.2011, 14:50 Uhr, schrieb Timon Gehr timon.g...@gmx.ch:

void foo(ref S);
...
foo(S(...));

is equivalent to one explicitly declaring the temporary:

{auto __temp=S(...); foo(__temp);}

The difference is that the first is more pleasant to write. If  
temporaries would become rvalues everyone would always have to write the  
second form manually. So imho it is just a syntax sugar issue.


I'd actually argue that ref-passing should work for arbitrary function  
results too.


+1, but const should be required.


Re: Should unreachable code be considered an error?

2011-08-19 Thread Sean Kelly
On Aug 18, 2011, at 10:29 AM, Nick Sabalausky wrote:

 Bernard Helyer b.hel...@gmail.com wrote in message 
 news:j2ithq$12kd$1...@digitalmars.com...
 I asked the Ars forums ( http://arstechnica.com/civis/viewtopic.php?
 f=20t=1153378p=21965411 ) and I ask the same of you: should
 unambiguously unreachable code be an error or a warning? ( see the linked
 forum post for more details ).
 
 No. That would be a royal pain in the ass during debugging. I expect to be 
 able to stick a return ; anywhere I want to test something and not 
 have the compiler crap out because I didn't deal with the overhead of 
 commenting out the rest.
 
 A warning might be nice, though.

A warning if anything.  I've never encountered a situation where code was made 
unreachable by accident.  I also get unreachable code warnings periodically, 
for code that is absolutely reachable.  I don't want my code to not compile 
simply because the compiler can't perform adequate flow analysis.

Re: Optional braces

2011-08-19 Thread Jacob Carlborg

On 2011-08-19 17:12, Andrei Alexandrescu wrote:

On 8/19/11 1:50 AM, Jacob Carlborg wrote:

This might sound like a crazy idea. I don't expect everyone to drop what
they're doing and start to implement this, it's just an idea.

In Java (C, C++ and others) braces are optional for statements like if,
while, for and so on, containing only one expression. In D this is true
as well, but compared with Java, D also allow try, catch and finally
statements to have optional braces.

What about extending this to allow optional braces everywhere, where the
braces contain a single expression? I'm thinking this will be most
useful for functions/methods, templates and delegates. Specially for
methods acting as properties that just forwards a value.

Examples:

class Foo
{
private int a_;
int a () return a_;
int a (int a) return a_ = a;
}

template Bar (T) alias T FooBar;

auto foo = delegate () return 3;
auto bar = return 3; // don't if this would be possible


One thing I'd subjectively like is to require braces on both branches of
if/else if at least one has braces.

Andrei



Why is that?

--
/Jacob Carlborg


Re: Optional braces

2011-08-19 Thread Jacob Carlborg

On 2011-08-19 16:33, kennytm wrote:

Trass3ru...@known.com  wrote:

Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehrtimon.g...@gmx.ch:

I think this makes code harder to read for no obvious benefit.
I don't think this is any better than

class Foo{
  private int a_;
  int a(){return a_;}
  int a(int a){return a_ = a;}
}


+1

Optional braces should be limited to statements.


I agree. Besides, a minor problem is that 'if' statements may be mistaken
as template conditions:

 void f1(T)(T x)   if (isFoo!T) { x ++; }
 void f2(T)(T x) { if (isFoo!T) { x ++; } }


Oh, never thought of that.

--
/Jacob Carlborg


Re: newsgroup availability

2011-08-19 Thread Jacob Carlborg

On 2011-08-19 15:44, Steven Schveighoffer wrote:

Has there been some strange issue with the newsgroup lately? Frequently,
I'm getting load errors (I assume this means the NG load is too large to
deal with my communication).

It seems to be happening daily...

-Steve


I'm getting the same error.

--
/Jacob Carlborg


Re: newsgroup availability

2011-08-19 Thread filgood

On 19/08/2011 14:44, Steven Schveighoffer wrote:

Has there been some strange issue with the newsgroup lately? Frequently,
I'm getting load errors (I assume this means the NG load is too large to
deal with my communication).

It seems to be happening daily...

-Steve


Yes, I've also had the same error in the last few days...maybe we can 
have a mirror (that is sync'd regularly)?


~filgood


Re: newsgroup availability

2011-08-19 Thread Marco Leise
Am 19.08.2011, 17:15 Uhr, schrieb Stijn Herreman  
stijn.herre...@telenet.be:



On 19/08/2011 16:18, kennytm wrote:

Timon Gehrtimon.g...@gmx.ch  wrote:

On 08/19/2011 03:44 PM, Steven Schveighoffer wrote:
Has there been some strange issue with the newsgroup lately?  
Frequently,
I'm getting load errors (I assume this means the NG load is too large  
to

deal with my communication).

It seems to be happening daily...

-Steve


It has been the same for me.


It's the same for everyone because it's a problem of the newsgroup  
server,
not the client. I guess the server(s) needs more CPU running in  
parallel to

reduce load.


Could it be the cause of frequent Thunderbird freezes? I can't tell  
because I only started using it for the newsgroup a few weeks ago.


You could use the web interface to the newsgroup when you see the lockup  
and check if that loads or displays an error message about some load factor


Re: newsgroup availability

2011-08-19 Thread Steven Schveighoffer

On Fri, 19 Aug 2011 15:18:34 -0400, Marco Leise marco.le...@gmx.de wrote:

Am 19.08.2011, 17:15 Uhr, schrieb Stijn Herreman  
stijn.herre...@telenet.be:



On 19/08/2011 16:18, kennytm wrote:

Timon Gehrtimon.g...@gmx.ch  wrote:

On 08/19/2011 03:44 PM, Steven Schveighoffer wrote:
Has there been some strange issue with the newsgroup lately?  
Frequently,
I'm getting load errors (I assume this means the NG load is too  
large to

deal with my communication).

It seems to be happening daily...

-Steve


It has been the same for me.


It's the same for everyone because it's a problem of the newsgroup  
server,
not the client. I guess the server(s) needs more CPU running in  
parallel to

reduce load.


Could it be the cause of frequent Thunderbird freezes? I can't tell  
because I only started using it for the newsgroup a few weeks ago.


You could use the web interface to the newsgroup when you see the lockup  
and check if that loads or displays an error message about some load  
factor


It does.

BTW, this problem really makes me want to avoid the newsgroup...  I get no  
indication from my newsreader when it's working, only when it's broken.   
So as a consequence, if I want to send a message or read messages, I have  
to keep polling to see if it works.


This seems like an artificial problem, does anyone know what the cause is?

-Steve


Re: CURL review request

2011-08-19 Thread jdrewsen

Den 19-08-2011 00:55, Timon Gehr skrev:

On 08/18/2011 11:33 PM, jdrewsen wrote:

Den 17-08-2011 18:21, Timon Gehr skrev:

On 08/17/2011 05:58 PM, Jonathan M Davis wrote:

On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote:

On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com
wrote:

Den 17-08-2011 15:51, Steven Schveighoffer skrev:

On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen
jdrew...@nospam.com

wrote:

On 17/08/11 00.21, Jonathan M Davis wrote:

On Tuesday, August 16, 2011 12:32 Martin Nowak wrote:

On Tue, 16 Aug 2011 20:48:51 +0200,
jdrewsenjdrew...@nospam.com

wrote:

Den 16-08-2011 18:55, Martin Nowak skrev:

On Tue, 16 Aug 2011 15:13:40 +0200,
dsimchadsim...@yahoo.com

wrote:

On 8/16/2011 7:48 AM, Jonas Drewsen wrote:

Hi all,

This is a review request for the curl wrapper. Please
read the
known
issues in the top of the source file and if possible
suggest a
solution.

We also need somebody for running the review process.
Anyone?

Code:
https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl
.d
Docs:
http://freeze.steamwinter.com/D/web/phobos/etc_curl.html

Demolish!

/Jonas


From a quick look, this looks very well thought out. I'll
review
it
more thoroughly when I have more time. A few
questions/comments
from a
quick look at the docs:

Does the async stuff use D threads, or does Curl have its
own
async
API?

In your examples for postData, you have onReceive a
ubyte[] and
write
it out to console. Did you mean to cast this to some kind
of
string?

For onReceive, what's the purpose of the return value?

If/when this module makes it into Phobos, are we going to
start
including a libcurl binary with DMD distributions so that
std.curl
feels truly **standard** and requires zero extra
configuration?


I was also wondering about the async handling. In the
long-term
I'd like
to see a bigger picture for async handling in phobos
(offering
some kind
of futures, maybe event-loops etc.).
Though this is not a requirement for the curl wrapper now.
std.parallelism also has some kind of this stuff and file
reading
would
benefit from it too.


This has been discussed before and I also think this is very
important.
But before that I think some kind of package management should
be
prioritized (A DIP11 implementaion or a more traditional
solution).


One thing I spotted at a quick glance, sending to be filled
buffers to
another thread should not be done by casting to shared not
immutable.


I'm not entirely sure what you mean. There is no use of shared
buffers
in the wrapper. I do cast the buffer between mutable/immutable
because
only immutable or by value data can be passed using
std.concurrency.
Since the buffers are only used by the thread that currently
has the
buffer this is safe. I've previously asked for a non-cast
solution
(ie.
some kind of move between threads semantic for
std.concurrency) but
was
advised that this was the way to do it.


martin


Pardon the typo. What I meant is that AFAIK casting from
immutable to
mutable has undefined behavior.
The intended method for sending a uint[] buffer to another
thread is
to
cast that
buffer to shared (cast(shared(uint[])) and casting away the
shared
on the
receiving side.
It is allowed to send shared data using std.concurrency.


Casting away immutability and then altering data is undefined.
Actually
casting it away is defined. So, if you have data in one thread
that
you know
is unique, you can cast it to immutable (or
std.exception.assumeUnique to do
it) and then send it to another thread. On that thread, you can
then
cast it
to mutable and alter it.

However, you're circumventing the type system when you do this.
So,
you have
to be very careful. You're throwing away the guarantees that the
compiler
makes with regards to const and immutable. It _is_ guaranteed to
work
though.
And I'm not sure that there's really any difference between
casting
to shared
and back and casting to immutable and back. In both cases, you're
circumventing the type system. The main difference would be that
if
you
screwed up with immutable and cast away immutable on something
that
really was
immutable rather than something that you cast to immutable just to
send it to
another thread, then you could a segfault when you tried to alter
it,
since it
could be in ROM.

- Jonathan M Davis


Yeah I know you have to be careful when doing these kind of things.
I
ran into the problem of sending buffers between threads (using
std.concurrency) so that they could be reused. There isn't any
move
ownership support in place so Andrei suggested I could do it by
casting immutable.

If anyone knows of a cleaner way to do this please tell.


casting to shared and back. Passing shared data should be
supported by
std.concurrency, and casting away shared is defined as long as you
know
only one thread owns the data after casting.

-Steve


Why is this cleaner than casting to immutable and back?


Once it's immutable, it can never be mutable again. Casting to
immutable
is a one-way 

Re: CURL review request

2011-08-19 Thread jdrewsen

Den 18-08-2011 20:12, Martin Nowak skrev:

On Tue, 16 Aug 2011 13:48:57 +0200, Jonas Drewsen jdrew...@nospam.com
wrote:


Hi all,

This is a review request for the curl wrapper. Please read the known
issues in the top of the source file and if possible suggest a solution.

We also need somebody for running the review process. Anyone?

Code:
https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl.d
Docs:
http://freeze.steamwinter.com/D/web/phobos/etc_curl.html

Demolish!

/Jonas


Just want to make sure these two code comments don't get lost.

https://github.com/jcd/phobos/commit/9177203c1e54c4be959fb0b81e9d84f3d5e861f9#etc/curl.d-P132

https://github.com/jcd/phobos/commit/9177203c1e54c4be959fb0b81e9d84f3d5e861f9#etc/curl.d-P192


martin


I did see them.

Thanks
/Jonas


Re: CURL review request

2011-08-19 Thread Jonathan M Davis
On Friday, August 19, 2011 04:58 Timon Gehr wrote:
 On 08/19/2011 01:50 AM, Jonathan M Davis wrote:
  On Thursday, August 18, 2011 16:00 Timon Gehr wrote:
  On 08/19/2011 12:35 AM, Jonathan M Davis wrote:
  On Thursday, August 18, 2011 14:33 jdrewsen wrote:
  Den 17-08-2011 18:21, Timon Gehr skrev:
  On 08/17/2011 05:58 PM, Jonathan M Davis wrote:
  On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote:
  On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com
  
  wrote:
  Den 17-08-2011 15:51, Steven Schveighoffer skrev:
  On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen
  jdrew...@nospam.com
  
  wrote:
  On 17/08/11 00.21, Jonathan M Davis wrote:
  On Tuesday, August 16, 2011 12:32 Martin Nowak wrote:
  On Tue, 16 Aug 2011 20:48:51 +0200,
  jdrewsenjdrew...@nospam.com
  
  wrote:
  Den 16-08-2011 18:55, Martin Nowak skrev:
  On Tue, 16 Aug 2011 15:13:40 +0200,
  dsimchadsim...@yahoo.com
  
  wrote:
  On 8/16/2011 7:48 AM, Jonas Drewsen wrote:
  Hi all,
  
  This is a review request for the curl wrapper. Please
  read the
  known
  issues in the top of the source file and if possible
  suggest a
  solution.
  
  We also need somebody for running the review process.
  Anyone?
  
  Code:
  https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl
  .d
  Docs:
  http://freeze.steamwinter.com/D/web/phobos/etc_curl.html
  
  Demolish!
  
  /Jonas
  
  From a quick look, this looks very well thought out. I'll
  
  review
  it
  more thoroughly when I have more time. A few
  questions/comments
  from a
  quick look at the docs:
  
  Does the async stuff use D threads, or does Curl have its
  own
  async
  API?
  
  In your examples for postData, you have onReceive a
  ubyte[] and
  write
  it out to console. Did you mean to cast this to some kind
  of
  string?
  
  For onReceive, what's the purpose of the return value?
  
  If/when this module makes it into Phobos, are we going to
  start
  including a libcurl binary with DMD distributions so that
  std.curl
  feels truly **standard** and requires zero extra
  configuration?
  
  I was also wondering about the async handling. In the
  long-term
  I'd like
  to see a bigger picture for async handling in phobos
  (offering
  some kind
  of futures, maybe event-loops etc.).
  Though this is not a requirement for the curl wrapper now.
  std.parallelism also has some kind of this stuff and file
  reading
  would
  benefit from it too.
  
  This has been discussed before and I also think this is very
  important.
  But before that I think some kind of package management
  should be
  prioritized (A DIP11 implementaion or a more traditional
  solution).
  
  One thing I spotted at a quick glance, sending to be filled
  buffers to
  another thread should not be done by casting to shared not
  immutable.
  
  I'm not entirely sure what you mean. There is no use of
  shared buffers
  in the wrapper. I do cast the buffer between
  mutable/immutable because
  only immutable or by value data can be passed using
  std.concurrency.
  Since the buffers are only used by the thread that currently
  has the
  buffer this is safe. I've previously asked for a non-cast
  solution
  (ie.
  some kind of move between threads semantic for
  std.concurrency) but
  was
  advised that this was the way to do it.
  
  martin
  
  Pardon the typo. What I meant is that AFAIK casting from
  immutable to
  mutable has undefined behavior.
  The intended method for sending a uint[] buffer to another
  thread is
  to
  cast that
  buffer to shared (cast(shared(uint[])) and casting away the
  shared
  on the
  receiving side.
  It is allowed to send shared data using std.concurrency.
  
  Casting away immutability and then altering data is undefined.
  Actually
  casting it away is defined. So, if you have data in one thread
  that
  you know
  is unique, you can cast it to immutable (or
  std.exception.assumeUnique to do
  it) and then send it to another thread. On that thread, you can
  then
  cast it
  to mutable and alter it.
  
  However, you're circumventing the type system when you do this.
  So,
  you have
  to be very careful. You're throwing away the guarantees that
  the compiler
  makes with regards to const and immutable. It _is_ guaranteed
  to work
  though.
  And I'm not sure that there's really any difference between
  casting
  to shared
  and back and casting to immutable and back. In both cases,
  you're circumventing the type system. The main difference
  would be that if
  you
  screwed up with immutable and cast away immutable on something
  that
  really was
  immutable rather than something that you cast to immutable just
  to send it to
  another thread, then you could a segfault when you tried to
  alter it,
  since it
  could be in ROM.
  
  - Jonathan M Davis
  
  Yeah I know you have to be careful when doing these kind of
  things. I
  ran into the problem of sending buffers between threads (using
  std.concurrency) so that they could be reused. 

Re: CURL review request

2011-08-19 Thread Timon Gehr

On 08/19/2011 10:36 PM, Jonathan M Davis wrote:

On Friday, August 19, 2011 04:58 Timon Gehr wrote:

On 08/19/2011 01:50 AM, Jonathan M Davis wrote:

On Thursday, August 18, 2011 16:00 Timon Gehr wrote:

On 08/19/2011 12:35 AM, Jonathan M Davis wrote:

On Thursday, August 18, 2011 14:33 jdrewsen wrote:

Den 17-08-2011 18:21, Timon Gehr skrev:

On 08/17/2011 05:58 PM, Jonathan M Davis wrote:

On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote:

On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com


wrote:

Den 17-08-2011 15:51, Steven Schveighoffer skrev:

On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen
jdrew...@nospam.com

wrote:

On 17/08/11 00.21, Jonathan M Davis wrote:

On Tuesday, August 16, 2011 12:32 Martin Nowak wrote:

On Tue, 16 Aug 2011 20:48:51 +0200,
jdrewsenjdrew...@nospam.com

wrote:

Den 16-08-2011 18:55, Martin Nowak skrev:

On Tue, 16 Aug 2011 15:13:40 +0200,
dsimchadsim...@yahoo.com

wrote:

On 8/16/2011 7:48 AM, Jonas Drewsen wrote:

Hi all,

This is a review request for the curl wrapper. Please
read the
known
issues in the top of the source file and if possible
suggest a
solution.

We also need somebody for running the review process.
Anyone?

Code:
https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl
.d
Docs:
http://freeze.steamwinter.com/D/web/phobos/etc_curl.html

Demolish!

/Jonas


 From a quick look, this looks very well thought out. I'll

review
it
more thoroughly when I have more time. A few
questions/comments
from a
quick look at the docs:

Does the async stuff use D threads, or does Curl have its
own
async
API?

In your examples for postData, you have onReceive a
ubyte[] and
write
it out to console. Did you mean to cast this to some kind
of
string?

For onReceive, what's the purpose of the return value?

If/when this module makes it into Phobos, are we going to
start
including a libcurl binary with DMD distributions so that
std.curl
feels truly **standard** and requires zero extra
configuration?


I was also wondering about the async handling. In the
long-term
I'd like
to see a bigger picture for async handling in phobos
(offering
some kind
of futures, maybe event-loops etc.).
Though this is not a requirement for the curl wrapper now.
std.parallelism also has some kind of this stuff and file
reading
would
benefit from it too.


This has been discussed before and I also think this is very
important.
But before that I think some kind of package management
should be
prioritized (A DIP11 implementaion or a more traditional
solution).


One thing I spotted at a quick glance, sending to be filled
buffers to
another thread should not be done by casting to shared not
immutable.


I'm not entirely sure what you mean. There is no use of
shared buffers
in the wrapper. I do cast the buffer between
mutable/immutable because
only immutable or by value data can be passed using
std.concurrency.
Since the buffers are only used by the thread that currently
has the
buffer this is safe. I've previously asked for a non-cast
solution
(ie.
some kind of move between threads semantic for
std.concurrency) but
was
advised that this was the way to do it.


martin


Pardon the typo. What I meant is that AFAIK casting from
immutable to
mutable has undefined behavior.
The intended method for sending a uint[] buffer to another
thread is
to
cast that
buffer to shared (cast(shared(uint[])) and casting away the
shared
on the
receiving side.
It is allowed to send shared data using std.concurrency.


Casting away immutability and then altering data is undefined.
Actually
casting it away is defined. So, if you have data in one thread
that
you know
is unique, you can cast it to immutable (or
std.exception.assumeUnique to do
it) and then send it to another thread. On that thread, you can
then
cast it
to mutable and alter it.

However, you're circumventing the type system when you do this.
So,
you have
to be very careful. You're throwing away the guarantees that
the compiler
makes with regards to const and immutable. It _is_ guaranteed
to work
though.
And I'm not sure that there's really any difference between
casting
to shared
and back and casting to immutable and back. In both cases,
you're circumventing the type system. The main difference
would be that if
you
screwed up with immutable and cast away immutable on something
that
really was
immutable rather than something that you cast to immutable just
to send it to
another thread, then you could a segfault when you tried to
alter it,
since it
could be in ROM.

- Jonathan M Davis


Yeah I know you have to be careful when doing these kind of
things. I
ran into the problem of sending buffers between threads (using
std.concurrency) so that they could be reused. There isn't any
move ownership support in place so Andrei suggested I could do
it by casting immutable.

If anyone knows of a cleaner way to do this please tell.


casting to shared and back. Passing shared data should be
supported by std.concurrency, and casting away shared is 

Re: newsgroup availability

2011-08-19 Thread Jeff Nowakowski

On 08/19/2011 02:51 PM, filgood wrote:


Yes, I've also had the same error in the last few days...maybe we can
have a mirror (that is sync'd regularly)?

~filgood


It's available through Gmane:

nntp://news.gmane.org/gmane.comp.lang.d.general


Re: CURL review request

2011-08-19 Thread Jonathan M Davis
On Friday, August 19, 2011 15:27 Timon Gehr wrote:
 On 08/19/2011 10:36 PM, Jonathan M Davis wrote:
  On Friday, August 19, 2011 04:58 Timon Gehr wrote:
  On 08/19/2011 01:50 AM, Jonathan M Davis wrote:
  On Thursday, August 18, 2011 16:00 Timon Gehr wrote:
  On 08/19/2011 12:35 AM, Jonathan M Davis wrote:
  On Thursday, August 18, 2011 14:33 jdrewsen wrote:
  Den 17-08-2011 18:21, Timon Gehr skrev:
  On 08/17/2011 05:58 PM, Jonathan M Davis wrote:
  On Wednesday, August 17, 2011 11:30:06 Steven Schveighoffer wrote:
  On Wed, 17 Aug 2011 11:05:56 -0400, jdrewsenjdrew...@nospam.com
  
  wrote:
  Den 17-08-2011 15:51, Steven Schveighoffer skrev:
  On Wed, 17 Aug 2011 05:43:00 -0400, Jonas Drewsen
  jdrew...@nospam.com
  
  wrote:
  On 17/08/11 00.21, Jonathan M Davis wrote:
  On Tuesday, August 16, 2011 12:32 Martin Nowak wrote:
  On Tue, 16 Aug 2011 20:48:51 +0200,
  jdrewsenjdrew...@nospam.com
  
  wrote:
  Den 16-08-2011 18:55, Martin Nowak skrev:
  On Tue, 16 Aug 2011 15:13:40 +0200,
  dsimchadsim...@yahoo.com
  
  wrote:
  On 8/16/2011 7:48 AM, Jonas Drewsen wrote:
  Hi all,
  
  This is a review request for the curl wrapper. Please
  read the
  known
  issues in the top of the source file and if possible
  suggest a
  solution.
  
  We also need somebody for running the review process.
  Anyone?
  
  Code:
  https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl
  .d
  Docs:
  http://freeze.steamwinter.com/D/web/phobos/etc_curl.html
  
  Demolish!
  
  /Jonas
  
  From a quick look, this looks very well thought out.
  I'll
  
  review
  it
  more thoroughly when I have more time. A few
  questions/comments
  from a
  quick look at the docs:
  
  Does the async stuff use D threads, or does Curl have its
  own
  async
  API?
  
  In your examples for postData, you have onReceive a
  ubyte[] and
  write
  it out to console. Did you mean to cast this to some kind
  of
  string?
  
  For onReceive, what's the purpose of the return value?
  
  If/when this module makes it into Phobos, are we going to
  start
  including a libcurl binary with DMD distributions so that
  std.curl
  feels truly **standard** and requires zero extra
  configuration?
  
  I was also wondering about the async handling. In the
  long-term
  I'd like
  to see a bigger picture for async handling in phobos
  (offering
  some kind
  of futures, maybe event-loops etc.).
  Though this is not a requirement for the curl wrapper now.
  std.parallelism also has some kind of this stuff and file
  reading
  would
  benefit from it too.
  
  This has been discussed before and I also think this is
  very important.
  But before that I think some kind of package management
  should be
  prioritized (A DIP11 implementaion or a more traditional
  solution).
  
  One thing I spotted at a quick glance, sending to be
  filled buffers to
  another thread should not be done by casting to shared not
  immutable.
  
  I'm not entirely sure what you mean. There is no use of
  shared buffers
  in the wrapper. I do cast the buffer between
  mutable/immutable because
  only immutable or by value data can be passed using
  std.concurrency.
  Since the buffers are only used by the thread that
  currently has the
  buffer this is safe. I've previously asked for a non-cast
  solution
  (ie.
  some kind of move between threads semantic for
  std.concurrency) but
  was
  advised that this was the way to do it.
  
  martin
  
  Pardon the typo. What I meant is that AFAIK casting from
  immutable to
  mutable has undefined behavior.
  The intended method for sending a uint[] buffer to another
  thread is
  to
  cast that
  buffer to shared (cast(shared(uint[])) and casting away the
  shared
  on the
  receiving side.
  It is allowed to send shared data using std.concurrency.
  
  Casting away immutability and then altering data is
  undefined. Actually
  casting it away is defined. So, if you have data in one
  thread that
  you know
  is unique, you can cast it to immutable (or
  std.exception.assumeUnique to do
  it) and then send it to another thread. On that thread, you
  can then
  cast it
  to mutable and alter it.
  
  However, you're circumventing the type system when you do
  this. So,
  you have
  to be very careful. You're throwing away the guarantees that
  the compiler
  makes with regards to const and immutable. It _is_ guaranteed
  to work
  though.
  And I'm not sure that there's really any difference between
  casting
  to shared
  and back and casting to immutable and back. In both cases,
  you're circumventing the type system. The main difference
  would be that if
  you
  screwed up with immutable and cast away immutable on
  something that
  really was
  immutable rather than something that you cast to immutable
  just to send it to
  another thread, then you could a segfault when you tried to
  alter it,
  since it
  could be in ROM.
  
  - Jonathan M Davis
  
  Yeah I know you have to be careful when doing these kind of
  things. I
  ran into 

Re: Should unreachable code be considered an error?

2011-08-19 Thread Stewart Gordon

On 18/08/2011 13:19, Bernard Helyer wrote:
snip

I'm talking about the unambiguous cases, the ones where a basic block has
no parents (i.e. there is no way to enter that code block).


So essentially you're looking to catch cases where, if you consider the function as a flow 
chart, there is no chain of arrows from the start of the function to the statement in 
question.  That should be straightforward.  But you're not worrying about catching cases 
where some arrow would never be followed.  Have I got that right?


snip

No, only if statements followed the assert(0) (which marks the control
flow block as terminated, just like return).


Not sure whether it should be allowed to be used e.g. to prevent execution of code that is 
under construction.


Stewart.


Re: More name hiding

2011-08-19 Thread Mehrdad

On 8/19/2011 8:17 AM, Andrej Mitrovic wrote:

It's not just globals. It's hiding fields as well:

class A
{
 int x;
 this()
 {
  int x; //- hides this.x
 }
}

I've had this happen during a cut/paste session, which happens when
I'm refactoring my code.
I actually use this on PURPOSE -- I always use the 'this' pointer when 
referring to members anyway. It's a great way to avoid unnecessarily 
renaming x to things like x1, x_1, x_, _x, x0, x_0, this_x, my_x, myx, 
etc...


Even more common with constructor parameters and instance fields.


Allocators in Phobos

2011-08-19 Thread David Simcha
I've massively improved my RegionAllocator (formerly TempAlloc) module thanks
to the excellent suggestions from Andrei and from Dimitri Olshansky (the GSoC
student working on regexes).

For the curious:

http://cis.jhu.edu/~dsimcha/d/phobos/std_regionallocator.html
https://github.com/dsimcha/TempAlloc/blob/master/regionallocator.d

The main point of this massive overhaul was Andrei's suggestion that
TempAlloc/RegionAllocator be converted from something fairly ad-hoc to an
implementation of the more general allocator interface that he proposed.  I
also think that three high-level functions were missing from Andrei's
proposal.  All of these will be included in RegionAllocator even if we decide
they're not standard allocator functions:

newArray:  Creates a new array.  Can be syntactic sugar for (cast(T*)
allocate(T.sizeof * nElements))[0..nElements] or can do something more
complicated based on knowing what type T is.

uninitializedArray:  Same as newArray but doesn't initialize elements.

array:  Converts a range into an array.

While I'm waiting in the review queue, I'm thinking of broadening the
allocator proposal to include a few more low-hanging fruit allocators:

GCAllocator:  An allocator wrapper over the garbage collector.  Question:
Should GCAllocator.free() call core.memory.GC.free() or be a no-op?

CAllocator:  An allocator wrapper over C's malloc and free.

FreeListAllocator:  A meta-allocator that allocates blocks of some fixed,
user-specified size off of some other base allocator and makes them available
via the allocate() function.  All allocation requests larger than the block
size throw.  All allocations smaller than the blolck size use whatever
fraction of a block they need and waste the rest.  Freeing memory via free()
puts it on a free list maintained by the FreeListAllocator object.
FreeListAllocator attempts to satisfy allocation requests from its free list
before allocating off the base allocator.  I'd probably make each
FreeListAllocator instance reference counted, and when the the last copy of an
instance goes out of scope, all blocks on the free list get freed.

Are there any other allocators that might be useful and could reasonably be
implemented as Phobos modules without major modifications to druntime or the
compiler?


Re: More name hiding

2011-08-19 Thread nsf
On Fri, 19 Aug 2011 11:07:12 -0400
bearophile bearophileh...@lycos.com wrote:

 Some ways to face this problem:
 
 1) Do nothing.
 2) Give optional explicit information about the source of all variable names 
 used in a function, using the optional @outer() I have proposed elsewhere.
 3) Statically disallow (gives an error) local variables from shadowing global 
 ones.
 4) Produce a warning when a local variable shadows a global ones, in a smart 
 way.
 5) As the leading dot to denote global variables, require the use of another 
 leading symbol (or some other mean) to denote local variable, when there is 
 ambiguity.

Well, D currently says I can't shadow variables:

void foo() {
int x = 10;
{
int x = 5; // error
}
}

which pisses me off personally. It's such a handy feature. And there is
exactly one way to solve your problem which comes in two parts:

1. Don't violate the rule: one or two screens of text per function.
2. Keep the low number of variables in a function, people say it should
be close to seven.

/me wants to be able to shadow his variables everywhere


Re: More name hiding

2011-08-19 Thread bearophile
nsf:

 Well, D currently says I can't shadow variables:

Right, that's a third way to shadow variables that D forbids, thank you. But in 
my post I've shown other kinds of shadowing that currently D accepts. Shadowing 
global variables has caused some problems in my C code. One good commercial C 
lint lists all such cases with a warning.


 which pisses me off personally. It's such a handy feature.

It's a handy anti-feature, good source of bugs. Style guides suggest to rename 
one of them. If I see production C/C++ code that does that, I rename one of the 
two variables. In Haskell in your situation you are allowed to use x and x'.


 And there is exactly one way to solve your problem which comes in two parts:

Surely there are some alternative ways to solve this problem, SPARK and Java 
doesn't use your solution.

 
 1. Don't violate the rule: one or two screens of text per function.
 2. Keep the low number of variables in a function, people say it should
 be close to seven.

I like to add a third rule, for D code:
3. Use pure functions everywhere possible. This avoids the shadowing problem.

But:
1) Old C code translated to D often doesn't follow your rules, unfortunately.
2) I have had colleagues that don't always follow your rules.
3) Even good codebases sometimes have longer functions. You find them even in 
the C sources of Python.
4) Even if you always follow your two rules, you are able to shadow a global 
(or outer) variable still, and 20 lines later sometimes you think that you are 
using the global variable, while you are modifying the local one. I have seen 
this happen even in code written by expert programmers, and it causes problems.


 /me wants to be able to shadow his variables everywhere

Good luck :-)

Bye and thank you for your comments,
bearophile


Re: Native Client in Chrome Beta

2011-08-19 Thread Nick Sabalausky
Marco Leise marco.le...@gmx.de wrote in message 
news:op.v0f018nh9y6...@dslb-088-070-152-209.pools.arcor-ip.net...

By not adopting a technology capable of competing with native apps on
iOS, Android, Windows, and Mac, web vendors are preventing important
classes of applications such as high-end games and simulations from moving 
to the open web.

That actually brings up an interestng point I hadn't really thought of 
before:

I've always liked the idea of using native code instead of JS, because it 
just makes so much more sense on a technical level. But, if something better 
than JS, like NaCl, is adopted on the web, something that can compete with 
real apps in efficiency, then that will only further encourage people to hop 
onto Google's bullshit web-as-an-OS agenda. Even if NaCl is universally 
adopted and completely eliminates the efficiency issues, the web will still 
be horrid as a so-called applicatins platform for other reasons, like UI 
(a big one), reliability, centralization, user-ownership, privacy... And 
those issues aren't realistically fixable within the confines of a web 
browser. So I think it's best if such a thing as NaCl *doesn't* get adopted, 
since it would only further encourage the biggest plague of the 21st 
century.




Removing entries from AAs

2011-08-19 Thread useo6
Hi,

I've create a little example of my problem:

module example;

class ExampleClass {

public {

int mi;

this(int i) {
mi = i;
}

}

}

int main(string[] args) {

ExampleClass[hash_t] exp;

ExampleClass cex = new ExampleClass(1);
exp[cex.toHash()] = cex;

cex = new ExampleClass(2);
exp[cex.toHash()] = cex;

cex = new ExampleClass(3);
exp[cex.toHash()] = cex;

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); }
}

return 0;

}

When I run this small example-app, I get an Access Violation. When
I insert a break into my foreach-loop like:

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); break; }
}

it works, but this means, I leave the foreach-loop. What I'm doing
wrong by using the foreach-block?

Thanks for any help!


Re: Removing entries from AAs

2011-08-19 Thread Timon Gehr

On 08/19/2011 02:01 PM, useo6 wrote:

Hi,

I've create a little example of my problem:

module example;

class ExampleClass {

public {

int mi;

this(int i) {
mi = i;
}

}

}

int main(string[] args) {

ExampleClass[hash_t] exp;

ExampleClass cex = new ExampleClass(1);
exp[cex.toHash()] = cex;

cex = new ExampleClass(2);
exp[cex.toHash()] = cex;

cex = new ExampleClass(3);
exp[cex.toHash()] = cex;

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); }
}

return 0;

}

When I run this small example-app, I get an Access Violation. When
I insert a break into my foreach-loop like:

foreach (ExampleClass c; exp) {
if (c.mi == 2) {exp.remove(c.toHash()); break; }
}

it works, but this means, I leave the foreach-loop. What I'm doing
wrong by using the foreach-block?

Thanks for any help!


The problem is that you change the AA while iterating over it. You could 
eg iterate over it and save all keys you want to remove into an array 
and then iterate over the array to remove the keys from the AA.


This works:


module example;

class ExampleClass {

public {

int mi;

this(int i) {
mi = i;
}

}

}

int main(string[] args) {

ExampleClass[hash_t] exp;

ExampleClass cex = new ExampleClass(1);
exp[cex.toHash()] = cex;

cex = new ExampleClass(2);
exp[cex.toHash()] = cex;

cex = new ExampleClass(3);
exp[cex.toHash()] = cex;

hash_t[] toRemove;

foreach (c; exp) {
if (c.mi == 2) { toRemove~=c.toHash(); }
}
foreach (h; toRemove) {
exp.remove(h);
}

return 0;

}





Re: Insert array into an AA

2011-08-19 Thread Steven Schveighoffer

On Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer nrgy...@gmail.com wrote:


== Auszug aus Robert Clipsham (rob...@octarineparrot.com)'s Artikel

On 16/08/2011 20:17, nrgyzer wrote:
 Hi everyone,

 I've the following:

 private static ubyte[][2][hash_t] classInstances;

 this() {

 classInstances[toHash()] = new ubyte[2]; // does not work

 }

 I want insert every class instance into the hashmap. Every class
 instance should be contained in the map after the constructor was
 called. When I compile my code, I get Error: cannot implicitly
 convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[][]
 which is logical. But is there any way to insert every instance into
 the array and define the array/map for this entry?

 Thanks in advance!
Is there any particular reason you're using ubyte[][2][hash_t] there? To
keep a reference to each instance simply use:

class MyClass {
 static MyClass[] classInstances;
 this() {
 classInstances ~= this;
 }
}

If you in fact want to have a hashmap indexed by the instances with
values of type ubyte[][2], you can do this:

class MyClass {
 static ubyte[][2][MyClass] classInstances;
 this() {
 classInstances[this] = new ubyte[][2];
 }
}

The problem in your original code is that you were using = new ubyte[2]
rather than = new ubyte[][2]. Hope this helps.


Ok, that works - thx.

@Steve: I'll delete the entries from the map, but what's about  
overriding the toHash()-function and return a simply int value?


If two instances return the same hash value (as is easily possible, but  
maybe not for your context), then a collision occurs.  Then opCmp is used  
to determine if they are actually identical.


If you use hash_t as your key, then only one object is stored in the map,  
the other is simply overwritten.


I also need this map-structure for further steps in my application. I's  
possible to change it to


ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass]
ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass]

but I thought one map for the same sense is better.


ubyte[][Object] should work for all class types.


Btw: I've two classes where one inherits:

class MyClassOne {

   protected {
  static __gshared {
 uint counter;
 uint[MyClassOne] fixedData;
  }
  uint otherData;

  this(uint d) {
 otherData = d;
  }
   }

   this() {
  fixedData[this] = ++counter;
   }

   @property ref {
  uint myPropOne() { return fixedData[this]; }
  uint myPropTwo() { return otherData; }
   }

}

class MyClassTwo : MyClassOne {

   shared(MyClassOne) supInstance;

   this(uint d, MyClassOne mco) {
  super(d);
  supInstance = mco;
   }

   override ref alias supInstance.myPropOne myPropOne;

}

When I create an instance of MyClassOne and call myPropOne on it, I get  
1. When I'm using this instance to create an instance of
MyClassTwo and call myPropOne, I get 0. Is there anything I'm doing  
wrong?


That crazy override ref alias line, I have no idea what you're doing  
there.  For sure, override ref is not needed.


I'm surprised all of this compiles.

What I'm trying to do is: One super-class which contains some fixed data  
(not inheritable) and some data which are different for each

class.


Note that protected does not prevent MyClassTwo from changing it.

Also note that even though you've only created one instance of MyClassOne,  
every MyClassTwo instance is a MyClassOne (and calls MyClassOne's  
constructor).  I think you have applied the wrong techniques to solving  
your design.  Without knowing further your design/context, I can't really  
help.


-Steve


Re: Removing entries from AAs

2011-08-19 Thread useo6
== Auszug aus Timon Gehr (timon.g...@gmx.ch)'s Artikel
 On 08/19/2011 02:01 PM, useo6 wrote:
  Hi,
 
  I've create a little example of my problem:
 
  module example;
 
  class ExampleClass {
 
  public {
 
  int mi;
 
  this(int i) {
  mi = i;
  }
 
  }
 
  }
 
  int main(string[] args) {
 
  ExampleClass[hash_t] exp;
 
  ExampleClass cex = new ExampleClass(1);
  exp[cex.toHash()] = cex;
 
  cex = new ExampleClass(2);
  exp[cex.toHash()] = cex;
 
  cex = new ExampleClass(3);
  exp[cex.toHash()] = cex;
 
  foreach (ExampleClass c; exp) {
  if (c.mi == 2) {exp.remove(c.toHash()); }
  }
 
  return 0;
 
  }
 
  When I run this small example-app, I get an Access Violation.
When
  I insert a break into my foreach-loop like:
 
  foreach (ExampleClass c; exp) {
  if (c.mi == 2) {exp.remove(c.toHash()); break; }
  }
 
  it works, but this means, I leave the foreach-loop. What I'm doing
  wrong by using the foreach-block?
 
  Thanks for any help!
 The problem is that you change the AA while iterating over it. You
could
 eg iterate over it and save all keys you want to remove into an
array
 and then iterate over the array to remove the keys from the AA.
 This works:
 module example;
 class ExampleClass {
   public {
   int mi;
   this(int i) {
   mi = i;
   }
   }
 }
 int main(string[] args) {
   ExampleClass[hash_t] exp;
   ExampleClass cex = new ExampleClass(1);
   exp[cex.toHash()] = cex;
   cex = new ExampleClass(2);
   exp[cex.toHash()] = cex;
   cex = new ExampleClass(3);
   exp[cex.toHash()] = cex;
   hash_t[] toRemove;
   foreach (c; exp) {
   if (c.mi == 2) { toRemove~=c.toHash(); }
   }
   foreach (h; toRemove) {
   exp.remove(h);
   }
   return 0;
 }

I already thought about that situation, but some explained the
removing/clearing of an array by iterate over each element and remove
it from the AA. I just solved the problem by using the HashSet-class
from the dcollection's.


Re: Empy program running time

2011-08-19 Thread Steven Schveighoffer

On Fri, 19 Aug 2011 01:29:05 -0400, Marco Leise marco.le...@gmx.de wrote:

Am 29.07.2011, 17:23 Uhr, schrieb Steven Schveighoffer  
schvei...@yahoo.com:


On Fri, 29 Jul 2011 10:50:52 -0400, bearophile  
bearophileh...@lycos.com wrote:



Steven Schveighoffer:

For example, D needs to call all the module ctors and do the import  
cycle

detection algorithm.


Even for an empty program?


Yes.  I bet even an empty program has on the order of 50 module  
ctor/dtors to run.  All the runtime can contain module ctor/dtors, and  
those modules are compiled in no matter what.  Plus dmd adds hidden  
modules with ctor/dtors.


There are other initializations, such as the GC, setting up the main  
thread, etc.



0.11 seconds is not unreasonable.


It means about 170_000_000 CPU clock ticks, to me it seems a lot.


I guess if you want to have an empty program benchmark?  It doesn't  
seem to mean much to me...


If it was on the order of seconds, I'd agree with you.  .11 seconds is  
barely noticeable.


You think in the wrong category. Imagine where this would matter, where  
you would invoke a program multiple times. From the top of my head there  
is batch execution. If your program is a converter of some sort that  
takes one input file and one output file at a time and someone writes a  
script to convert all files in a directory structure. Every 545 files  
you get an additional minute of initialization on that test machine! If  
the actual conversion algorithms is fast and the files are small (i.e.  
converting character encodings in text files) this is well noticeable.
A more abstract idea is the boot process of an old-school Linux  
installation. Every start script (mail server, keyboard layout, swap,  
logging, ...) invokes the shell several times. If the shell was written  
in D it would slow down the boot process more than necessary. But here  
efforts were made to reduce the amount of processes spawned during the  
boot process so this can not be a valid argument.
The file utility opens files and prints their mime-type looking at  
magic bytes and other identifiers. This is another good example of a  
program that may be run on a large number of files, but doesn't run for  
long. It could be used by a file system browser to display the file-type  
of every file in a directory.


I agree for simple frequently used utilities, the initialization time can
be bad.  But I have actually written scripting utility programs
(ironically, to help boot a custom linux OS that I built), and I didn't
notice terrible slowdown.

Another question is, would someone who is using D be more likely to write
their script in D, and simply use D libraries, or write a file utility
in D, and use a shell script?

It all depends on the situation, and to me, .11 seconds isn't that
terrible.  If it can be improved, then I think we should do it, but IMO
it's not a critical piece right now.

-Steve


core.stdc.stdio.stderr != std.stdio.stderr ?

2011-08-19 Thread bearophile
Is this all correct?


static import core.stdc.stdio;
static import std.stdio;
void main() {
std.stdio.fprintf(core.stdc.stdio.stderr, Error\n); // OK
std.stdio.fprintf(std.stdio.stderr, Error\n); // line 5, error
}

The latest DMD gives:

test.d(5): Error: function core.stdc.stdio.fprintf (shared(_iobuf)* stream, in 
const(char*) format,...) is not callable using argument types (File,string)
test.d(5): Error: cannot implicitly convert expression (stderr) of type File to 
shared(_iobuf)*

Bye,
bearophile


Re: core.stdc.stdio.stderr != std.stdio.stderr ?

2011-08-19 Thread Steven Schveighoffer
On Fri, 19 Aug 2011 10:12:11 -0400, bearophile bearophileh...@lycos.com  
wrote:



Is this all correct?


static import core.stdc.stdio;
static import std.stdio;
void main() {
std.stdio.fprintf(core.stdc.stdio.stderr, Error\n); // OK
std.stdio.fprintf(std.stdio.stderr, Error\n); // line 5, error
}

The latest DMD gives:

test.d(5): Error: function core.stdc.stdio.fprintf (shared(_iobuf)*  
stream, in const(char*) format,...) is not callable using argument types  
(File,string)
test.d(5): Error: cannot implicitly convert expression (stderr) of type  
File to shared(_iobuf)*


Yes, std.stdio.stderr is a D File struct, whereas core.stdc.stdio.stderr  
is a C FILE * opaque type.


-Steve


Re: assertion failure in std.range.iota

2011-08-19 Thread Andrej Mitrovic
http://d.puremagic.com/issues/show_bug.cgi?id=6531


Re: core.stdc.stdio.stderr != std.stdio.stderr ?

2011-08-19 Thread David Nadlinger

On 8/19/11 4:12 PM, bearophile wrote:

static import core.stdc.stdio;
static import std.stdio;
void main() {
 std.stdio.fprintf(core.stdc.stdio.stderr, Error\n); // OK
 std.stdio.fprintf(std.stdio.stderr, Error\n); // line 5, error
}


std.stdio.stderr is a wrapper around core.stdc.stdio.stderr (a D File), 
you can use std.stdio.stderr.getFP() to get the C FILE pointer from it.


David


help understanding import libraries

2011-08-19 Thread maarten van damme
I'm really getting confused as to how import libraries actually work.
Someone once told me that in order to use an import library one has to write
d files declaring the functions so that the dmd compiler knows what's in the
lib files.
I've never thought any further untill I compiled the gtkd project to a lib
file.

the compiler flags I needed to add was -I for every src directory and -L for
the lib file. The problem with that was that those files in the src dir
don't declare the functions but also define them. They are the real source
code files so I didn't understand why the -L flag was necessary. I never
experimented further though :)

Today I've looked  in the lib files and saw that phobos.lib was there. just
for fun I decided to compile a simple hello world file and compile it with
the standard compiler options. Then I compiled without linking and did the
linking manually. The resulting executable was 146 kb while the executable
using the standard compiler options was almost 2 megabytes.

Is the compiler really including all the garbage I use from phobos from
the source files instead of linking to the phobos.lib file? Can I avoid
this? does the -L flag pointing to my gtkd.lib file actually do something?

Secondly I've also used implib to convert a dll file to a .lib file. The
resulting lib file was WAY smaller then the dll file so I concluded that the
lib file only contains information like this:
in dll XXX
function YYY at export adress Y
function ZZZ at export adress Z
...

But where does the lib file searches for the dll file? how can we control
that? Is my hunch right?

Maarten


Re: Insert array into an AA

2011-08-19 Thread nrgyzer
== Auszug aus Steven Schveighoffer (schvei...@yahoo.com)'s Artikel
 On Thu, 18 Aug 2011 06:47:32 -0400, nrgyzer nrgy...@gmail.com
wrote:
  == Auszug aus Robert Clipsham (rob...@octarineparrot.com)'s
Artikel
  On 16/08/2011 20:17, nrgyzer wrote:
   Hi everyone,
  
   I've the following:
  
   private static ubyte[][2][hash_t] classInstances;
  
   this() {
  
   classInstances[toHash()] = new ubyte[2]; // does not work
  
   }
  
   I want insert every class instance into the hashmap. Every
class
   instance should be contained in the map after the constructor
was
   called. When I compile my code, I get Error: cannot implicitly
   convert expression (new ubyte[](2u)) of type ubyte[] to ubyte[]
[]
   which is logical. But is there any way to insert every
instance into
   the array and define the array/map for this entry?
  
   Thanks in advance!
  Is there any particular reason you're using ubyte[][2][hash_t]
there? To
  keep a reference to each instance simply use:
  
  class MyClass {
   static MyClass[] classInstances;
   this() {
   classInstances ~= this;
   }
  }
  
  If you in fact want to have a hashmap indexed by the instances
with
  values of type ubyte[][2], you can do this:
  
  class MyClass {
   static ubyte[][2][MyClass] classInstances;
   this() {
   classInstances[this] = new ubyte[][2];
   }
  }
  
  The problem in your original code is that you were using = new
ubyte[2]
  rather than = new ubyte[][2]. Hope this helps.
 
  Ok, that works - thx.
 
  @Steve: I'll delete the entries from the map, but what's about
  overriding the toHash()-function and return a simply int value?
 If two instances return the same hash value (as is easily possible,
but
 maybe not for your context), then a collision occurs.  Then opCmp
is used
 to determine if they are actually identical.
 If you use hash_t as your key, then only one object is stored in
the map,
 the other is simply overwritten.
  I also need this map-structure for further steps in my
application. I's
  possible to change it to
 
  ubyte[][hash_t] classInstancesOne; // or ubyte[][MyClass]
  ubyte[][hash_t] classInstancesTwo; // or ubyte[][MyClass]
 
  but I thought one map for the same sense is better.
 ubyte[][Object] should work for all class types.
  Btw: I've two classes where one inherits:
 
  class MyClassOne {
 
 protected {
static __gshared {
   uint counter;
   uint[MyClassOne] fixedData;
}
uint otherData;
 
this(uint d) {
   otherData = d;
}
 }
 
 this() {
fixedData[this] = ++counter;
 }
 
 @property ref {
uint myPropOne() { return fixedData[this]; }
uint myPropTwo() { return otherData; }
 }
 
  }
 
  class MyClassTwo : MyClassOne {
 
 shared(MyClassOne) supInstance;
 
 this(uint d, MyClassOne mco) {
super(d);
supInstance = mco;
 }
 
 override ref alias supInstance.myPropOne myPropOne;
 
  }
 
  When I create an instance of MyClassOne and call myPropOne on it,
I get
  1. When I'm using this instance to create an instance of
  MyClassTwo and call myPropOne, I get 0. Is there anything I'm
doing
  wrong?
 That crazy override ref alias line, I have no idea what you're doing
 there.  For sure, override ref is not needed.
 I'm surprised all of this compiles.
  What I'm trying to do is: One super-class which contains some
fixed data
  (not inheritable) and some data which are different for each
  class.
 Note that protected does not prevent MyClassTwo from changing it.
 Also note that even though you've only created one instance of
MyClassOne,
 every MyClassTwo instance is a MyClassOne (and calls MyClassOne's
 constructor).  I think you have applied the wrong techniques to
solving
 your design.  Without knowing further your design/context, I can't
really
 help.
 -Steve

I'm working on a game where the player can build different buildings.
There are some general building-structures which defines the costs to
build it and some other things, but the name of each building can be
modified by the player. So, each building can have it's own name, but
the costs to build are always the same for each building.
To prevent the redefinition of all the property-methods, I want
redirect the properties of a simple building-property to it's
building structure. For example:

class BuildingShell {

   private float[BuildingShell] pCostsToBuild;

   protected {
  string pName;
  this(string name) {
 pName = name;
  }
   }

   this(string name, float costs) {
  pName = name;
  pCostsToBuild[this] = costs;
   }

   @property {
  ref float costsToBuild() { return pCostsToBuild[this]; }
  string name() { return pName; }
   }

}

class Building : BuildingShell {

   shared(BuildingShell) pShell;

   this(BuldingShell bs, string name) {
  super(name);
  pShell = cast(shared) bs;
   }

   override @property 

Re: help understanding import libraries

2011-08-19 Thread Jesse Phillips
maarten van damme Wrote:

 the compiler flags I needed to add was -I for every src directory and -L for
 the lib file. The problem with that was that those files in the src dir
 don't declare the functions but also define them. They are the real source
 code files so I didn't understand why the -L flag was necessary. I never
 experimented further though :)

The process of creating an executable goes from generating machine code from 
source to linking the machine code for execution, as you know. The -I flag is 
the compiler import/include directory while -L is flags passed to the linker. 
That so while you may have complete source code in the import directory the 
compiler is only looking at the declaration and does not compile the files, it 
then informs the linker where the symbols can be found from the information you 
provide after the -L flag.

If you wanted (and didn't run out of command line characters) you could list 
all .d files in every library you are using and have dmd compile everything for 
you. Then the -L would not be required.


Re: help understanding import libraries

2011-08-19 Thread Andrej Mitrovic
You don't need the damn -L flag, just pass the .lib file directly and
DMD will pass it to the linker.


Re: help understanding import libraries

2011-08-19 Thread Graham Fawcett
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote:

 If you wanted (and didn't run out of command line characters) you could
 list all .d files in every library you are using and have dmd compile
 everything for you. Then the -L would not be required.

Just a reminder, you have dmd @cmdfile for cases where you want to put 
a long command line's options into a file for easier management.

Graham


Re: help understanding import libraries

2011-08-19 Thread Graham Fawcett
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote:

 If you wanted (and didn't run out of command line characters) you could
 list all .d files in every library you are using and have dmd compile
 everything for you. Then the -L would not be required.

Just a reminder, you have dmd @cmdfile for cases where you want to put 
a long command line's options into a file for easier management.

Graham


Re: help understanding import libraries

2011-08-19 Thread Graham Fawcett
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote:

 If you wanted (and didn't run out of command line characters) you could
 list all .d files in every library you are using and have dmd compile
 everything for you. Then the -L would not be required.

Just a reminder, you have dmd @cmdfile for cases where you want to put 
a long command line's options into a file for easier management.

Graham


Re: help understanding import libraries

2011-08-19 Thread Graham Fawcett
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote:

 If you wanted (and didn't run out of command line characters) you could
 list all .d files in every library you are using and have dmd compile
 everything for you. Then the -L would not be required.

Just a reminder, you have dmd @cmdfile for cases where you want to put 
a long command line's options into a file for easier management.

Graham


Re: help understanding import libraries

2011-08-19 Thread Graham Fawcett
On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote:

 If you wanted (and didn't run out of command line characters) you could
 list all .d files in every library you are using and have dmd compile
 everything for you. Then the -L would not be required.

Just a reminder, you have dmd @cmdfile for cases where you want to put 
a long command line's options into a file for easier management.

Graham


Re: help understanding import libraries

2011-08-19 Thread Andrew Wiley
On Fri, Aug 19, 2011 at 9:38 AM, Jesse Phillips
jessekphillip...@gmail.comwrote:

 maarten van damme Wrote:

  the compiler flags I needed to add was -I for every src directory and -L
 for
  the lib file. The problem with that was that those files in the src dir
  don't declare the functions but also define them. They are the real
 source
  code files so I didn't understand why the -L flag was necessary. I never
  experimented further though :)

 The process of creating an executable goes from generating machine code
 from source to linking the machine code for execution, as you know. The -I
 flag is the compiler import/include directory while -L is flags passed to
 the linker. That so while you may have complete source code in the import
 directory the compiler is only looking at the declaration and does not
 compile the files, it then informs the linker where the symbols can be found
 from the information you provide after the -L flag.


Technically it's not saying anything about where the symbols can be found,
it's just putting them into the object file as external symbols that the
linker needs to resolve, but yes. The compiler basically ignores lib files
and passes them to the linker.


Re: help understanding import libraries

2011-08-19 Thread maarten van damme
and how come the executable I manually linked was 17 times smaller then the
other executable?
and how does the dll searching works?


Re: duplicates (Re: help understanding import libraries)

2011-08-19 Thread maarten van damme
I saw the same with another user using the web interface, seems like it's
buggy

2011/8/19 Graham Fawcett fawc...@uwindsor.ca

 On Fri, 19 Aug 2011 17:35:00 +, Graham Fawcett wrote:

  On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote:
 
  If you wanted (and didn't run out of command line characters) you could
  list all .d files in every library you are using and have dmd compile
  everything for you. Then the -L would not be required.
 
  Just a reminder, you have dmd @cmdfile for cases where you want to put
  a long command line's options into a file for easier management.
 
  Graham

 Sorry for the duplicate posts, I have no idea why that happened.

 Graham




Re: help understanding import libraries

2011-08-19 Thread Jesse Phillips
Graham Fawcett Wrote:

 On Fri, 19 Aug 2011 12:38:01 -0400, Jesse Phillips wrote:
 
  If you wanted (and didn't run out of command line characters) you could
  list all .d files in every library you are using and have dmd compile
  everything for you. Then the -L would not be required.
 
 Just a reminder, you have dmd @cmdfile for cases where you want to put 
 a long command line's options into a file for easier management.
 
 Graham

Yes but that just adds an extra lesson on top of learning what -I and -L do, 
why they are different and why both are used together.


gdc ldc problems

2011-08-19 Thread maarten van damme
so I have installed ldc,gdc and dmd on my linux box(debian testing)
the problem now is that when I try to compiler something using gdc or ldc
that imports from core it gives an error (core.* can not be found).
the versions of phobos between the 3 are completely out of sync, did I
install it the wrong way (simple apt-getting?)


Re: gdc ldc problems

2011-08-19 Thread Jesse Phillips
On Sat, 20 Aug 2011 03:37:52 +0200, maarten van damme wrote:

 so I have installed ldc,gdc and dmd on my linux box(debian testing) the
 problem now is that when I try to compiler something using gdc or ldc
 that imports from core it gives an error (core.* can not be found). the
 versions of phobos between the 3 are completely out of sync, did I
 install it the wrong way (simple apt-getting?)

The compilers found in the repository support D1, core.* is part of D2.


Re: gdc ldc problems

2011-08-19 Thread maarten van damme
ooh, thank you :)

2011/8/20 Jesse Phillips jessekphillip...@gmail.com

 On Sat, 20 Aug 2011 03:37:52 +0200, maarten van damme wrote:

  so I have installed ldc,gdc and dmd on my linux box(debian testing) the
  problem now is that when I try to compiler something using gdc or ldc
  that imports from core it gives an error (core.* can not be found). the
  versions of phobos between the 3 are completely out of sync, did I
  install it the wrong way (simple apt-getting?)

 The compilers found in the repository support D1, core.* is part of D2.



[Issue 6365] AutoTupleDeclaration

2011-08-19 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=6365



--- Comment #30 from bearophile_h...@eml.cc 2011-08-18 23:35:27 PDT ---
(In reply to comment #26)

 We should step back and figure out what we want to do with tuples in the much
 more general case.

I think this point is mostly solved, because while tuples are useful for many
different purposes and situations, such purposes are well known. Languages like
Python, Haskell and Scala show and contain most significant usages for tuples.



 I am nervous we are building a special case for tuples. I think
 any expansion of tuple support should be part of a more comprehensive design
 for tuples.

I agree. This is why I have created issue 6383 . It deals with more general
idea of unpacking. Issue 6383 doesn't cover all possible situations, but they
are enough to start.


 If we grow tuple support by adding piecemeal special cases for this and that,
 without thinking about them more globally, we are liable to build ourselves
 into a box we can't get out of.

I have done my best. But the discussion has stopped.
So my suggestion is to put this in the next DMD release as *experimental*
feature, and let people:
1) Try it and find what's good and bad of it through practical experience, and
even trial and error;
2) Use this concrete implementation as a trampoline to think in abstract about
that good and bad of this current design.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 6365] AutoTupleDeclaration

2011-08-19 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=6365



--- Comment #31 from bearophile_h...@eml.cc 2011-08-18 23:47:46 PDT ---
Regarding this change, removing tuple unpacking for arrays is not a good idea,
in my opinion. You are making tuples less handy, with zero gain in doing so.

https://github.com/9rnsr/dmd/commit/6fa008162fe29a1459c35dccb9e08009598206d0

Conceptually it's the same thing as doing:

void main() {
int[] a = [1, 2];
int[2] b = a;
}

The compiler will need to verify at runtime that a has length 2. Given this
precedent in the language, there is no point in forbidding a similar operation
on tuples:

void main() {
int[] a1 = [1, 2];
auto (x, y) = a1;
int[2] a2 = [1, 2];
auto (z, w) = a2; // no need to verify a2 length at runtime here
}


I think this is what Walter was talking about in comment 26:

I think any expansion of tuple support should be part of a more comprehensive 
design for tuples.


Python tuples support this operation, that feels natural enough to Python
programmers:

 a1 = [1, 2]
 (x, y) = a1
 x
1
 y
2

So in my opinion Andrei is wrong here.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 6510] [CTFE] internal error: illegal stack value when compiled with -inline

2011-08-19 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=6510



--- Comment #9 from Don clugd...@yahoo.com.au 2011-08-19 05:53:36 PDT ---
Further reduced, showing that templates are not required. Seems to require an
inlined member function call to a member of a nested struct, called from a
nested function. No alias trick works in this case.

struct Stack6510 {
struct Proxy { 
void shrink() {}
}
Proxy stack;
void pop() {
stack.shrink();
}
}

int bug6510() {
static int used() {
Stack6510 junk;
junk.pop();
return 3;
}
return used();
}

void main() {
static assert(bug6510()==3);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 5710] cannot use delegates as parameters to non-global template

2011-08-19 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=5710



--- Comment #10 from David Simcha dsim...@yahoo.com 2011-08-19 07:03:02 PDT 
---
(In reply to comment #9)
 My idea:
 doStuff receives a context pointer that points 'an array of context pointers'.
 Backend receives code like follows...
 
 uint doStuff(uint a, uint b, void** this)  // not void* this
 {
 // (*this + 0) points the object Foo
 // (*this + 1) points the stack frame of main()
 
 //return fun(a, b);
 return fun(a, b, (*this + 1));
 }
 
 Caller of doStuff have to create array of context pointers.
 
 void main(){
 ...
 //foo.doStuff!add(1, 2);
 void*[2] thisarray = [(stack frame of main), foo];
 doStuff(a, b, thisarray.ptr);
 }

Sounds great if you can pull it off.  I was thinking the same thing, but I'm
not familiar enough with the DMD codebase to know how easy/hard it would be to
implement.  This would remove some really silly/annoying limitations from
std.parallelism.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 6531] New: assertion failure in std.range.iota

2011-08-19 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=6531

   Summary: assertion failure in std.range.iota
   Product: D
   Version: D2
  Platform: Other
OS/Version: Windows
Status: NEW
  Severity: major
  Priority: P2
 Component: Phobos
AssignedTo: nob...@puremagic.com
ReportedBy: andrej.mitrov...@gmail.com


--- Comment #0 from Andrej Mitrovic andrej.mitrov...@gmail.com 2011-08-19 
07:49:29 PDT ---
import std.range;
import std.stdio;

void main()
{
   auto r1 = iota(0.0, 4.0, 0.03);  // ok
   auto r2 = iota(0.0, 3.0, 0.03);  //
core.exception.AssertError@std.range(4001): Assertion failure
}

I want a range in steps of 0.03, beginning at 0.0 and ending at the
closest point to 3.0.

Line 4001 is:
assert(start + count * step = end);

There's no documentation, and no custom assert message, so I don't know what
was the intention of the author.

It doesn't help that this fails in debug mode but works fine in release mode.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 1001] print stack trace (in debug mode) when program die

2011-08-19 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=1001



--- Comment #56 from Sean Kelly s...@invisibleduck.org 2011-08-19 14:12:24 
PDT ---
If you want exceptions for these events on Posix, create a signal handler and
throw one.  On some OSes it will work and on others it won't.  Assuming you're
targeting a platform where it works though, doing so might be a net win.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---


[Issue 6533] New: Compiler should catch duplicate overrides

2011-08-19 Thread d-bugmail
http://d.puremagic.com/issues/show_bug.cgi?id=6533

   Summary: Compiler should catch duplicate overrides
   Product: D
   Version: D2
  Platform: Other
OS/Version: Windows
Status: NEW
  Severity: enhancement
  Priority: P2
 Component: DMD
AssignedTo: nob...@puremagic.com
ReportedBy: andrej.mitrov...@gmail.com


--- Comment #0 from Andrej Mitrovic andrej.mitrov...@gmail.com 2011-08-19 
19:26:40 PDT ---
class Foo
{
abstract void foo();
}

class Bar : Foo
{
override void foo() 
{
// code
}

override void foo() { }
}

void main() {}

This ends up being a linker error such as:  Offset 00542H Record Type 00C3
 Error 1: Previous Definition Different : _D12overridetest3Bar3fooMFZv

The problem is in a large class you might end up mistakenly defining an
overriden function twice, and you won't get a compile-time error, you will get
a linker error instead.

Making this a compile-time error would be an improvement.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
--- You are receiving this mail because: ---