Re: How do I simulate variadic parameters for template (range) functions?

2011-08-25 Thread Jacob Carlborg

On 2011-08-24 19:40, Andrej Mitrovic wrote:

Here's what I can do with a variadic function:

void main()
{
 int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];

 process(a[a.countUntil(7) .. $]);
 process(1);
}

void process(int[] vals...)
{
 foreach (val; vals)
 {
 }
}

Very simple, pass one or multiple arguments. But then I thought about
using the `until` template instead of countUntil. However `until`
returns a range. So my next guess was to write:

void main()
{
 int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];

 process(a.until(7));  // ok
 process(4);  // error since 4 is not a range
}

void process(Range)(Range vals) if (isInputRange!Range
is(ElementType!Range == int))
{
 foreach (val; vals)
 {
 }
}

Is it somehow possible to automatically convert a literal to a range?
I really miss the convenience of variadic functions. I thought about
making an overload that only takes an int and constructing a simple
input range around it so it can be passed to process(), e.g.:

void process(Range)(Range vals) if (isInputRange!Range
is(ElementType!Range == int))
{
 foreach (val; vals)
 {
 }
}

void process(int arg)
{
 process(makeInputRange(arg));  // make an input range, pass to
above process()
}

But I can't overload templated and non-templated functions, I think
this is one of those old-standing bugs.


Use a variadic template function and check if the first argument is a 
range or not.


--
/Jacob Carlborg


Create a foreach-able struct? Multi-dimensional even?

2011-08-25 Thread Heywood Floyd

Hello!

1) How do I create a struct that I can foreach over?

I get the impression opApply has something do to with this, but I can't find 
any documentation on it? (And I'm abroad without my TDPL.)


2) Also, is it possible to do something like this? 

  MyData!(100,100,100) data;
  foreach(x, y, z, ref cell; data){
 cell = x*y*z;
  }

(The idea here is cells are stored in a plain 1-dimensional array behind the 
scenes, but iterated as a 3-dimensional array.)


Kind regards
/HF


Re: Create a foreach-able struct? Multi-dimensional even?

2011-08-25 Thread Heywood Floyd
Heywood Floyd Wrote:

 
 Hello!
 
 1) How do I create a struct that I can foreach over?
 
 I get the impression opApply has something do to with this, but I can't find 
 any documentation on it? (And I'm abroad without my TDPL.)
 
 
 2) Also, is it possible to do something like this? 
 
   MyData!(100,100,100) data;
   foreach(x, y, z, ref cell; data){
  cell = x*y*z;
   }
 
 (The idea here is cells are stored in a plain 1-dimensional array behind the 
 scenes, but iterated as a 3-dimensional array.)
 
 
 Kind regards
 /HF


Ah, I'm sorry, I found the documentation regarding opApply() now. Typical. (The 
site-search didn't seem to work there. Ok..)

Still, is the multi-dimensional part possible?

/HF


Re: Create a foreach-able struct? Multi-dimensional even?

2011-08-25 Thread Heywood Floyd
Christophe Wrote:

  Still, is the multi-dimensional part possible?
 
 Sure, you have to make an opApply that takes several parameters in its 
 delegate.
 An exemple:
 
 struct TwoDArray(int nx, int ny)
 {
   int[nx][ny] data;
 
   int opApply(int delegate(ref int i, ref int j, ref int cell)
 {
   foreach (i; 0..nx)
 foreach (j; 0..ny)
   {
 int result = dg(i, j, data[i][j]);
 if (result != 0) return result;
   }
return 0;
 }
 }
 
 
 // this program prints a multiplication table:
 int main()
 {
   TwoDArray!(10, 10) data;
   
   foreach(i, j, ref cell; data)
 {
   cell = i * j;
 }
 
   foreach(i, j, cell; data)
 {
   writefln(%s * %s = %s, i, j, cell);
 }
   return 0;
 }
 


Ha! Beautiful, thanks!!



Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Timon Gehr

On 08/25/2011 01:11 PM, Steven Schveighoffer wrote:

On Wed, 24 Aug 2011 19:01:31 -0400, Timon Gehr timon.g...@gmx.ch wrote:


On 08/25/2011 12:47 AM, Mafi wrote:

Am 24.08.2011 21:04, schrieb Timon Gehr:

On 08/24/2011 08:04 PM, Andrej Mitrovic wrote:

Here's some code that iterates through parents of some class object
until it finds an object with no parent (where parent is null):

import std.stdio;

class Foo
{
Foo parent;
int state;

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

void main()
{
auto foo = new Foo(0);
foo.parent = new Foo(1);
foo.parent.parent = new Foo(2);

while (true)
{
if (auto par = foo.parent)
{
writeln(par.state);
foo = par;
}
else
{
break;
}
}
}

(syntax-highlighted: http://codepad.org/8yHRmICh)

But I was hoping I could simplify this by doing:

while (auto par = foo.parent)
{
writeln(par.state);
foo = par;
}

However that doesn't work, I get back:
expression expected, not 'auto'

Is there a limitation on why this couldn't work or can this be added
to the language?


Afaics, this could be added just like it could be added for if. In fact
the compiler should be able to simply rewrite it to your first example.
I think it is worth an enhancement request, because there are
situations
where this would be useful, and implementation should be trivial, if
somebody has the time. (I also think it adds to the consistency of the
language, but others may disagree.)


(btw, i always use for(;;) instead of while(true), it is usually faster
in debug mode and faster to type :))


I just have to say that it already works for 'if'. It's a great feature
because in the body of the 'if' you know the value is non-null and
outside, where there could be an segfault, the variable is not visible.
I'm not really sure if it's good for 'while'.
I'm unsure because there are two somewhat natural semantics for such a
construct.

//example
//more to the nature of while
while(auto obj = init) { work(obj); }

//1 (your interpretation)
typeof(init) obj;
while(obj = init) { work(obj); }

//2
/*
seems more natural for me because init runs only once (like any other
init and like in 'for' or 'if')
*/


for(;;){int x=init;} // init runs infinitely many times


if(auto a=init){} is really more trying to solve

if(???){auto a=init;} // correct scoping but cannot refer to it in cond

than

{auto a=init; if(a){}} // correct scoping as long as there is no else

That is why there is the language construct. That it has not been
adopted for while is because it is so much more useful for if, but I
personally think while could/should get the possibility as well.




auto obj = init;
while(obj) { work(obj); }

This could confuse many people, I think. What do you think?



I think that by the same argument, you could say that the fact that
the body of a looping statement is executed multiple times could
confuse many people.

1 is more natural imho. (and 2 would be rather useless)


I disagree -- I think the semantics are confusing.


while(condition) do_this;
while(auto d=condition) do_this_and_use_d;

I still think it is simple, but it is not a feature I miss often.



I'd say just leave the auto x = y for if and for loops, where there is a
clear run once section.

Also, what do you do with a do while loop if the while contains this
construct?



In do while it is useless because the scope ends after the condition.



Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Jonathan M Davis
On Thursday, August 25, 2011 07:11:31 Steven Schveighoffer wrote:
 On Wed, 24 Aug 2011 19:01:31 -0400, Timon Gehr timon.g...@gmx.ch wrote:
  On 08/25/2011 12:47 AM, Mafi wrote:
  Am 24.08.2011 21:04, schrieb Timon Gehr:
  On 08/24/2011 08:04 PM, Andrej Mitrovic wrote:
  Here's some code that iterates through parents of some class
  object
  until it finds an object with no parent (where parent is null):
  
  import std.stdio;
  
  class Foo
  {
  Foo parent;
  int state;
  
  this (int state) { this.state = state; }
  }
  
  void main()
  {
  auto foo = new Foo(0);
  foo.parent = new Foo(1);
  foo.parent.parent = new Foo(2);
  
  while (true)
  {
  if (auto par = foo.parent)
  {
  writeln(par.state);
  foo = par;
  }
  else
  {
  break;
  }
  }
  }
  
  (syntax-highlighted: http://codepad.org/8yHRmICh)
  
  But I was hoping I could simplify this by doing:
  
  while (auto par = foo.parent)
  {
  writeln(par.state);
  foo = par;
  }
  
  However that doesn't work, I get back:
  expression expected, not 'auto'
  
  Is there a limitation on why this couldn't work or can this be
  added
  to the language?
  
  Afaics, this could be added just like it could be added for if. In
  fact
  the compiler should be able to simply rewrite it to your first
  example.
  I think it is worth an enhancement request, because there are
  situations
  where this would be useful, and implementation should be trivial, if
  somebody has the time. (I also think it adds to the consistency of
  the
  language, but others may disagree.)
  
  
  (btw, i always use for(;;) instead of while(true), it is usually
  faster
  in debug mode and faster to type :))
  
  I just have to say that it already works for 'if'. It's a great
  feature
  because in the body of the 'if' you know the value is non-null and
  outside, where there could be an segfault, the variable is not
  visible.
  I'm not really sure if it's good for 'while'.
  I'm unsure because there are two somewhat natural semantics for such a
  construct.
  
  //example
  //more to the nature of while
  while(auto obj = init) { work(obj); }
  
  //1 (your interpretation)
  typeof(init) obj;
  while(obj = init) { work(obj); }
  
  //2
  /*
  seems more natural for me because init runs only once (like any other
  init and like in 'for' or 'if')
  */
  
  for(;;){int x=init;} // init runs infinitely many times
  
  
  if(auto a=init){} is really more trying to solve
  
  if(???){auto a=init;} // correct scoping but cannot refer to it in cond
  
  than
  
  {auto a=init; if(a){}} // correct scoping as long as there is no else
  
  That is why there is the language construct. That it has not been
  adopted for while is because it is so much more useful for if, but I
  personally think while could/should get the possibility as well.
  
  auto obj = init;
  while(obj) { work(obj); }
  
  This could confuse many people, I think. What do you think?
  
  I think that by the same argument, you could say that the fact that the
  body of a looping statement is executed multiple times could confuse
  many people.
  
  1 is more natural imho. (and 2 would be rather useless)
 
 I disagree -- I think the semantics are confusing.
 
 I'd say just leave the auto x = y for if and for loops, where there is a
 clear run once section.
 
 Also, what do you do with a do while loop if the while contains this
 construct?
 
 I just find the whole thing confusing.

I don't see why it would be confusing. Because it's unclear whether it's set 
every time or whether it's a new variable every time? It's actually one of 
those things that I do periodically thinking that it works and then get 
frustrated when it doesn't, so I'd love to see it added.

- Jonathan M Davis


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Steven Schveighoffer
On Thu, 25 Aug 2011 11:15:44 -0400, Jonathan M Davis jmdavisp...@gmx.com  
wrote:



On Thursday, August 25, 2011 07:11:31 Steven Schveighoffer wrote:

 On 08/25/2011 12:47 AM, Mafi wrote:



 I'm not really sure if it's good for 'while'.
 I'm unsure because there are two somewhat natural semantics for such  
a

 construct.

 //example
 //more to the nature of while
 while(auto obj = init) { work(obj); }

 //1 (your interpretation)
 typeof(init) obj;
 while(obj = init) { work(obj); }

 //2
 /*
 seems more natural for me because init runs only once (like any other
 init and like in 'for' or 'if')
 */

I'd say just leave the auto x = y for if and for loops, where there is a
clear run once section.

Also, what do you do with a do while loop if the while contains this
construct?

I just find the whole thing confusing.


I don't see why it would be confusing. Because it's unclear whether it's  
set
every time or whether it's a new variable every time? It's actually one  
of

those things that I do periodically thinking that it works and then get
frustrated when it doesn't, so I'd love to see it added.


See Mafi's response above.

What it boils down to is, I usually replace code like this:

auto x = condition;
if(x)
{
   // use x
}

with this:

if(auto x = condition)
{
   // use x.
}

so the logical mapping to while would map this:

auto x = condition;
while(x)
{
   // use x.
}

to this:

while(auto x = condition)
{
   // use x.
}

But it looks like every time through the loop x gets reassigned to  
condition.  That's not what I'd want.  At the very least, it's confusing  
semantics one way or the other.


If you use the construct in the *init* section of a for loop, it reads the  
same as the if statement, since that part is only executed once.


The while loop just doesn't fit the model.

-Steve


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Jonathan M Davis
On Thursday, August 25, 2011 11:31:56 Steven Schveighoffer wrote:
 On Thu, 25 Aug 2011 11:15:44 -0400, Jonathan M Davis jmdavisp...@gmx.com
 
 wrote:
  On Thursday, August 25, 2011 07:11:31 Steven Schveighoffer wrote:
   On 08/25/2011 12:47 AM, Mafi wrote:
   I'm not really sure if it's good for 'while'.
   I'm unsure because there are two somewhat natural semantics for
   such
  
  a
  
   construct.
   
   //example
   //more to the nature of while
   while(auto obj = init) { work(obj); }
   
   //1 (your interpretation)
   typeof(init) obj;
   while(obj = init) { work(obj); }
   
   //2
   /*
   seems more natural for me because init runs only once (like any
   other
   init and like in 'for' or 'if')
   */
  
  I'd say just leave the auto x = y for if and for loops, where there is
  a
  clear run once section.
  
  Also, what do you do with a do while loop if the while contains this
  construct?
  
  I just find the whole thing confusing.
  
  I don't see why it would be confusing. Because it's unclear whether it's
  set
  every time or whether it's a new variable every time? It's actually one
  of
  those things that I do periodically thinking that it works and then get
  frustrated when it doesn't, so I'd love to see it added.
 
 See Mafi's response above.
 
 What it boils down to is, I usually replace code like this:
 
 auto x = condition;
 if(x)
 {
 // use x
 }
 
 with this:
 
 if(auto x = condition)
 {
 // use x.
 }
 
 so the logical mapping to while would map this:
 
 auto x = condition;
 while(x)
 {
 // use x.
 }
 
 to this:
 
 while(auto x = condition)
 {
 // use x.
 }
 
 But it looks like every time through the loop x gets reassigned to
 condition.  That's not what I'd want.  At the very least, it's confusing
 semantics one way or the other.
 
 If you use the construct in the *init* section of a for loop, it reads the
 same as the if statement, since that part is only executed once.
 
 The while loop just doesn't fit the model.

Well, I'd definitely want it so that x is the value of the condition every 
time, and it surprises me that anyone would have thought that that would do 
anything else. The whole point of creating the variable in the if or while 
condition like that IMHO is so that you can save what the exact condition was 
for that run of the if statement or while loop without having to have to run 
the condition twice or have the variable exist outside the scope of the if-
statement or while-loop. If you wanted it to just be the value of the 
condition on the first iteration, then for does that already quite explicitly. 
But then again, assuming that for allows you to assign in the condition as 
well, then at least it's more explicit there, but I would have thought that 
the semantics of the while loop would have been quite clear.

- Jonathan M Davis


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Timon Gehr

On 08/25/2011 05:31 PM, Steven Schveighoffer wrote:
 On Thu, 25 Aug 2011 11:15:44 -0400, Jonathan M Davis
 jmdavisp...@gmx.com wrote:

 On Thursday, August 25, 2011 07:11:31 Steven Schveighoffer wrote:
  On 08/25/2011 12:47 AM, Mafi wrote:

  I'm not really sure if it's good for 'while'.
  I'm unsure because there are two somewhat natural semantics for
 such a
  construct.
 
  //example
  //more to the nature of while
  while(auto obj = init) { work(obj); }
 
  //1 (your interpretation)
  typeof(init) obj;
  while(obj = init) { work(obj); }
 
  //2
  /*
  seems more natural for me because init runs only once (like any 
other

  init and like in 'for' or 'if')
  */
 
 I'd say just leave the auto x = y for if and for loops, where there 
is a

 clear run once section.

 Also, what do you do with a do while loop if the while contains this
 construct?

 I just find the whole thing confusing.

 I don't see why it would be confusing. Because it's unclear whether
 it's set
 every time or whether it's a new variable every time? It's actually
 one of
 those things that I do periodically thinking that it works and then get
 frustrated when it doesn't, so I'd love to see it added.

 See Mafi's response above.

 What it boils down to is, I usually replace code like this:

 auto x = condition;
 if(x)
 {
 // use x
 }

 with this:

 if(auto x = condition)
 {
 // use x.
 }

 so the logical mapping to while would map this:

 auto x = condition;
 while(x)
 {
 // use x.
 }

 to this:

 while(auto x = condition)
 {
 // use x.
 }

 But it looks like every time through the loop x gets reassigned to
 condition. That's not what I'd want. At the very least, it's confusing
 semantics one way or the other.

 If you use the construct in the *init* section of a for loop, it reads
 the same as the if statement, since that part is only executed once.

 The while loop just doesn't fit the model.

 -Steve

I usually replace code like this:

x++;
if(x  100)
{
  // use x
}

with this:

if(++x  100) {
// use x
}

so the logical mapping to while would map this:

x++;
while(x  100)
{
// use x.
}

to this:

while(++x  100) {
// use x.
}


But it looks like every time through the loop x gets incremented.
That's not what I'd want. At the very least, it's confusing
semantics one way or the other.

If you use the construct in the *init* section of a for loop, it reads
the same as the if statement, since that part is only executed once.

The while loop just doesn't fit the model. Let's ditch the while loop.

-Timon


Reading by character and by line from stdin

2011-08-25 Thread bellinom
Hello,

I'm in the process of learning D, and I have some questions about reading from
stdin. I've checked out the documentation but it's really not helping too
much. I'd like to know how to read from stdin one character at a time, read
with whitespace as a delimiter, and read line by line. Essentially just the
equivalents of cin.get(), cin , and cin.getline(). At the momoent I'm using
the D compiler on www.ideone.com, which I assume uses Phobos.

Thanks in advance for any help.

Malcolm


Re: Reading by character and by line from stdin

2011-08-25 Thread Jonathan M Davis
On Thursday, August 25, 2011 10:49 bellinom wrote:
 Hello,
 
 I'm in the process of learning D, and I have some questions about reading
 from stdin. I've checked out the documentation but it's really not helping
 too much. I'd like to know how to read from stdin one character at a time,
 read with whitespace as a delimiter, and read line by line. Essentially
 just the equivalents of cin.get(), cin , and cin.getline(). At the
 momoent I'm using the D compiler on www.ideone.com, which I assume uses
 Phobos.
 
 Thanks in advance for any help.

I would point out that www.ideone.com is horribly out of date. It uses dmd 
2.042, while the latest version is 2.054. So, some stuff will not work there 
in the same way that they work with the latest release.

- Jonathan M Davis


Re: Regarding nothrow and @safe

2011-08-25 Thread Nick Sabalausky
Jacob Carlborg d...@me.com wrote in message 
news:j2qn7n$1db7$1...@digitalmars.com...
 On 2011-08-21 02:26, Jonathan M Davis wrote:

 The short answer: You don't. It's an incredibly bad idea.

 The long answer: You catch Error - or OutOfMemoryError if you want that
 specific one. So, you could try and catch it and handle it, but most of 
 the
 cleanup during the unwinding of the stack gets skipped. scope statements 
 and
 destructors don't get called. Your program is not likely to be in state 
 where
 it makes any real sense to try and continue. You _can_ do it, but it's a 
 bad
 idea.

 - Jonathan M Davis

 What about if you have an application doing heavy image/video processing, 
 the application could empty some caches or similar. The application could 
 still work, just not as fast as with caches.


I remember some discussion awhile back about having some sort of scheme in 
the GC where you could tell the GC Hey, in low-memory situations, instead 
of bailing out with an Error, call this delegate I'm giving you and I'll try 
to clear out my caches to free up some memory. Unfortunately, I don't think 
anything's actually come out of that so far. I really hope it does though, 
it's a great idea.




Re: Regarding nothrow and @safe

2011-08-25 Thread Jonathan M Davis
On Thursday, August 25, 2011 11:38 Nick Sabalausky wrote:
 Jacob Carlborg d...@me.com wrote in message
 news:j2qn7n$1db7$1...@digitalmars.com...
 
  On 2011-08-21 02:26, Jonathan M Davis wrote:
  The short answer: You don't. It's an incredibly bad idea.
  
  The long answer: You catch Error - or OutOfMemoryError if you want that
  specific one. So, you could try and catch it and handle it, but most of
  the
  cleanup during the unwinding of the stack gets skipped. scope statements
  and
  destructors don't get called. Your program is not likely to be in state
  where
  it makes any real sense to try and continue. You _can_ do it, but it's a
  bad
  idea.
  
  - Jonathan M Davis
  
  What about if you have an application doing heavy image/video processing,
  the application could empty some caches or similar. The application could
  still work, just not as fast as with caches.
 
 I remember some discussion awhile back about having some sort of scheme in
 the GC where you could tell the GC Hey, in low-memory situations, instead
 of bailing out with an Error, call this delegate I'm giving you and I'll
 try to clear out my caches to free up some memory. Unfortunately, I don't
 think anything's actually come out of that so far. I really hope it does
 though, it's a great idea.

Not a bad idea. It would still have to throw an OutOfMemoryError if it really 
couldn't free enough memory, but it would still improve the situation for 
anyone looking to use caches or anything else which could have its memory 
freed and still allow the program to function correctly if the memory 
consumption gets too high.

- Jonathan M Davis


Re: Importing D libraries

2011-08-25 Thread Dainius (GreatEmerald)
Yeap, it's definitely a bug, and the temp file is in fact the library
that I need.

Anyway I'm trying to compile it on Windows now. However, there are two
problems. First of all, the Windows Command Prompt does not expand
wildcards, and DMD does not take it as an argument. Thus importing
LuaD as a source library is quite a hassle, because it has a whole lot
of files, and they don't even fit into one notepad line.

The second issue is that even if I do compile it and get an
executable, it doesn't run correctly. It says that the application
failed to initialise, and the system log says that it failed to
initialise lua51.dll, even though I used it with C just fine. Any
ideas about what could be wrong here?

This is the batch file that I use to compile my executable:
https://github.com/GreatEmerald/Arcomage-GreatEmerald/blob/libarcomage-dev/clarcomage/src/compile.cmd


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Steven Schveighoffer

On Thu, 25 Aug 2011 12:21:19 -0400, Timon Gehr timon.g...@gmx.ch wrote:




I usually replace code like this:

x++;
if(x  100)
{
   // use x
}

with this:

if(++x  100) {
 // use x
}

so the logical mapping to while would map this:

x++;
while(x  100)
{
 // use x.
}

to this:

while(++x  100) {
 // use x.
}


But it looks like every time through the loop x gets incremented.
That's not what I'd want. At the very least, it's confusing
semantics one way or the other.

If you use the construct in the *init* section of a for loop, it reads
the same as the if statement, since that part is only executed once.

The while loop just doesn't fit the model. Let's ditch the while loop.


Not relevant, you are not declaring a variable in your example.  The  
benefit of using the auto x = y is that you can move the declaration of  
the variable, which is used only during the loop, into the loop statement.


I have written loops like this:

bool found = false;
while(!found)
{
  // things that might set found to true
}

There is also this construct, which is what you are arguing for:

bool continueloop;
while(continueloop = someComplexFunction())
{
  // use continueloop as rvalue in places
}

So there are legitimate cases for while(auto x = y) being a shortcut for  
both behaviors, hence the confusion.


I agree your case yields more fruit, since I think the above is actually  
invalid (can't use = as a boolean expression), but it doesn't stop me from  
being confused about whether the initialization happens once or every  
time.  It just reads like it happens once to me, even if it happens every  
loop.  That confusion isn't there for if statements or for loops.


-Steve


Re: Reading by character and by line from stdin

2011-08-25 Thread bellinom
Thanks for that, I didn't realize they were that far out of date. I use the 
latest
version of the compiler on my home PC, so I'd like to know the most current ways
of reading from stdin.

Thanks


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Timon Gehr

On 08/25/2011 10:51 PM, Steven Schveighoffer wrote:
 On Thu, 25 Aug 2011 12:21:19 -0400, Timon Gehr timon.g...@gmx.ch wrote:



 I usually replace code like this:

 x++;
 if(x  100)
 {
 // use x
 }

 with this:

 if(++x  100) {
 // use x
 }

 so the logical mapping to while would map this:

 x++;
 while(x  100)
 {
 // use x.
 }

 to this:

 while(++x  100) {
 // use x.
 }


 But it looks like every time through the loop x gets incremented.
 That's not what I'd want. At the very least, it's confusing
 semantics one way or the other.

 If you use the construct in the *init* section of a for loop, it reads
 the same as the if statement, since that part is only executed once.

 The while loop just doesn't fit the model. Let's ditch the while loop.

 Not relevant, you are not declaring a variable in your example.

It was _the whole point_ that I am not declaring a variable in my 
example. Our two examples are equivalent in what they are saying on a 
conceptual level. Whether the condition contains a declaration or an 
increment operation does not matter.


 The
 benefit of using the auto x = y is that you can move the declaration of
 the variable, which is used only during the loop, into the loop 
statement.


The benefit of using the auto x = y is that you can declare a new 
variable inside the condition, plus useful scoping.



 I have written loops like this:

 bool found = false;
 while(!found)
 {
 // things that might set found to true
 }

for(;;) {
... break; ...
}

or even

for(bool found=false;!found;){
// things that might set found to true
}



 There is also this construct, which is what you are arguing for:

 bool continueloop;
 while(continueloop = someComplexFunction())
 {
 // use continueloop as rvalue in places
 }


I am not arguing for this esoteric case, I wouldn't use a boolean flag, 
but a reference or pointer that is then guaranteed to be non-null inside 
each loop body execution. Pragmatic and consistent with how it would 
normally be used in if.


 So there are legitimate cases for while(auto x = y) being a shortcut for
 both behaviors, hence the confusion.

There is really no legitimate reason for while(auto x = y) being a 
shortcut for the first.



 I agree your case yields more fruit, since I think the above is actually
 invalid (can't use = as a boolean expression), but it doesn't stop me
 from being confused about whether the initialization happens once or
 every time. It just reads like it happens once to me, even if it happens
 every loop. That confusion isn't there for if statements or for loops.


Why does the _loop condition_ read like it happens only once to you? I 
don't get that.



for(init; condition; statement){}
while(condition   ){}

The init part of for is irrelevant for this discussion because it does 
not exist in while. conditions work for both kinds of loops in the same 
way: They are executed and checked before the loop body is run. The body 
of an if is only executed once, therefore the condition is only executed 
and checked once. If there is an inline-declaration or not does not 
matter for the execution semantics, and it *WOULD* be confusing if it was.









Re: Reading by character and by line from stdin

2011-08-25 Thread Trass3r
I'd like to know how to read from stdin one character at a time, read  
with whitespace as a delimiter, and read line by line.


A nifty way of reading by byte is the undocumented (only the writer is  
documented):


import std.stdio;
void main()
{
foreach(c; LockingTextReader(stdin))

}

by line is
foreach(c; stdin.byLine)

and you should also be able to abuse the function to split by whitespace:
http://d-programming-language.org/phobos/std_stdio.html#ByLine
See the terminator parameter.


Re: Reading by character and by line from stdin

2011-08-25 Thread Trass3r

A nifty way of reading by byte is


Of course I mean by character.


Re: Reading by character and by line from stdin

2011-08-25 Thread Jonathan M Davis
On Thursday, August 25, 2011 14:34 bellinom wrote:
 Thanks for that, I didn't realize they were that far out of date. I use the
 latest version of the compiler on my home PC, so I'd like to know the most
 current ways of reading from stdin.

That's probably not something that has changed, but many bugs have been fixed, 
and whole modules have been added or deprecated since 2.042, so it does affect 
a lot of stuff.

As for exactly how to read from stdin, it's not something that I normally do, 
so I'm not particularly well-versed in it, but stdin is a std.stdio.File with 
read-only access, so all of the std.stdio.File operations which read from the 
file should work. readln reads in a single line, and I believe that there's a 
version of it in stdio's module scope, so readln by itself should work rather 
than needing stdin.readln. If you want to read in a particular type, then 
std.stdio.File.rawRead would be what you would use, I believe, and you can 
probably use that to read a single character if you want to, but I don't know. 
There's also readf, which is similar to C's scanf.

All in all, I'd suggest reading the documentation for std.stdio ( http://d-
programming-language.org/phobos/std_stdio.html ) and playing around with it a 
bit, though perhaps someone who is actually familiar with reading from stdin 
could provide better insight. Personally, the closest that I normally get to 
operating on stuff from stdin is by operator on program arguments. Most of my 
programs which operate on I/O, operate on files, and I usually just use 
std.file.readText for that, since it's nice and simple. But that won't work 
for stdin.

- Jonathan M Davis


Re: Reading by character and by line from stdin

2011-08-25 Thread Timon Gehr

On 08/25/2011 11:34 PM, bellinom wrote:
 Thanks for that, I didn't realize they were that far out of date. I 
use the latest
 version of the compiler on my home PC, so I'd like to know the most 
current ways

 of reading from stdin.

 Thanks

Currently what you get is readf and readln with std.conv.to, and if you 
need speed for formatted reads, use the C function scanf.



Some examples:

import std.stdio;

read a single line:

string r=readln();

read array of whitespace-delimited integers on a single line:

auto arr=to!(int[])(strip!(readln()));

read all of stdin by line:

foreach(s; stdin.byLine){
// s is the current line
}

int i;
readf( %s,i); // read i, skipping leading whitespace

with readf, you can always use %s in your format strings.

Don't use readf if you care for performance, because the current 
implementation is very slow.





Re: Reading by character and by line from stdin

2011-08-25 Thread Timon Gehr

On 08/26/2011 12:19 AM, Timon Gehr wrote:

On 08/25/2011 11:34 PM, bellinom wrote:
  Thanks for that, I didn't realize they were that far out of date. I
use the latest
  version of the compiler on my home PC, so I'd like to know the most
current ways
  of reading from stdin.
 
  Thanks

Currently what you get is readf and readln with std.conv.to, and if you
need speed for formatted reads, use the C function scanf.


Some examples:

import std.stdio;

read a single line:

string r=readln();

read array of whitespace-delimited integers on a single line:

auto arr=to!(int[])(strip!(readln()));


whoops, this is better:

auto arr=to!(int[])(split(strip!(readln(;



read all of stdin by line:

foreach(s; stdin.byLine){
// s is the current line
}

int i;
readf( %s,i); // read i, skipping leading whitespace

with readf, you can always use %s in your format strings.

Don't use readf if you care for performance, because the current
implementation is very slow.






Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Steven Schveighoffer

On Thu, 25 Aug 2011 17:31:26 -0400, Timon Gehr timon.g...@gmx.ch wrote:


On 08/25/2011 10:51 PM, Steven Schveighoffer wrote:
  On Thu, 25 Aug 2011 12:21:19 -0400, Timon Gehr timon.g...@gmx.ch  
wrote:

 
 
 
  I usually replace code like this:
 
  x++;
  if(x  100)
  {
  // use x
  }
 
  with this:
 
  if(++x  100) {
  // use x
  }
 
  so the logical mapping to while would map this:
 
  x++;
  while(x  100)
  {
  // use x.
  }
 
  to this:
 
  while(++x  100) {
  // use x.
  }
 
 
  But it looks like every time through the loop x gets incremented.
  That's not what I'd want. At the very least, it's confusing
  semantics one way or the other.
 
  If you use the construct in the *init* section of a for loop, it  
reads

  the same as the if statement, since that part is only executed once.
 
  The while loop just doesn't fit the model. Let's ditch the while  
loop.

 
  Not relevant, you are not declaring a variable in your example.

It was _the whole point_ that I am not declaring a variable in my  
example. Our two examples are equivalent in what they are saying on a  
conceptual level. Whether the condition contains a declaration or an  
increment operation does not matter.


Except the declaration is not currently allowed in a while-loop
conditional expression.  Nor was it allowed in an if conditional
expression, until it was added.  Prior to that addition, it was necessary
to declare the variable outside the if statement in order to only call the
intializer once.



  The
  benefit of using the auto x = y is that you can move the declaration  
of
  the variable, which is used only during the loop, into the loop  
statement.


The benefit of using the auto x = y is that you can declare a new  
variable inside the condition, plus useful scoping.


I think you just said the same thing I did :)



 
  I have written loops like this:
 
  bool found = false;
  while(!found)
  {
  // things that might set found to true
  }

for(;;) {
 ... break; ...
}


This doesn't always work, you may need to delay exiting the loop.


or even

for(bool found=false;!found;){
 // things that might set found to true
}


This also works in your case too.  You can simply declare your variable,
then assign it in the condition.  Insert whatever case you wish there.




 
  There is also this construct, which is what you are arguing for:
 
  bool continueloop;
  while(continueloop = someComplexFunction())
  {
  // use continueloop as rvalue in places
  }
 

I am not arguing for this esoteric case, I wouldn't use a boolean flag,  
but a reference or pointer that is then guaranteed to be non-null inside  
each loop body execution. Pragmatic and consistent with how it would  
normally be used in if.


Well, it was just a contrived example, not a full-fledged program.



  So there are legitimate cases for while(auto x = y) being a shortcut  
for

  both behaviors, hence the confusion.

There is really no legitimate reason for while(auto x = y) being a  
shortcut for the first.


I disagree, especially since it *reads* that way to me.



 
  I agree your case yields more fruit, since I think the above is  
actually

  invalid (can't use = as a boolean expression), but it doesn't stop me
  from being confused about whether the initialization happens once or
  every time. It just reads like it happens once to me, even if it  
happens

  every loop. That confusion isn't there for if statements or for loops.
 

Why does the _loop condition_ read like it happens only once to you? I  
don't get that.


Because it is a declaration.  Declarations do not typically get executed
more than once, unless it is *inside* a loop.

I'm not saying the functionality you want to create is not useful, or that
it would not help in many cases.  I'm not saying it should be either my
way or your way.  I'm saying, it *reads* like it could be both ways, and
therefore is confusing, and not worth adding to the language.  It will
lead to people expecting one case, even though it means the other, no
matter which way you choose it to mean.  We already have several people
split about evenly on what they expect.

-Steve


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Timon Gehr

On 08/26/2011 12:38 AM, Steven Schveighoffer wrote:

On Thu, 25 Aug 2011 17:31:26 -0400, Timon Gehr timon.g...@gmx.ch wrote:


On 08/25/2011 10:51 PM, Steven Schveighoffer wrote:
 On Thu, 25 Aug 2011 12:21:19 -0400, Timon Gehr timon.g...@gmx.ch
wrote:



 I usually replace code like this:

 x++;
 if(x  100)
 {
 // use x
 }

 with this:

 if(++x  100) {
 // use x
 }

 so the logical mapping to while would map this:

 x++;
 while(x  100)
 {
 // use x.
 }

 to this:

 while(++x  100) {
 // use x.
 }


 But it looks like every time through the loop x gets incremented.
 That's not what I'd want. At the very least, it's confusing
 semantics one way or the other.

 If you use the construct in the *init* section of a for loop, it reads
 the same as the if statement, since that part is only executed once.

 The while loop just doesn't fit the model. Let's ditch the while loop.

 Not relevant, you are not declaring a variable in your example.

It was _the whole point_ that I am not declaring a variable in my
example. Our two examples are equivalent in what they are saying on a
conceptual level. Whether the condition contains a declaration or an
increment operation does not matter.


Except the declaration is not currently allowed in a while-loop
conditional expression. Nor was it allowed in an if conditional
expression, until it was added. Prior to that addition, it was necessary
to declare the variable outside the if statement in order to only call the
intializer once.



 The
 benefit of using the auto x = y is that you can move the declaration of
 the variable, which is used only during the loop, into the loop
statement.

The benefit of using the auto x = y is that you can declare a new
variable inside the condition, plus useful scoping.


I think you just said the same thing I did :)


As an analogy, you said: We have loops so that we can hide gotos. I 
said: We have loops so that we can execute code sequences multiple 
times. :)







 I have written loops like this:

 bool found = false;
 while(!found)
 {
 // things that might set found to true
 }

for(;;) {
... break; ...
}


This doesn't always work, you may need to delay exiting the loop.


or even

for(bool found=false;!found;){
// things that might set found to true
}


This also works in your case too. You can simply declare your variable,
then assign it in the condition. Insert whatever case you wish there.



Yes, but then I don't get type inference, which is not very D-like.





 There is also this construct, which is what you are arguing for:

 bool continueloop;
 while(continueloop = someComplexFunction())
 {
 // use continueloop as rvalue in places
 }


I am not arguing for this esoteric case, I wouldn't use a boolean
flag, but a reference or pointer that is then guaranteed to be
non-null inside each loop body execution. Pragmatic and consistent
with how it would normally be used in if.


Well, it was just a contrived example, not a full-fledged program.



 So there are legitimate cases for while(auto x = y) being a shortcut
for
 both behaviors, hence the confusion.

There is really no legitimate reason for while(auto x = y) being a
shortcut for the first.


I disagree, especially since it *reads* that way to me.



I suggest you reconsider.




 I agree your case yields more fruit, since I think the above is
actually
 invalid (can't use = as a boolean expression), but it doesn't stop me
 from being confused about whether the initialization happens once or
 every time. It just reads like it happens once to me, even if it
happens
 every loop. That confusion isn't there for if statements or for loops.


Why does the _loop condition_ read like it happens only once to you? I
don't get that.


Because it is a declaration. Declarations do not typically get executed
more than once, unless it is *inside* a loop.


while(condition) statement;
 ~~~
  ^- inside loop

How can you say the condition is not part of the loop? It is looped too.


I'm not saying the functionality you want to create is not useful, or that
it would not help in many cases. I'm not saying it should be either my
way or your way. I'm saying, it *reads* like it could be both ways, and
therefore is confusing, and not worth adding to the language. It will
lead to people expecting one case, even though it means the other, no
matter which way you choose it to mean. We already have several people
split about evenly on what they expect.

-Steve


Well, I don't get it. If I ever write a D compiler, this feature will be 
supported. =)


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Ali Çehreli
On Thu, 25 Aug 2011 23:31:26 +0200, Timon Gehr wrote:

 for(init; condition; statement){}
 while(condition   ){}

That's a very interesting way of looking at the question.

I bet that explains the other way around: there can't be a variable 
definition in the 'for' loop's condition clause, because 'while' doesn't 
allow it. :p

The compiler probably uses 'while's implementation. The 'for' loop 
probably becomes this:

{
for_init;
while (for_condition) {
for_body;
for_statement;
}
}

So there is no discrepancy: the condition clauses cannot define a 
variable in either loop. :)

If 'while' gets this enhancement, 'for' could be written as the following:

for (int i = 0; auto c = condition(); ++i) {

// Yes, we know that c doesn't evaluate to 'false', but
// we can use c here when it evaluates to 'true'.
// e.g. if it's a pointer:

writeln(*c);
}

Ali


Re: Why no (auto foo = bar) in while loops?

2011-08-25 Thread Timon Gehr

On 08/26/2011 02:00 AM, Ali Çehreli wrote:

On Thu, 25 Aug 2011 23:31:26 +0200, Timon Gehr wrote:


for(init; condition; statement){}
while(condition   ){}


That's a very interesting way of looking at the question.

I bet that explains the other way around: there can't be a variable
definition in the 'for' loop's condition clause, because 'while' doesn't
allow it. :p

The compiler probably uses 'while's implementation. The 'for' loop
probably becomes this:

{
 for_init;
 while (for_condition) {
 for_body;
 for_statement;
 }
}

So there is no discrepancy: the condition clauses cannot define a
variable in either loop. :)


There is a little discrepancy because 'if' condition clauses can. ;)



If 'while' gets this enhancement, 'for' could be written as the following:

for (int i = 0; auto c = condition(); ++i) {

 // Yes, we know that c doesn't evaluate to 'false', but
 // we can use c here when it evaluates to 'true'.
 // e.g. if it's a pointer:

 writeln(*c);
}



Only if it is specifically enabled. The compiler can only rewrite it to 
the while form if it can successfully parse it. But I think that indeed 
iff while is enhanced, for should be too.




Multiple subtyping

2011-08-25 Thread Joel Christensen

Hi,

Has anyone had much experience with multiple subtyping.

//Org: based on page 232 (6.13.1) in The D Programming Language book
//#save(); without storeShape does not work
import std.stdio;

class Shape {
void shape() {
writeln( Shape );
}
}

class DataBase {
void save() {
writeln( I'm the top - save );
}
}

class StoreShape : Shape {
private class MyDataBase : DataBase {
override void save() {
super.save();
writeln( Data base: save );
}
}

private MyDataBase _store;
alias _store this;

this() {
_store = this.new MyDataBase;
}
}

void main() {
auto storeShape = new StoreShape;

with( storeShape ) {
shape();
storeShape.save(); //#save(); without storeShape. does not work
}
}

- Joel



Re: Reading by character and by line from stdin

2011-08-25 Thread Joel Christensen

On 26-Aug-11 10:20 AM, Timon Gehr wrote:

On 08/26/2011 12:19 AM, Timon Gehr wrote:

On 08/25/2011 11:34 PM, bellinom wrote:

whoops, this is better:

auto arr=to!(int[])(split(strip!(readln(;



Or,
auto arr2=to!(int[])( readln.strip.split );

Got rid of the second ! too (does not work with it). I not sure about 
having no () for 3 of the functions though.


- Joel