views:

1003

answers:

4

I've been trying lately to implement some clean coding practices in AS3. One of these has been to not give away references to Arrays from a containing object. The point being that I control addition and removal from one Class and all other users of the Array receive read only version.

At the moment that read only version is a ArrayIterator class I wrote, which implements a typical Iterator interface (hasNext, getNext). It also extends Proxy so it can be used in for each loops just as a Array can.

So my question is should this not be a fundamental feature of many languages? The ability to pass around references to read only views of collections?

Also now that there is improved type safety for collections in AS3 , in the form of the Vector class, when I wrap a a Vector in a VectorIterator I lose typing for the sake of immutability. Is there a way to implement the two desires, immutability and typing in AS3?

A: 

Some would argue that the fact that you can implement such patterns as libraries is an argument against adding features to the language itself (for example, the C++ language designers typically say that).

Assaf Lavie
I think what Brian meant was that it should be part of the core library, not the language itself. (AS3 is handled by ECMA.)
bzlm
In C++ const is part of the language and frequently used to return immutable views of member variables. So this not something which was believed could be made as a library. (it might be implementable now, since C++ gained templates, but not in its original form)
Pete Kirkham
Yes I do mean the core library, in the case of AS3. I just wonder why immutable views on collections are not considered important? It seems like a fundamentally good design practice, to be able to say "I guarantee that this collection will only be modified within this class".
Brian Heylin
Remember, AS was hardly OO at all before AS3. It still has a long way to go if it wants to be the new Java. But does it? Do we want it to?
bzlm
No Java desires here, a lot of my issues with AS3 is that it is not defining itself as a language, rather it is stuck between Javascript and Java. I do appreciate the many changes and clean ups AS3 made. I've been looking at Scala recently, that has got me thinking :D
Brian Heylin
I often (semi-jokingly) think of AS3 as a combination of the worst features of JavaScript and Java. The late-parameter checking on callback arguments, for example makes all the Array methods (.every(), .map()) practically useless.
Simon Buchan
A: 

Do you have the immutability you want via the proxy object or not? Note, you can have the VectorIterator constructor take a mandatory Class parameter. Admittedly this is not designer friendly at the moment, but lets hope things will improve in the future.

dirkgently
I do have immutability now through the Proxy, Iterator combination, but I loose the typing of the Vector class due to the Proxy objects typeless functions.
Brian Heylin
Yea the addition of a type to the VectorIterator constructor would be a possible solution for catching run-time type casting issues. my point here is that I wonder why read only collections do not exist in many languages/core libs, from the very first release? They seem like good design practice.
Brian Heylin
I can't say why it isn't there. But, if you make your implementation public and the problems you had to face, based on importance/popularity it may well be picked up by Adobe for the next version. AS is still very much in its teen years.
dirkgently
True, there are many changes I would like to make to AS3, but that's always the case with any language :) What I would really like is for Array and Vector to implement an two interfaces, one for read operations and another for write. Then it would be easy to define your own collections.
Brian Heylin
You mean const accessors ala C++?
dirkgently
As I see it, const accessor in C++ restricts change within the defining class. What I mean is that if i need to give away a reference to a collection (from the defining class, through a getter), then I would like to hand out a read only collection. Only the defining class can change the collection
Brian Heylin
The problem is that your read-only interface needs to have separate object identity from the collection, otherwise code you don't trust can just cast it. (Ok, so its more self-documenting, so its not *useless*)
Simon Buchan
@Brian Heylin: A class can change it's own data *anytime*. The const accessor is part of the public interface: why would you want to make modifications there? Moreover, a const accessor is a *design const*, mutable can always get you there ;)
dirkgently
@dirkgently: That's fine about C++, but.. I'm concerned about AS3 as it is the language is use mostly. I'm looking for a way to protect collections, to guarantee that a collection will not be modified, if it is spread across the system.
Brian Heylin
+3  A: 

It seems that using an Iterator pattern is the best way currently in AS3 to pass a collection around a system, while guaranteeing that it will not be modified.

The IIterator interface I use is modeled on the Java Iterator, but I do not implement the remove() method, as this is considered a design mistake by many in the Java community, due to it allowing the user to remove array elements. Below is my IIterator implemention:

 public interface IIterator
 {
     function get hasNext():Boolean
     function next():*
 }

This is then implemented by classes such as ArrayIterator, VectorIterator etc.

For convenience I also extend Proxy on my concrete Iterator classes, and provide support for the for-each loops in AS3 by overriding the nextNameIndex() and nextValue() methods. This means code that typically used Arrays does not need to change when using my IIterator.

var array:Array = ["one", "two", "three"]

for each (var eachNumber:String in array)
{
    trace(eachNumber)
}

var iterator:IIterator = new ArrayIterator(array)

for each (var eachNumber:String in iterator)
{
    trace(eachNumber)
}

Only problem is... there is no way for the user to look at the IIterator interface and know that they can use a for-each loop to iterate over the collection. They would have to look at the implementation of ArrayIterator to see this.

Brian Heylin
What is the rationale behind the iterator being unidirectional? This is not a critique, I'm just curious. Also, is it possible to extend this to provide access-by-index type functionality with the familiar bracket syntax (myArray[i] = "foo"), without the object being dynamic?
macke
I think I didn't read the Proxy documentation diligently enough the first time. Second time around it seems as though this is exactly what the proxy class is meant to be used for.
macke
Brian Heylin
A: 

I have created a small library of immutable collection classes for AS3, including a typed ordered list, which sounds like it would meet your needs. See this blog post for details.

David Arno
Thanks David, looks good, I've also implemented something quite similar with the Proxy. I'll give your code a look, see if I can get some nice ideas
Brian Heylin