Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Damian Conway

Juerd wrote:


But will they also see foo ~ $bar as something different from
foo$bar? 


They ought to, since the two are different in Perl 5.
For example:

my @bar = 'bar';
print [EMAIL PROTECTED];
print foo[ . @bar . ]baz\n;


And what context does foo{ $bar } use?

Stringification, of course. No interpolation is occurring.



In my opinion, making the string value in interpolation different from
the value in Str context is madness.


It's dwimmery. Which often looks like madness until you realize that it's just 
a reflection of how most hackers think. ;-)


Damian


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Juerd
Damian Conway skribis 2005-09-24  8:31 (+1000):
 In my opinion, making the string value in interpolation different from
 the value in Str context is madness.
 It's dwimmery.

It's dwymmery, or dwdmmery indeed. Not at all what I mean, am likely to
mean, or will ever mean.

 Which often looks like madness until you realize that it's just a
 reflection of how most hackers think. ;-)

This calls for a poll, because I believe nothing of this most.

Hackers on this list, what do you think?


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


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Juerd
Damian Conway skribis 2005-09-24  8:31 (+1000):
 They ought to, since the two are different in Perl 5.
 For example:
 my @bar = 'bar';
 print [EMAIL PROTECTED];
 print foo[ . @bar . ]baz\n;

This does not compare stringification to interpolation. It compares
scalarification to interpolation. Interpolation (stringification) was
needed because Perl 5's arrays weren't as smart as Perl 6's, and didn't
usefully stringify in string scalar context.

 @foo

 Context   Perl 5   Perl 6
 numeric   number   number
 stringnumber   join
 scalarnumber   ref

This huge difference in how smart an array is makes it kind of
useless to take Perl 5 as an example of how arrays should behave in Perl
6, because that would also dictate that foo ~ @bar end in the number
of elements in @bar. Bad idea.


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


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread wolverian
On Sun, Sep 25, 2005 at 12:52:08PM +0200, Juerd wrote:
 Hackers on this list, what do you think?

I think separating the two is extremely confusing. I do not see any uses
for it, but maybe I am not thinking hard enough. 

-- 
wolverian


signature.asc
Description: Digital signature


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Yuval Kogman
On Sun, Sep 25, 2005 at 12:52:08 +0200, Juerd wrote:
 Damian Conway skribis 2005-09-24  8:31 (+1000):
  In my opinion, making the string value in interpolation different from
  the value in Str context is madness.
  It's dwimmery.
 
 It's dwymmery, or dwdmmery indeed. Not at all what I mean, am likely to
 mean, or will ever mean.
 
  Which often looks like madness until you realize that it's just a
  reflection of how most hackers think. ;-)
 
 This calls for a poll, because I believe nothing of this most.
 
 Hackers on this list, what do you think?

I think there is no merit in separating the two since you can't have
a default interpolation. There is no one canonical right way to
visually render any object as text.

Based on this claim I think that if we make 2 stringication
operations, one pure and one interpolated, we should have roughly
30 interpolation operators, for each possible scenario of
interpolation (interpolation to STDERR, interpolation when we're
printing many other lines, interpolation into a string that gets
sent to a file (we can use type inferrence)), and so on and so
forth.

What I'm getting at is that the distinction between interpolation
and stringification is between the purposing of the stringified
forms - programmatic or visual. This distinction is wrong to make
without separating the types of the output, since there are two
implicit constructors for the Str data type, which are not directly
visible to the naive user.

Furthermore, since the two are combinable, e.g.

foo${bar}gorch ~ $moose;

the train of thought the user follows is that of taking four
elements (foo, $bar, gorch, $moose) and making one big result
out of them. The separation of interpolation from stringification
here is tricky because it actually does 2 different operations
instead of seemingly one big operation on four operands.

For every Oh crap, i get it i've said in my perl 5 programming
career i think i'll have about 3-4 just related to these
interpolation semantics in perl 6.

This also stops users from picking between interpolation and
concatenation on a case by case basis for the purpose of enhancing
readability.

On top of that there is the fact that perl 5 people come to expect
that ($foo) means (.$foo), except that the first version is
easier to read.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me groks YAML like the grasshopper: neeyah!!



pgp7w51MXUWh8.pgp
Description: PGP signature


Exceptuations

2005-09-25 Thread Yuval Kogman
Hi,

Suppose I'm writing a file browser, with a pane on the left to
display the filesystem hierarchy, and a frame on the right to
preview the file.

Suppose I have a convenience function, preview_file which takes a
path and returns a value that the frame display view knows to
render.

Let's define this for HTML files, where the desired preview is a
summary of the text:

use Text::Summarize;
use HTML::ToAscii;

multi sub preview_file ($filename where /\.html$/ ) {
my $handle = open($filename, :r); # might fail if $filename is 
unreadable
return summarize(html2ascii(=$handle)); # might fail if HTML is 
invalid
}

And this code is called when the user clicks on a file in the pane:

class NiftyUI {
use fatal;

method handl_some_click ($file) {
$.right_frame.display(preview_file($file.name));
}

method handle_event ($event) {
$?SELF.dispatch_event($event);

CATCH {
when NiftyBackend::Exception {
$?SELF.display_error_box($!);
}

default { die $! };
}
}
}

With the current shape of the code if any of the possible failures
in the backend code happen, they are reported in a message dialog.

Now, let's say we would like to add a feature, that lets the user
change the mode of the file if it's unreadable.

Several approaches to doing this:

* give the backend an abstract object, a Frontend of sorts:

$frontend.ask_user(do you want to make the file readable?)

* throw internal exceptions, and let the frontend handle the
exception and retry the action:

method handle_some_click ($file) {
$.right_frame.display(preview_file($file.name));

CATCH {
when IO::Errors::PERMISSION_DENIED {
if ($?SELF.ask_user_to_chmod_file($file)) {
make_readable($file);
$?SELF.handle_some_click($file); # 
retry the event
} else { die $! }
}
}
}

I propose a new model - each exception has a continuation that
allows it to be unfatalized.

The exception object has info on whether the fatality of the
exception was due to a die, or a use fatal, and lets the exception
handler decide accordingly.

Then we have code that looks like this:

method handle_some_click ($file) {
$.right_frame.display(preview_file($file.name));

CATCH {
when IO::Errors::PERMISSION_DENIED {
if ($?SELF.ask_user_to_chmod_file($file)) {
make_readable($file);
$!.continue(open($file, :r)); # the 
return value of the failed open is
# overridden by the return value of 
this (hopefully successful) open.
} else { die $! }
}
when HTML::ToAscii::Exception { # badly formed
$!.continue(The HTML file contained a syntax 
error);
# this string is passed to summarize instead of 
the undef exception object
}
}
}

The value this has is in handler cascading... If, for example,
make_readdable($file) failed too, then an exception handler around
handle_some_click could handle display a sudo box, to try it again,
and eventually continue back into the make_readable($file) call,
which will then continue into the failed open.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me tips over a cow: neeyah!!



pgprazW7gmwVh.pgp
Description: PGP signature


Re: Exceptuations

2005-09-25 Thread Yuval Kogman
In order to support continuable exception generators, here is a
style guide for exception values, and an observation on what
exceptions should support at the language level:

* Exceptions should preserve data

All exceptions should contain as much of the original data that
caused them...

With Luke's new theory proposal, storing the argument tuple for the
call the raised the exception is logical. For example, for a
Permission Denied error raised in open() we should have access to
the filename that we tried to open, and the mode we tried to open it
with.

* Each thrown exception should contain the value of $! from before
it was thrown

* Each thrown exception has to know whether it was thrown because of
'use fatal' or because of an explicit 'die'

* fail should be used except for very strict conditions

* use fatal should be encouraged by the documentation, for one
liners, scripts, and full blown apps.

* Context data should be overridable at the exception object level

Carp and friends should be implemented not by using a different
keyword than fail, but failing with a value that specifies a certain
context.

sub croak (*$a) { # tuples again
fail Exception.new(*$a, :position($?CALLER::CALLER::POSITION));
}

* fail should cascade such that every time a block is left with a
failing return value, the block's caller should be checked for use
fatal.

* When continuing into an exception, the parameters to the
continuation are substituted for the error.

use fatal;

my $value = {
fail foo;

CATCH {
$!.continue(bar);
}
}

say $bar;

Continuing into the exception with no arguments is like ignoring
'use fatal' for this specific exception, causing the failed value to
propagate out of the fatalized block.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me wields bonsai kittens: neeyah



pgpE7Wb5OOFbg.pgp
Description: PGP signature


Re: Exceptuations

2005-09-25 Thread Yuval Kogman
On Sun, Sep 25, 2005 at 18:11:22 +0300, Yuval Kogman wrote:
 In order to support continuable exception generators, here is a
 style guide for exception values, and an observation on what
 exceptions should support at the language level:

And more...

* Exception strings are for humans

Humans need to know what happened in their own words. They have a
hard time analyzing error codes, or constant names.

Computers have a hard time analyzing strings, and prefer hard data.

It should be easy to identify each error in a way that is meaningful
to computers, and this way should be orthogonal to the string that
is displayed to the user when possible.

This means that it should be incredibly easy for the user to declare
exception classes as they are used, perhaps by stealing goodness
from enumish constructs, or somesuch.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: *shu*rik*en*sh*u*rik*en*s*hur*i*ke*n*: neeyah



pgpcpkWrPtIwr.pgp
Description: PGP signature


Re: Exceptuations - CPS explained

2005-09-25 Thread Yuval Kogman
To ease the understanding of exactly how this might work, assume
that perl 6 is really all continuation passing style under the
surface (parrot is ;-).

use fatal;
my $x = do_bar();
do_foo();

sub do_bar {
fail bah;
}

The way CPS works is really simple. The principal is that there is
no concept of return. Instead, the call to do_bar, for example, gets
an additional implicit parameter. This parameter is the code ref to
the rest of the code, and could look something like this if
deparsed:

sub ($rv) {
my $x = $rv;
do_foo()
}

So do_bar knows to make a goto to that code ref with it's return
value.

Now, fail gets something similar - it gets the code ref which
applies do_bar's passed in code ref, and it applies it the exception
constructed from bah.

Fail will also check first to see if the continuation might, at some
level, use fatal. If it does, it takes a dynamically scoped value
instead - the continuation for the last encountered CATCH block.

When it throws the exception, fail will store the continuation it
got (the $x = ... stuff) in the exception object.

CATCH can then choose either to goto it's parent block's
continuation (exit normally), or to goto the continuation stored in
the exception object, which is indirectly the assignment to $x.

Autrijus's example makes this clear (he prefers resume over
continue):

use fatal;
my $x = { 1/0 * 3 CATCH { $!.resume(9) } }; # 27

What's happening is that infix:/ checks if it's divisor is 0,
and if it is, it will fail. Fail has a continuation to 'multiply by
3 - exit from block - assign to $x', and it stores that in the
exception object. Instead of gotoing to that continuation, it will
instead take the last CATCH block that was relevant, in this case
the only one. This one finds the continuation to * 3 etc in the
exception object, and effectively augments the result of
infix:/(1, 0) to be 9 instead of an undefined value.

I hope this makes things clear.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me does not drink tibetian laxative tea: neeyah!



pgpC58pLTHBic.pgp
Description: PGP signature


Allomopherencing

2005-09-25 Thread Yuval Kogman
Hmm... Making up these subjects is fun =)

Anywho...

Since type inferrencing is going to make into Perl 6, and
allomorphism is very richly supported by the type system, i'm
wondering on the nature of the optionality...

What excatly do the users get to control? Are functions with '--'
rich type signatures going to limit the user in any way? What should
the functions in the prelude be defined as?

Under strict type inferrencing, i'd expect this to be a compile time
error:

my $dog = Dog.new;

if ($condition) {
my Cat $c = $dog;
} else {
...
}

since it's guaranteed to be a runtime error if $condition is ever
true.

Is there any situation where a compile time error is not a good
thing to have?

If allomorphism is enough such that the class that implements the
actual integers, which does Str, Int, Num, Ord and all that for the
yummy operations we can do on it, and expressions like

foo ~ 42 ~ Bar

are type safe, is there really any reason to ever not give compile
time errors to type errors?

Also, is it rational to say, within a lexical pragma, that such
zealous allomorphism is prohibited, in order to get more rigid type
semantics for that block? If so, how is this defined?

On the other side of the spectrum, is there any situation where type
safety is ever a bad thing, if it's inferred, and flexible?

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me supports the ASCII Ribbon Campaign: neeyah!!!



pgpPThiBbNSi3.pgp
Description: PGP signature


Re: Exceptuations

2005-09-25 Thread Luke Palmer
On 9/25/05, Yuval Kogman [EMAIL PROTECTED] wrote:
 I propose a new model - each exception has a continuation that
 allows it to be unfatalized.

I think we've already talked about something like this.  But in the
presence of use fatal, it makes a lot more sense.

Something comes to mind:

use fatal;
sub foo()  { bar()  }
sub bar()  { baz()  }
sub baz()  { quux() }
sub quux() { fail }
{
say foo();
CATCH { $!.continue(42) }
}

Exactly which exception is continued?  Where do we cut off the call
chain and replace our own value?  This comes up again with open(). 
Let's say open is implemented with a series of five nested calls, the
innermost which knows how to fail and propagate outwards.  However,
the programmer using open() has no idea of its internals, so it ought
to override the return value of open() itself, rather than its utility
functions.  However, we can't go with outermost, because then you'd
only be fixing the lexical call (say foo() above).  So it's
somewhere in between.  Where?

Luke


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Ashley Winters
On 9/25/05, Yuval Kogman [EMAIL PROTECTED] wrote:
 On Sun, Sep 25, 2005 at 12:52:08 +0200, Juerd wrote:
  Damian Conway skribis 2005-09-24  8:31 (+1000):
   In my opinion, making the string value in interpolation different from
   the value in Str context is madness.
   It's dwimmery.
 
  It's dwymmery, or dwdmmery indeed. Not at all what I mean, am likely to
  mean, or will ever mean.
 
   Which often looks like madness until you realize that it's just a
   reflection of how most hackers think. ;-)
 
  This calls for a poll, because I believe nothing of this most.
 
  Hackers on this list, what do you think?

 [...snip...]

 On top of that there is the fact that perl 5 people come to expect
 that ($foo) means (.$foo), except that the first version is
 easier to read.

Yes, that's how I explain it to anyone who really needs to know, which
is usually to someone asking about overloading.

However, I see a useful difference between Str[ingification] and 'does
Interpolate' or whatever that role might be. However, the names might
want to change to protect the innocent.

The Stringification of a UnixEpochTimestamp should probably be the
same as its Integerization -- 12345678900. However, the Interpolation
of it should be the locale-specific POSIX-style datetime string.

Here's how I would do it if $Ashley == any(@Larry)

The .as(Str) of an object would be its serialization -- what you would
spit out for the Perl6 version of pickle/Storable/whatnot. Ideally,
the Str representation would be lossless, informationally, so you
could call the deserialize/unpickle (.from?) method using its
return-value:

my Thingy $foo .=from($thing);

The Interpolate role's method would return the pretty-printed,
possibly LOSSY presentation of the object's information.

For example:

my $color = new HTML::Color(magenta);
if $color.as(Str) eq '#FF00FF' and $color eq magenta {
  $Ashley++;
}

So, to summarize, I want .as(Str) to be the lossless canonical
representation, as well as the basis for the default .hash method,
while Interpolate would be the pretty-printed localized lossy
presentation Role.

Ashley Winters


Re: Exceptuations

2005-09-25 Thread Michael Walter
On 9/25/05, Luke Palmer [EMAIL PROTECTED] wrote:
 [...]
 Exactly which exception is continued?
 [...]
Named restarts in Common Lisp appear to try to solve a related
problem, if I'm skimming this thread correctly. :-) (see [1]).

Michael

[1] 
http://www.supelec.fr/docs/cltl/clm/node312.html#SECTION00330


Re: Allomopherencing

2005-09-25 Thread Ashley Winters
On 9/25/05, Yuval Kogman [EMAIL PROTECTED] wrote:
 Hmm... Making up these subjects is fun =)

Very interesting. :)

 Under strict type inferrencing, i'd expect this to be a compile time
 error:

 my $dog = Dog.new;

 if ($condition) {
 my Cat $c = $dog;
 } else {
 ...
 }

 since it's guaranteed to be a runtime error if $condition is ever
 true.

I can't accept that. While you can infer that $dog will be a Dog at
that line of code, it isn't being enforced, which means no
compile-time error. $dog is allowed to store any kind of data, and you
only know what methods exist in Dog at compile-time. After all, I was
planning to add a Dog::as(Cat) method at runtime. Yes, I'm a mad
scientist. Muahahaha!!!

In order to enforce that level of compile-time type safely, you should
need to declare my Dog $dog, or stick a pragma up top: use sadistic
inferencing; either of those declarations can disregard my potential
for runtime tomfoolery, and abort the compiliation when there's
something illogical.

Ashley Winters


Re: Allomopherencing

2005-09-25 Thread Ashley Winters
On 9/25/05, Ashley Winters [EMAIL PROTECTED] wrote:
 On 9/25/05, Yuval Kogman [EMAIL PROTECTED] wrote:
  Under strict type inferrencing, i'd expect this to be a compile time
  error:

I quoted but didn't read close enough. You DID say strict type
inferencing. Never mind. :)

Ashley Winters


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Yuval Kogman
On Sun, Sep 25, 2005 at 10:59:38 -0700, Ashley Winters wrote:

 The Stringification of a UnixEpochTimestamp should probably be the
 same as its Integerization -- 12345678900. However, the Interpolation
 of it should be the locale-specific POSIX-style datetime string.

Why? What value does the stringification of a date have as a
stringified integer? If we were to implement such semantics,
wouldn't it be wiser to print The time in seconds since the epoch
is { +$time }? That's much more readable, obvious and
nonsurprising, without being overly long or tedious.

I would never say something like

the time $time is  ~ $time ~  seconds since the epoch

That's simply absurd. Especially when the context of the string (the
stuff it's being interpolated to - not the programmatic context) is
not 100% self explanatory - then I would need to comment it.

 Here's how I would do it if $Ashley == any(@Larry)

You mean eqv.. =(

 The .as(Str) of an object would be its serialization

as is formatting, not serialization:

$time.as('%d');

or something... I don't really know how this works

For serialization you have the .perl method, which is roughly the
same as Data::Dumper (code to be evaled), or some more heavy duty
package (i expect Storable to have a pretty consistent interface).

 my Thingy $foo .=from($thing);

my Thingy $foo = eval($thing.perl);

 The Interpolate role's method would return the pretty-printed,
 possibly LOSSY presentation of the object's information.

Uhuh, which is a flawed concept, because whose to decide what should
be lost? why does the perl prelude have to decide what's valueable
and what can be lost during *stringification or interpolation* now,
when this language is supposed to live for another 20 years?

 For example:
 
 my $color = new HTML::Color(magenta);
 if $color.as(Str) eq '#FF00FF' and $color eq magenta {
   $Ashley++;
 }

$color.hex_triplet; # no alpha
$color.name; # if we have one... or we can try to make one up (#ff0033 is 
bluish red ;-)

I see no reason why these two should behave in anyway, except that
one of them is the canonical format. There is no mnemonic device
whatsoever to link interpolation to color naming, and
stringification to hexadecimal representation.

Why isn't the str method (255,0,255)? Why isn't interpolation more
expressive and Dwimmy?

 So, to summarize, I want .as(Str) to be the lossless canonical
 representation, as well as the basis for the default .hash method,
 while Interpolate would be the pretty-printed localized lossy
 presentation Role.

For localization we need another thing. I propose a new prefix
operator, with some funny char we haven't used yet. It would be a
part of the Localizable role, and it would return a Str.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me supports the ASCII Ribbon Campaign: neeyah!!!



pgpbuSYDHJ9p9.pgp
Description: PGP signature


Re: Exceptuations

2005-09-25 Thread Yuval Kogman
On Sun, Sep 25, 2005 at 11:32:54 -0600, Luke Palmer wrote:

 Exactly which exception is continued?
...
 This comes up again with open().  So it's somewhere in between.
 Where?

For the open() example I don't have a solution but I know in what
direction to throw it: the same thing that makes croak appear to
work from the caller =)

Several things come to mind... First is this: (ugly)

sub open {
...
CATCH { fail $! }; # force it to go up
}

This is the most flexible, but also the crudest method.

Another idea is to use the same namespace hopping logic that Carp
does right now. This doesn't work for exceptions in the same class
so it should be optional and off by default... Perhaps:

fail error :package_boundry; # better word needed

Another idea is to use a lexical pragme that delays all errors,
which is like CATCH { fail $! } but more declarative:

sub open {
use fatal propagate;
...
}

For when it isn't specified, when doing evil things such as stepping
into the continuation of an exception, we assume that the code doing
the CATCH knows about the code that raised the exception at least
something.

Encapsulation is sort of maintained by specifying what kinds of
operations are fixed.. For example, errors having to do with opening
files are fixuppable by taking the arguments to open found in the
exception, and trying to reopen the file after some fudging, and
returning a handle. This is common knowlege about the interface of
open, and we are simply saying that for the rest of the dynamic
scope (dangerous, perhaps) we are trying to fixup every call to open
that fails with this handler.

This is no different than catching that exception in terms of
encapsulation, except that the failure is defatalized. My claim is
that just as you know the kind of error it is when you explicitly
catch it for the purpose of reporting, you have the same knowlege
when you are fixing.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me sushi-spin-kicks : neeyah



pgpCOTXugoPT2.pgp
Description: PGP signature


Re: Allomopherencing

2005-09-25 Thread Yuval Kogman
On Sun, Sep 25, 2005 at 11:24:05 -0700, Ashley Winters wrote:
 I can't accept that. While you can infer that $dog will be a Dog at
 that line of code, it isn't being enforced, which means no
 compile-time error. $dog is allowed to store any kind of data, and you
 only know what methods exist in Dog at compile-time. After all, I was
 planning to add a Dog::as(Cat) method at runtime. Yes, I'm a mad
 scientist. Muahahaha!!!

If you say

my $pet = Dog.new;

if ($condition) {
$pet = Cat.new;
}

my Car $spot = $pet;

Then $pet's type is inferred to Cat|Dog, and must be able to contain
either of those, but that is still not a Car.

I'm assuming under use optimize where everything is closed.;

 In order to enforce that level of compile-time type safely, you should
 need to declare my Dog $dog, or stick a pragma up top:

That's the point of my question - why? What do I lose by
inferrencing?

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me climbs a brick wall with his fingers: neeyah!



pgpEkBSPIsL67.pgp
Description: PGP signature


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Ashley Winters
On 9/25/05, Yuval Kogman [EMAIL PROTECTED] wrote:
 On Sun, Sep 25, 2005 at 10:59:38 -0700, Ashley Winters wrote:

  The Stringification of a UnixEpochTimestamp should probably be the
  same as its Integerization -- 12345678900. However, the Interpolation
  of it should be the locale-specific POSIX-style datetime string.

 Why? What value does the stringification of a date have as a
 stringified integer? If we were to implement such semantics,
 wouldn't it be wiser to print The time in seconds since the epoch
 is { +$time }? That's much more readable, obvious and
 nonsurprising, without being overly long or tedious.

It's not a Date, it's a UnixEpochTimestamp. I'm choosing my classes
for maximum expositive effect, and in this case a UnixEpochTimestamp
is explicitly defined as number-of-non-leap-seconds-since-1970. You
probably need to either .strftime(), .posix_localtime(),
posix_gmtime() or .as(Perl6::Time) to get a proper formatting.

  Here's how I would do it if $Ashley == any(@Larry)

 You mean eqv.. =(

Ouch. You're right, but that's a painful adjustment.

  The .as(Str) of an object would be its serialization

 as is formatting, not serialization:

 $time.as('%d');

 or something... I don't really know how this works

 For serialization you have the .perl method, which is roughly the
 same as Data::Dumper (code to be evaled), or some more heavy duty
 package (i expect Storable to have a pretty consistent interface).

Yes, .perl, .json, .xml, .repr, whatever.


  my Thingy $foo .=from($thing);

 my Thingy $foo = eval($thing.perl);

This should really really really be discouraged and/or prevented. This
will be a Perl6 Worst Practice in short order. Please, consider:

my Thingy $foo = eval:data $thing.perl or eval:json $thing.json or
eval:xml $thig.xml

eval() itself feels like the wrong function for doing this. I'm trying
to parse(), not eval().

But, I digress...

  The Interpolate role's method would return the pretty-printed,
  possibly LOSSY presentation of the object's information.

 Uhuh, which is a flawed concept, because whose to decide what should
 be lost? why does the perl prelude have to decide what's valueable
 and what can be lost during *stringification or interpolation* now,
 when this language is supposed to live for another 20 years?

In Perl5, stringified NVs are only printed to however many digits Perl
thinks are worth printing. At the extreme range, it decides to print
with scientific notation. That is done for the convenience for
interpolation into an output string -- the real decimal representation
could be 0.002378462387462341220983458672348961234

I'm not necessarily arguing this is the right or the best dividing
line, but I'm saying a line can be drawn if we want.

  For example:
 
  my $color = new HTML::Color(magenta);
  if $color.as(Str) eq '#FF00FF' and $color eq magenta {
$Ashley++;
  }

 $color.hex_triplet; # no alpha
 $color.name; # if we have one... or we can try to make one up (#ff0033 is 
 bluish red ;-)

 I see no reason why these two should behave in anyway, except that
 one of them is the canonical format. There is no mnemonic device
 whatsoever to link interpolation to color naming, and
 stringification to hexadecimal representation.

 Why isn't the str method (255,0,255)? Why isn't interpolation more
 expressive and Dwimmy?

I chose this class for expositive purposes as well. It's the canonical
representation of a color in HTML -- 6 digit hex. The DWIM factor
comes from printing what the object thinks its own value is. A
UnixEpochTimestamp thinks of itself as seconds-since-1970. An HTML
color thinks of itself as whatever you passed to its constructor,
whether that was #A4c or MaGeNtA or #ff

say The Unix Epoch Timestamp is $time -- The Unix Epoch Timestamp
is 1234567890
say The HTML Color is $color -- The HTML Color is magenta


  So, to summarize, I want .as(Str) to be the lossless canonical
  representation, as well as the basis for the default .hash method,
  while Interpolate would be the pretty-printed localized lossy
  presentation Role.

 For localization we need another thing. I propose a new prefix
 operator, with some funny char we haven't used yet. It would be a
 part of the Localizable role, and it would return a Str.

I'm not attached to the name or the function. I want something for
presentation that's different from representation that's different
from serialization and I want them to be easy and safe, and I want to
know which one will be used to hash my object by default. :)

Ashley Winters


matching colors (was Stringification, numification, and booleanification of pairs)

2005-09-25 Thread Juerd
Yuval Kogman skribis 2005-09-25 21:34 (+0300):
  if $color.as(Str) eq '#FF00FF' and $color eq magenta {
$Ashley++;
  }
 $color.hex_triplet; # no alpha
 $color.name; # if we have one... or we can try to make one up (#ff0033 is 
 bluish red ;-)

We can do better than equivalence testing for colors. Instead, try to
match. Surely a *smart* match operator really is smart? 

$color ~~ '#FF00FF'
   ==
$color ~~ 'magenta' 
   == 
$color ~~ [ 255, 0, 255 ]


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


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Juerd
Ashley Winters skribis 2005-09-25 12:26 (-0700):
 It's not a Date, it's a UnixEpochTimestamp. 

That is precisely the flaw. Are you honestly likely to have that class? 

If you really need an unix epoch timestamp, wouldn't you just use a very
simple integer for that? Because that's what it *is*, by definition. Not
an object.

And having an epoch timestamp stringify (or interpolate, which as far as
I will accept leads to stringification) as anything other than what it
is, an integer, is pure nonsense.

   my Thingy $foo .=from($thing);
  my Thingy $foo = eval($thing.perl);
 eval() itself feels like the wrong function for doing this. I'm trying
 to parse(), not eval().

Neither names are good. Parsing isn't the only thing you want to do, and
eval is for executable code that is in a string, not for serialized data.

I suggest that we keep data and code separate and use thaw and eval
respectively. Also, this means that .perl shouldn't be used for storing
objects, at most it should be used for demonstration and debugging.
Let's not forget freeze.

Objects are both code and data, and thus hard. We may have to consider
it all code.

 say The Unix Epoch Timestamp is $time -- The Unix Epoch Timestamp
 is 1234567890

I thought you wanted it to interpolate as a well formatted,
human-readable date? Don't you mean `~ $time` here? Wow, separating
stringification and interpolation really IS confusing!


It is NOT TRUE that strings with variables interpolated are always for
presentation.

It is NOT TRUE that uninterpolated strings are always for storage.

Both can be used either way, and in practice are used both ways.


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


Re: matching colors (was Stringification, numification, and booleanification of pairs)

2005-09-25 Thread Luke Palmer
On 9/25/05, Juerd [EMAIL PROTECTED] wrote:
 We can do better than equivalence testing for colors. Instead, try to
 match. Surely a *smart* match operator really is smart?

 $color ~~ '#FF00FF'
==
 $color ~~ 'magenta'
==
 $color ~~ [ 255, 0, 255 ]

Hmm.  That violates my proposal that the right side is the thing that
determines how the left side is matched.  So there's something wrong
with one of the two...

If we keep my proposal, then we get:

$color ~~ color('#FF00FF')
$color ~~ color('magenta')

etc., for some definition of color().   In fact, that's probably the
right thing to do, is to make color a pattern constructor.  Then you
can even put it in signatures:

   sub name(color('#FF00FF')) { magenta }

Whatever that buys you

If we ditch my proposal, then we can write it as you did.  But I feel
uncomfortable with that (thus the proposal), since you never know how
people may have overloaded ~~ for dwimminess, and when you say:

sub print_colored ($color, $text) {
$color = do given $color {
when 'red'   { Color.new('#FF') }
when 'green' { Color.new('#00FF00') }
when Color   { $color }
default  { fail Unknown color }
}
}

Though in this case it's not much of an issue, unless the red pattern
matches /#../ or something, in which case you are losing
granularity.  I guess the reason it makes me uncomfortable is that old
obsession of mine where things that look orthogonal ought to be, like
'red' (a string) and Color (a class).

Then again, would one expect:

$foo ~~ 'bar'

To be equivalent to:

~$foo eq 'bar'

Or not?  I mean, that can be the string pattern's job, but then 'red'
and Color aren't really equivalent anymore.

/me punts patterns until he understands more.

Luke


Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Mark Overmeer
* wolverian ([EMAIL PROTECTED]) [050925 11:57]:
 On Sun, Sep 25, 2005 at 12:52:08PM +0200, Juerd wrote:
  Hackers on this list, what do you think?
 
 I think separating the two is extremely confusing. I do not see any uses
 for it, but maybe I am not thinking hard enough. 

Of course, having  $thing.'x'  produce something else than $thing.'x'
is very confusion, however, they have a different purpose:

Stringification/Numification should be used to let an object play its
natural role within the program.  For instance, some Temperature
object producing 273 when compared to the melting point of water.

Interpolation should be used on places where output is generated, where
the outside consumer has less knowledge about the internals.  Like 273'C
for the same Temperature object.  Sorry, my program uses Celcius ;-)

I like to have this behavior.

The question is: will the two different uses be visible enough that
the average programmer will understand it after a while, or will this
become one of those nasty dark corners of the language which no-one
dares to touch?  The more constructs (like pairs, junctions, and hashes)
produce different results for both cases, the better the choice for
distinction is, because people get aware of it without reading a book.
-- 
   MarkOv


   Mark Overmeer MScMARKOV Solutions
   [EMAIL PROTECTED]  [EMAIL PROTECTED]
http://Mark.Overmeer.net   http://solutions.overmeer.net



Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Juerd
Mark Overmeer skribis 2005-09-25 17:28 (+0200):
 Stringification/Numification should be used to let an object play its
 natural role within the program.

Agreed, but...

 For instance, some Temperature object producing 273 when compared to
 the melting point of water.

That's for numeric context, in which it will do this. It doesn't say
much (or anything) about strings.

For a temperature, it happens to make sense to use the number for
stringification as well, because we humans are used to numbers for
temperatures.

I think more abstract types are more interesting, when it comes to how
they behave as strings and in string literals (which I think should be
exactly the same).

I think that indeed arrays, hashes and pairs are great objects of this
discussion. Pairs in much lesser extent, because what they should do in
any scalar context is still under discussion: evaluate to the .value,
propagating context, or evaluate to something that has to do with the
pair itself. For the record, I prefer the latter, for several reasons.

Arrays and hashes as numbers evaluate to their number of elements. This
is terribly useful. Arrays and hashes as further unspecified scalars
evaluate to references to themselves. This too is very useful indeed,
especially because we also have automatic dereferencing nowadays.

In string context, an array evaluates to its stringified elements joined
by whitespace. This is possibly lossy, because the elements may contain
spaces as well. It doesn't make sense to me to make it behave any
differently in string context than in interpolation. Or, as I really do
prefer to put it: to have items in non-string context when they're
interpolated. A part of a string is a string, and we shouldn't
differentiate between it being part of a string that was built in
pieces and it being part of a string that was built as a whole, a string
literal.

 Interpolation should be used on places where output is generated, where
 the outside consumer has less knowledge about the internals.  Like 273'C
 for the same Temperature object.  Sorry, my program uses Celcius ;-)

Sure, including the unit does make sense. Still, how you built the
complete string for the end user shouldn't determine how the object is
stringified.

Whether I use

say t= ~ $temperature;

or

say t=, $temperature;

or

say t=$temperature;

it is all presentation to the human. I don't want to be told that for
telling things to humans, I must use interpolation. Mostly, because most
of the time I don't (I pass the value to a templating thing (and I don't
want to have to care about HOW that uses the value later on), and often
I use printf). 

 I like to have this behavior.

You're not commenting on the difference between using it as a string and
using it as an interpolated value, though. Your example compares numeric
use to string use, and indeed those should be different.

This thread is about strings only, and would your temperature ever make
sense as both one form of string and another? In other words, what would

say $temp;

print, and what would

say $temp;

print instead? And to conclude it, what would you want

say get_temperature();

to print? Are you willing to have this big difference between this and

say { get_temperature() };


(Still assuming we won't have auto freezing and auto thawing in much
the same way we will have auto referencing and auto dereferencing,
because I'd like those operations to be very clear and explicit.)

 The more constructs (like pairs, junctions, and hashes) produce
 different results for both cases, the better the choice for
 distinction is, because people get aware of it without reading a book.

Yes, if things are different, they should be really different.

For this reason I want ~$foo and +$foo be different where something
making sense can be thought of and implemented without much effort, and
pairs to evaluate to something OTHER than their values (they're not
aliases, and this is most evident with \$pair, which shouldn't be in any
way like \$pair.value, and in $pair, which shouldn't be in any way
different from ~$pair.)


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


numification and stringification of objects

2005-09-25 Thread Juerd
Whenever possible, object should have useful numeric and string
representations. These are generally lossy, but this is not a problem, because
a scalar stays a scalar even after being used in a certain context, and the
object isn't lost.

When a protocol or data format that already has a string format is represented
as an object, it should of course evaluate to its common string form when used
in string context. Good examples of this can be found in the LWP package.

Class   Num   Str

HTTP::Headers   number of headers Foo: bar{crlf}Bar: baz{crlf}
HTTP::Status200   HTTP/1.1 200 OK
HTTP::Date  universal epochtime   Sun, 06 Nov 1994 08:49:37 GMT   
 
HTML::Form  number of elementsform ../form

One must be careful NOT to pick a certain numification or stringification just
because a certain number or string found in the object will be useful. For code
to be understandable, the numification or stringification must really BE what
the object represents. Again, LWP provides good examples.

Class   Num   Str

HTTP::Request   - GET / HTTP/1.1{crlf}...
LWP::UserAgent  - -

There's no single obvious meaningful number that represents HTTP::Request, but
a careless designer could try and guess that people would be interested in the
HTTP version number, the number of headers, or the number of bytes in the body.
It should therefor produce a warning when it's used in numeric context. What it
returns, is mostly irrelevant but I'd go as far as returning a random number,
just to avoid that people actually do this. (This is no problem. Compare it to
Perl 5's habit of returning the memory address.) There is, however, a good
string representation of an HTTP message. Whether or not this includes the body
is irrelevant at this point, but if it's know, it probably should. It can
hopefully do so lazily.

An UserAgent object has no single obvious meaningful number that it represents,
and it's hard to express a machine as a string too. Still, someone who feels a
need to use every feature that Perl provides, might use the number of requests
and the last requested URL, thinking these would be very popular. In a good
design, it shouldn't be a number or a string at all, because it would lead to
non-obvious code and would require a comment or diving into documentation, and
then an explicit method name serves both ease of programming and readability
much better.

However, I do think there should be some kind of useful stringification for ALL
objects, because objects are often printed for debugging purposes. But I
suggest that this be a global method that all objects implicitly inherit from,
and not be defined in the object itself. This helps to make all these
stringified-for-debugging strings look the same (one programmer could for
example perhaps implement a coloured scheme) and to enable us to make using
them fatal. Because every object may have its own attributes or even other
calculations that will be useful for debugging, there must be a way to specify
which ones are used. I think a simple method that returns a string is most
appropriate. 

One example of what this debugging output could be is:

{ LWP::UserAgent(aen3kx) }

aen3kx being the id of the object, and {} being simple delimiters to visually
group. Another example, this time with some attributes that a certain method in
LWP::UserAgent told Perl to use:

{ LWP::UserAgent(c23hee) libwww-perl/6.00; 200 }

Or, for example a database connection object:

{ DBI(938eo) connected; dbi:SQLite:foo.db; in transaction }

But, as arrays do have a useful way to be represented as a string:

element1 element2 element3

and not { Array(123abc) }.

It's all very Perl 5-y, and that's because that is a good way to do it: the
default is useful for debugging, but you can specify different stringification
in case there's an obvious way to stringify. It just gets much less scary to
actually do override stringification.

In any case, I do think that everything should be explicitly fetchable as well
as implicitly. This means that I want .as_html, and not just the HTML::Element
in string context. The debugging info mentioned above could be .as_debug, for
example, and then we could get { Array(123abc) 0..15 contiguous } from an Array
object. I personally like to work without the as_ prefix, so that I get
.celcius and .html instead of .as_celcius and .as_html.

Always, string context should be primarily concerned with use, not debugging or
storage (serialization). Whether this use is for presentation to the user,
sending over a wire or storage, the object can't and shouldn't know. It should
have one that is most important and very obviously connected to the object, and
that one should be used in all stringification. Most objects won't ever need to
be presented to the user, and others won't be part of a protocol. In fact, I

Re: Stringification, numification, and booleanification of pairs

2005-09-25 Thread Mark A. Biggar
In a private conversation with Larry this afternoon, he said that by 
default $foo and ~$foo and $foo.as(Str) all give the same result 
(assuming scalar context, etc.).  And that @foo[] and [EMAIL PROTECTED] and 
@foo.as(Str) are the same as join(' ', @foo) where join is effectively:


sub join(Str $x is rw, @A) {
my Str $y = '';
for $z - (@A) {
$y ~= ~$z;
} continue {
$y ~= $x:
}
return $y;
}

Also that a pair ($x = $y) stringifies to $x\t$y and that [EMAIL PROTECTED] for an 
array of pairs is the same as join(\n, @A);


It is also intended that .as(Str, ...) takes extra named args (names 
TDB) for things like separators and sprintf like format strings so you 
can customize it, including ways to change the defaults for a class 
(like the separator for arrays of pairs being \n instead of ' ').


--
[EMAIL PROTECTED]
[EMAIL PROTECTED]