Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Definition of containers.

5 views
Skip to first unread message

Autrijus Tang

unread,
Jul 30, 2005, 6:49:10 PM7/30/05
to perl6-c...@perl.org
I have just checked in the container type part of the new PIL runcore:

http://svn.openfoundry.org/pugs/src/PIL.hs

In the Pugs directory, you can run a sample test with:

*PIL> tests
==> %ENV =:= %ENV;
True
==> %ENV =:= %foo;
False
==> untie(%ENV); my %foo := %ENV;
()
==> my %foo := %ENV;

Following is a semi-formal treatment for containers, directly transliterated
from the Haskell source.

Containers come in two flavours: Non-tieable and Tieable. Both are typed,
mutable references. There is no way in runtime to change the flavour.

data Container s a
= NCon (STRef s (NBox a))
| TCon (STRef s (TBox a))

A Non-tieable container is comprised of an Id and a storage of that type, which
can only be Scalar, Array or Hash. Again, there is no way to cast a Scalar
container into a Hash container at runtime.

type NBox a = (BoxId, a)

A Tieable container also contains an Id and a storage, but also adds a
tie-table that intercepts various operations for its type.

type TBox a = (BoxId, a, Tieable a)

The type of tie-table must agree with the storage type. Such a table
may be empty, as denoted by the nullary constructor "Untied". Each of
the three storage types comes with its own tie-table layout.

data Tieable a where
Untied :: Tieable a
TieScalar :: TiedScalar -> Tieable Scalar
TieArray :: TiedArray -> Tieable Array
TieHash :: TiedHash -> Tieable Hash

Binding only happens between containers of the same type:

bind :: Container s a -> Container s a -> ST s ()

Additionally, the compiler needs to compile ($x := @y) into ($x := \@y).

To bind a container to another, we first check to see if they are of the
same tieableness. If so, we simply overwrite the target one's Id,
storage and tie-table (if any):

bind (TCon x) (TCon y) = writeSTRef x =<< readSTRef y
bind (NCon x) (NCon y) = writeSTRef x =<< readSTRef y

To bind an non-tieable container to a tieable one, we implicitly remove
any current ties on the target, although it can be retied later:

-- %*ENV := %foo
bind (TCon x) (NCon y) = do
(id, val) <- readSTRef y
writeSTRef x (id, val, Untied)

To bind a tieable container to a tied one, we first check if it is
actually tied. If yes, we throw a runtime exception. If not, we
proceed as if both were non-tieable.

-- %foo := %*ENV
bind (NCon x) (TCon y) = do
(id, val, tied) <- readSTRef y
case tied of
Untied -> writeSTRef x (id, val)
_ -> fail "Cannot bind a tied container to a non-tieable one"

We can compare two containers for Id equivalence. If the container types
differ, this should never return True:

(=:=) :: Container s a -> Container s b -> ST s Bool
x =:= y = do
x_id <- readId x
y_id <- readId y
return (x_id == y_id)

Untie an non-tieable container is a no-op:

untie (NCon x) = return ()

For a tieable container, we first invokes the "UNTIE" handler, then set
its "tied" slot to Untied:

untie (TCon x) = do
(id, val, tied) <- readSTRef x
case tied of
Untied -> return ()
_ -> do
tied `invokeTie` UNTIE
writeSTRef x (id, val, Untied)

Thanks,
/Autrijus/

Sam Vilain

unread,
Jul 30, 2005, 10:00:13 PM7/30/05
to Autrijus Tang, perl6-c...@perl.org
Autrijus Tang wrote:
> Containers come in two flavours: Non-tieable and Tieable. Both are typed,
> mutable references. There is no way in runtime to change the flavour.
> data Container s a
> = NCon (STRef s (NBox a))
> | TCon (STRef s (TBox a))
> A Non-tieable container is comprised of an Id and a storage of that type, which
> can only be Scalar, Array or Hash. Again, there is no way to cast a Scalar
> container into a Hash container at runtime.

Is 'tie' even required?

Tieing a hash would be the same as sub-classing it, and overriding
.post_circumfix:<{}>. Similarly with arrays and .post_circumfix:<[]>.

Tieing a scalar would be achieved using those "Proxy" objects discussed
earlier and in S06.

Or is this merely a mechanism for the above?

Sam.

Autrijus Tang

unread,
Jul 31, 2005, 2:05:41 AM7/31/05
to Sam Vilain, Autrijus Tang, perl6-c...@perl.org
On Sun, Jul 31, 2005 at 02:00:13PM +1200, Sam Vilain wrote:
> Tieing a hash would be the same as sub-classing it

Sub-classing a container is exactly what tying is all about.
That, and not losing the original non-tied storage inbetween ties.

> Or is this merely a mechanism for the above?

You can say that, yes. :)

Thanks,
/Autrijus/

0 new messages