View mode: basic / threaded / horizontal-split · Log in · Help
December 14, 2011
Re: Fixing const arrays
On 2011-12-14 13:27:57 +0000, "Regan Heath" <regan@netmail.co.nz> said:

> On Wed, 14 Dec 2011 02:36:43 -0000, Michel Fortin
> <michel.fortin@michelf.com> wrote:
> 
>> By "code patterns", you mean something like this?
>> 
>> 	struct Foo
>> 	{
>> 		int getBar();
>> 		void setBar(int);
>> 	}
>> 
>> 	void main()
>> 	{
>> 		Foo foo;
>> 		int a = foo.bar;  // calls getBar()
>> 		foo.bar = a;      // calls setBar(a)
>> 	}
> 
> Why not something similar to C# syntax...

I know the basics of the C# property syntax, but how do you take the 
address of the getter with it? And how do you define array-member 
properties like you can do with functions? And how do you disambiguate 
access those array members properties if two imported modules define a 
property with the same name for an array? It basically has the same 
undefined areas as the current syntax using @property.

With the code pattern syntax used above:

	&foo.bar; // take the address of the returned value (if returned by ref)
	&foo.getBar; // take the address of the getter
	&foo.setBar; // take the address of the setter


	void getFront(int[] array) { return array[0]; }

	int[] a;
	a.front; // array-member property made from a module-level function

	
	// disambiguated access if two imported modules
	// define the same array-member property
	std.range.getFront(a);
	other.mod.getFront(a);


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
December 14, 2011
Re: Fixing const arrays
On Tue, 13 Dec 2011 18:08:43 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail@erdani.org> wrote:

> On 12/13/11 5:14 PM, Peter Alexander wrote:
>> On 13/12/11 10:17 PM, Vladimir Panteleev wrote:
>>> On Tuesday, 13 December 2011 at 21:10:22 UTC, Andrei Alexandrescu  
>>> wrote:
>>>> There's a phrase in Romanian that quite applies: "From the lake into
>>>> the well".
>>>
>>> I believe the English version is "Out of the frying pan, into the
>>> fire" :)
>>>
>>> Inconsequential space-filler opinion: I am OK with @property, mainly
>>> because it's a common feature among PLs, it's better than nothing, and
>>> don't know better solutions.
>>
>> In my opinion, it's not better than nothing.
>>
>> What it gives you:
>>
>> 1. A bit of syntactic sugar.
>> 2. The ability to refactor member look up easily.
>>
>> What it costs:
>>
>> 1. Overloads syntax.
>> a. obj.field can now be an arbitrary function call.
>> b. May have arbitrary cost (e.g. T[].length)
>> 2. Complicating the language (proof: this discussion)
>> 3. Another thing to learn.
>> 4. Another thing for tools to process.
>>
>>
>> I don't think the syntax sugar it provides counts for anything really.
>>
>> The ability to refactor member look ups is nice, but I find that this
>> rarely occurs in practice and even when it occurs, it's not hard to
>> replace obj.field with obj.field() or obj.getField().
>>
>> The costs far outweigh the benefits IMO.
>
> We could have inferred property intention from the code pattern, without  
> requiring any keyword. That solution (which was discussed and rejected  
> in this newsgroup) was miles ahead from the drivel of @property we have  
> now.
>
> I noticed there's a tunnel vision phenomenon when it comes to  
> keyword-based solutions: once a special notation is on the table,  
> there's no appreciation for anything else. That's what happened with  
> lazy (another design misfire I'm very unhappy about) and with @property.  
> I literally feel my heart rate getting up when I think of them.

@property wasn't my first choice, there were probably a dozen proposals on  
the table.  I liked the C# version the best:  
http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP4

But here is the phenomenon I noticed:

N different solutions get proposed, and are debated by the community.   
Walter is very vocal about what he doesn't like, but silent on other  
aspects (presumably because he is considering them?)

All of a sudden Walter picks a solution, then posts a thread to flesh out  
the details.  After that, it's hard to change his mind.

For the property debate, looking back through the newsgroups, it looks  
like Walter and you came up with a solution that nobody had proposed and  
nobody liked.  Then somehow @property was chosen.  Not sure how that  
happened or what the convincing argument was.

But you will notice in that discussion that many of the solutions did not  
involve keywords, and all were given equal air time (I don't see tunnel  
vision).

Thread:  
http://dfeed.kimsufi.thecybershadow.net/discussion/post/h53g3i$elk$1@digitalmars.com

I personally don't mind @property, even if there are better solutions.   
It's not as horrible as you say IMO.

-Steve
December 14, 2011
Re: Fixing const arrays
I don't mind @property, usually I just create one property block for a
class, e.g.:
@property
{
   // funcs..
}
December 14, 2011
Re: Fixing const arrays
On Wed, 14 Dec 2011 13:50:09 -0000, Michel Fortin  
<michel.fortin@michelf.com> wrote:

> On 2011-12-14 13:27:57 +0000, "Regan Heath" <regan@netmail.co.nz> said:
>
>> On Wed, 14 Dec 2011 02:36:43 -0000, Michel Fortin
>> <michel.fortin@michelf.com> wrote:
>>
>>> By "code patterns", you mean something like this?
>>>  	struct Foo
>>> 	{
>>> 		int getBar();
>>> 		void setBar(int);
>>> 	}
>>>  	void main()
>>> 	{
>>> 		Foo foo;
>>> 		int a = foo.bar;  // calls getBar()
>>> 		foo.bar = a;      // calls setBar(a)
>>> 	}
>>  Why not something similar to C# syntax...
>
> I know the basics of the C# property syntax, but how do you take the  
> address of the getter with it?

I hadn't given this a lot of thought.  But, here goes.. :)

The compiler (whatever the syntax used) will generate the get/set  
functions internally.  So, it will technically be possible to take the  
address of both the getter and setter.

Using my suggested syntax there is only 1 property name 'bar' and  
typically the function called is determined by the usage, e.g.

Foo foo;
int a = foo.bar; // getter called
foo.bar = 4;     // setter called

So, what happens when we take the address..

Foo foo;
int delegate(void) getter = &foo.bar;  // takes the address of the getter
void delegate(in) setter = &foo.bar;   // takes the address of the setter

I think that works, what do you reckon?

> And how do you define array-member properties like you can do with  
> functions?

I don't think we should call these "properties".  What we're actually  
doing is adding members to built in types which can have any number of  
arguments and are therefore they're not strictly "properties".  I think  
part of the confusion around properties comes from conflating these two  
ideas into one and calling them both "properties".

> And how do you disambiguate access those array members properties if two  
> imported modules define a property with the same name for an array?

I'd like to split the "adding array members" feature away from  
"properties" and look at it again, specifically due to problem cases like  
this.  For example, in this case we could require the use of () for  
"adding array members" while for actual properties (user defined, on user  
defined types, using a c# like syntax or similar) we could require () not  
to be used.  I think that pretty much avoids the whole can of worms,  
doesn't it?

Regan

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 14, 2011
Re: Fixing const arrays
On 14/12/11 8:16 AM, Timon Gehr wrote:
> On 12/14/2011 12:35 AM, Peter Alexander wrote:
>> On 13/12/11 11:11 PM, Timon Gehr wrote:
>>> On 12/14/2011 12:14 AM, Peter Alexander wrote:
>>>> On 13/12/11 10:17 PM, Vladimir Panteleev wrote:
>>>>> On Tuesday, 13 December 2011 at 21:10:22 UTC, Andrei Alexandrescu
>>>>> wrote:
>>>>>> There's a phrase in Romanian that quite applies: "From the lake into
>>>>>> the well".
>>>>>
>>>>> I believe the English version is "Out of the frying pan, into the
>>>>> fire" :)
>>>>>
>>>>> Inconsequential space-filler opinion: I am OK with @property, mainly
>>>>> because it's a common feature among PLs, it's better than nothing, and
>>>>> don't know better solutions.
>>>>
>>>> In my opinion, it's not better than nothing.
>>>>
>>>> What it gives you:
>>>>
>>>> 1. A bit of syntactic sugar.
>>>> 2. The ability to refactor member look up easily.
>>>>
>>>> What it costs:
>>>>
>>>> 1. Overloads syntax.
>>>> a. obj.field can now be an arbitrary function call.
>>>> b. May have arbitrary cost (e.g. T[].length)
>>>
>>> ??? T[].length is a field access, not a property function. It takes a
>>> small constant amount of time.
>>
>> Assigning to the length of an array may reallocate it, which is not a
>> small, nor constant amount of time.
>>
>> int[] a;
>> ...
>> a.length = n; // may invoke a GC allocation + O(n) memcpy
>
> OK, I see, thanks. I don't think it is problematic in this particular
> case though.

Well, it is a little. It makes it difficult to scan code looking for GC 
allocations, or even scan code looking for inefficiencies.

Obviously I know now that I have to look for .length assignments on 
arrays, but it can be quite horrific when looking at code that uses 
third party libraries that you aren't familiar with.

An example of this I encountered in practice was in Unity3D's libraries.

http://unity3d.com/support/documentation/ScriptReference/WWW-texture.html

The WWW class has a 'texture' property. A small sentence in the middle 
of its documentation reveals the horror.

"Each invocation of texture property allocates a new Texture2D."

That's right. Every time you read WWW.texture, it allocates a large 
chunk of memory. In my particular case, I was copying the pixels from 
the texture into another array, something like this:

WWW www = ...;

for (int i = 0; i < www.texture.width; ++i)
    for (int j = 0; j < www.texture.height; ++j)
        buffer[i][j] = www.texture.GetPixel(i, j);

For a small 100x100 texture, that code allocates over 10,000, 100x100 
textures.

Luckily, that was horrific enough to prompt me to investigate, but a 
less obvious problem would have likely slipped past me unnoticed.
December 14, 2011
Re: Fixing const arrays
On 12/14/2011 09:39 PM, Peter Alexander wrote:
> On 14/12/11 8:16 AM, Timon Gehr wrote:
>> On 12/14/2011 12:35 AM, Peter Alexander wrote:
>>> On 13/12/11 11:11 PM, Timon Gehr wrote:
>>>> On 12/14/2011 12:14 AM, Peter Alexander wrote:
>>>>> On 13/12/11 10:17 PM, Vladimir Panteleev wrote:
>>>>>> On Tuesday, 13 December 2011 at 21:10:22 UTC, Andrei Alexandrescu
>>>>>> wrote:
>>>>>>> There's a phrase in Romanian that quite applies: "From the lake into
>>>>>>> the well".
>>>>>>
>>>>>> I believe the English version is "Out of the frying pan, into the
>>>>>> fire" :)
>>>>>>
>>>>>> Inconsequential space-filler opinion: I am OK with @property, mainly
>>>>>> because it's a common feature among PLs, it's better than nothing,
>>>>>> and
>>>>>> don't know better solutions.
>>>>>
>>>>> In my opinion, it's not better than nothing.
>>>>>
>>>>> What it gives you:
>>>>>
>>>>> 1. A bit of syntactic sugar.
>>>>> 2. The ability to refactor member look up easily.
>>>>>
>>>>> What it costs:
>>>>>
>>>>> 1. Overloads syntax.
>>>>> a. obj.field can now be an arbitrary function call.
>>>>> b. May have arbitrary cost (e.g. T[].length)
>>>>
>>>> ??? T[].length is a field access, not a property function. It takes a
>>>> small constant amount of time.
>>>
>>> Assigning to the length of an array may reallocate it, which is not a
>>> small, nor constant amount of time.
>>>
>>> int[] a;
>>> ...
>>> a.length = n; // may invoke a GC allocation + O(n) memcpy
>>
>> OK, I see, thanks. I don't think it is problematic in this particular
>> case though.
>
> Well, it is a little. It makes it difficult to scan code looking for GC
> allocations, or even scan code looking for inefficiencies.
>
> Obviously I know now that I have to look for .length assignments on
> arrays, but it can be quite horrific when looking at code that uses
> third party libraries that you aren't familiar with.
>

Oh yes, certainly. That is what I meant by 'in this particular case': 
Because the .length on arrays is built into the language, you know that 
it must allocate as soon as you have a sufficiently good mental model of 
how dynamic arrays work. (and anyone who wants to write effective D code 
that uses dynamic arrays should)

> An example of this I encountered in practice was in Unity3D's libraries.
>
> http://unity3d.com/support/documentation/ScriptReference/WWW-texture.html
>
> The WWW class has a 'texture' property. A small sentence in the middle
> of its documentation reveals the horror.
>
> "Each invocation of texture property allocates a new Texture2D."
>
> That's right. Every time you read WWW.texture, it allocates a large
> chunk of memory. In my particular case, I was copying the pixels from
> the texture into another array, something like this:
>
> WWW www = ...;
>
> for (int i = 0; i < www.texture.width; ++i)
> for (int j = 0; j < www.texture.height; ++j)
> buffer[i][j] = www.texture.GetPixel(i, j);
>
> For a small 100x100 texture, that code allocates over 10,000, 100x100
> textures.
>
> Luckily, that was horrific enough to prompt me to investigate, but a
> less obvious problem would have likely slipped past me unnoticed.
>

oO. That is quite an API design problem there.
December 14, 2011
Re: Fixing const arrays
Peter Alexander:

> Well, it is a little. It makes it difficult to scan code looking for GC 
> allocations, or even scan code looking for inefficiencies.
> 
> Obviously I know now that I have to look for .length assignments on 
> arrays, but it can be quite horrific when looking at code that uses 
> third party libraries that you aren't familiar with.

A proposed idea to help is to add a compilation switch that produces a list of all heap allocation points in the current compilation unit (in Bugzilla there is a related issue that asks for a list of just heap allocations of closures).

Bye,
bearophile
December 14, 2011
Re: Fixing const arrays
On Wed, 14 Dec 2011 15:39:55 -0500, Peter Alexander  
<peter.alexander.au@gmail.com> wrote:

> On 14/12/11 8:16 AM, Timon Gehr wrote:
>> On 12/14/2011 12:35 AM, Peter Alexander wrote:
>>> On 13/12/11 11:11 PM, Timon Gehr wrote:
>>>> On 12/14/2011 12:14 AM, Peter Alexander wrote:
>>>>> On 13/12/11 10:17 PM, Vladimir Panteleev wrote:
>>>>>> On Tuesday, 13 December 2011 at 21:10:22 UTC, Andrei Alexandrescu
>>>>>> wrote:
>>>>>>> There's a phrase in Romanian that quite applies: "From the lake  
>>>>>>> into
>>>>>>> the well".
>>>>>>
>>>>>> I believe the English version is "Out of the frying pan, into the
>>>>>> fire" :)
>>>>>>
>>>>>> Inconsequential space-filler opinion: I am OK with @property, mainly
>>>>>> because it's a common feature among PLs, it's better than nothing,  
>>>>>> and
>>>>>> don't know better solutions.
>>>>>
>>>>> In my opinion, it's not better than nothing.
>>>>>
>>>>> What it gives you:
>>>>>
>>>>> 1. A bit of syntactic sugar.
>>>>> 2. The ability to refactor member look up easily.
>>>>>
>>>>> What it costs:
>>>>>
>>>>> 1. Overloads syntax.
>>>>> a. obj.field can now be an arbitrary function call.
>>>>> b. May have arbitrary cost (e.g. T[].length)
>>>>
>>>> ??? T[].length is a field access, not a property function. It takes a
>>>> small constant amount of time.
>>>
>>> Assigning to the length of an array may reallocate it, which is not a
>>> small, nor constant amount of time.
>>>
>>> int[] a;
>>> ...
>>> a.length = n; // may invoke a GC allocation + O(n) memcpy
>>
>> OK, I see, thanks. I don't think it is problematic in this particular
>> case though.
>
> Well, it is a little. It makes it difficult to scan code looking for GC  
> allocations, or even scan code looking for inefficiencies.
>
> Obviously I know now that I have to look for .length assignments on  
> arrays, but it can be quite horrific when looking at code that uses  
> third party libraries that you aren't familiar with.
>
> An example of this I encountered in practice was in Unity3D's libraries.
>
> http://unity3d.com/support/documentation/ScriptReference/WWW-texture.html
>
> The WWW class has a 'texture' property. A small sentence in the middle  
> of its documentation reveals the horror.
>
> "Each invocation of texture property allocates a new Texture2D."
>
> That's right. Every time you read WWW.texture, it allocates a large  
> chunk of memory. In my particular case, I was copying the pixels from  
> the texture into another array, something like this:
>
> WWW www = ...;
>
> for (int i = 0; i < www.texture.width; ++i)
>      for (int j = 0; j < www.texture.height; ++j)
>          buffer[i][j] = www.texture.GetPixel(i, j);
>
> For a small 100x100 texture, that code allocates over 10,000, 100x100  
> textures.
>
> Luckily, that was horrific enough to prompt me to investigate, but a  
> less obvious problem would have likely slipped past me unnoticed.

Yes, but length as a read property does not allocate anything (nor does  
reducing the length).  In fact, length as a read property reduces to a  
field access (it is a language builtin, after all).

Would you expect that setting the length of an array to a *larger* size  
would not allocate?  Your example shows something that doesn't look like  
it should be costly, but it actually is.  Expanding length *looks* costly  
(and it is).

You do have a point that it shouldn't necessarily be a property.  I also  
don't think dup, reverse, or sort should be array properties.  But these  
are pieces of the language that have been there forever.  To change them  
now would be disruptive for very little gain.

-Steve
December 14, 2011
Re: Fixing const arrays
Steven Schveighoffer:

> I also don't think dup, reverse, or sort should be array properties.  But these  
> are pieces of the language that have been there forever.  To change them  
> now would be disruptive for very little gain.

sort and reverse properties will be deprecated and later removed.

Bye,
bearophile
December 14, 2011
Re: Fixing const arrays
On 14/12/11 8:59 PM, Steven Schveighoffer wrote:
> On Wed, 14 Dec 2011 15:39:55 -0500, Peter Alexander
> <peter.alexander.au@gmail.com> wrote:
>
>> On 14/12/11 8:16 AM, Timon Gehr wrote:
>>> On 12/14/2011 12:35 AM, Peter Alexander wrote:
>>>> On 13/12/11 11:11 PM, Timon Gehr wrote:
>>>>> On 12/14/2011 12:14 AM, Peter Alexander wrote:
>>>>>> On 13/12/11 10:17 PM, Vladimir Panteleev wrote:
>>>>>>> On Tuesday, 13 December 2011 at 21:10:22 UTC, Andrei Alexandrescu
>>>>>>> wrote:
>>>>>>>> There's a phrase in Romanian that quite applies: "From the lake
>>>>>>>> into
>>>>>>>> the well".
>>>>>>>
>>>>>>> I believe the English version is "Out of the frying pan, into the
>>>>>>> fire" :)
>>>>>>>
>>>>>>> Inconsequential space-filler opinion: I am OK with @property, mainly
>>>>>>> because it's a common feature among PLs, it's better than
>>>>>>> nothing, and
>>>>>>> don't know better solutions.
>>>>>>
>>>>>> In my opinion, it's not better than nothing.
>>>>>>
>>>>>> What it gives you:
>>>>>>
>>>>>> 1. A bit of syntactic sugar.
>>>>>> 2. The ability to refactor member look up easily.
>>>>>>
>>>>>> What it costs:
>>>>>>
>>>>>> 1. Overloads syntax.
>>>>>> a. obj.field can now be an arbitrary function call.
>>>>>> b. May have arbitrary cost (e.g. T[].length)
>>>>>
>>>>> ??? T[].length is a field access, not a property function. It takes a
>>>>> small constant amount of time.
>>>>
>>>> Assigning to the length of an array may reallocate it, which is not a
>>>> small, nor constant amount of time.
>>>>
>>>> int[] a;
>>>> ...
>>>> a.length = n; // may invoke a GC allocation + O(n) memcpy
>>>
>>> OK, I see, thanks. I don't think it is problematic in this particular
>>> case though.
>>
>> Well, it is a little. It makes it difficult to scan code looking for
>> GC allocations, or even scan code looking for inefficiencies.
>>
>> Obviously I know now that I have to look for .length assignments on
>> arrays, but it can be quite horrific when looking at code that uses
>> third party libraries that you aren't familiar with.
>>
>> An example of this I encountered in practice was in Unity3D's libraries.
>>
>> http://unity3d.com/support/documentation/ScriptReference/WWW-texture.html
>>
>> The WWW class has a 'texture' property. A small sentence in the middle
>> of its documentation reveals the horror.
>>
>> "Each invocation of texture property allocates a new Texture2D."
>>
>> That's right. Every time you read WWW.texture, it allocates a large
>> chunk of memory. In my particular case, I was copying the pixels from
>> the texture into another array, something like this:
>>
>> WWW www = ...;
>>
>> for (int i = 0; i < www.texture.width; ++i)
>> for (int j = 0; j < www.texture.height; ++j)
>> buffer[i][j] = www.texture.GetPixel(i, j);
>>
>> For a small 100x100 texture, that code allocates over 10,000, 100x100
>> textures.
>>
>> Luckily, that was horrific enough to prompt me to investigate, but a
>> less obvious problem would have likely slipped past me unnoticed.
>
> Yes, but length as a read property does not allocate anything (nor does
> reducing the length). In fact, length as a read property reduces to a
> field access (it is a language builtin, after all).

Length reading is fine.

> Would you expect that setting the length of an array to a *larger* size
> would not allocate? Your example shows something that doesn't look like
> it should be costly, but it actually is. Expanding length *looks* costly
> (and it is).

It's not that I wouldn't expect it (I would), but at a glance (i.e. 
without thinking about it) you wouldn't notice it. It just looks like a 
member assignment.

It's like overloading operator& in C++. It takes something that had one 
meaning and changes it into something else without a change in syntax. 
It's essentially the syntactic version of function hijacking.

> You do have a point that it shouldn't necessarily be a property. I also
> don't think dup, reverse, or sort should be array properties. But these
> are pieces of the language that have been there forever. To change them
> now would be disruptive for very little gain.

Agreed.
Next ›   Last »
7 8 9 10 11
Top | Discussion index | About this forum | D home