Mailing List Archive

Proposal: anonymous(TYPE) (was ^HANDLE)
Okay. I think I'm seeing why there are two camps. Some are saying
"Give file handles a distinct identity" (Charles Bailey and me being
most vocal), while others are saying "File handles don't need a
distinct identity, now that we have objects and anonymous globs" (Tom
Christiansen being most vocal).

Well, we're both right. It's a floor wax _and_ a dessert topping.

First, I agree with Tom that most new code should use FileHandle. I
have no qualms about recommending it. That's why I have put a lot of
effort into the FileHandle package.

However, while the interface of FileHandle seems straightfoward, its
implementation uses anonymous globs. And I consider the use of globs
(anonymous or otherwise) as file handles to be a kludge. (Datamation
defines a kludge as "an ill-assorted collection of poorly-matching
parts, forming a distressing whole".)

You see, globs are symbol table entries. And there is *NO*REASON* why
the concept of file handles should be tied to the concept of symbol
tables. Granted we can now make "anonymous" globs. But that just
adds a hack on top of the kludge. I want something cleaner, better.

Tom hates the ^FH syntax. Personally, I don't like it much either.
But in order to lexically scope a Perl variable, that variable must
have a name, so I just tried to come up with a unique name. But if
there were another way to create a lexically scoped file handle --
which is NOT the same as "new FileHandle", because I'm talking about
implementation of FileHandle::new, not interface -- then the issue
would disappear.

(Mind you, this analysis assumes that Larry provides or allows
two-parameter ref() or $*glob{FILEHANDLE}, which solves the related
but distinct issue of aliasing named file handle without disturbing
entire symbol table entries.)

So I propose a facility for creating anonymous entities without
lexical scoping or anonymous globs:

anonymous(TYPE)

where:

anonymous("SCALAR") means do { my $x; \$x }
anonymous("ARRAY") means do { my $x; \@x }
anonymous("HASH") means do { my $x; \%x }
anonymous("FILEHANDLE") means do { my ^x; \^x } # :-)
anonymous("GLOB") means do { local *::X; \delete $::{X} }

So, what do you think?
--
Chip Salzenberg, aka <chs@nando.net>
"Hey, it's the Miss Alternate Universe Pageant!"
-- Crow T. Robot, MST3K: "Stranded In Space"
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
A followup, on STDIN/STDOUT/STDERR:

If anonymous() were in place, then Perl startup could do the
moral equivalent of:

BEGIN {
package CORE;

$_stdin = anonymous("FILEHANDLE");
open($_stdin, "<&=0");
sub STDIN { $_stdin }
sub main::stdin { $_stdin }

$_stdout = anonymous("FILEHANDLE");
open($_stdout, ">&=1");
sub STDOUT { $_stdout }
sub main::stdout { $_stdout }

$_stderr = anonymous("FILEHANDLE");
open($_stderr, ">&=2");
sub STDERR { $_stderr }
sub main::stderr { $_stderr }
}

Share and enjoy.
--
Chip Salzenberg, aka <chs@nando.net>
"Hey, it's the Miss Alternate Universe Pageant!"
-- Crow T. Robot, MST3K: "Stranded In Space"
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
: A followup, on STDIN/STDOUT/STDERR:
:
: If anonymous() were in place, then Perl startup could do the
: moral equivalent of:
:
: BEGIN {
: package CORE;
:
: $_stdin = anonymous("FILEHANDLE");
: open($_stdin, "<&=0");
: sub STDIN { $_stdin }
: sub main::stdin { $_stdin }
:
: $_stdout = anonymous("FILEHANDLE");
: open($_stdout, ">&=1");
: sub STDOUT { $_stdout }
: sub main::stdout { $_stdout }
:
: $_stderr = anonymous("FILEHANDLE");
: open($_stderr, ">&=2");
: sub STDERR { $_stderr }
: sub main::stderr { $_stderr }
: }

Conflating two formerly separate namespaces is not to be undertaken
lightly. I think I'd prefer that filehandles remain proto-bearwords
with a forced interpretation in the proper contexts.

Larry
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
According to Larry Wall:
> : If anonymous() were in place, then Perl startup could do the
> : moral equivalent of:
> : $_stdin = anonymous("FILEHANDLE");
> : open($_stdin, "<&=0");
> : sub STDIN { $_stdin }
>
> I think I'd prefer that filehandles remain proto-bearwords
> with a forced interpretation in the proper contexts.

No arguments from me -- it was just a thought. (Actually, now that I
think about it, the "sub STDIN" idea and the "anonymous 'FILEHANDLE'"
idea are orthagonal. So I shouldn't have implied a connection.)
--
Chip Salzenberg, aka <chs@nando.net>
"Hey, it's the Miss Alternate Universe Pageant!"
-- Crow T. Robot, MST3K: "Stranded In Space"
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
Chip Salzenberg writes:
> So I propose a facility for creating anonymous entities without
> lexical scoping or anonymous globs:
>
> anonymous(TYPE)
>
> where:
>
> anonymous("SCALAR") means do { my $x; \$x }
> anonymous("ARRAY") means do { my $x; \@x }

Anonymous scalars are missing from the language, ind this loss is
quite feelable. The proposed semantic looks fine for me, but not the
syntax (do not know why though).

Ilya
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
Ilya Zakharevich writes:
>Chip Salzenberg writes:
>> So I propose a facility for creating anonymous entities without
>> lexical scoping or anonymous globs:
>>
>> anonymous(TYPE)
>>
>> where:
>>
>> anonymous("SCALAR") means do { my $x; \$x }
>> anonymous("ARRAY") means do { my $x; \@x }
>
> Anonymous scalars are missing from the language, ind this loss is
> quite feelable.

Yes!

> The proposed semantic looks fine for me, but not the
> syntax (do not know why though).

Because there already is a syntax to express what type a variable has?

I like \@ANONYMOUS better than anonymous("ARRAY"), and the same for %
and $. (With for example `*ANONYMOUS = *^U;' in English.pm.)
But this would be in addition to the `anonymous()' syntax, which is
needed for HANDLEs and possibly GLOBs.

BTW, @ANONYMOUS might also be used as an lvalue in places where an
explicit temporary variable is useful but will only be used once. Like
{ my @x; return scalar(@x = &wantarray_should_be_true_here()); }. Or
give it an additional short name `@ANON', otherwise we'd save exactly 0
characters in the code above:-)


Regards,

Hallvard
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
Catching up on last few days' mail . . .

Chip Salzenburg writes:
> So I propose a facility for creating anonymous entities without
> lexical scoping or anonymous globs:

Hmm. So what precisely gets created? In other words, does the
resulting thing live in a symbol table, a PAD, or just on the stack?

> anonymous(TYPE)
>
> where:
>
> anonymous("SCALAR") means do { my $x; \$x }
> anonymous("ARRAY") means do { my $x; \@x }
> anonymous("HASH") means do { my $x; \%x }
> anonymous("FILEHANDLE") means do { my ^x; \^x } # :-)
> anonymous("GLOB") means do { local *::X; \delete $::{X} }
>
> So, what do you think?

I think it'll do the job. As you mention, it'll need to be combined with
another technique to allow one to manipulate existing objects. Aliasing
in typeglobs could be handled either via Larry Wall's pseudohash idea,
or by an extension to the assignment operator, by which the expression
thing = *foo;
assigns to C<thing> the part of C<*foo> which matches C<thing>s type.
This lets one say
thing = anonymous("FILEHANDLE");
thing = *foo;
to get at the I/O data in *foo. Now how do we write C<thing>? As a
scalar, and just "remember" its type internally? As a bearword? (Bleah.)
Some sort of type symbols? (Ducks. :-))

BTW, one tangential request: If we do set up a type to deal with I/O,
could we call it something other than "FILEHANDLE"? A file handle
is one of a set of I/O possibilities, including pipes, callbacks, sockets,
etc. Once we get ties worked out, the object needn't bear any
resemblance to a C FILE *. Could we make the distinction now by
naming the type "STREAM" or "CHANNEL" or even just "IO"?

Please accept my apologies if some of this has already been addressed in
messages I haven't got to yet -- I've only been able to skim so far.

Regards,
Charles Bailey bailey@genetics.upenn.edu
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
According to Charles Bailey:
> Chip Salzenburg writes:
> > So I propose a facility for creating anonymous entities without
> > lexical scoping or anonymous globs:
>
> Hmm. So what precisely gets created?

An SV* on the stack.

> [...] an extension to the assignment operator, by which the expression
> thing = *foo;
> assigns to C<thing> the part of C<*foo> which matches C<thing>s type.

Could you elaborate? I don't think I understand, because it seems to
make no sense. ;-)

> BTW, one tangential request: If we do set up a type to deal with I/O,
> could we call it something other than "FILEHANDLE"?

That name is already enshrined in the output of C<ref>.
--
Chip Salzenberg, aka <chs@nando.net>
"Hey, it's the Miss Alternate Universe Pageant!"
-- Crow T. Robot, MST3K: "Stranded In Space"
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
Chip Salzenburg writes:
> > [...] an extension to the assignment operator, by which the expression
> > thing = *foo;
> > assigns to C<thing> the part of C<*foo> which matches C<thing>s type.
>
> Could you elaborate? I don't think I understand, because it seems to
> make no sense. ;-)

That's probably because I was being unclear. :-) Basically, I was thinking of
the inverse of current behavior on assignment *to* a typeglob. For example,
one might say
$scalar = *foo;
@array = *foo;
%hash = *foo;
&sub = *foo;
my($fh) = anonymous("FILEHANDLE"); $fh = *foo;
in order to, respectively, make
$scalar equivalent to $foo
@array equivalent to @foo
%hash equivalent to %foo
&sub equivalent to &foo
$fh equivalent to the IO living hidden in *foo.
This has two disadvantags, from what I can see:
- it's playing with the lvalue context, in that it's always assigning
to a name, not to a list, despite @ or % on the LHS, nor is it
making a function call an lvalue, despite & on the LHS.
- the $fh case is still ambiguous notation, in that it's lexically
identical to the $scalar case, but $fh and $scalar are very
different things beneath the $.
I'm not arguing for this at all strongly; it's simply a way to get the
anonymous objects hooked up to global symbols when one's ultimate goal
is to create a lexical alias of some global variable.

> > BTW, one tangential request: If we do set up a type to deal with I/O,
> > could we call it something other than "FILEHANDLE"?
>
> That name is already enshrined in the output of C<ref>.

True. I'm comfortable with changing this, though, for two reasons. It's a
relatively new addition, so I expect it's not in common use. Further, right
now it's produced only by CORE operators which do, in fact, create FILE *s, and
which appear to be on their way out of favor in the face of a file handling
package. This'll mean that links to files will carry the name of that package
(whatever it turns out to be), and code which currently checks for ref($foo) eq
'FILEHANDLE' will have to be adjusted. While we have the opportunity, I think
we should make the distinction between I/O in general, and I/O on a FILE *, so
I'm suggesting that the I/O data type be STREAM or CHANNEL or IO. This may be
my non-Unix background showing, in that I tend to think of FILE *s (== file
descriptors) as one type of I/O, not the common interface to all sorts of I/O.
I expect that I/O extensions will be written for Perl in which the object
passed around isn't a C FILE* (tied filehandles, "terminals", etc.), so I'd
like to make the break now.

Regards,
Charles Bailey bailey@genetics.upenn.edu
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
According to Hallvard B Furuseth:
> I like \@ANONYMOUS better than anonymous("ARRAY"), and the same for %
> and $.

Me too. But that means we need punctuation for each data type that
might be created -- i.e., ^HANDLE. (Oh no! Run away!)

> BTW, @ANONYMOUS might also be used as an lvalue in places where an
> explicit temporary variable is useful but will only be used once.

Hm. Maybe so. But a "list" operator seems more reasonable.
--
Chip Salzenberg, aka <chs@nando.net>
"Hey, it's the Miss Alternate Universe Pageant!"
-- Crow T. Robot, MST3K: "Stranded In Space"
Re: Proposal: anonymous(TYPE) (was ^HANDLE) [ In reply to ]
According to Chip Salzenberg:
>According to Hallvard B Furuseth:
>> I like \@ANONYMOUS better than anonymous("ARRAY"), and the same for %
>> and $.
>
> Me too. But that means we need punctuation for each data type that
> might be created -- i.e., ^HANDLE. (Oh no! Run away!)

No, that's why I wrote:

But this would be in addition to the `anonymous()' syntax, which is
needed for HANDLEs and possibly GLOBs.

In short, my suggestion covers only datatypes that did *not* prompt the
anonymous() proposal:-)


>> BTW, @ANONYMOUS might also be used as an lvalue in places where an
>> explicit temporary variable is useful but will only be used once.
>
> Hm. Maybe so. But a "list" operator seems more reasonable.

In that particular case, yes. But there are several times when perl
requires a variable which we don't really need. I don't remember
exactly, though I seem to remember needing
return temporary = expression;
instead of
return expression;
some places. Or &foo($tmp = $val); when &foo might modify its argument.
Though I wouldn't exactly call it a major problem...


Regards,

Hallvard