[IronPython] Array Access Problem

Timothy Fitz firemoth at gmail.com
Thu May 26 08:58:34 CEST 2005


On 5/10/05, Jim Hugunin <jimhug at exchange.microsoft.com> wrote:
> >>> apt[0] = pt
> What do we do here?  We need to copy the data in pt into apt[0].  This
> is what it means to have an array of structs.  No matter what we do with
> proxies or wrappers there's no way out of this copy.  We could add some
> kind of pointer to the ValueProxy<Point> keeping track of the fact that
> there's a copy of this variable now held in apt[0].  This would need to
> be an arbitrarily large list of pointers.  This list would also be easy
> to break with CLI code that directly modified apt or other containers
> holding on to the value types.

I thought I understood this, but now I'm second guessing myself.

Why can't

>>> apt[0] = pt

indicate a copy by value if apt is a CLI array? Python lists would
still get a reference to
ValueProxy. 

>>> pt = apt[0]

Here ValueProxy would be a reference to apt[0], so pt.x += 10 is still fine.

What am I missing?

> 
> >>> pt.X = 0
> The only way this can modify apt[0] is if we keep the full list of
> references in ValueProxy.  See above for why keeping that full list
> still wouldn't always work.
> 
> >>> apt[0].X = 0
> This example would work using the ValueProxy that pointed to apt[0];
> however, when apt[0] is assigned to a variable the situation becomes as
> bad as it is for pt.
> 
> >>> for pt in apt:
> >>>   pt.X = 0
> The for loop uses an Enumerator to loop through the points in apt.
> Without constructing a custom enumerator for arrays there's no way to
> get anything but copy semantics here.  While we could build a custom
> enumerator for arrays this wouldn't solve the general case of value
> types being returned from methods.
> 
> When I played with this example in C#, I discovered something
> interesting:
> 
> Point[] pa = new Point[3];
> foreach (Point p in pa) {
>     pt.X = 10;
> }
> 
> The code above generates an error from the C# compiler:
> "Cannot modify members of 'p' because it is a 'foreach iteration
> variable'"
> 
> The C# compiler is treating these iteration variables as semi-immutable
> in order to minimize the confusion that can come from the copy semantics
> of value types.  This seems like a promising idea...
> 
> > > (2) Make value types immutable (or at least the ones you grab from
> > > collections)
> 
> All of the problems with value types stem from their mutability.  Nobody
> ever complains that int, double, char, etc. are value types because
> those are all immutable.  For immutable objects there's no difference
> between pass by reference and pass by value.
> 
> The CLR team's API Design Guidelines say this:
> - Do not create mutable value types.
> http://blogs.msdn.com/kcwalina/archive/2004/09/28/235232.aspx
> (or see here - http://peter.golde.org/2003/10/13.html#a16)
> 
> In some ways, this would be just reflecting in IronPython this good
> design sense.
> 
> One advantage of immutability is that it would make failures like the
> following much more obvious:
> 
> >>> apt[0].X = 0
> If value types were immutable this would throw.  The exception message
> might give people enough information to get started tracking down the
> issue and modifying their code to work correctly.
> 
> What are the problems with this approach?
> 
> 1. C#/VB examples won't port very naturally to IronPython and the docs
> will need a section explaining the various workarounds to the fact that
> IronPython doesn't support this idiom.  This isn't ideal, but I could
> easily live with this doc burden.
> 
> 2. There's no way that I know of to make a value type 100% immutable
> without controlling its implementation.  IronPython could block setting
> of fields and properties on value types, but there's no way to reliably
> detect and block all sets that came through methods.  Just getting the
> properties and fields would probably cover 95% of the cases where people
> try to mutate a value type, but it seems pretty awkward to me to say
> that value types in IronPython are sort-of immutable unless there are
> mutating methods.  The fact that this is what the C# compiler does for
> iteration variables is encouraging at least in that it's a precedent.
> 
> 3. There might be things that are impossible to express with this
> restriction.  I don't think that's true, particularly with the use of
> named parameters to initialize fields and properties in the value type's
> constructor.  However, one of the principles of IronPython is that it
> should be able to use any CLS library and it's possible there's some
> weird library design with value types that wouldn't work if they were
> considered virtually immutable by IronPython.
> 
> If we went down the immutable value type route, it would be interesting
> to look at different kinds of sugar that could be provided to make the
> impact on most programs less than it currently is.
> 
> -Jim
> _______________________________________________
> users-ironpython.com mailing list
> users-ironpython.com at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>



More information about the Ironpython-users mailing list