www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Embedded Containers

reply A Guy With a Question <aguywithanquestion gmail.com> writes:
The following doesn't appear to be valid syntax. Array!Item!T

I get the following error:

"multiple ! arguments are not allowed"	

Which is ok...I get THAT error, however, this does not work 
either:

alias Items(T) = Array!Item(T);

This gives me the error:

Error: function declaration without return type. (Note that 
constructors are always named `this`)	

Item is defined as follows:

interface Item(T)
{
     property
    T member();
}

That part compiles fine. However, even when I remove the 
aliasing, I can't import this interface. I get "Error: undefined 
identifier 'Item'"

I'm not quite sure I understand how to create a generic container 
interface or class in D. Half of how I expect it to work works, 
but the other half doesn't. The docs aren't too helpful. I'm not 
sure if it's a case where there's just too much to go through or 
if what I'm trying to do isn't really covered. Essentially I'm 
trying to create an array of this type 'Item' that has some 
generic members. I think people who come from C# will kind of get 
what I'm trying to do here, because I'm trying to port C# code.
Dec 05 2017
next sibling parent A Guy With a Question <aguywithanquestion gmail.com> writes:
Ah crud, I posted this to the wrong forum. Sorry.
Dec 05 2017
prev sibling next sibling parent John Chapman <johnch_atms hotmail.com> writes:
On Tuesday, 5 December 2017 at 19:01:48 UTC, A Guy With a 
Question wrote:
 The following doesn't appear to be valid syntax. Array!Item!T

 I get the following error:

 "multiple ! arguments are not allowed"	

 Which is ok...I get THAT error, however, this does not work 
 either:

 alias Items(T) = Array!Item(T);

 This gives me the error:

 Error: function declaration without return type. (Note that 
 constructors are always named `this`)	
Your wrapping the wrong part in parentheses. Array!(Item!T) It would actually be Array!(Item!(T)), but if a single type is specified you're allowed to omit the parentheses when instantiating.
 Item is defined as follows:

 interface Item(T)
 {
     property
    T member();
 }

 That part compiles fine. However, even when I remove the 
 aliasing, I can't import this interface. I get "Error: 
 undefined identifier 'Item'"

 I'm not quite sure I understand how to create a generic 
 container interface or class in D. Half of how I expect it to 
 work works, but the other half doesn't. The docs aren't too 
 helpful. I'm not sure if it's a case where there's just too 
 much to go through or if what I'm trying to do isn't really 
 covered. Essentially I'm trying to create an array of this type 
 'Item' that has some generic members. I think people who come 
 from C# will kind of get what I'm trying to do here, because 
 I'm trying to port C# code.
What other problems are you having? I did the same and it was fairly straightforward.
Dec 05 2017
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 5 December 2017 at 19:01:48 UTC, A Guy With a 
Question wrote:
 alias Items(T) = Array!Item(T);
try: Array!(Item!(T))
 I'm not quite sure I understand how to create a generic 
 container interface or class in D.
Just using the parenthesis should help. The thing with A!B!C is that the reader can easily be confused: did you mean A!(B!C) or (A!B)!C or what? Now the compiler is a bit stupider about this than it should be IMO - it should be able to figure it out and the meaning be fairly clear with association - but it isn't, so you can and must write parens to clarify most the time.
Dec 05 2017
next sibling parent reply A Guy With a Question <aguywithanquestion gmail.com> writes:
On Tuesday, 5 December 2017 at 19:09:50 UTC, Adam D. Ruppe wrote:
 On Tuesday, 5 December 2017 at 19:01:48 UTC, A Guy With a 
 Question wrote:
 alias Items(T) = Array!Item(T);
try: Array!(Item!(T))
 I'm not quite sure I understand how to create a generic 
 container interface or class in D.
Just using the parenthesis should help. The thing with A!B!C is that the reader can easily be confused: did you mean A!(B!C) or (A!B)!C or what? Now the compiler is a bit stupider about this than it should be IMO - it should be able to figure it out and the meaning be fairly clear with association - but it isn't, so you can and must write parens to clarify most the time.
Ok, so that worked. I still have the problem with importing though: mypackage: Item seems to generate the error: "Error: undefined identifier 'Item'" Which is weird, because I'm able to bring in Array through std.container.array: Array;
Dec 05 2017
next sibling parent reply colin <grogan.colin gmail.com> writes:
On Tuesday, 5 December 2017 at 19:13:10 UTC, A Guy With a 
Question wrote:
 On Tuesday, 5 December 2017 at 19:09:50 UTC, Adam D. Ruppe 
 wrote:
 [...]
Ok, so that worked. I still have the problem with importing though: mypackage: Item seems to generate the error: "Error: undefined identifier 'Item'" Which is weird, because I'm able to bring in Array through std.container.array: Array;
Is Item public in your package?
Dec 05 2017
parent A Guy With a Question <aguywithanquestion gmail.com> writes:
On Tuesday, 5 December 2017 at 19:19:50 UTC, colin wrote:
 On Tuesday, 5 December 2017 at 19:13:10 UTC, A Guy With a 
 Question wrote:
 On Tuesday, 5 December 2017 at 19:09:50 UTC, Adam D. Ruppe 
 wrote:
 [...]
Ok, so that worked. I still have the problem with importing though: mypackage: Item seems to generate the error: "Error: undefined identifier 'Item'" Which is weird, because I'm able to bring in Array through std.container.array: Array;
Is Item public in your package?
Yes. I fixed it by not referencing it by the package but by the file specific module I created. That worked. All errors are resolved now. Thanks! I think maybe the import issue was because there was a circular import happening. So I have a few sub modules: module item.d other.d package.d where other.d uses Item from item.d. But I was pulling item from package. When I pulled it directly from item.d it compiled fine. So maybe it can't handle the circular referencing there.
Dec 05 2017
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 5 December 2017 at 19:13:10 UTC, A Guy With a 
Question wrote:
 
 Ok, so that worked. I still have the problem with importing 
 though:

 mypackage: Item

 seems to generate the error:

 "Error: undefined identifier 'Item'"

 Which is weird, because I'm able to bring in Array through 
 std.container.array: Array;
mypackage.mymodule : Item;
Dec 05 2017
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Tue, Dec 05, 2017 at 07:09:50PM +0000, Adam D. Ruppe via Digitalmars-d wrote:
 On Tuesday, 5 December 2017 at 19:01:48 UTC, A Guy With a Question wrote:
 alias Items(T) = Array!Item(T);
try: Array!(Item!(T))
 I'm not quite sure I understand how to create a generic container
 interface or class in D.
Just using the parenthesis should help. The thing with A!B!C is that the reader can easily be confused: did you mean A!(B!C) or (A!B)!C or what? Now the compiler is a bit stupider about this than it should be IMO - it should be able to figure it out and the meaning be fairly clear with association - but it isn't, so you can and must write parens to clarify most the time.
Here's an idea for a DIP: make '!' right-to-left associative (i.e., similar to the ^^ exponentiation operator), so that A!B!C is understood as A!(B!C). Rationale: the most common use cases are of the A!(B!C) variety; it's pretty rare IME to need the (A!B)!C form, since usually a template expands to a type, which can then be passed to another template, i.e., A!(B!C). The (A!B)!C form is when the template instantiated with B produces another template that takes another type argument. There aren't many use cases for this that I can think of. Though the point is probably moot, because in the current grammar you'd need parentheses as soon as the template argument is anything more than a single token, i.e., you can write A!int but you have to write A!(const(int)). And in the cases where you actually want something of the form A!(B!C), usually the arguments are themselves pretty complicated, so wouldn't benefit from top-level associativity anyway. T -- Doubt is a self-fulfilling prophecy.
Dec 05 2017
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 05.12.2017 20:11, H. S. Teoh wrote:
 On Tue, Dec 05, 2017 at 07:09:50PM +0000, Adam D. Ruppe via Digitalmars-d
wrote:
 On Tuesday, 5 December 2017 at 19:01:48 UTC, A Guy With a Question wrote:
 alias Items(T) = Array!Item(T);
try: Array!(Item!(T))
 I'm not quite sure I understand how to create a generic container
 interface or class in D.
Just using the parenthesis should help. The thing with A!B!C is that the reader can easily be confused: did you mean A!(B!C) or (A!B)!C or what? Now the compiler is a bit stupider about this than it should be IMO - it should be able to figure it out and the meaning be fairly clear with association - but it isn't, so you can and must write parens to clarify most the time.
Here's an idea for a DIP: make '!' right-to-left associative (i.e., similar to the ^^ exponentiation operator), so that A!B!C is understood as A!(B!C). Rationale: the most common use cases are of the A!(B!C) variety; it's pretty rare IME to need the (A!B)!C form, since usually a template expands to a type, which can then be passed to another template, i.e., A!(B!C). The (A!B)!C form is when the template instantiated with B produces another template that takes another type argument. There aren't many use cases for this that I can think of. ...
Curried templates are actually common enough in Phobos. (map, filter, etc.)
 Though the point is probably moot, because in the current grammar you'd
 need parentheses as soon as the template argument is anything more than
 a single token, i.e., you can write A!int but you have to write
 A!(const(int)).  And in the cases where you actually want something of
 the form A!(B!C), usually the arguments are themselves pretty
 complicated, so wouldn't benefit from top-level associativity anyway.
 
 
 T
 
IMHO the inconsistency with function call syntax ought to kill this proposal. Also, it is a bit more confusing than it is useful. Related: It's quite annoying that (A!B)!C does not work because the parser thinks it's a C-style cast and errors out even though C-style casts are not even valid D syntax.
Dec 05 2017
parent reply A Guy With a Question <aguywithanquestion gmail.com> writes:
On Tuesday, 5 December 2017 at 20:38:01 UTC, Timon Gehr wrote:
 On 05.12.2017 20:11, H. S. Teoh wrote:
 On Tue, Dec 05, 2017 at 07:09:50PM +0000, Adam D. Ruppe via 
 Digitalmars-d wrote:
 On Tuesday, 5 December 2017 at 19:01:48 UTC, A Guy With a 
 Question wrote:
 alias Items(T) = Array!Item(T);
try: Array!(Item!(T))
 I'm not quite sure I understand how to create a generic 
 container
 interface or class in D.
Just using the parenthesis should help. The thing with A!B!C is that the reader can easily be confused: did you mean A!(B!C) or (A!B)!C or what? Now the compiler is a bit stupider about this than it should be IMO - it should be able to figure it out and the meaning be fairly clear with association - but it isn't, so you can and must write parens to clarify most the time.
Here's an idea for a DIP: make '!' right-to-left associative (i.e., similar to the ^^ exponentiation operator), so that A!B!C is understood as A!(B!C). Rationale: the most common use cases are of the A!(B!C) variety; it's pretty rare IME to need the (A!B)!C form, since usually a template expands to a type, which can then be passed to another template, i.e., A!(B!C). The (A!B)!C form is when the template instantiated with B produces another template that takes another type argument. There aren't many use cases for this that I can think of. ...
Curried templates are actually common enough in Phobos. (map, filter, etc.)
 Though the point is probably moot, because in the current 
 grammar you'd
 need parentheses as soon as the template argument is anything 
 more than
 a single token, i.e., you can write A!int but you have to write
 A!(const(int)).  And in the cases where you actually want 
 something of
 the form A!(B!C), usually the arguments are themselves pretty
 complicated, so wouldn't benefit from top-level associativity 
 anyway.
 
 
 T
 
IMHO the inconsistency with function call syntax ought to kill this proposal. Also, it is a bit more confusing than it is useful. Related: It's quite annoying that (A!B)!C does not work because the parser thinks it's a C-style cast and errors out even though C-style casts are not even valid D syntax.
Is there actually a difference between the c style cast and cast(type)? Other than verbosity...
Dec 05 2017
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, December 05, 2017 22:09:12 A Guy With a Question via 
Digitalmars-d wrote:
 Is there actually a difference between the c style cast and
 cast(type)? Other than verbosity...
They're not the same. D's cast is not split up like C++'s casts are, but it's not exactly the same as C's cast either - e.g. like C++'s dynamic_cast, if a class to class conversion fails, you get null, which C's cast doesn't do. Also, I think that D's cast is pickier about what it will let you do, whereas C's cast is more likely to want to smash something into something else if you ask it even if it doesn't make sense. And of course, D's cast understands D stuff that doesn't even exist in C (like delegates). I don't know exactly what all of the differences are though. Regardless, the reason for the verbosity is so that you can easily grep for casts in your code. - Jonathan M Davis
Dec 05 2017
parent A Guy With a Question <aguywithanquestion gmail.com> writes:
On Tuesday, 5 December 2017 at 22:21:51 UTC, Jonathan M Davis 
wrote:
 On Tuesday, December 05, 2017 22:09:12 A Guy With a Question 
 via Digitalmars-d wrote:
 Is there actually a difference between the c style cast and
 cast(type)? Other than verbosity...
They're not the same. D's cast is not split up like C++'s casts are, but it's not exactly the same as C's cast either - e.g. like C++'s dynamic_cast, if a class to class conversion fails, you get null, which C's cast doesn't do. Also, I think that D's cast is pickier about what it will let you do, whereas C's cast is more likely to want to smash something into something else if you ask it even if it doesn't make sense. And of course, D's cast understands D stuff that doesn't even exist in C (like delegates). I don't know exactly what all of the differences are though. Regardless, the reason for the verbosity is so that you can easily grep for casts in your code. - Jonathan M Davis
That's the best reason for verbosity I've heard.
Dec 05 2017