# Transparent / Opaque references

19 views

### Luke Palmer

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 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

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

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

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

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