Re: Embrace polymorphic builtins, for they are cool.

2001-06-20 Thread Mark J. Reed

I would argue that eval BLOCK and eval STRING are closer than indicated
by Mr. Schwern.  In either case, you supply an argument which contains
code, and that code is executed.  As a small amount of protection
from this dynamic element, fatal errors within the eval()ed code
are trapped and prevented from causing the entire program to
die.  Whether the code is a string or a block doesn't alter the behavior
of eval() other than by changing the point in time at which the
argument code is compiled.

That you can use what is really a side effect of eval's
behavior in conjunction with deliberately-generated fatal errors
to implement a kind of exception system doesn't change
the fact that eval() is doing the same thing in both cases.
Thus, it is good polymorphism.

(I would say that the practice of using eval/die to provide an
exception system is itself at best unclear, though that can be
mitigated by the use of modules like Error.pm; but that doesn't
mean there's a problem with the behavior of eval).

However, I agree that close(variable) is less justifiable. 
I know what it means to close a file (even if only because I've
been steeped in the world of computers and their filesystems for
years; the analogy to physically closing a paper folder is loose
at best), but the ideas of "closing" and "variable" don't go
together in my head to form any kind of coherent concept.

If I wanted to make variable read-only, I would expect to do it
by setting the read-only attribute on that variable, which I would
further expect to do the same way I would set any other attribute at
any other time.  Orthogonality has its good points, even in Perl;
you just shouldn't be afraid to veer off diagonally when it makes sense.
I don't think close(var) makes sense.

-- 
Mark J. REED<[EMAIL PROTECTED]>



Re: Embrace polymorphic builtins, for they are cool.

2001-06-20 Thread David L. Nicol



> 
> Now look at eval.  When acting on a string, it compiles and runs it as
> code.  When acting on a block, it traps any errors and prevents dying.
> You may be able to come up with some weak analogies between the two,
> but they're two different functionalities.


i have nothing to add.  you obviosly want to scrap eval-block for try.
This is turning into a religious dispute.

 
> Different object, same action:   ok
> Different object, different action:  not ok
> 
> >   close (IO)  # closes an open stream, returns
> >   # true on success or false on failure,
> >   # sets  $! on failure
> >
> >   close (\$)  # overwrites the ASSIGN method of the
> 
> 
> close.  Closing a filehandle means you're no longer going to read
> and/or write to it (depending on how it was opened).  Closing a
> variable means you're no longer going to write to it... but reading is
> ok.  The analogy is there, but its not a particularly strong or
> obvious one, and there's the jarring difference that you can no longer
> read from a closed filehandle, but you can read from a closed variable.

 
> You've got to be careful with polymorphism and ensure that you've got
> strong analogous action in all cases.  Not just because its clever or
> you like the name.  This is not to say we shouldn't have polymorphic
> built-ins (we already have more than you might think) but they must be
> chosen with extreme care.


So I take it that you object wholeheartedly to C++ Streams libraries
using << and >> for IO operations because even though there is never any
confusion, since bitshifting file handles is silly, it is in your terms
WRONG?

I think the limited set of objects that close(filehandle) is defined on
makes it a perfect candidate for overloading with something completely
different, just like the bitshift operators were overloaded for file
ops in C++.  I will continue to use it as described in discussion of
How Capabilities Might Work In This Context until whacked over the head
with a better keyword.


 
> Some more counter-examples... un/pack() on a filehandle could compress
> and decompress the file!  It might be perfectly logical if un/pack
> didn't already do something completely different.
> 
> Some good examples... delete/exists work on both arrays and hashes.
> delete() completely removes an array/hash element, exists() checks to
> see if an array/hash element has been populated (even if its
> undefined).  The details might start to diverge a bit, but the basic
> meaning doesn't change.
> 
> Homogeneous operators are potentially confusing (just because English
> has homonyms doesn't mean its not confusing) but not all polymorphic
> functions are homonyms.  Find the ones which retain their basic
> meaning across all their objects, those are the good ones.
> 
> PS  delete() and exists() are also polymorphic, as is reverse(),
> chomp(), chop(), goto() and die().  There are probably more, but I
> can't think of them, probably because they mesh so well we don't even
> think about it.  You could consider functions which have default
> arguments as polymorphic, then there's lots and lots of polymorphism
> in Perl.  But I digress.

Great!  So you agree that we need better polymorphism in prototype and
dispatch of user-defined routines?






-- 
   David Nicol 816.235.1187
  Signature closed for repaving




Re: Embrace polymorphic builtins, for they are cool.

2001-06-20 Thread Michael G Schwern

On Mon, Jun 11, 2001 at 09:18:14PM -0500, David L. Nicol wrote:
> But I'm digressing.  What I want to talk about is overloaded builtins.
> 
> I recently suggested that C be overloaded to make its argument,
> when its argument is not a filehandle, become read-only.  An objection
> was made to this, on the grounds that homonymous operators are confusing,
> with eval block and eval string being given as an example of something
> that is confusing.
> 
> This post is intended to be a response to that objection.
> 
> Natural language contains many homonyms.  This is rarely, outside of
> dramatic plots, a problem, as there are other indicators, up to and 
> including requests for clarification, but generally "context," to
> guide us human beings as we apply our common sense to the great
> questions of What Is Fair and What Is Right without taking wrong turns
> or digressing into discussions of propagandistic trends in modern
> journalism while dividing chocolate cake evenly among party guests.
> 
> Okay?
> 
> C (string/block) is but one.

I'd hold this up as a failure of polymorphic functions.  eval STRING
and eval BLOCK do completely different things and people associate
their behaviors, merits and flaws together because they have the same
name.


> C might be considered another.

Another fine counter-example.  Who understands all the different
things that do() does??  Its particularly bad because of the name.
"do" is about as generic as "foo".  It could mean anything.


> overloading C to do what beginners expect.

This is an example of polymorphism done for good.  Why?  First,
there's a relatively obvious expectation of what length() will do with
a string and an array (a hash might be a little less obvious).
Second, and much more subtle, is that while the object of the function
changes, its basic functionality does not.

Its very important.  Think of it as a verb (function) and object of
that verb (arguments).  length() is the verb, a string or array is the
object.  When acting on a string, you get the number of characters in
the string.  When acting on an array, you get the number of elements
in the array.  Basically the same operation, adapted for the object.
This is polymorphism for Good.

Now look at eval.  When acting on a string, it compiles and runs it as
code.  When acting on a block, it traps any errors and prevents dying.
You may be able to come up with some weak analogies between the two,
but they're two different functionalities.

Different object, same action:   ok
Different object, different action:  not ok


>   close (IO)  # closes an open stream, returns 
>   # true on success or false on failure,
>   # sets  $! on failure
> 
>   close (\$)  # overwrites the ASSIGN method of the


close.  Closing a filehandle means you're no longer going to read
and/or write to it (depending on how it was opened).  Closing a
variable means you're no longer going to write to it... but reading is
ok.  The analogy is there, but its not a particularly strong or
obvious one, and there's the jarring difference that you can no longer
read from a closed filehandle, but you can read from a closed variable.

You've got to be careful with polymorphism and ensure that you've got
strong analogous action in all cases.  Not just because its clever or
you like the name.  This is not to say we shouldn't have polymorphic
built-ins (we already have more than you might think) but they must be
chosen with extreme care.


Some more counter-examples... un/pack() on a filehandle could compress
and decompress the file!  It might be perfectly logical if un/pack
didn't already do something completely different.

Some good examples... delete/exists work on both arrays and hashes.
delete() completely removes an array/hash element, exists() checks to
see if an array/hash element has been populated (even if its
undefined).  The details might start to diverge a bit, but the basic
meaning doesn't change.


Homogeneous operators are potentially confusing (just because English
has homonyms doesn't mean its not confusing) but not all polymorphic
functions are homonyms.  Find the ones which retain their basic
meaning across all their objects, those are the good ones.


PS  delete() and exists() are also polymorphic, as is reverse(),
chomp(), chop(), goto() and die().  There are probably more, but I
can't think of them, probably because they mesh so well we don't even
think about it.  You could consider functions which have default
arguments as polymorphic, then there's lots and lots of polymorphism
in Perl.  But I digress.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/
Perl6 Quality Assurance <[EMAIL PROTECTED]>   Kwalitee Is Job One
kiloconway: unit of extreme mind expansion.  Equal to 1024 conways,
  one kiloconway gives the sensation that all of the quantuum particles
  in your