Transparent / Opaque references

19 views
Skip to first unread message

Luke Palmer

unread,
May 27, 2005, 4:59:17 PM5/27/05
to perl6-l...@perl.org
When we heard that Larry didn't acutally want $$foo to infinitely
dereference, some of us were overjoyed, and others severely
disappointed. Both transparent dereferencing (infinite $$foo) and
opaque dereferencing (one-level $$foo) have their uses, but they are
definitely distinct. Instead of adding different syntax for each
kind, I'll propose something different: two types of references:
Opaque and transparent.

Opaque references always need to be explicitly dereferenced (except
for binding an array to an array reference, etc.). Transparent
references always automatically dereference. The decision of what
type of dereferencing will go on is left up to the reference taker.

What I can't decide is which one \ will create, and how you will
create the other kind. Also, I can't decide how to one-level
dereference the transparent references so that you can change them.

Luke

Juerd

unread,
May 27, 2005, 7:19:43 PM5/27/05
to Luke Palmer, perl6-l...@perl.org
Juerd skribis 2005-05-28 1:15 (+0200):
> There are named arrays, @foo, and anonymous arrays, [].
>
> There are named hashes, %foo, and anonymous hashes, {}.
>
> There are only anonymous pairs. You can't dereference a pair, or bind a
> name to it.

I forgot an important one:

There are named scalars, $foo, and anonymous scalars, but they are
'literals', and read only, like 42.

There is no way to get an anonymous rw scalar, is there?


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Juerd

unread,
May 27, 2005, 7:15:04 PM5/27/05
to Luke Palmer, perl6-l...@perl.org
Luke Palmer skribis 2005-05-27 20:59 (+0000):

> Opaque references always need to be explicitly dereferenced (except
> for binding an array to an array reference, etc.). Transparent
> references always automatically dereference. The decision of what
> type of dereferencing will go on is left up to the reference taker.

The way I see things, an opaque reference is a value, while a
transparent reference is a name. And thus we already have both.

The name $foo points to a container, and so does \bar. However, to get
at the container using $foo, you use simply $foo. To get at the
container using the reference to bar, you have to dereference explicitly
with another $.

To bind a name (and thus have a transparent reference), we can either
declare the name, creating the variable at that point, or use some other
means of creating the variable, and use := to bind it later.

There are named arrays, @foo, and anonymous arrays, [].

There are named hashes, %foo, and anonymous hashes, {}.

There are only anonymous pairs. You can't dereference a pair, or bind a
name to it.

> What I can't decide is which one \ will create, and how you will


> create the other kind. Also, I can't decide how to one-level
> dereference the transparent references so that you can change them.

The only real problem with having only infix := for binding, is that you
can't easily use an alias (aka transparent reference) in a list. You can
have an array of aliases, but it's harder to have an array or hash in
which one element is an alias. Binding can be done explicitly:

%hash = { key => undef, foo => 'bar' };
%hash<key> := $variable;
%hash<key> = 5; # $variable is now 5 too

But there is no way to set the transparent reference (aka alias)
initially, because we lack a \-like syntax.

So I propose that := becomes a prefix operator as well as an infix one,
allowing:

%hash = { key => := $variable, foo => 'bar' };
%hash<key> = 5; # $variable is now 5 too

(This almost makes \ want to be \=, and $foo \= $bar to be what we now
write as $foo = \$bar, and $foo = := $bar to be the same as $foo :=
$bar, and stacked :=s to be irrelevant... But let's not think about this
too much...)

Ashley Winters

unread,
May 27, 2005, 11:19:11 PM5/27/05
to perl6-l...@perl.org
On 5/27/05, Juerd <ju...@convolution.nl> wrote:
>
> There is no way to get an anonymous rw scalar, is there?

Can't the [] and {} syntaxes be considered aliases for new Array(...)
and new Hash(...)?

my $x := new int = 10; # looks like it should work

Ashley Winters

Brent 'Dax' Royal-Gordon

unread,
May 28, 2005, 2:43:49 AM5/28/05
to Juerd, Luke Palmer, perl6-l...@perl.org
Juerd <ju...@convolution.nl> wrote:
> There is no way to get an anonymous rw scalar, is there?

There's always the Perl 5 hack:

\do { my $x }

Although that's not truly anonymous, I suppose.

--
Brent 'Dax' Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker

Damian Conway

unread,
May 28, 2005, 3:29:21 AM5/28/05
to perl6-l...@perl.org
Brent 'Dax' Royal-Gordon wrote:

> Juerd <ju...@convolution.nl> wrote:
>
>>There is no way to get an anonymous rw scalar, is there?
>
>
> There's always the Perl 5 hack:
>
> \do { my $x }
>
> Although that's not truly anonymous, I suppose.

There's a less-well-known hack that *is* truly anonymous:

$anon_scalar_ref = \eval{undef};

Or, of you prefer your anonymous scalar initialized:

$anon_scalar_ref = \eval{ $init_val };


However, in A6
(http://dev.perl.org/perl6/doc/design/apo/A06.html#Digression_on_types),
Larry muses:

Though for the closure case, it's possible we could define some kind
of non-my article to introduce a type unambiguously:

$closure = a Camel sub ($name) {...}
$closure = an Aardvark sub () {...}

Presumably "a" or "an" is short for "anonymous". Which is more or
less what the indefinite article means in English.


So presumably, one could also envisage:

$anon_scalar_ref = a Scalar;

Damian


Thomas Sandlass

unread,
May 28, 2005, 11:34:13 AM5/28/05
to perl6-l...@perl.org
Juerd wrote:
> The only real problem with having only infix := for binding, is that you
> can't easily use an alias (aka transparent reference) in a list. You can
> have an array of aliases, but it's harder to have an array or hash in
> which one element is an alias. Binding can be done explicitly:
>
> %hash = { key => undef, foo => 'bar' };
> %hash<key> := $variable;
> %hash<key> = 5; # $variable is now 5 too

Sorry to interrupt, but wasn't {} not derefed when assigned
to a % variable? Don't get me wrong, I like this meaning. And
it seems to be intuitive once in a while ;)


> But there is no way to set the transparent reference (aka alias)
> initially, because we lack a \-like syntax.

Why isn't \ good enough there? Because it requires $%hash<key> = 5?

> So I propose that := becomes a prefix operator as well as an infix one,
> allowing:
>
> %hash = { key => := $variable, foo => 'bar' };
> %hash<key> = 5; # $variable is now 5 too

I propose %hash = { key => :\$variable, foo => 'bar' };
Or should we also invent :=> to make a key/link pair?


Question: when a variable contains an opaque Ref and one
uses this variable in an assignment as lhs, that still goes
to the referee? How is the variable then detached? To wit:

$var = 7;

$ref = \$var;

$$ref = 12; # should $ref suffice?

say $var; # prints 12

$ref = 17; # detaches? Or is :\$ref = 17 needed?

say $var; # still prints 12
--
TSa (Thomas Sandlaß)

Thomas Sandlass

unread,
May 28, 2005, 9:12:46 AM5/28/05
to perl6-l...@perl.org
Luke wrote:
> Both transparent dereferencing (infinite $$foo) and
> opaque dereferencing (one-level $$foo) have their uses, but they are
> definitely distinct.

Well, they are more like variations on a theme.


> Instead of adding different syntax for each
> kind, I'll propose something different: two types of references:
> Opaque and transparent.

Which could be as simple as a boolean property .opaque on the Ref class
or with the reverse meaning .transparent or .autoref which I think
is better self documenting. OTOH for MMD distinct types are better.
Other well known terms for indirection besides reference are pointer
and link. Pointer sounds a bit too low level. So we could choose

Ref = opaque, one-level (this also maintains the Perl 5 meaning)
Link = transparent, chain following

Jargon would be that you deref a Ref but you follow a Link. The latter
is actually an intrinsic feature of the language. Links will be hardly
visible on language level. Something like

my Link $x;
sub foo( Link $l ) { ... }

would be errors but could also be just superfluous because every
variable basically is a link. I haven't worked that out.


> Opaque references always need to be explicitly dereferenced (except
> for binding an array to an array reference, etc.).

Which is easily achievable with overloads of &infix:{'='} for Array and
Ref of Array. While Link should be more of a subtype of the value it
links to. Thus links are more intrinsic to the language infra-structure
while Ref is an application level concept.




> Transparent
> references always automatically dereference. The decision of what
> type of dereferencing will go on is left up to the reference taker.

> What I can't decide is which one \ will create, and how you will
> create the other kind. Also, I can't decide how to one-level
> dereference the transparent references so that you can change them.

I would make &prefix:<\> a normal operator available for overloading.
Nourishing my idea that none of ::=, := and =:= are overloadable I
would like to invent another colon op like :\ or \: which if given
term precedence might give access to the Link of a variable such that

\:$link.some_link_method() or :\$link.some_link_method()

mean

(\:$link).some_link_method() or (:\$link).some_link_method()

Hmm, I like the :\ better because it goes with its counterpart :=
the link operator. This nicely mirrors the pair \ and = somewhat.

The only question that remains is how then to single step down
the link chain if that isn't contradicting the link concept in
the first place. But I think it doesn't need an operator.
A method might suffice:

:\$link.follow.follow
--

TSa (Thomas Sandlaß)

Juerd

unread,
May 28, 2005, 12:45:44 PM5/28/05
to Thomas Sandlass, perl6-l...@perl.org
Thomas Sandlass skribis 2005-05-28 17:34 (+0200):

> > %hash = { key => undef, foo => 'bar' };
> > %hash<key> := $variable;
> > %hash<key> = 5; # $variable is now 5 too
> Sorry to interrupt, but wasn't {} not derefed when assigned
> to a % variable? Don't get me wrong, I like this meaning. And
> it seems to be intuitive once in a while ;)

You're right, {} there was wrong. I originally had $hash there, but
later realised using a ref was needlessly making the example more
complex.

> Why isn't \ good enough there? Because it requires $%hash<key> = 5?

Because transparent isn't opaque, and we need opaque, and the same
operator can'tbe used for both, and \ has always meant opaque, so it's
best to keep it that way and invent a new operator for the new feature,
keeping the existing operator for the existing feature.

> I propose %hash = { key => :\$variable, foo => 'bar' };

:\$variable looks like many things to me, but not an alias.

> Question: when a variable contains an opaque Ref and one
> uses this variable in an assignment as lhs, that still goes
> to the referee?

No. A reference ("opaque reference" in this thread) is a value.
Assignment throws away the old value.

We already have both opaque and transparent references, but jargon is
different: transparent references are called aliases and opaque
references are just called references.

> $var = 7;
> $ref = \$var;
> $$ref = 12; # should $ref suffice?

No, if you would use $ref, $ref itself would be 12, but $var not,
because the 12 would overwrite the reference in $ref.

> say $var; # prints 12
> $ref = 17; # detaches?

Yes.

> say $var; # still prints 12

Yes.

Juerd

unread,
May 30, 2005, 6:08:34 AM5/30/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-05-30 8:58 (+0200):
> [This is a repost, somehow it didn't get through before, sorry.]

This is the fourth time it did get through to my mailbox, at least.

Juerd

unread,
Jun 2, 2005, 2:53:23 PM6/2/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-06-02 20:36 (+0200):
> Might it be applicable to use .() as the dereferencer
> of scalar variables that derefs to the next none(Ref)
> type and if that is a Code it dispatches to it as expected?

Or perhaps postfix $, to deref recursively.

my $foo = 5;

my $bar = \\\\\\$foo;

print $bar$; # 5

Just don't call your variable $Id ;)

Or of course a very simple .deref method.

I still think the feature isn't needed at all.

> $y() = 7;

No, sorry, that looks to me as if $y is a reference to an lvalue sub,
not like any form of referencing of scalars.

Juerd

unread,
Jun 2, 2005, 3:34:51 PM6/2/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-06-02 21:30 (+0200):
> And it nicely lines up with $y[], $y{}, @a[], %h{} etc. as
> dereferential expressions.

Except that () doesn't return a reference to an anonymous scalar of the
list it surrounds.

Juerd

unread,
Jun 2, 2005, 4:45:45 PM6/2/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" skribis 2005-06-02 22:22 (+0200):
> The only thing that is a bit unclear to me is if the dot is part of the
> operator name---like a sigil---or purely syntactical. A method is e.g.
> also not defined with the dot:
> class Blahh
> {
> method .example ( $non_invocant ) {...}
> }

Good question.

Attributes are declared with a dot:

has $.foo;

And the colon in private method names appears to be part of the name:

method :foo { ... }

However, while $:foo corresponds to :foo, $.foo does so to foo, not
.foo

(I personally hate the weird thing with private attributes and methods.)

Every postcircumfix operator we have can be used with and without the
dot, and it's unclear if the dot is part of the name.

While with reduce we include the dot

[.{}]

the operator itself is declared without:

&postcircumfix:<{ }>

Hm, back to methods: in Perl 5 I used to make the mistake of writing
"sub .foo" when I meant what we now call "method foo".

If we allow "sub .foo", "sub :foo" comes naturally, and another
asymmetry is gone.

It would also allow "multi sub" and "multi method" to simply become
"multi".

This leaves submethods, and perhaps they just need a third character,
that joins . and :. I have no idea what character would be useful, but
assuming >, it would also give $>foo, which would be to attributes what
submethods are to methods.

Wolverian

unread,
Jun 2, 2005, 4:55:50 PM6/2/05
to perl6-l...@perl.org
On Thu, Jun 02, 2005 at 10:45:45PM +0200, Juerd wrote:
> If we allow "sub .foo", "sub :foo" comes naturally, and another
> asymmetry is gone.
>
> It would also allow "multi sub" and "multi method" to simply become
> "multi".

I _really_ like the explicit 'method' name that methods have. Calling
them subs doesn't make sense to me.

--
wolverian

signature.asc
Reply all
Reply to author
Forward
0 new messages