Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Stringification, numification, and booleanification of pairs

13 views
Skip to first unread message

Ingo Blechschmidt

unread,
Sep 21, 2005, 10:47:22 AM9/21/05
to perl6-l...@perl.org
Hi,

quick questions:

my $pair = (a => 42);
say ~$pair; # "a\t42"? "a\t42\n"? "a 42"?
say +$pair; # 0 (pairs aren't numbers)?
# 42?
# 0 ("a" is not a number)?
# 0 (~$pair can't be used as a number)?
say ?$pair; # true (because 42 is true)?
# true (because pairs are always true)?

FWIW, I'd opt for ~$pair to be "a\t42", +$pair to be +(~$pair) [1],
and ?$pair to be always true.


--Ingo

[1] The numification of match objects used to *not* be the numification
of their stringification, causing confusion, see
http://tinyurl.com/asocc.

Juerd

unread,
Sep 21, 2005, 11:13:51 AM9/21/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt skribis 2005-09-21 14:47 (+0000):

> my $pair = (a => 42);
> say ~$pair; # "a\t42"? "a\t42\n"? "a 42"?
> say +$pair; # 0 (pairs aren't numbers)?
> # 42?
> # 0 ("a" is not a number)?
> # 0 (~$pair can't be used as a number)?
> say ?$pair; # true (because 42 is true)?
> # true (because pairs are always true)?
> FWIW, I'd opt for ~$pair to be "a\t42", +$pair to be +(~$pair) [1],
> and ?$pair to be always true.

Pairs are objects, thus references.

I like your suggestions for ~$pair (though any separator except other \s
characters would do) and ?$pair.

I don't think +(~$pair) makes any sense, though. It's basically the same
as +(~$pair.key). It's probably wise to avoid that $pair can be confused
for its key or value. A good alternative is hard to find, though. I tend
to prefer 1 at this moment (coincidentally, that's +?$pair).


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

Eric

unread,
Sep 21, 2005, 6:46:03 PM9/21/05
to Juerd, Ingo Blechschmidt, perl6-l...@perl.org
Hey,

Since you wouldn't expect an object to stringify or numify why expect pairs
to? I'm not sure i see any value in thatm, $pair.perl.say would be the best
way to output one anyway.


my $pair1 = (a => 2);
my $pari2 = (b => 3);
say $pair1 + $par2; # Error: illegal stringification of pair.?

I know nothing, but couldn't users create there own pair class that does
what they want? Or extend the builting one to override operators they way
they want?

Just my 2 cents.

--
__________
Eric Hodges

Juerd

unread,
Sep 21, 2005, 6:56:01 PM9/21/05
to Eric, Ingo Blechschmidt, perl6-l...@perl.org
Eric skribis 2005-09-21 16:46 (-0600):
> Since you wouldn't expect an object to stringify or numify [...]

Oh? I would in fact expect many objects to stringify or numify to useful
values. Just like I expect an array reference to stringify as if it was
an array, I expect an HTTP header object to stringify as an actual HTTP
header.

By the way, is it really this simple?

class HTTP::Header is Pair {
foo {
"{.key}: {.value ~~ s/\n/\n /g}"
}
}

Where "foo" is whatever is needed to override stringification.

I am assuming that s/// does not mutate, because mutation isn't
something I think a smart *match* operator should do. (To be honest, I
don't think s/// and ~~ should belong together.) How does this actually
work?

Also, it'd be nice to be able to say s/^^/ /g, but have it skip the
first. There's :2nd, but is there also something like :(2...)th?

> On 9/21/05, Juerd <ju...@convolution.nl> wrote:

Please reply properly: below quotation (not above), per subject
(usually: per paragraph), and stripping useless junk like signatures.

> --

Speaking of signatures... Instruct your mailer to use sigdashes, that
is: dash, dash, space. Without the space, it's not special, and not
recognised automatically by the many mailers that are capable of
recognising sigdashes.

Stuart Cook

unread,
Sep 21, 2005, 8:20:10 PM9/21/05
to perl6-l...@perl.org
On 22/09/05, Juerd <ju...@convolution.nl> wrote:
> By the way, is it really this simple?
>
> class HTTP::Header is Pair {
> foo {
> "{.key}: {.value ~~ s/\n/\n /g}"
> }
> }
>
> Where "foo" is whatever is needed to override stringification.

Something along the lines of `method prefix:<~>`, IIRC.


> I am assuming that s/// does not mutate, because mutation isn't
> something I think a smart *match* operator should do. (To be honest, I
> don't think s/// and ~~ should belong together.) How does this actually
> work?

This always bugged me as well. I think it currently still mutates (for
culture-backwards-compatibility reasons), but I do think the match
operator needs to be distinguished from the substitute/translate
operator. We also need to be able to choose between copying and
mutation. In my view, smart-match (~~) should be first and foremost
about returning a meaningful boolifiable value.

(If people want to discuss it further it's probably best to start a new thread.)


> Also, it'd be nice to be able to say s/^^/ /g, but have it skip the
> first. There's :2nd, but is there also something like :(2...)th?

S05 has:
# Lists and junctions are allowed: :nth(1|2|3|5|8|13|21|34|55|89).

So I assume :nth(2...) would work as expected.

Oh, and remember to start putting your `:g`s at the start of the
substitution/rule :-)


Stuart

Stuart Cook

unread,
Sep 21, 2005, 8:39:36 PM9/21/05
to perl6-l...@perl.org
On 22/09/05, Juerd <ju...@convolution.nl> wrote:
> I don't think +(~$pair) makes any sense, though. It's basically the same
> as +(~$pair.key). It's probably wise to avoid that $pair can be confused
> for its key or value. A good alternative is hard to find, though. I tend
> to prefer 1 at this moment (coincidentally, that's +?$pair).

While having stringification on everything is quite useful (for
debugging dumps, if nothing else), I'm wary of giving numification
behaviour to objects that simply can't produce a meaningful value.

If there's no (single) obvious interpretation of "turn a value into a
number" for a particular type, then don't struggle to come up with a
non-obvious one--I say just leave it undefined, or have it fail(), or
whatever.

Otherwise, if someone just says to himself "I think a pair is a
collection of two elements, so it will obviously numify to 2" and then
unknowingly gets `1` back, things can get confusing *real* quick.


Stuart

Mark A. Biggar

unread,
Sep 21, 2005, 8:44:39 PM9/21/05
to Eric, Juerd, Ingo Blechschmidt, perl6-l...@perl.org
Eric wrote:
> Hey,
>
> Since you wouldn't expect an object to stringify or numify why expect pairs
> to? I'm not sure i see any value in thatm, $pair.perl.say would be the best
> way to output one anyway.
>
> my $pair1 = (a => 2);
> my $pari2 = (b => 3);
> say $pair1 + $par2; # Error: illegal stringification of pair.?
>
> I know nothing, but couldn't users create there own pair class that does
> what they want? Or extend the builting one to override operators they way
> they want?

Actually I do except some object to stringify or numify. For example en
object of type date should stringify to something like "January 1, 2000"
and also to numify to the Julian day number.

Now for a related question: is it intended that ~$x and +$n be the same
as $x.as(Str) and $x.as(Num)? How locked in stone would this be, I.e.,
~ and + are macros that give the .as() form?

--
ma...@biggar.org
mark.a...@comcast.net

Juerd

unread,
Sep 22, 2005, 3:42:23 AM9/22/05
to Mark A. Biggar, perl6-l...@perl.org
Mark A. Biggar skribis 2005-09-21 17:44 (-0700):

> Now for a related question: is it intended that ~$x and +$n be the same
> as $x.as(Str) and $x.as(Num)? How locked in stone would this be, I.e.,
> ~ and + are macros that give the .as() form?

If I read everything correctly, this is the case.

This is also why I'm not sure stringification is done by a prefix:<~>
method -- it's probably done by something that does coercion in general,
but I have no idea what the syntax for that would be.

Juerd

unread,
Sep 22, 2005, 3:45:12 AM9/22/05
to Stuart Cook, perl6-l...@perl.org
Stuart Cook skribis 2005-09-22 10:39 (+1000):

> If there's no (single) obvious interpretation of "turn a value into a
> number" for a particular type, then don't struggle to come up with a
> non-obvious one--I say just leave it undefined, or have it fail(), or
> whatever.

Leaving it undefined is wrong whenever it can be avoided. Iff it has no
meaningful value, then we should try and make it meaningful in the scope
of the other two.

~$pair, because it has a \t in it, will always be true booleanly, and so
will ?$pair off course. Because of this, I think that ?+$pair should
also be true.

Damian Conway

unread,
Sep 21, 2005, 7:37:41 PM9/21/05
to perl6-l...@perl.org
Eric wrote:

> Since you wouldn't expect an object to stringify or numify...

You wouldn't??! I certainly would.

Object references already stringify/numerify/boolify in Perl 5. Unfortunately,
they do so with problematic default behaviours, which is why C<use overload>
allows you to overload q{""}, q{0+} and q{bool} (a practice I strongly
recommend in "Perl Best Practices").

Finding useful and predictable defaults for the basic coercions on all
built-in types is a vital part of the design of Perl 6.

Damian


Damian Conway

unread,
Sep 21, 2005, 6:20:42 PM9/21/05
to perl6-l...@perl.org
Ingo Blechschmidt asked:

> my $pair = (a => 42);
> say ~$pair; # "a\t42"? "a\t42\n"? "a 42"?

Not yet specified but I believe it should be "42" (i.e. stringifies to value).

Note that S02 does specify that pairs *interpolate* to key-tab-val-newline,
so you can still get "a\t42\n" by writing "$pair" instead.


> say +$pair; # 0 (pairs aren't numbers)?
> # 42?
> # 0 ("a" is not a number)?
> # 0 (~$pair can't be used as a number)?

Not yet specified, but I believe it should be 42 (i.e. numerifies to the value)


> say ?$pair; # true (because 42 is true)?
> # true (because pairs are always true)?

Not yet specified but I believe it should be true because 42 is true

In summary: when applied to a pair, the value-coercing operators should coerce
the pair's value.

Damian

Juerd

unread,
Sep 22, 2005, 7:57:08 AM9/22/05
to Damian Conway, perl6-l...@perl.org
Damian Conway skribis 2005-09-22 8:20 (+1000):

> Note that S02 does specify that pairs *interpolate* to
> key-tab-val-newline, so you can still get "a\t42\n" by writing "$pair"
> instead.

I think separating stringification and interpolation leads to
unpredictability, and is a very bad thing.

Yuval Kogman

unread,
Sep 22, 2005, 11:47:26 AM9/22/05
to Damian Conway, perl6-l...@perl.org
On Thu, Sep 22, 2005 at 08:20:42 +1000, Damian Conway wrote:
> Ingo Blechschmidt asked:
>
> > my $pair = (a => 42);
> > say ~$pair; # "a\t42"? "a\t42\n"? "a 42"?
>
> Not yet specified but I believe it should be "42" (i.e. stringifies to value).
>
> Note that S02 does specify that pairs *interpolate* to key-tab-val-newline,
> so you can still get "a\t42\n" by writing "$pair" instead.

Can we override &circumfix:<" ">?

Seriously though, this is too much dichotomy between correctness and
ease of use.

A pair is not it's value, it is a pair, and should be consistently
handled as such when e.g. stringifying.

The reasons for this claim are:

* Coercion to a string creates something interpolatable.
Introducing another type or context or metaphor for string
handling is counter intuitive and surprising.

* We have powerful facilities for interpolation and
stringification that don't have to be hidden behind operator
overloading:

"this is my special pair: $pair";
"otherwise: $pair.key -> $pair.value";
my multi &prefix:<~> (Pair $p) {
"key: $p.key, value: $key.value";
}
"not like the first interpolation: $pair";
$pair.as(...);

These examples are flexible, explicit and stable in their
behavior. They are good enough as they are and don't need to be
"improved" by adding flexibility in something that is almost a
special case.

* This adds complexity without much benefit. It heaps up the core
with a special case that people will have to look out for later,
and it hinders the usability of higher order functions by making
it harder for them to accept the stringiciation operator, for
instance.

This lessens Perl 6 stability and cleanliness into something
resembling Perl 5 with more builtin data types and operations

--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &
/\ kung foo master: /me whallops greyface with a fnord: neeyah!!!!!!!

Matt Fowles

unread,
Sep 22, 2005, 11:59:32 AM9/22/05
to Yuval Kogman, Damian Conway, perl6-l...@perl.org
Yuval~

Well said! I completely agree that string interpolation should be
handled exactly the same as stringification. I would like C< ("foo is
$foo of course") eq ("foo is " ~ $foo ~ " of course") > at all times.

Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-Stan Kelly-Bootle, The Devil's DP Dictionary

Damian Conway

unread,
Sep 22, 2005, 9:04:03 AM9/22/05
to perl6-l...@perl.org
Juerd wrote:

> I think separating stringification and interpolation leads to
> unpredictability, and is a very bad thing.

I disagree. I think it's likely that people will think of ~$val and +$val the
same way (i.e. as "coerce the value"), but that they will think of "$val"
quite differently (i.e. as "interpolate a useful string representation of the
entire value").

More importantly, as we have already seen with regexes, inconsistent
numerification and stringification is an even more serious problem.

Damian

Juerd

unread,
Sep 23, 2005, 6:08:37 AM9/23/05
to Damian Conway, perl6-l...@perl.org
Damian Conway skribis 2005-09-22 23:04 (+1000):

> I disagree. I think it's likely that people will think of ~$val and +$val
> the same way (i.e. as "coerce the value"), but that they will think of
> "$val" quite differently (i.e. as "interpolate a useful string
> representation of the entire value").

But will they also see "foo" ~ $bar as something different from
"foo$bar"? And what context does "foo{ $bar }" use?

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

Nathan Gray

unread,
Sep 22, 2005, 12:58:26 PM9/22/05
to Matt Fowles, Yuval Kogman, Damian Conway, perl6-l...@perl.org
On Thu, Sep 22, 2005 at 11:59:32AM -0400, Matt Fowles wrote:
> Well said! I completely agree that string interpolation should be
> handled exactly the same as stringification. I would like C< ("foo is
> $foo of course") eq ("foo is " ~ $foo ~ " of course") > at all times.

Yes.

S03 states:

Unary ~ now imposes a string context on its argument, and + imposes a
numeric context (as opposed to being a no-op in Perl 5). Along the
same lines, ? imposes a boolean context, and * imposes a list context.

That seems to indicate that ~$foo eq "$foo".

If however, you want $foo to interpolate to something else, you can do
that in several ways:

"hello { +$foo }"
"hello { $foo.as(...) }"

Or when concatenating:

"" ~ +$foo ~ ""
"" ~ $foo.as(...) ~ ""

-kolibrie

TSa

unread,
Sep 23, 2005, 9:42:22 AM9/23/05
to Juerd, Damian Conway, perl6-l...@perl.org
HaloO Juerd,

you wrote:
> Damian Conway skribis 2005-09-22 23:04 (+1000):
>
>>I disagree. I think it's likely that people will think of ~$val and +$val
>>the same way (i.e. as "coerce the value"), but that they will think of
>>"$val" quite differently (i.e. as "interpolate a useful string
>>representation of the entire value").

Aha, that to me implies three things

1) the circumfix operator " " has an arity >= 1 with the not yet
interpolated string beeing the only non-invocant parameter
(that is somewhat untrue because the string is sliced into
a list of strings of the stuff between the variable data
interleaved with links to the enteties what replaces it
---in other words there is a parser macro that converts "..."
to a call of a printf like multi dispatched on all the variables
and code literals mentioned in the string)

2) The arity > 1 part is dispatched according to SMD/MMD in effect
at the call site or according to the definition the compiler
knows about when compiling it. Question: which is it?

3) there's an arity == 1..Inf catch-all implementation that (eagerly?)
iterates the incoming arglist and invokes the stringification
prefix op ~ on them---these are of course dispatched as well

If that does not give enough rope the users have to switch from
operator " " to output formatters or whatever.


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

I might *not* be representative but nonetheless I try to explain what
I perceive. Sorry, if that is intimidating this list. And please tell
me if that is the case---thanks.

That beeing said here I come:

We have: "foo" ~ $bar
I see: a juxtaposition of two operators and an item,
all three separated by whitespace

At that point I start to wonder: "What do I know about these three things?"
And I guess the compiler does the same ;)


> "foo$bar"? And what context does "foo{ $bar }" use?

We have: "foo$bar"
I see: a single invocation of operator " " with a string and an item.
(In other words, a parametric string!)


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

I would call it late binding!
The decision what difference it makes is deferred :)

But I agree that the catch-all case from 3) above should
result in whatever you mean with "the value in Str context".
Actually, the outcome then still depends on what is bound lately
to the implicit, dispatched calls of prefix ~ and again I agree
that the default behaviour shouldn't have any surprises in store.
Or in yet another way: all the MTOWTDIs should yield the same
result unless the hooks on particular ways are bound to something
non-standard.

If you feel at unease with these multiple levels of lately bound
uncertainties when you write your code, then just put in more
type constraints. Unfortunately the enforcement level of such
contraints seems to be bound lately as well---and that puts me
at unease *before* I have even started writing Perl6 code =8)

<slighty off-topic>
What could $someone.sees($helicopter) mean?
Think e.g.

$someone := 'vietnamese child in the sixties';
$someone := 'insured person waiting for the rescue team';
$someone := 'paraglider flying high in the air';
$someone := your_pick();

Questions I pose myself while flying in

my TSa $helicopter;

through spacetime are for example:

Does the vietnamese child expect medical help?
How does the rescue team arrive? By car?
What sex does the paraglider have?
What type of action does the .sees method do
with my $helicopter, when invoked
on the return type of &your_pick?
Should I be carefull and allow only read access to my $helicopter?
What $word.does(German) yields a %dictionary<sees> lookup where
:key.does(English)?
</slightly off-topic>
--
$TSa.greeting := "HaloO"; # mind the echo!

Juerd

unread,
Sep 23, 2005, 9:48:59 AM9/23/05
to TSa, perl6-l...@perl.org
TSa skribis 2005-09-23 15:42 (+0200):

> 1) the circumfix operator " " has an arity >= 1

I think it's parsed, not having specific arity.

> We have: "foo" ~ $bar
> I see: a juxtaposition of two operators and an item,
> all three separated by whitespace

I can only hope you mean two items and one operator.

> At that point I start to wonder: "What do I know about these three things?"

> >"foo$bar"? And what context does "foo{ $bar }" use?


> We have: "foo$bar"
> I see: a single invocation of operator " " with a string and an item.

I see a shorter way to write "foo" ~ $bar, as implemented by the
circumfix "" operator.

> $TSa.greeting := "HaloO"; # mind the echo!

echo off

Mark Reed

unread,
Sep 23, 2005, 10:26:58 AM9/23/05
to Juerd, Damian Conway, perl6-l...@perl.org
On 2005-09-23 06:08, "Juerd" <ju...@convolution.nl> wrote:
> In my opinion, making the string value in interpolation different from
> the value in Str context is madness.

Hear, hear! I agree 100%. This is another place where we should move the
Rubyometer down rather than up, I think (to_s vs. to_str, anybody?).

TSa

unread,
Sep 23, 2005, 1:11:24 PM9/23/05
to perl6-l...@perl.org
Halo,

someone has switched off my echo ;)

Juerd wrote:
> TSa skribis 2005-09-23 15:42 (+0200):
>
>> 1) the circumfix operator " " has an arity >= 1
>
>
> I think it's parsed, not having specific arity.

Of course it's parsed, how else should it reach the semantic analyzer?
And I don't consider (arity >= 1) as a very specific constraint :)
Actually the subtyping rules should distinguish between optional and
required arity with the latter beeing more specific. But I've no idea
what distance quantification they should have such that e.g. 5 optionals
are outperformed by one required or whatever.


>> We have: "foo" ~ $bar
>> I see: a juxtaposition of two operators and an item,
>> all three separated by whitespace
>
>
> I can only hope you mean two items and one operator.

So, at last there is hope somewhere. But I fear I'm hopelessly
drowned in my own misconceptions and really meant two ops and an
item. But I hope---ahh hope again---that the optimizer boils down
the "foo" invocation to 'foo' at compile time. Which immediately
raises the question whether I consider ' ' as an operator or not :)
Do you?

OTOH, I think we agree that a "foo $bar" is parametric with respect
to $bar and as such requires some code to evaluate it? The same applies
to matches /foo.*/ which are backed by some code that is build from
the text between the //. And how is this creation process of a match
closure parameterizable other then giving the resulting code a parameter
from which a new closure is created at runtime? And why is this not the
case for string interpolation? To a certain extent I see these two
closure manipulations as inverse operations. Interpolation creates
strings while matching analyzes them. But they don't guarranty mutual
round-trip invariance.

So the only thing that the language specification has to define in|for
my eyes is a level of unspecificity that the return value of " "
shouldn't exceed. In other words it's forced to return a Str and
nothing less specific like a Value or an Item. And then my mind
transforms the "foo" ~ $bar perception of my eyes into the mental
typing Str ~ Item.


Just ranting again a bit of my difficulties of integrating junctions
into my mental picture. How many times do you expect foo and ~ in

"{foo}" ~ $bar

beeing called? Consider ($bar = 42) versus ($bar = any(1,2,3)).

In the latter case we expect the junctive value to contain something
like any( "{foo}" ~ 1, "{foo}" ~ 2, "{foo}" ~ 3 ), right? That might
interpolate "{foo}" once and call infix ~ three times, but what if
foo shall count the number of invocations of ~ on Ints? Not to mention
that the possibility of a junction in $bar means that it becomes a
potential postfix meta operator that swallows ~ and after analyzing
it as an infix operator reaches out---at runtime fully dynamic---and
pulls in the return value of "{foo}" three times, or perhaps calculates
it three times.
--

Juerd

unread,
Sep 23, 2005, 1:53:22 PM9/23/05
to TSa, perl6-l...@perl.org
TSa skribis 2005-09-23 19:11 (+0200):

> >> We have: "foo" ~ $bar
> >> I see: a juxtaposition of two operators and an item,
> >> all three separated by whitespace
> >I can only hope you mean two items and one operator.
> So, at last there is hope somewhere. But I fear I'm hopelessly
> drowned in my own misconceptions and really meant two ops and an
> item. But I hope---ahh hope again---that the optimizer boils down
> the "foo" invocation to 'foo' at compile time. Which immediately
> raises the question whether I consider ' ' as an operator or not :)

Ah, the "" operator. But still, "foo" as a whole is an item too. (The
entire expression is too, but I'm not considering that, for simplicity)

> OTOH, I think we agree that a "foo $bar" is parametric with respect
> to $bar and as such requires some code to evaluate it? The same applies
> to matches /foo.*/ which are backed by some code that is build from
> the text between the //. And how is this creation process of a match
> closure parameterizable other then giving the resulting code a parameter
> from which a new closure is created at runtime? And why is this not the
> case for string interpolation? To a certain extent I see these two
> closure manipulations as inverse operations. Interpolation creates
> strings while matching analyzes them. But they don't guarranty mutual
> round-trip invariance.

I have a hard time parsing this. Are you suggesting that interpolation
is somehow translated to a sub call like i("foo ", $bar)?

> Just ranting again a bit of my difficulties of integrating junctions
> into my mental picture. How many times do you expect foo and ~ in
> "{foo}" ~ $bar
> beeing called? Consider ($bar = 42) versus ($bar = any(1,2,3)).

Once. The foo is not part of the junction, so it is not changing in
different iterations of autothreading.

Consider:

sub foo { @_.join(":") }
my $bar = 2;
my $baz = foo($bar *= 2, 1|2|3);
say $bar;

The foo call line evaluates to:

my $baz = foo(4, 1) | foo(4, 2) | foo(4, 3);
# Except that the 4 is really $bar, the lvalue return value of *=

not to:

my $baz = foo($bar *= 2, 1) | foo($bar *= 2, 2) | foo($bar *= 2, 3);

So eventually, "4" is said, not "16", and there is no question of which
$bar *= 2 is evaluated first.

Damian Conway

unread,
Sep 23, 2005, 6:31:09 PM9/23/05
to perl6-l...@perl.org
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 "foo[@bar]baz\n";
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

Juerd

unread,
Sep 25, 2005, 6:52:08 AM9/25/05
to Damian Conway, perl6-l...@perl.org
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

unread,
Sep 25, 2005, 7:01:38 AM9/25/05
to perl6-l...@perl.org
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 "foo[@bar]baz\n";
> 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
string number join
scalar number 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.

Wolverian

unread,
Sep 25, 2005, 7:57:21 AM9/25/05
to perl6-l...@perl.org
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

Yuval Kogman

unread,
Sep 25, 2005, 8:44:32 AM9/25/05
to Juerd, Damian Conway, perl6-l...@perl.org
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 <nothi...@woobling.org> 0xEBD27418 perl hacker &

/\ kung foo master: /me groks YAML like the grasshopper: neeyah!!!!!!

Ashley Winters

unread,
Sep 25, 2005, 1:59:38 PM9/25/05
to perl6-l...@perl.org
On 9/25/05, Yuval Kogman <nothi...@woobling.org> 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

Yuval Kogman

unread,
Sep 25, 2005, 2:34:21 PM9/25/05
to Ashley Winters, perl6-l...@perl.org
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 <nothi...@woobling.org> 0xEBD27418 perl hacker &

/\ kung foo master: /me supports the ASCII Ribbon Campaign: neeyah!!!

Ashley Winters

unread,
Sep 25, 2005, 3:26:29 PM9/25/05
to perl6-l...@perl.org
On 9/25/05, Yuval Kogman <nothi...@woobling.org> 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.00000000000000000000002378462387462341220983458672348961234

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

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

Juerd

unread,
Sep 25, 2005, 3:47:53 PM9/25/05
to perl6-l...@perl.org
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

unread,
Sep 25, 2005, 7:28:52 PM9/25/05
to perl6-l...@perl.org
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.)

Mark Overmeer

unread,
Sep 25, 2005, 11:28:38 AM9/25/05
to perl6-l...@perl.org
* wolverian (wo...@sci.fi) [050925 11:57]:

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 MSc MARKOV Solutions
Ma...@Overmeer.net solu...@overmeer.net
http://Mark.Overmeer.net http://solutions.overmeer.net

Mark A. Biggar

unread,
Sep 25, 2005, 10:42:13 PM9/25/05
to perl6-l...@perl.org
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 ~@foo 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 ~@A 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 ' ').

--
ma...@biggar.org
mark.a...@comcast.net

Juerd

unread,
Sep 26, 2005, 4:42:22 AM9/26/05
to perl6-l...@perl.org
Mark A. Biggar skribis 2005-09-25 19:42 (-0700):

> 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 ~@foo and
> @foo.as(Str) are the same as join(' ', @foo) where join is effectively:

This news pleases me.

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

Did he happen to mention what would be done with mixed arrays? Or is
this "of pairs" not related to content, but to declaration, and thus "of
Pair"?

> 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 ' ').

Just the way I imagined it. Great!

0 new messages