Re: Multi dimensional array question.

2010-07-16 Thread Heywood Floyd
Lars T. Kyllingstad Wrote:
 
> I do agree that, if possible, the language should match how most people 
> think.  But in this case, it is impossible, because of templates.  How 
> would the following example work with T = int[3], if arrays worked the 
> way you want?
> 
>   struct MyArray(T)
>   {
>   T[] a;
>   }
> 
> C doesn't have this issue, because it doesn't have templates.  And I'll 
> have my templates over C-style array declarations any time, thank you. :)
> 
> -Lars


Well, I suppose the obvious way is to introduce array as a proper type, and not
just as syntactical sugar. For instance, consider:

array[11] int myArr; 

The array "wraps around" a more basic type. It's simply read from left to right.
This should feel "right" for most people. Now it's easy extend this to 
multidimensional arrays. We just allow arrays to wrap arrays:

array[3] array[11] int myArr2d;

This way it's clear what's happening. It's "true" to what's going on at the
compiler level. We have an "outer" array that holds 3 "inner" arrays of 11 
ints. 
And, it's "true" to our high level semantics—when we later access the elements, 
the order is kept intact, as we traverse down the array stack:

myArr2d[outer][inner] = 9;

It's then not too far of a stretch to allow this array-keyword to accept
multidimensional declarations, without reversing the order. Here, it's
still quite clear what's happening: (At least if we have seen the above.)

array[3][11] int myArr2d;
myArr2d[0][10] = 9; //ok

When we introduce templates, this should still work:

struct MyArray(T){
   array[3] T a;
}

// Let's try
T == array[11] int

array[3] T a;
array[3] (array[11] int) a;
array[3] array[11] a;
array[3][11] a;

a[0][10] = 9; //ok

This makes a lot more sense, for me anyway. It's closer to what's actually 
happening,
and it doesn't reverse things at a higher level.

BR
/HF




Anyone know why this CTFE isn't working?

2010-07-16 Thread Rory McGuire




import std.stdio;struct State {	string s; string getString() { return s; }	static State opCall(string s) {		State ret;		ret.s = s;		return ret;	}}void main() {	auto s = State("adf");	pragma(msg, s.getString());}dmd Output: (line 14 is the pragma statement)struct.d(14): Error: variable s cannot be read at compile timestruct.d(14): Error: cannot evaluate s.getString() at compile times.getString()

Rory McGuire
R&D
Tel : +27 (033) 386 7263

Cell : +27 (082) 856 3646
Email: rmcgu...@neonova.co.za
Website: www.neonova.co.za
VCard: View


  This email and its attachments may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of NeoNova. If you are not the intended recipient of this email and its attachments, you must take no action based upon them, nor must you copy or show them to anyone. Please contact the sender if you believe you have received this email in error.



Re: Anyone know why this CTFE isn't working?

2010-07-16 Thread Lars T. Kyllingstad
On Fri, 16 Jul 2010 11:46:48 +0200, Rory McGuire wrote:

> import std.stdio;
> 
> struct State {
>   string s; string getString() { return s; } static State opCall(string
>   s) {
>   State ret;
>   ret.s = s;
>   return ret;
>   }
> }
> 
> void main() {
>   auto s = State("adf");
>   pragma(msg, s.getString());
> }
> 
> dmd Output: (line 14 is the pragma statement)
> 
> struct.d(14): Error: variable s cannot be read at compile time
> struct.d(14): Error: cannot evaluate s.getString() at compile time
> s.getString()

It's not working because s isn't a compile-time quantity.  Try:

  enum s = State("adf");

-Lars


Re: Anyone know why this CTFE isn't working?

2010-07-16 Thread Rory McGuire

Sorry about the html

On Fri, 16 Jul 2010 11:46:48 +0200, Rory McGuire   
wrote:


import std.stdio;

struct State {
string s; string getString() { return s; }
static State opCall(string s) {
State ret;
ret.s = s;
return ret;
}
}

void main() {
auto s = State("adf");
pragma(msg, s.getString());
}

dmd Output: (line 14 is the pragma statement)

struct.d(14): Error: variable s cannot be read at compile time
struct.d(14): Error: cannot evaluate s.getString() at compile time
s.getString()


Re: Anyone know why this CTFE isn't working?

2010-07-16 Thread Jonathan M Davis
On Friday 16 July 2010 02:46:48 Rory McGuire wrote:
> import std.stdio;
> 
> struct State {
>   string s; string getString() { return s; }
>   static State opCall(string s) {
>   State ret;
>   ret.s = s;
>   return ret;
>   }
> }
> 
> void main() {
>   auto s = State("adf");
>   pragma(msg, s.getString());
> }

Make s an enum and it'll work. As it is, it's a local variable created at 
runtime rather than a constant at compile-time. So, use

enum s = State("adf");


- Jonathan M Davis


Re: Anyone know why this CTFE isn't working?

2010-07-16 Thread Rory McGuire
On Fri, 16 Jul 2010 11:58:57 +0200, Lars T. Kyllingstad  
 wrote:



On Fri, 16 Jul 2010 11:46:48 +0200, Rory McGuire wrote:


import std.stdio;

struct State {
  string s; string getString() { return s; } static State opCall(string
  s) {
  State ret;
  ret.s = s;
  return ret;
  }
}

void main() {
  auto s = State("adf");
  pragma(msg, s.getString());
}

dmd Output: (line 14 is the pragma statement)

struct.d(14): Error: variable s cannot be read at compile time
struct.d(14): Error: cannot evaluate s.getString() at compile time
s.getString()


It's not working because s isn't a compile-time quantity.  Try:

  enum s = State("adf");

-Lars


Awesome thanks, worked.

So is the difference that "auto s" is a Struct which can change whereas  
"enum s" is a constant?

If it is a constant its just "s" that is constant right?

Thanks Lars


-Rory


Re: Anyone know why this CTFE isn't working?

2010-07-16 Thread Rory McGuire
On Fri, 16 Jul 2010 12:05:02 +0200, Jonathan M Davis  
 wrote:



On Friday 16 July 2010 02:46:48 Rory McGuire wrote:

import std.stdio;

struct State {
  string s; string getString() { return s; }
  static State opCall(string s) {
  State ret;
  ret.s = s;
  return ret;
  }
}

void main() {
  auto s = State("adf");
  pragma(msg, s.getString());
}


Make s an enum and it'll work. As it is, it's a local variable created at
runtime rather than a constant at compile-time. So, use

enum s = State("adf");


- Jonathan M Davis


Thanks

worked


Re: Anyone know why this CTFE isn't working?

2010-07-16 Thread Lars T. Kyllingstad
On Fri, 16 Jul 2010 12:12:38 +0200, Rory McGuire wrote:

> On Fri, 16 Jul 2010 11:58:57 +0200, Lars T. Kyllingstad
>  wrote:
> 
>> On Fri, 16 Jul 2010 11:46:48 +0200, Rory McGuire wrote:
>>
>>> import std.stdio;
>>>
>>> struct State {
>>>   string s; string getString() { return s; } static State
>>>   opCall(string s) {
>>>   State ret;
>>>   ret.s = s;
>>>   return ret;
>>>   }
>>> }
>>>
>>> void main() {
>>>   auto s = State("adf");
>>>   pragma(msg, s.getString());
>>> }
>>>
>>> dmd Output: (line 14 is the pragma statement)
>>>
>>> struct.d(14): Error: variable s cannot be read at compile time
>>> struct.d(14): Error: cannot evaluate s.getString() at compile time
>>> s.getString()
>>
>> It's not working because s isn't a compile-time quantity.  Try:
>>
>>   enum s = State("adf");
>>
>> -Lars
> 
> Awesome thanks, worked.
> 
> So is the difference that "auto s" is a Struct which can change whereas
> "enum s" is a constant?
> If it is a constant its just "s" that is constant right?
> 
> Thanks Lars

Yes.  Writing "auto s = State("adf");" is equivalent to writing

  State s = State("adf");

and since s can change at runtime, it would be meaningless to say that it 
has a value at compile time.  However, its *initial value*, the struct 
literal State("adf"), is known at compile time -- otherwise it would be 
impossible to assign it to an enum.

And actually, an enum is not only a constant, it is a manifest constant.  
When you declare "enum x = someFixedValue", the compiler will just 
replace all later uses of x with someFixedValue.  It's basically the same 
as using the literal value in those places.

This has the consequence that you can't take the address of an enum, nor 
pass an enum by reference.  Doing

  enum i = 3;
  int* p = &i;

is equivalent to

  int* p = &3;

which doesn't make sense.

-Lars


Re: CT usage only in executable

2010-07-16 Thread Daniel Murphy
"strtr"  wrote in message news:i1lro6$307...@digitalmars.com...
> == Quote from bearophile (bearophileh...@lycos.com)'s article
>> strtr:
>> > Not that the memory is really significant compared to the rest of my 
>> > program,
>> > but I have a few fairly large arrays I use only in compile time and I 
>> > was
>> > wondering why dmd still includes those in the executable (simple text 
>> > search
>> > dug them up).
>> Are you able to create a smallish test case?
>> Bye,
>> bearophile
>
> 
> module main;
>
> const char[] CT_STRING = "int i=0;";
>
> void main(){
> mixin( CT_STRING );
> }
> 
> The string can be found in the executable.
>

I think if you use enum instead of const/immutable the compiler is not meant 
to put them in the executable (it might anyway in some/all cases).

eg.
module main;

enum CT_STRING = "int i=0;";

void main(){
mixin( CT_STRING );
} 




Re: Multi dimensional array question.

2010-07-16 Thread Tim Verweij
On 16 July 2010 11:12, Heywood Floyd  wrote:

> Lars T. Kyllingstad Wrote:
> (...)
>
> When we introduce templates, this should still work:
>
> struct MyArray(T){
>   array[3] T a;
> }
>
> // Let's try
> T == array[11] int
>
> array[3] T a;
> array[3] (array[11] int) a;
> array[3] array[11] a;
> array[3][11] a;
>
> a[0][10] = 9; //ok
>

The 'int' goes missing there. I guess you meant to write:

array[3] T a;
array[3] (array[11] int) a;
array[3] array[11] int a;
array[3][11] int a;

Right? Pretty nice. I must say that I quite like this. It does feel 'right'.

Groet,
Tim


Re: Multi dimensional array question.

2010-07-16 Thread Mafi

Am 16.07.2010 11:12, schrieb Heywood Floyd:

Lars T. Kyllingstad Wrote:


I do agree that, if possible, the language should match how most people
think.  But in this case, it is impossible, because of templates.  How
would the following example work with T = int[3], if arrays worked the
way you want?

   struct MyArray(T)
   {
   T[] a;
   }

C doesn't have this issue, because it doesn't have templates.  And I'll
have my templates over C-style array declarations any time, thank you. :)

-Lars



Well, I suppose the obvious way is to introduce array as a proper type, and not
just as syntactical sugar. For instance, consider:

array[11] int myArr;

...

I don't really like it. Of course the order of indices feels better but 
it breaks the rule of reading types from right to left. It also 
introduces more parenthesis and a new keyword into types (amongst const, 
immutable and delegate etc). Consider:

  shared array[3](const( array[5] immuttable((SList!(int)*)[]) ))
WTF, that doesn't look good. I would be a real type if your answer was 
accepted.


It was
  shared const( immutable(Slist!(int)*[])[5] )[3]
which reads perfectly from right to left.

What about this:
  // int[width,height] as sugar for int[height][width]
  int[width,height] arr = ...;
  // arr[x,y] as sugar for arr[x][y]
  int element = arr[x,y];
  // then this works as expected
  int[height] column = arr[x];


Re: Multi dimensional array question.

2010-07-16 Thread Tim Verweij
On 16 July 2010 20:11, Mafi  wrote:

> Am 16.07.2010 11:12, schrieb Heywood Floyd:
>
>  Lars T. Kyllingstad Wrote:
>>
>>  I do agree that, if possible, the language should match how most people
>>> think.  But in this case, it is impossible, because of templates.  How
>>> would the following example work with T = int[3], if arrays worked the
>>> way you want?
>>>
>>>   struct MyArray(T)
>>>   {
>>>   T[] a;
>>>   }
>>>
>>> C doesn't have this issue, because it doesn't have templates.  And I'll
>>> have my templates over C-style array declarations any time, thank you. :)
>>>
>>> -Lars
>>>
>>
>>
>> Well, I suppose the obvious way is to introduce array as a proper type,
>> and not
>> just as syntactical sugar. For instance, consider:
>>
>> array[11] int myArr;
>>
> ...
>
> I don't really like it. Of course the order of indices feels better but it
> breaks the rule of reading types from right to left. It also introduces more
> parenthesis and a new keyword into types (amongst const, immutable and
> delegate etc). Consider:
>  shared array[3](const( array[5] immuttable((SList!(int)*)[]) ))
> WTF, that doesn't look good. I would be a real type if your answer was
> accepted.
>
> It was
>  shared const( immutable(Slist!(int)*[])[5] )[3]
> which reads perfectly from right to left.
>
>
So why all the extra parenthesis? Do you think they are required? Instead
of:
shared array[3](const( array[5] immutable((SList!(int)*)[]) ))
consider this:
shared array[3] const array[5] immutable array (SList!(int)*)
(or array[] instead of just array)

Actually, tbh I think they all look horrible. :-P I hope I never encounter
such an impractical beast.


> What about this:
>  // int[width,height] as sugar for int[height][width]
>  int[width,height] arr = ...;
>  // arr[x,y] as sugar for arr[x][y]
>  int element = arr[x,y];
>  // then this works as expected
>  int[height] column = arr[x];
>

That doesn't look too bad.

Groet,
Tim


multiple subtype vs. multiple inheritance

2010-07-16 Thread Neal Becker
What's the difference between the (forbidden) multiple inheritance, and 
multiple subtyping?

BTW, IMO the syntax of multiple subtyping is strange and ugly.


Re: CT usage only in executable

2010-07-16 Thread strtr
== Quote from Daniel Murphy (yebbl...@nospamgmail.com)'s article
> I think if you use enum instead of const/immutable the compiler is not meant
> to put them in the executable (it might anyway in some/all cases).
> eg.
> module main;
> enum CT_STRING = "int i=0;";
> void main(){
> mixin( CT_STRING );
> }

I'm using D1.

Should I report this as a bug?


Re: Multi dimensional array question.

2010-07-16 Thread Heywood Floyd
Mafi Wrote:

> 
> I don't really like it. Of course the order of indices feels better but 
> it breaks the rule of reading types from right to left. It also 
> introduces more parenthesis and a new keyword into types (amongst const, 
> immutable and delegate etc). Consider:
>shared array[3](const( array[5] immuttable((SList!(int)*)[]) ))
> WTF, that doesn't look good. I would be a real type if your answer was 
> accepted.
> 
> It was
>shared const( immutable(Slist!(int)*[])[5] )[3]
> which reads perfectly from right to left.
> 
> What about this:
>// int[width,height] as sugar for int[height][width]
>int[width,height] arr = ...;
>// arr[x,y] as sugar for arr[x][y]
>int element = arr[x,y];
>// then this works as expected
>int[height] column = arr[x];




Interesting!

First of all, I definitely think that how arrays are declared now would have to 
stay just the way it is, no matter what. I don't think stuff like that is 
changeable this late in a language. But, seems to me these two methods of 
declaring arrays could coexist. One is the shorter syntactical "sugar" method, 
the other is the elaborate, but perhaps clearer method. These kinds of long 
way/shortcuts are already in the language, I believe. Like how void()() is 
automatically a template, comes to mind. (Or did that make sense?)

Then, I simply can't resist commenting this exceptional beauty. I'm gonna call 
it theThing:

   shared const( immutable(Slist!(int)*[])[5] )[3] theThing;

Well. I have to confess, to me, it doesn't read perfectly from right to left. I 
might be reading it wrong, but to me it reads from right to left, and from left 
to right, at the same time. Is it a shared const array of something, or a 
shared array of const something? You can't really tell unless you go back and 
forth, and almost count the parenthesis. For instance, by looking at the 
declaration above, what type is a

   theThing[0][1] ::= ??

It's really not easy to say, for me anyway. I'm sure you get better at reading 
these things. So it might not be fair to say that it's "unclear". It's just my 
subjective opinion, and that may be biased by my lack of experience in the 
matter. Now back to the other thing:

   shared array[3] const array[5] immutable array[] (SList!(int)*)

Sure, this is too verbose. I agree. Still, I think it's clearer. Much clearer. 
Verbose, but clear.

Here I couldn't help but making an interesting obvservation: Those storage 
classes could also be seen as types. What if we allowed the storage classes to 
have some syntactical sugar too, for arrays? We could have:

   shared[3] const[5] immutable[] SList!(int)* theThing;

That does read from left to right in one go, and to me, it's still clear what's 
going on, and, it's not verbose. In fact, it's less verbose than the 
parenthesis-sprinkled version we saw first. Further, it's almost magically easy 
to read: We have a shared array of 3 const arrays of 5 immutable dynamic arrays 
of Slist!(int)*. It just reads, like you read text, quite naturally. (I'm not 
sure this would actually be the same type as the first declaration, erh, but 
yes. You get my intention.)

So again, what type is a 

   theThing[0][1] ::= ??

Well, if we look at the declaration above it's quite easy: We just cut the line 
after the second array, const[5], and the rest of the line, that's our type.

   theThing[0][1] ::= immutable[] SList!(int)*

Now, to me, that's just plain beautiful.

***

And last, the

   int[x,y] arr;

I like it. Simple. Nice. 
Maybe it becomes weird when we have mixed array types, like int[uint,,5] arr? 
Well at least the illusion of an intact order is maintained.

BR
/HF




Re: Multi dimensional array question.

2010-07-16 Thread bearophile
Heywood Floyd:
> First of all, I definitely think that how arrays are declared now would have 
> to stay just the way it is,
> no matter what. I don't think stuff like that is changeable this late in a 
> language.

Recently I have suggested to remove the syntax:
new int[20];
And allow only:
new int[](20);


>shared array[3] const array[5] immutable array[] (SList!(int)*)
> 
> Sure, this is too verbose. I agree. Still, I think it's clearer. Much 
> clearer. Verbose, but clear.

I don't know how you can write that in a Go-language-like syntax, maybe it's a 
bit worse.


> And last, the
>int[x,y] arr;
> 
> I like it. Simple. Nice. 

It's nice, but unfortunately the comma syntax is present in C too, where:
int[10] arr;
int element = arr[x, y];
Equals to:
int[10] arr;
int element = arr[y];
So in D the usage of comma inside [] was recently forbidden. Keeping some kind 
of backward compatibility with C is something a kind of damnation (see also 
switch syntax, tuple syntax, etc).

Bye,
bearophile


Re: CT usage only in executable

2010-07-16 Thread Daniel Murphy

"strtr"  wrote in message news:i1ql53$306...@digitalmars.com...
> == Quote from Daniel Murphy (yebbl...@nospamgmail.com)'s article
>> I think if you use enum instead of const/immutable the compiler is not 
>> meant
>> to put them in the executable (it might anyway in some/all cases).
>> eg.
>> module main;
>> enum CT_STRING = "int i=0;";
>> void main(){
>> mixin( CT_STRING );
>> }
>
> I'm using D1.
>
> Should I report this as a bug?


Sorry, I don't have D1 installed.  Can you use enum to declare manifest 
constants in D1 or is it a D2 thing?

If the string is left in the executable from

const char[] CT_STRING = "blah blah";
void main () {}

then I think this is a bug/enhancement for the linker. 




Re: CT usage only in executable

2010-07-16 Thread Simen kjaeraas

Daniel Murphy  wrote:


Sorry, I don't have D1 installed.  Can you use enum to declare manifest
constants in D1 or is it a D2 thing?


It's a D2 thing. I believe the D1 way to do it is with static const.


If the string is left in the executable from

const char[] CT_STRING = "blah blah";
void main () {}

then I think this is a bug/enhancement for the linker.


Enhancement, I'd say. And yes, DMD does that. It's the reason for
the enum manifest constants in D2.

--
Simen