Re: Creating an array of unique elements
Guilherme Vieira wrote: dynamic array object which will only accept unique elements What are your requirements so that you call this data structure array? -manfred
Re: Creating an array of unique elements
On 27.12.2010 10:22, Guilherme Vieira wrote: Hi, guys. — said the shy newcomer. I've started reading The D Programming Language just yesterday and I'm making my first attempts to dig into D now. I must say I'm loving the language beyond recognition. I never thought there was a language out there that had everything I ever wanted in C++ (I even considered developing my own language before knowing D!). Right now I'm wondering how's the best way to create a dynamic array object which will only accept unique elements (i.e., elements != from the existing elements in the array). I wanted a class that kept all the functionality of an array (e.g. being the right range types so that they can be passed to std.format.formatValue and trigger the right specialization) for maximum integration with the standard library. I thought about writing a class template privately containing an array and redirecting everything but the assignment/insertion operations to it. All ways of placing an object that was already there should throw an exception, but everything else should work the same. Doing it this way is a lot of work for a simple thing, so some sort of internal alert in me tell me I might just be doing-it-wrong. I want to know what your ideas are. I want some way to achieve this sort of thing: import myproject.helpers.UniqueArray; void main() { auto a0 = [1, 2, 3]; // I'm not yet sure how to go about the constructor, since: auto a1 = UniqueArray!(int)(a0[1 .. $]); // error: should not be able to internally hold reference to I suspect the best would be to copy whatever got passed to constructor, since to provide such contracts UniqueArray needs to own data. Also you could use fancy homogeneous variadic function for ctor: this(T[] args...){ _payload = args.dup;//assume member _payload holds internal array } Then auto a = UniqueArray!(int)(1,2,3,4);//fills array with elements [1,2,3,4] auto a = UniqueArray!(int)([5,6,7]); //works with the same signature // a raw array since this could be used to break the unique // elements contract promise of UniqueArray // copy of elements can be considered, but I'd rather // have clients copy the array themselves so that they // know it is happening auto a2 = UniqueArray!(int)(a0[1 .. $].dup); // should be fine if D had some sort of non-const // rvalue reference support, but I think it does not; // am I wrong? auto a3 = UniqueArray!(int)(a0[1 .. $].idup); // semantically pleasing at first sight, but // suboptimal: the constructor would have to copy // the passed array again to get rid of immutability auto a4 = bestOptionOutOf(a1, a2, a3); // (: a4[1 .. $] = [3, 4, 5]; // ok: would first construct a UniqueArray out of the rvalue (thus ensuring // uniqueness of elements) and then would work like a usual slice // assignment a4 ~= 5; // throws exception: 5 is already in the array! a4 ~= 6; // ok: 6 is not there writeln(a4); // ok, output: [2, 3, 4, 5, 6] // could just implement UniqueArray.toString() for this to work, but making UniqueArray // properly model the ranges an array models solves this problem and others at the same // time auto a5 = a4.dup; // all properties of an array, such as dup here, should hold and overall // the object should behave as one would expect from an array int[] a6 = a5; // error: obviously shouldn't work since a6 could then be used to break the // UniqueArray contract } What do you think? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira -- Dmitry Olshansky
Re: Creating an array of unique elements
On Mon, 27 Dec 2010 05:22:14 -0200 Guilherme Vieira n2.nitro...@gmail.com wrote: Right now I'm wondering how's the best way to create a dynamic array object which will only accept unique elements (i.e., elements != from the existing elements in the array). (Take my words with precaution because I don not know D very well myself.) Hello Guilherme. If I understand your purpose correctly, what you're trying to define is a set, not an array, in the common sense of the terms in programming. To ensure uniqueness, you'd need to check whether the element exits already, which can only be very slow using an array (O(n)): you need to traverse the array element per element. Sets instead are build using data structures that allow this check to be far faster, by looking up a given element in a more clever way. There is no builtin Set type in D yet. The simplest way (and maybe the best) would be use associative arrays where keys would be actual elements and values just fake. (e in set) would tell you what you need. Depending on your requirements, trying to put an existing element would just put it again with no change, or should throw an error. In the latter case, you need to check it yourself or build a wrapper type (struct or class) around builtin associative arrays. For instance: Existence[Element] set; Element[] elements = ['a','c','e']; Element[] values = ['a','b','c','d','e']; foreach (element ; elements) set[element] = EXISTS; // Note: 'in' actually return a pointer to element. foreach (value ; values) writeln(cast(bool)(value in set)); Note: I have a Set type in stock at https://bitbucket.org/denispir/denispir-d/src/b543fb352803/collections.d, but wonder whether it's really necessary given the above. But you can have a look to see how it's done (this would give you some hints about language methods called 'opSomething', see TDPL's index). Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Nested Structs
Greetings All I have a situation where I have a struct nested inside a class. I would like to make the enclosing class' members visible inside the nested struct's constructor. I see that such preposition is feasible for nested classes, but not for nested structs. Why so? Are there some alternative constructs which could give me this behavior for nested constructs? Regards - Cherry
Re: declaration with typedef
That's because you're creating a new type with typedef, and writeln() doesn't know how to work with a number type. Use an alias: void main() { alias int number; number x; x = 314; writeln(x); } AFAIK typedef is scheduled for deprecation in D2 (if that's what you're using). On 12/27/10, Hamad Mohammad h.bat...@hotmail.com wrote: I can't compile this code void main() { typedef int number; number x; x = 314; writeln(x); }
Re: Creating an array of unique elements
On Mon, Dec 27, 2010 at 12:14 PM, Guilherme Vieira n2.nitro...@gmail.comwrote: Ah, yeah. I think you're right. Set is exactly what I need, and the fact that it works with hashes is even better. A pity D still doesn't have it, since it looks very useful, but thanks for your response. I'll take a look at your implementation later. Is there any prevision for sets in core D or Phobos? -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Mon, Dec 27, 2010 at 11:39 AM, spir denis.s...@gmail.com wrote: On Mon, 27 Dec 2010 05:22:14 -0200 Guilherme Vieira n2.nitro...@gmail.com wrote: Right now I'm wondering how's the best way to create a dynamic array object which will only accept unique elements (i.e., elements != from the existing elements in the array). (Take my words with precaution because I don not know D very well myself.) Hello Guilherme. If I understand your purpose correctly, what you're trying to define is a set, not an array, in the common sense of the terms in programming. To ensure uniqueness, you'd need to check whether the element exits already, which can only be very slow using an array (O(n)): you need to traverse the array element per element. Sets instead are build using data structures that allow this check to be far faster, by looking up a given element in a more clever way. There is no builtin Set type in D yet. The simplest way (and maybe the best) would be use associative arrays where keys would be actual elements and values just fake. (e in set) would tell you what you need. Depending on your requirements, trying to put an existing element would just put it again with no change, or should throw an error. In the latter case, you need to check it yourself or build a wrapper type (struct or class) around builtin associative arrays. For instance: Existence[Element] set; Element[] elements = ['a','c','e']; Element[] values = ['a','b','c','d','e']; foreach (element ; elements) set[element] = EXISTS; // Note: 'in' actually return a pointer to element. foreach (value ; values) writeln(cast(bool)(value in set)); Note: I have a Set type in stock at https://bitbucket.org/denispir/denispir-d/src/b543fb352803/collections.d, but wonder whether it's really necessary given the above. But you can have a look to see how it's done (this would give you some hints about language methods called 'opSomething', see TDPL's index). Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com Eek..! sorry for top-posting. -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira
Re: Creating an array of unique elements
On 12/27/10 3:14 PM, Guilherme Vieira wrote: Ah, yeah. I think you're right. Set is exactly what I need, and the fact that it works with hashes is even better. A pity D still doesn't have it, since it looks very useful, but thanks for your response. I'll take a look at your implementation later. Is there any prevision for sets in core D or Phobos? I don't know about the Phobos part, but for your D1/D2 collection needs, DCollections (http://www.dsource.org/projects/dcollections) might be worth a look. David
Re: declaration with typedef
On 12/27/10 3:44 PM, Hamad Mohammad wrote: excuse me but why that code works […] If you tried to assign person2 to person1 or vice versa, the same error would occur. But as Andrei already said, typedef has been deemed deprecated in D2. David
Re: declaration with typedef
If you tried to assign person2 to person1 or vice versa how?
Re: [D1] type of type
On Thu, 23 Dec 2010 17:28:49 -0500, %u e...@ee.com wrote: Should have been this: void func(type t){ new t(); } void func(T)(){ new T(); } When you are passing types into functions, use templates. -Steve
Re: Nested Structs
On Mon, 27 Dec 2010 08:54:37 -0500, d coder dlang.co...@gmail.com wrote: Greetings All I have a situation where I have a struct nested inside a class. I would like to make the enclosing class' members visible inside the nested struct's constructor. I see that such preposition is feasible for nested classes, but not for nested structs. Why so? A struct nested in a class does not have a hidden outer pointer as a nested class does. It's because a struct is generally more bare-bones than a class (which has loads of hidden pieces: vtable, interfaces, classinfo, etc.). Also, instantiating such a struct does not tie it to a class instance. Are there some alternative constructs which could give me this behavior for nested constructs? You need to implement this behavior on your own: class C { struct S { private C _outer; this(C c) { this._outer = c; _outer.x = 5;} // access enclosing class instance via _outer. } int x; } -Steve
Re: Nested Structs
On Mon, 27 Dec 2010 12:50:47 -0500, bearophile bearophileh...@lycos.com wrote: Steven Schveighoffer: A struct nested in a class does not have a hidden outer pointer as a nested class does. But I think this will eventually change, once this part is implemented: http://www.digitalmars.com/d/2.0/struct.html Nested Structs: A nested struct is a struct that is declared inside the scope of a function or a templated struct that has aliases to local functions as a template argument. Nested structs have member functions. It has access to the context of its enclosing scope (via an added hidden field). That is implemented, but notice the conditions that form a nested struct do not include inside a class or inside a struct (that templated struct that has aliases to local functions as a template argument condition is pretty specific, I'm talking about just putting it in any old struct). This is decidedly different from a nested class: http://www.digitalmars.com/d/2.0/class.html#nested A nested class is a class that is declared inside the scope of a function or another class. A nested class has access to the variables and other symbols of the classes and functions it is nested inside This is what the OP was desiring. -Steve
Re: declaration with typedef
On 12/27/2010 06:41 PM, Hamad Mohammad wrote: If you tried to assign person2 to person1 or vice versa how? I don't think I got what David meant with it either. Assigning instances of the same type is perfectly valid as long as you do not define some very peculiar opAssign. Andrej, on the other hand, made a perfect point. A typedef is deprecated in D2. typedef in D2 differs from C/C++ one. What typedef does (in the old, D1 way) is introducing a new, distinct type. Many D constructs, especially templates, can handle only certain types. Those, depending on conditions, may or may not include user-defined types. writeln requires that a given value is 'formattable' to string. It knows how to deal with numerics, strings, arrays, structs and classes. But it does not put out assumptions on unknown types (and typedef'd type is unknown to D's type system). There are some ways to introduce your types to certain constructs. For example, if you do writeln(person1) in your code, you'll get Human on the console - this is a default way writeln handles structs. But if you define a method toString for your Human struct, e.g: import std.conv; struct Human { //... string toString() { return text(name, : , age); } } , then writeln(person1) would output ': 12' to the console. (Mind that this 'toString' idiom may change, which is the effect of recent discussions about this certain topic). Generally, if you want a distinct type in D2, define a struct (or a class if you want your type to have reference semantics). If you want a simple alias to existing type, use alias declaration (alias is an analog of C/C++ typedef, though the keyword itself does more than this. You can find out additional uses in documentaion or The D Programming Language book). At this point, language gurus should start throwing rotten tomatoes at my general location, but I tried to explain the thing in the easiest way I could.
Re: declaration with typedef
On 12/28/2010 04:09 AM, Stanislav Blinov wrote: typedef in D2 differs from C/C++ one. Scratch that. I meant in D (having in mind D1 actually, oh well...)
Re: Nested Structs
A struct nested in a class does not have a hidden outer pointer as a nested class does. It's because a struct is generally more bare-bones than a class (which has loads of hidden pieces: vtable, interfaces, classinfo, etc.). Also, instantiating such a struct does not tie it to a class instance. Thanks Steve As far as I am concerned, this is a very limiting behavior wrt structs nested inside classes. I have also observed that if you define a constant (using enum for example) inside the enclosing class, the constant remains visible in the nested struct too. So I believe the language is making the hidden outer scope visible to the nested struct (or maybe there is some other mechanism for enums that I am not aware of). You need to implement this behavior on your own: Actually I am trying to define a DSEL and the end users are not typically programmers. I am in a situation where the end-user decides the unit in an enclosing class (unit of length as an inch for example) and later whenever he instantiates a line or a shape, the particular unit is automatically considered at the time of instantiation. For my application, I need value semantics and therefor using nested classes in place of structs can not be considered. Making the end-users pass the unit or its context (in form of this pointer) everytime they instantiate a shape would be atrocious. It would defeat the very purpose of letting the end-user define a unit. I know I am not on the right mailing group, but I want to ask for this particular language enhancement. I believe this would make the behavior of the language more straight wrt nested structs inside classes (are not these beasts expected to serve like nested classes or even structs nested inside function scopes?). I hope my requirement is generic enough and fits the bill for an enhancement request. Regards - Cherry