Re: CALL-ME vs. Callable

2016-11-14 Thread Jon Lang
So what is the assuming method, and why is it in a callable role? What was
the logic behind that decision?

On Nov 14, 2016 1:38 PM, "Brandon Allbery"  wrote:

> This should probably have been cc-d to the list.
>
> Callable claims to be the thing we want. What it actually is, is a mix-in
> that adds the assuming method. I am not sure these can be conflated.
>
> Note that the current docs actually do claim it is what I want. This is
> because I first brought this up in IRC while the documentation for
> Callable was being written, and it got modified to match my then current
> musings because nobody who actually works on the spec was around. I had in
> fact specified that this was a "would be nice" but that I wasn't sure if it
> would actually work; I have since concluded that it likely won't, and needs
> to be a distinct role. Which is part of why I brought this up: the current
> doc does not match what currently happens, and may not actually be
> implementable without breaking the spec (that is, 6.d would have a
> fundamental conflict with 6.c over the meaning of Callable).
>
> On Mon, Nov 14, 2016 at 4:30 PM, Jon Lang  wrote:
>
>> Okay, let's go with that. What does Callable do, and why is it called
>> that?
>>
>> On Nov 14, 2016 1:09 PM, "Brandon Allbery"  wrote:
>>
>>>
>>> On Mon, Nov 14, 2016 at 3:42 PM, Aaron Sherman  wrote:
>>>
>>>> I do think, though that if the concern is really with "the 4 cases
>>>> when nqp hauls a CALL-ME out of its bowels" then that's what should be
>>>> addressed...
>>>>
>>>
>>> The main addressing of that is some kind of role to abstract it
>>> properly. I just think the current situation is bad and even if we come up
>>> with a name for the new role, it's still going to be confusing ("ok, why do
>>> we have both Callable and Invokable? ...uh wait, Callable means *what*
>>> exactly?").
>>>
>>>
>>> --
>>> brandon s allbery kf8nh   sine nomine
>>> associates
>>> allber...@gmail.com
>>> ballb...@sinenomine.net
>>> unix, openafs, kerberos, infrastructure, xmonad
>>> http://sinenomine.net
>>>
>>
>
>
> --
> brandon s allbery kf8nh   sine nomine
> associates
> allber...@gmail.com
> ballb...@sinenomine.net
> unix, openafs, kerberos, infrastructure, xmonad
> http://sinenomine.net
>


Re: Anonymous multi-subs

2015-06-24 Thread Jon Lang
On Wednesday, June 24, 2015, yary  wrote:

> Now that I've thought about it for 90 seconds (not fully-formed idea), if
> one were to have an anonymous multi-sub, it ought to be constructed from a
> list of *signature*, *body *pairs.
>
> And/or, any non-finalized sub could have a method to add another *signature,
> body* to its dispatch list.
>
> apologies if this discussion is already captured in a design doc, I am
> posting this without having read much of the past.
>

 Or, in the body, be able to examine the actual signature passed in and
decide what to do based on that,  That [i]could[/i] be done using a
given/when structure, which would be equivalent to a list of signature/body
pairs.


-- 
Jonathan "Dataweaver" Lang


Re: How to make a new operator.

2012-03-22 Thread Jon Lang
On Thu, Mar 22, 2012 at 9:07 AM, Bruce Gray  wrote:

> On Mar 21, 2012, at 11:49 PM, Jonathan Lang wrote:
>
>  What I want to know is whether there's a way to define a step function
>> that's based in part or in whole on the current term's index.  For example,
>> how would I use infix:<...> to generate the perfect squares between 0 and
>> 100?  Namely, '0,1,4,9,16,25,36,49,64,81,**100'.  For example, is Perl 6
>> set up to try to pass the current element's index into the step function by
>> means of a named parameter?
>>
>> I would hope for something like:
>>
>>  -> :index { $index * $index } ... 100
>>
>> or
>>
>>  1, *+:index ... * # 1,3,6,10,15,21,28,36,45,...
>>
>> (Note: I _don't_ expect the above to work as is; they're merely intended
>> to convey a rough idea of what I _do_ want.)
>>
>> If not, how _would_ I generate these lists?
>>
>
>
> In real life, you would just use this:
>   my @squares = map { $_ * $_ }, 0..10;
> or, for an infinite list, use a binding instead of an assignment:
>   my @squares := map { $_ * $_ }, 0..*;
>

True enough.


> But you were asking about ... specifically :^)
>

Yes, I was.


> On freenode/#perl6, I was pointed to part of the spec that I had
> overlooked.
> The "sequence operator" is defined in S03:
>   
> http://perlcabal.org/syn/S03.**html#List_infix_precedence
> Buried in its definition is this gem:
>   
> http://perlcabal.org/syn/S03.**html#line_1884
>   The function may also be slurpy (n-ary), in which case all
>   the preceding values are passed in (which means they must
>   all be cached by the operator, so performance may suffer,
>   and you may find yourself with a "space leak").
>

Interesting; it never occurred to me to try to retrieve the current index
by slurping in all of the previous elements and counting them.


> After writing all the above, it occurred to me that the use of @_ should
> implicitly define a closure as slurpy/n-ary. That would remove the need
> for the arrow, and make the code much less ugly.
> Also, the first value (0) might be unnecessary. The spec says that it
> should not be required when the closure is 0-ary, but I think that
> should also be true for slurpy/n-ary closures.
>

Agreed: starting values should only be mandatory when dealing with a step
function that definitely requires them.


> These work in Niecza:
>
>my @squares := { @_ ** 2 } ... *;
>

And this is rather elegant, syntactically (though not so much in the
performance department).

-- 
Jonathan "Dataweaver" Lang


Re: dimensionality in Perl 6

2010-11-18 Thread Jon Lang
Buddha Buck wrote:
> Jon Lang wrote:
>> Here's my proposal for how to handle dimensionality in Perl 6:
>>
>> Create a "units" trait that is designed to attach to any Numeric
>> object.  Dimensional information gets stored as a baggy object - that
>> is, something that  works just like a Bag, except that the count can
>> go negative.  (I don't know if the count should be a signed integer or
>> a Num; what happens in dimensional analysis when you try to take the
>> square root of two inches?)  Overload the Numeric operators to
>> properly track the units as well as performing their normal
>> activities.  Add one or two methods that allow you to easily extract
>> the raw number and/or the units.
>
> An added complication is "dimensionality".  ergs, joules, btu and eV
> are all units of energy, and it isn't unreasonable to want to add or
> subtract energies of different units (my house used (100 therm +
> 8000kWh) of energy last month, for example).  However, it is incorrect
> to add ergs and Newtons, since they are of different dimensionality.

Right.  And in the basic package, it would be the programmer's
responsibility to convert therms to kWh, or vice versa, before the
addition takes place.  And just like Perl 6 implements Instant without
reference to a specific calendar system, leaving that to be
implemented by appropriate modules, dimensionality would leave the
implementation of specific systems of measurement to appropriate
modules.

With that in mind, your further suggestions would work well for the
purpose of defining such a module:

> The more robust units/dimensional analysis packages I've seen might
> not allow one to add therms and kWh, but they do know that therms and
> kWh are both [ML^2/T^2],  I believe at the time I was looking at
> JScience's work on JSR-275.  In this setup, when units are registered,
> they are given a dimensionality (essentially, a "baggy" of
> dimensions), and values are given a "baggy" of units (and thus an
> implicit "baggy" of dimensions, the union of the dimensions of the
> units).

I was using "Baggy" to describe an as-yet-hypothetical role that is to
Bags and Sets as Numeric is to Num, Rat, Int, Complex, and so on.  The
actual type for units would probably best be called an "SBag", where
the S stands for "Signed" (meaning that its count can be negative as
well as positive).  That said, it might need to be a RatBag, or
possibly even a NumBag, if we want to leave open the possibility of
fractal dimensions.  Still, I'm thinking that an SBag would be good
enough to start with.

Your idea of having a registered unit be associated with an SBag of
dimensions (e.g., ML^2T^-2) would be good for allowing more
intelligent exceptions, and would cover what I was talking about in
terms of defining what kind of value a unit measures.

> I don't think a Num is necessary, but I could see a Rat.

As is, is Duration implemented by means of a Num, or a Rat?  Whichever
it is, that's the type that the difference of two Instances would
return (properly tagged with seconds, of course).

-- 
Jonathan "Dataweaver" Lang


Re: dimensionality in Perl 6

2010-11-18 Thread Jon Lang
On Thu, Nov 18, 2010 at 8:25 PM, Carl Mäsak  wrote:
> Jon (>):
>> Here's my proposal for how to handle dimensionality in Perl 6:
>>
>> [...]
>>
>> Thoughts?
>
> The idea has come up before, everyone thinks that Perl 6 and unit
> handling are a good fit for each other, and we're basically waiting
> for someone to write such a module. Incidentally, your phrase "a
> complication that we needn't deal with up front" is exactly why
> there's no pressing need to put this in Perl 6 "core" (fsvo "core").

I'm suggesting this because the recent thread about Duration indicates
to me that there _is_ a need to put at least a minimally-featured unit
handling system into the core, if for no other reason than to ensure
that Durations will be part of said system.  The trick is to come up
with something that's simple enough that including it in the core
won't unduly delay release of Perl 6, but robust enough that we can
build on it after release.

> See also the Physical::Unit example in a blog post of mine, for an
> example of how postfix ops can be used to mark the units:
>
>  

Nice.  "5 sec" definitely beats "5 but units" for legibility, and
would be a very nice way of generating Durations on the fly.

-- 
Jonathan "Dataweaver" Lang


dimensionality in Perl 6

2010-11-18 Thread Jon Lang
Here's my proposal for how to handle dimensionality in Perl 6:

Create a "units" trait that is designed to attach to any Numeric
object.  Dimensional information gets stored as a baggy object - that
is, something that  works just like a Bag, except that the count can
go negative.  (I don't know if the count should be a signed integer or
a Num; what happens in dimensional analysis when you try to take the
square root of two inches?)  Overload the Numeric operators to
properly track the units as well as performing their normal
activities.  Add one or two methods that allow you to easily extract
the raw number and/or the units.

For now, unit conversions are always handled manually, and the units
themselves are completely arbitrary   At some later date we might
consider adding a robust database of units and conversion rates; but
that's a complication that we needn't deal with up front.  Indeed, it
might work best as a module to be included by those who want the added
tools.  Regardless, such a module should not interfere in the ability
to use made-up units on the fly; instead, it should provide additional
details for units that have been properly registered (such as what
kind of value is being measured, which measurement system it's a part
of, what the conversion rates are, and what synonyms exist for it).
The goal should be to enhance, not restrict.

If this is implemented, Duration should be an alias for something to
the effect of "Num but units".  Otherwise, Instant and
Duration remain unchanged.

Thoughts?

-- 
Jonathan "Dataweaver" Lang


Re: exponentiation of Duration's

2010-11-17 Thread Jon Lang
Moritz Lenz wrote:
> Am 17.11.2010 17:50, schrieb Jon Lang:
>> More generally, I wonder if maybe we _should_ provide a tool to help
>
> I think this question can only be answered in a meaningful way if somebody
> actually implements such a thing as a module (which should be entirely
> possible in Rakudo right now). Then we'll see if people take it up and use
> it.
>
>> That said, it's possible that this would open up a can of worms.
>> Would it?
>
> Another reason to prototype it as a module.

Agreed.  I'll look into writing something up.  That said, I'm short on
time, so don't hold your breath waiting for me to do it.

I've been thinking about this some more: perhaps the dimensionality
feature, if included at all, should be done as a trait; e.g., "5
seconds" would be C< 5 but units("sec") >, or something to that
effect.  That way, you could easily add units to Num, Rat, Int,
Complex, or anything else that could reasonably be dimensional, and
they would continue to be usable in their original context.

With respect to Instant and Duration, my gut instinct would be to
change things so that in the default Perl setting, Duration goes away
and is replaced by Num; but the Dimensionality module would modify
Instant to be aware of units, and to act accordingly (e.g., Instant -
Instant returns Num but units("sec"); Instant + Num looks for units on
the Num and throws an exception if it finds the wrong ones, or none).
If you don't want to bother with dimensionality, use the standard perl
setting; if you want perl tracking these things for you, "use
Dimensionality".  In short, take Duration out of the default setting,
but make its added functionality available by means of a module.

-- 
Jonathan "Dataweaver" Lang


Re: exponentiation of Duration's

2010-11-17 Thread Jon Lang
If I'm following this correctly, shouldn't we just say that Duration
does Num?  That way, a Duration can be used exactly like a Num is
(with units measured in seconds); but it could also have special
capabilities above and beyond what a Num can do, if such capabilities
are needed.

More generally, I wonder if maybe we _should_ provide a tool to help
with dimensional analysis: a role that does Num, but also tracks the
units for you.  The simplest version would leave it up to the
programmer to handle unit conversions (e.g., divide a Dimensional that
uses the "seconds" unit by a Dimensional that contains 86400 for its
value and "seconds/day" for its units to get a Dimensional that uses
the "days" unit, rather than providing built-in unit conversion
routines).  Indeed, th simplest form of Dimensional ought to be able
to work with arbitrary units.  The idea here isn't to place
limitations on anything, but rather to make it easier to track
additional data that's relevant to the calculations being performed.

With this in place, Duration would be synonymous with "Dimensional,
measured in 'seconds'".

That said, it's possible that this would open up a can of worms.
Would it?  If so, it can be postponed; Perl 6 has this nice little
versioning ability that lets us retroactively alter roles; so one
could easily put together a Dimensionality module at a later date that
redefines what a Duration is.

-- 
Jonathan "Dataweaver" Lang


Re: Packed arrays and assignment vs binding

2010-11-14 Thread Jon Lang
On Sun, Nov 14, 2010 at 2:54 AM, Moritz Lenz  wrote:
> On IRC, Jonathan said that 1 is basically an Int, which is something
> like a boxed int. So whatever operation works removes the box, and puts
> the result in the variable.
>
> However I wonder how well that's going to work, since Int can store
> arbitrarily large integers, while int can't.
> What happens on overflow?

An exception gets thrown, I'm guessing.

-- 
Jonathan "Dataweaver" Lang


Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-13 Thread Jon Lang
Darren Duncan wrote:
> Jon Lang wrote:
>>
>> That saves a singlr character over Bag( ... ) and Set( ... ),
>> respectively (or three characters, if you find decent unicode bracket
>> choices).  It still wouldn't be a big enough deal to me to bother with
>> it.
>>
>> As well, my first impression upon seeing [! ... !] was to think
>> "you're negating everything inside?"  That said, I could get behind
>> doubled brackets:
>>
>>    [[1, 2, 3]] # same as Bag(1, 2, 3)
>>    {{1, 2, 3}} # same as Set(1, 2, 3)
>
> 
>
> I prefer to have the mnemonic that {} means unordered and that [] means
> ordered, so please stick to [] meaning arrays or ordered collections, an {}
> meaning unordered collections, so set and bag syntax should be based around
> {} if either.
>
> This said, I specifically think that a simple pair of curly braces is the
> best way to mark a Set.
>
> So:
>
>  {1,2,3}  # a Set of those 3 elements
>
> ... and this is also how it is done in maths I believe (and in Muldis D).
>
> In fact, I strongly support this assuming that all disambiguation eg with
> hashes can be specified.

That would be great.

>  {a=>1,b=>2}  # a Hash of 2 pairs
>
>  {:a<1>, :a<2>}  # we'll have to pick a meaning

My preference would be for this to be a Set that contains two items in
it, both of which are pairs.  IIRC, there's already behavior along
these lines when it comes to pairs.

>  {}  # we'll have to pick a meaning (Muldis D makes it a Set; %:{} is its
> Hash)

Is there any difference between an empty Set and an empty Hash?  If
so, is one more general than the other?  Just as importantly, what
does {} do right now?

>  {;}  # an anonymous sub or something
>
>  {a=>1}  # Hash
>
>  {1}  # Set
>
>  {1;}  # anonymous sub or something

Sets built from multi-dimensional arrays migt be a problem:

{1, 2, 3: 4, 5, 6}

> But keep that simple an let nesting work normally, so:
>
>  {{1}}  # a Set of 1 element that is a Set of 1 element
>
>  {{a=>1}}  # a Set with 1 Hash element
>
>  {[1]}  # a Set with 1 Array element
>
>  [{1}]  # an Array with 1 Set element
>
> In certain cases, we can always still fall back to this:
>
>  Set()  # empty Set
>
>  Hash()  # empty Hash
>
>  Set(:a<1>)  # if that's what we wanted
>
> As for bags, well I think that is where we could get fancier.
>
> But *no* doubling up, as we don't want to interfere with nesting.
>
> Instead, it is common in maths to associate a "+" with set syntax to refer
> to bags instead.
>
> So, does Perl already ascribe a meaning to putting a + with various
> bracketing characters, such as this:
>
>  +{1,2,2,5}  # a Bag of 4 elements with 2 duplicates
>
>  +{}  # an empty Bag, unless that already means something
>
> So would the above try to cast the collection as a number, or take the count
> of its elements, or can we use something like that?

I'd expect +{...} to count the elements.



-- 
Jonathan "Dataweaver" Lang


Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-13 Thread Jon Lang
Carl Mäsak wrote:
> Jonathan Lang (>):
>> That saves a singlr character over Bag( ... ) and Set( ... ),
>> respectively (or three characters, if you find decent unicode bracket
>> choices).  It still wouldn't be a big enough deal to me to bother with
>> it.
>
> +1. Let's leave it at that.

That said, I do think that Bag( ... ) should be able to take pairs, so
that one can easily create a Bag that holds, say, twenty of a given
item, without having to spell out the item twenty times.  Beyond that,
the only other syntax being proposed is a set of braces to be used to
create Bags and Sets, as part of the initiative to make them nearly as
easy to use as lists.  In essence, you'd be introducing two operators:
circumfix:<|[ ]|> and circumfix:<|{ }|>, as aliases for the respective
Set and Bag constructors.  As I said, it's not a big deal - either
way.

Really, my main issue remains the choice of sigil for a variable
that's supposed to hold baggy containers.

-- 
Jonathan "Dataweaver" Lang


Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-13 Thread Jon Lang
Brandon S Allbery KF8NH wrote:
> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA1
>
> On 11/7/10 23:19 , Jon Lang wrote:
>>     1 -- 2 -- 3
>>
>> Would be a Bag containing three elements: 1, 2, and 3.
>>
>> Personally, I wouldn't put a high priority on this; for my purposes,
>>
>>    Bag(1, 2, 3)
>>
>> works just fine.
>
> Hm. Bag as [! 1, 2, 3 !] and Set as {! 1, 2, 3 !}, with the outer bracket by
> analogy with arrays or hashes respectively and the ! having the mnemonic of
> looking like handles?  (I have to imagine there are plenty of Unicode
> brackets to match.)

That saves a singlr character over Bag( ... ) and Set( ... ),
respectively (or three characters, if you find decent unicode bracket
choices).  It still wouldn't be a big enough deal to me to bother with
it.

As well, my first impression upon seeing [! ... !] was to think
"you're negating everything inside?"  That said, I could get behind
doubled brackets:

[[1, 2, 3]] # same as Bag(1, 2, 3)
{{1, 2, 3}} # same as Set(1, 2, 3)

AFAIK, this would cause no conflicts with existing code.

Or maybe these should be reversed:

[[1, 1, 2, 3]] # a Set containing 1, 2, and 3
{{1, 1, 2, 3}} # a Bag containing two 1s, a 2, and a 3
{{1 => 2, 2 => 1, 3 => 1}} # another way of defining the same Bag,
with explicit counts.

OTOH, perhaps the outermost character should always be a square brace,
to indicate that it operates primarily like a list; while the
innermost character should be either a square brace or a curly brace,
to hint at thye kind of syntax that you might find inside:

[[1, 1, 2, 3]] # a Set containing 1, 2, and 3
[{1, 1, 2, 3}] # a Bag containing two 1s, a 2, and a 3
[{1 => 2, 2 => 1, 3 => 1}] # another way of defining the same Bag,
with explicit counts.

Yeah; I could see that.  The only catch is that it might cause
problems with existing code that nests square or curly braces inside
of square braces:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]] # fail; would try to create Set
from "1, 2, 3], [4, 5, 6], [7, 8, 9"
[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] # creates 3-by-3 array

...so maybe not.

It should never be more than two characters on either side; and
there's some benefit to using square or curly braces as one of them,
to hint at proper syntax within.  Hmm... how about:

|[1, 2, 3]| # Set literal
|[1=>true, 2=>true, 3=>true]| # technically possible; but why do it?
|{1, 1, 2, 3}| # Bag literal
|{1=>2, 2=>1, 3=>1}| # counted Bag literal

-- 
Jonathan "Dataweaver" Lang


Re: Packed arrays and assignment vs binding

2010-11-13 Thread Jon Lang
Jonathan Worthington wrote:
> In the latter case, it's fairly clear how these differ:
>
> @x[0] = 1;
> @x[0] := 1;
>
> In the first, we look up the container in slot 0 or the array and assign a 1
> into it. In the second, we bind a 1 directly into the slot. There's no
> container any more (so any future assignment attempts will fail, for
> example).

I'll have to beg to differ.  My understanding of it is as follows: the
first case works as you describe.  The second case differs, though,
because there is no way to bind a variable directly to a value;
variables can only be bound to containers.  So the interpreter creates
a new item container, assigns "1" to it, and binds the zero slot to
it.  Mind you: when the optimizer gets its hands on this, it'll
probably just simplify it to the first case, as the two are
functionally equivalent.  The distinction only really matters when
you're binding to an already-existing container (e.g., "@x[0] = $foo"
vs. "@x[0] := $foo").

> With packed arrays, however, I'm less clear what they mean. Since the point
> of a packed array is compact storage, there's no chance to actually have
> containers. Thus does assignment to a slot in a compact array ever make
> sense? There's not a container to look up and store things in.

Assignment makes perfect sense: the compact storage is the container
(which is bound to @x), and you assign a value to a slot in that
container.  What doesn't make sense is binding a slot of a packed
array to some other container:

  @x[0] := $foo; # this should die.

The only way I can see this working is if perl first converts the
packed array into a normal array, and then binds slot 0 to $foo.

-- 
Jonathan "Dataweaver" Lang


Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-08 Thread Jon Lang
This is going to be a rambling answer, as I have a number of questions
but no firm conclusions.  Please bear with me.

Mason Kramer wrote:
> Having Bags flatten in list context is pretty crucial to their being "as
> easy and terse to use as arrays", because flattening is fundamental to
> how Arrays are used, and Bags will be used like Arrays.  Luckily,
> however, %, which implies the Associative contract, also flattens in list
> context.  If Bags and Sets are sigiled with %, they should flatten, and
> all that remains is to make sure they flatten into a list of keys, and
> not a list of enums.

The only qualm that I have with using % as a prefix for baggy things
is that % carries the connotation that you're dealing with key/value
pairs.  While baggy things _can_ be thought of as pairs, they're
value/membership pairs rather than key/value pairs; and the membership
side of the pair should be hidden from view unless explicitly
requested.  In short, a casual programmer ought to be encouraged to
think of a baggy thing as being a collection of values; the % sigil
implicitly encourages him to think of it as a collection of pairs.

That said, the problem with % is that baggies implement its features
in an unusual way; the problem with @ is that baggies don't implement
all of its features.  Conceptually, @ (a collection of values) is a
better fit  than % (a collection of pairs); but technically, the
reverse is true: % (does Associative) is a better fit than @ (does
Positional).

Query: should %x.k, %x.v, %x.kv, and %x.pair produce lists, bags, or
sets?  As I understand it, right now all four produce lists.  I could
see a case for having %x.k and %x.pair produce sets, while %x.kv
definitely should produce a list (since even though the overall order
doesn't matter, which even element follows which odd element _does_
matter); and %x.v might reasonably produce a bag.  OTOH, if this is
done then there will be no way to talk about, e.g., "%x.k[0]".

I'm wondering if bags and sets _should_ do Positional, but with the
caveat that the order is arbitrary.  After all, that's what currently
happens with %x.k: you get a list of the keys, but with the
understanding that the order in which you get them is ultimately
meaningless.  Or is it that the difference between Iterable and
Positional is that Positional provides random access to its
membership, whereas Iterable only guarantees that you can walk through
the members?

Another way to phrase my concern is this: one reason why Perl 6 has
gone with nominal typing rather than structural typing is that "does
x" can and does promise more than just "implements the same features
that x implements"; it also promises something about the way in which
said features will be implemented.  In this regard, I would argue that
baggies should not do Associative; because even though they implement
all of the same features that Associative promises to implement, they
don't do so in a way that's compatible with Associative's underlying
philosophy of keys and values.  And if they don't do Associative, it
doesn't make sense for them to use the % sigil.

I hesitate to suggest this; but might we want a special sigil for
Iterable, to be used when neither Positional nor Associative is quite
right?  Such a sigil might be useful for more than just baggies; for
instance, a stream is Iterable but neither Positional nor Associative.

--
Jonathan "Dataweaver" Lang


Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-08 Thread Jon Lang
Solomon Foster wrote:
> Well, hyperoperators work fine on Hashes, they operate on the values,
> paired up by key if needed.  (That is, %hash>>++ doesn't care about
> the keys, %hash1 >>+<< %hash2 sums based on keys.)  I would assume
> that Bag should work in the exact same way.  Dunno how Set should work
> in this context, though.

I would hope that Bags would not work the same way.  If they do, then
you get things like:

Bag(1, 3, 2, 1) >>+<< Bag(2, 3, 1, 2) # same as Bag(1, 1, 1, 2, 2, 2, 3, 3)

I'm not sure how (or even if) Bags _should_ work in this context; but
the above is definitely not what I'd expect.

IMHO, a key point about Bags and Sets (no pun intended) is that the
values of the elements _are_ the keys; the existence of separate
values (unsigned integers in the case of Bags; booleans in the case of
Sets) are - or should be - mostly a bookkeeping tool that rarely shows
itself.

Incidently, we might want to set up a role to define the shared
behavior or Bags, Sets, et al.  My gut instinct would be to call it
"Baggy"; "Setty" would make the stargazers happy, but otherwise
wouldn't mean much.  With this, you could do things like creating a
FuzzySet that stores a number between zero and one for each key, but
which otherwise behaves like a Set.

-- 
Jonathan "Dataweaver" Lang


Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-07 Thread Jon Lang
Mason Kramer wrote:
> I'd like to anticipate one objection to this - the existence of the 'hyper' 
> operator/keyword.  The hyper operator says, "I am taking responsibility for 
> this particular code block and promising that it can execute out of order and 
> concurrently".  Creating a Bag instead of an Array says, "there is no meaning 
> to the ordering of this group of things, ever".  Basically, if I know at 
> declaration time that my collection has no sense of ordering, then I 
> shouldn't have to annotate every iteration of that collection as having no 
> sense of ordering, which is nearly what hyper does (though, I readily admit, 
> not quite, because there are unordered ways to create race conditions).

My understanding of the hyperoperator is that its primary use is to
say "operate on the individual elments of this collection, instead of
on the collection itself".  In that regard, it's just as applicable to
Bags and Sets as it is to lists.  Except...

Except that the hyperoperator assumes that the collections are
ordered.  It matches the first element on the left with the first
element on the right; the second element on the left with the second
on the right; and so on.  Bags and Sets don't have a useful notion of
"first", "second", etc.  So what should happen if I try to apply a
hyperoperator with a Bag or Set on one side?

The cross operators should also be looked at in this regard, though I
anticipate fewer problems there.

> This, however, probably requires a change to S03, which says that the @ sigil 
> is a means of coercing the object to the "Positional (or Iterable?)" role.  
> It seems to me, based on the guiding principle that perl6 should support 
> functional idioms and side-effect free computing, the more fundamental and 
> important aspect of things with @ in front is that you can go through them 
> one by one, and not that they're ordered (since ordering is irrelevant in 
> functional computing, but iterating is not).  My feeling is that we should 
> reserve the special syntax for the more fundamental of the two operations, so 
> as not to bias the programmer towards rigid sequentiality through syntax.

I tend to agree here - though to be clear, "my @x" should still
normally result in a list, sans further embellishments (e.g., "my Bag
@x").

> Second, I would be even more likely to replace my ordered lists with Bags if 
> there were a convenient operator for constructing Bags.  I can't think of any 
> good non-letter symbols that aren't taken right now (suggestions welcome), 
> but, at  least, &b and &s as aliases to bag and set would be convenient.

Such a character ought to be some sort of punctuation, preferably of a
type that's similar to the comma and semicolon.  For a Bag, you might
consider an emdash ("—"), with the ascii equivalent being infix:<-->.
So:

1 -- 2 -- 3

Would be a Bag containing three elements: 1, 2, and 3.

Personally, I wouldn't put a high priority on this; for my purposes,

   Bag(1, 2, 3)

works just fine.

-- 
Jonathan "Dataweaver" Lang


Re: Bag / Set ideas - making them substitutable for Arrays makes them more useful

2010-11-07 Thread Jon Lang
Darren Duncan wrote:
> However, if the above proposal is done, I would still want an easy way to
> get the value-count pairs from a bag if I wanted them.

I don't see any problem there.  Mason's suggestion only deals with the
Bag as seen through the the lens of the Iterable role; when viewed as
a hash, the value/count pairs will still be readily available as the
hash's key/value pairs.

IMHO, this is one of the few reasons to maintain a separate hash-like
interface for Bags and Sets.  But for the most part, we should be
thinking of them as being array-like rather than hash-like.

-- 
Jonathan "Dataweaver" Lang


Re: Lists vs sets

2010-10-25 Thread Jon Lang
Darren Duncan wrote:
> If a list is a set, does that mean that a list only contains/returns each
> element once when iterated?  If a list can have duplicates, then a list
> isn't a set, I would think. -- Darren Duncan

Thus Mason's point about Bags.  Really, I think that Mason's right in
that we should be looking as which roles each of these does rather
than which classes each of them "is".

-- 
Jonathan "Dataweaver" Lang


Re: Lists vs sets

2010-10-25 Thread Jon Lang
Mason Kramer wrote:
> But I don't think that thinking about who is subclassing whom is is how to
> think about this in Perl 6.  All of these types are capable of doing the
> Iterable role, and that is what methods that could operate on a List, Array,
> Bag, or Set, should be calling for.

This.  Really, as long as Set does Iterable, it's not as important if
it's treated as hash-like or list-like - though I'd still prefer to
deal with @sets rather than %sets.  Conceptually, it feels like a
better fit.

--
Jonathan "Dataweaver" Lang


Re: Lists vs sets

2010-10-25 Thread Jon Lang
yary wrote:
> +1 on this
> On Mon, Oct 25, 2010 at 4:56 PM, Jon Lang  wrote:
>> As for the bit about sets vs. lists: personally, I'd prefer that there
>> not be quite as much difference between them as there currently is.
>> That is, I'd rather sets be usable wherever lists are called for, with
>> the caveat that there's no guarantee about the order in which you'll
>> get the set's members; only that you'll get each member exactly once.
>> The current approach is of much more limited value in programming.
>
> I think of a list conceptually as a subclass of a set- a list is a
> set, with indexing and ordering added. Implementation-wise I presume
> they are quite different, since a set falls nicely into the keys of a
> hash in terms of what you'd typically want to do with it.

By "implementation-wise", are you referring to "under the hood
details"?  If so, I agree: it's OK to implement a set internally as a
hash.  But as far as the user is concerned, it ought to look like a
list.

Well, technically, a list should look like a set that has additional
features.  But as Damian pointed out earlier, one reason why he chose
to use lists in his transjunction module instead of sets is that as
they are now, you can iterate over a list; but you can't iterate over
a set.  From a practical standpoint, sets would be considerably more
attractive if you could iterate over them as well without having to
first turn them into lists via the .k method.  Thus my suggestion to
treat a set as a list of unique values without a guaranteed order, at
least as far as the user is concerned.

-- 
Jonathan "Dataweaver" Lang


Re: Tweaking junctions

2010-10-25 Thread Jon Lang
First off, let me weigh in on Damian's original point: I agree that
Junction!eigenvalues should be renamed to more accurately reflect what
it is (perhaps to something like Junction!seedvalues, since what it's
really trying to produce is a list of the values that it's using to
define the Junction), and that some means of generating a junction's
actual eigenvalues ought to be employed.

Personally, I don't think that it should be a public method: one thing
about junctions is that you can use them interchangeably with ordinary
scalars; giving them a public method breaks that.  In particular, code
that makes use of a Junction public method would break if you were to
hand it a non-Junction.  (Generalizing this, Junction should never
have any public methods.)  But I could see a function that passes an
item through as a one-item list (unless, maybe, it's a nil value, in
which case it might return an empty list?), but passes a junction
through as a list of all values that match the junction.  To
illustrate:

those(Nil)   # ()
those(1)# 1
those(any(1, 2, 3))  # 1, 2, 3
those(all(1, 2, 3))  # ()
those(one(1, 2, 3))  # 1, 2, 3
those(none(1, 2, 3)) # infinite list of everything except 1, 2, 3

I went with "those" because it's more layman-friendly than
"eigenvalues"; and as a plural word, one would expect it to produce a
list.  Note also that if Damian's transjunction idea does indeed
auto-eigenvalue in list context, then "those($x)" would be equivalent
to forcing list context onto a transjunction: if "select" is the
transjunction constructor, then "@( select(...) )" ought to be exactly
equivalent to "those(...)".

As for the bit about sets vs. lists: personally, I'd prefer that there
not be quite as much difference between them as there currently is.
That is, I'd rather sets be usable wherever lists are called for, with
the caveat that there's no guarantee about the order in which you'll
get the set's members; only that you'll get each member exactly once.
The current approach is of much more limited value in programming.

-- 
Jonathan "Dataweaver" Lang


Re: threads?

2010-10-12 Thread Jon Lang
When Larry decided that Perl 6 would incorporate concepts from
prototype-based objects, he did so at least in part because it's more
intuitive for people to work with, e.g., "a cow" than it is to try to
work with "the concept of a cow" as a thing unto itself.  In a similar
way, I think that Perl's dominant concurrency system ought to be of a
type that people who aren't computer scientists can grok, at least
well enough to do something useful without first having to delve into
the arcane depths of computing theory.

As such, I'm wondering if an Actor-based concurrency model[1] might be
a better way to go than the current threads-based mindset.  Certainly,
it's often easier to think of actors who talk to each other to get
things done than it is to think of processes (or threads) as things
unto themselves.

[1] http://en.wikipedia.org/wiki/Actor_model

-- 
Jonathan "Dataweaver" Lang


Re: r31972 -[S05] specify what .keys, .values and .kv do on Match objects

2010-08-12 Thread Jon Lang
How does a Match compare to a Parcel?

-- 
Jonathan "Dataweaver" Lang


Re: pattern alternation (was Re: How are ...)

2010-08-05 Thread Jon Lang
Aaron Sherman wrote:
> You know, this problem would go away, almost entirely, if we had a :f[ull]
> adverb for regex matching that imposed ^[...]$ around the entire match. Then
> your code becomes:
>
>  m:f/<[A..Z]>+|<[a..z]>+/
>
> for grins, :f[ull]l[ine] could use ^^ and $$.
>
> I suspect :full would almost always be associated with TOP, in fact. Boy am
> I tired of typing ^ and $ in TOP ;-)

The regex counterpart of C< say "$x" > vs. C< print "$x\n" >.  Yes,
this would indeed solve a lot of problems.  It also reflects a
tendency in some regular expression engines out there to automatically
impose full string matching (i.e., an implicit ^ at the start and $ at
the end).

That said: for mnemonic purposes, I'd be inclined to have :f do
/^[<$pattern>]$/, while :ff does /^^[<$pattern>]$$/.

-- 
Jonathan "Dataweaver" Lang


Re: S26 broken link

2010-08-02 Thread Jon Lang
Moritz Lenz wrote:
> Offer Kaye wrote:
>> The link to the S26 Synopsis on http://perlcabal.org/syn/ points to
>> http://perlcabal.org/syn/S26.html which is a broken link - would it be
>> possible to fix this?
>
> I't not that easy, because we currently don't have tool to turn p6doc
> into HTML. I can remove the link for now, if it's a concern to you.

And a major reason why we don't have a p6doc-to-HTML converter is
because there are still some outstanding issues with the p6doc spec:
it's not ready for prime time, as it were.

IIRC, the biggest unresolved issues involved the code-sensitive
documentation features: getting a pod6 parser to read perl code and
extract appropriate values on the one hand, vs. safety concerns about
its ability to _run_ perl code on the other.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-30 Thread Jon Lang
Aaron Sherman wrote:
> In the end, I'm now questioning the difference between a junction and
> a Range... which is not where I thought this would go.

Conceptually, they're closely related.  In particular, a range behaves
a lot like an any() junction.  Some differences:

1. An any() junction always has a discrete set of options in it; but a
Range could (and generally does) have a continuous set of options.

2. An any() junction can have an arbitrary set of options; a Range's
set of options is defined entirely by its endpoints.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-28 Thread Jon Lang
On Wed, Jul 28, 2010 at 10:35 PM, Brandon S Allbery KF8NH
 wrote:
>  On 7/28/10 8:07 PM, Michael Zedeler wrote:
>> On 2010-07-29 01:39, Jon Lang wrote:
>>> Aaron Sherman wrote:
>>>>> In smart-match context, "a".."b" includes "aardvark".
>>>> No one has yet explained to me why that makes sense. The continued
>>>> use of
>>>> ASCII examples, of course, doesn't help. Does "a" .. "b" include
>>>> "æther"?
>>>> This is where Germans and Swedes, for example, don't agree, but
>>>> they're all
>>>> using the same Latin code blocks.
>>> This is definitely something for the Unicode crowd to look into.  But
>>> whatever solution you come up with, please make it compatible with the
>>> notion that "aardvark".."apple" can be used to match any word in the
>>> dictionary that comes between those two words.
>> The key issue here is whethere there is a well defined and meaningful
>> ordering of the characters in question. We keep discussing the nice
>> examples, but how about "apple" .. "ส้ม"?
>
> I thought that was already disallowed by spec.

As a range, it ought to work; it's only when you try to generate a
list from it that you run into trouble, as the spec currently assumes
that "z".succ eqv "aa".

Anyway: whatever default algorithm we go with for resolving "cmp", I
strongly recommend that we define the default .succ so that "$x lt
$x.succ" is always true.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-28 Thread Jon Lang
Michael Zedeler wrote:
> Jon Lang wrote:
>> This is definitely something for the Unicode crowd to look into.  But
>> whatever solution you come up with, please make it compatible with the
>> notion that "aardvark".."apple" can be used to match any word in the
>> dictionary that comes between those two words.
>
> The key issue here is whether there is a well defined and meaningful
> ordering of the characters in question. We keep discussing the nice
> examples, but how about "apple" .. "ส้ม"?

All I'm saying is: don't throw out the baby with the bathwater.  Come
up with an interim solution that handles the nice examples intuitively
and the ugly examples poorly (or better, if you can manage that right
out of the gate); then revise the model to improve the handling of the
ugly examples as much as you can; but while you do so, make an effort
to keep the nice examples working.

> I don't know enough about Unicode to suggest how to solve this. All I can
> say is that my example above should never return a valid Range object unless
> there is a way I can specify my own ordering and I use it.

That actually says something: it says that we may want to reconsider
the notion that all string values can be sorted.  You're suggesting
the possibility that "a" cmp "ส้" is, by default, undefined.

There are some significant problems that arise if you do this.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-28 Thread Jon Lang
Aaron Sherman wrote:
>> In smart-match context, "a".."b" includes "aardvark".
>
>
> No one has yet explained to me why that makes sense. The continued use of
> ASCII examples, of course, doesn't help. Does "a" .. "b" include "æther"?
> This is where Germans and Swedes, for example, don't agree, but they're all
> using the same Latin code blocks.

This is definitely something for the Unicode crowd to look into.  But
whatever solution you come up with, please make it compatible with the
notion that "aardvark".."apple" can be used to match any word in the
dictionary that comes between those two words.

> I've never accepted that the range between two strings of identical length
> should include strings of another length. That seems maximally non-intuitive
> (well, I suppose you could always return the last 100 words of Hamlet as an
> iterable IO object if you really wanted to confuse people), and makes string
> and integer ranges far too divergent.

This is why I dislike the notion of the range operator being used to
produce lists: the question of what values you'd get by iterating from
one string value to another is _very_ different from the question of
what string values qualify as being between the two.  The more you use
infix:<..> to produce lists, the more likely you are to conflate lists
with ranges.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-28 Thread Jon Lang
Darren Duncan wrote:
> Does "..." also come with the 4 variations of endpoint inclusion/exclusion?
>
> If not, then it should, as I'm sure many times one would want to do this,
> say:
>
>  for 0...^$n -> {...}

You can toggle the inclusion/exclusion of the ending condition by
choosing between "..." and "...^"; but the starting point is the
starting point no matter what: there is neither "^..." nor "^...^".

> In any event, I still think that the mnemonics of "..." (yadda-yadda-yadda)
> are more appropriate to a generator, where it says "produce this and so on".
>  A ".." does not have that mnemonic and looks better for an interval.

Well put.  This++.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-28 Thread Jon Lang
TSa wrote:
> Swapping the endpoints could mean swapping inside test to outside
> test. The only thing that is needed is to swap from && to ||:
>
>   $a .. $b   # means  $a <= $_ && $_ <= $b  if $a < $b
>   $b .. $a   # means  $b <= $_ || $_ <= $a  if $a < $b

This is the same sort of discontinuity of meaning that was causing
problems with Perl 5's use of negative indices to count backward from
the end of a list; there's a reason why Perl 6 now uses the [*-$a]
notation for that sort of thing.

Consider a code snippet where the programmer is given two values: one
is a minimum value which must be reached; the other is a maximum value
which must not be exceeded.  In this example, the programmer does not
know what the values are; for all he knows, the minimum threshold
exceeds the maximum.  As things stand, it's trivial to test whether or
not your sample value is viable: if "$x ~~ $min .. $max", then you're
golden: it doesn't matter what "$min cmp $max" is.  With your change,
I'd have to replace the above with something along the lines of:
  "if $min <= $max && $x ~~ $min .. $max { ... }" - because if $min >
$max, the algorithm will accept values that are well below the minimum
as well as values that are well above the maximum.

Keep it simple, folks!  There are enough corner cases in Perl 6 as
things stand; we don't need to be introducing more of them if we can
help it.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-28 Thread Jon Lang
Dave Whipp wrote:
> To squint at this slightly, in the context that we already have 0...1e10 as
> a sequence generator, perhaps the semantics of iterating a range should be
> unordered -- that is,
>
>  for 0..10 -> $x { ... }
>
> is treated as
>
>  for (0...10).pick(*) -> $x { ... }
>
> Then the whole question of reversibility is moot.

No thanks; I'd prefer it if $a..$b have analogous meanings in item and
list contexts.  As things stand, 10..1 means, in item context,
"numbers that are greater or equal to ten and less than or equal to
one", which is equivalent to "nothing"; in list context, it means "an
empty list". This makes sense to me; having it provide a list
containing the numbers 1 through 10 creates a conflict between the two
contexts regardless of how they're arranged.

As I see it, C< $a..$b > in list context is a useful shorthand for C<
$a, *.succ ... $b >.  You only get into trouble when you start trying
to have infix:<..> do more than that in list context.

If anything needs to be done with respect to infix:<..>, it lies in
changing the community perception of the operator.  The only reason
why we're having this debate at all is that in Perl 5, the .. operator
was used to generate lists; so programmers coming from Perl 5 start
with the expectation that that's what it's for in Perl 6, too.  That
expectation needs to be corrected as quickly as can be managed, not
catered to.  But that's not a matter of language design; it's a matter
to be addressed by whoever's going to be writing the Perl 6 tutorials.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-27 Thread Jon Lang
Aaron Sherman wrote:
> As a special case, perhaps you can treat ranges as special and not as simple
> iterators. To be honest, I wasn't thinking about the possibility of such
> special cases, but about iterators in general. You can't generically reverse
> lazy constructs without running afoul of the halting problem, which I invite
> you to solve at your leisure ;-)

A really obvious example occurs when the RHS is a Whatever:

   (1..*).reverse;

.reverse magic isn't going to be generically applicable to all lazy
lists; but it can be applicable to all lazy lists that have predefined
start points, end points, and bidirectional iterators, and on all lazy
lists that have random-access iterators and some way of locating the
tail.  Sometimes you can guess what the endpoint and backward-iterator
should be from the start point and the forward-iterator, just as the
infix:<...> operator is able to guess what the forward-iterator should
be from the first one, two, or three items in the list.

This is especially a problem with regard to lists generated using the
series operator, as it's possible to define a custom forward-iterator
for it (but not, AFAICT, a custom reverse-iterator).  In comparison,
the simplicity of the range operator's list generation algorithm
almost guarantees that as long as you know for certain what or where
the last item is, you can lazily generate the list from its tail.  But
only almost:

   (1..3.5); # list context: 1, 2, 3
   (1..3.5).reverse; # list context: 3.5, 2.5, 1.5 - assuming list is
generated from tail.
   (1..3.5).reverse; # list context: 3, 2, 1 - but only if you
generate it from the head first, and then reverse it.

Again, the proper tool for list generation is the series operator,
because it can do everything that the range operator can do in terms
of list generation, and more.

1 ... 3.5 # same as 1, 2, 3
3.5 ... 1 # same as 3.5, 2.5, 1.5 - and obviously so.

With this in mind, I see no reason to allow any magic on .reverse when
dealing with the range operator (or the series operator, for that
matter): as far as it's concerned, it's dealing with a list that lacks
a reverse-iterator, and so it will _always_ generate the list from its
head to its tail before attempting to reverse it.  Maybe at some later
point, after we get Perl 6.0 out the door, we can look into revising
the series operator to permit more powerful iterators so as to allow
.reverse and the like to bring more dwimmy magic to bear.

-- 
Jonathan "Dataweaver" Lang


Re: series operator issues

2010-07-22 Thread Jon Lang
On Thu, Jul 22, 2010 at 11:35 AM, Aaron Sherman  wrote:
> On Thu, Jul 22, 2010 at 1:13 PM, Jon Lang  wrote:
>>  Yes, it would be a
>> special tool; but it would be much more in keeping with the "keep
>> simple things easy" philosophy that Perl 6 tends to promote:
>>
>>    0, { $^a + $:i } ... * # series of triangle numbers
>>    0, { $^a + (2 * $:i - 1)  } ... * # series of square numbers
>>    { $:i ** 2 } ... * # series of square numbers
>>    1, { $^a * $:i } ... * # series of factorials
>
> I do have to admit that that's awfully clean-looking, but the implementation
> would force a closure in a series to behave differently from a closure
> anywhere else.

How so?

> Without changing closure definitions and without extending the syntax any,
> you could make the series operator do a little bit more introspection work
> and if a parameter is named "index", track an index value and pass it by
> name, passing any remaining parameters positionally from the previous n
> values as normal.

...which differs from my example in several ways, all of which are
detrimental: it puts the index in among the positional parameters,
meaning that odd things would have to happen if you ever decide to
use, say, $^i and $^j as your "prior items" parameters; and it locks
you into a specific name for the index instead of letting you choose
one of your own liking.

> That makes your examples:
>  0, { $^a + $^index } ... *
>  0, { $^a + (2 * $^index - 1)  } ... *
>  { $^index ** 2 } ... *
>  1, { $^a * $^index } ... *
> Not changing the syntax of closures seems like a reasonable goal at this
> late stage.

Who said anything about changing the syntax?  "$:i" is perfectly valid
syntax that is already spelled out in S06, under Placeholder
Variables.  Granted, it's rarely used; but it exists.  And unless I'm
missing something, this would be a perfectly valid use for it.

Essentially, my suggestion is this: if the step function's signature
(or implied signature, in the case of a function with placeholder
variables) includes any named parameters, then the index is used as
the argument corresponding to the first one.  (the only catch would be
if you decide to use the slurpy named placeholder, since the compiler
can't be expected to know which keys are being used inside the block;
in this case, it would be fair to assume that "index" is to be used,
or maybe "0".)  As such, the above examples could also be done as:

0, -> $a, :$i { $a + $i } ... * # series of triangle numbers
0, sub ($_, :$x) { $_ + (2 * $x - 1)  } ... * # series of square numbers
{ %_{"0"} ** 2 } ... * # series of square numbers
1, { @_[0] * %_<0> } ... * # series of factorials

My own preference would be to angle for the more compact form that I
originally illustrated, unless and until its limitations force me to
do otherwise.  But then, TIMTOWTDI.

-- 
Jonathan "Dataweaver" Lang


Re: series operator issues

2010-07-22 Thread Jon Lang
On Thu, Jul 22, 2010 at 9:25 AM, Aaron Sherman  wrote:
> On Thu, Jul 22, 2010 at 11:41 AM, Moritz Lenz  wrote:
>> The difficulty you're running into is that you're trying to use the wrong
>> tool for the job. Just don't use the series operator when it's not easy to
>> use. Perl 6 has other mechanism too, which are better suited for these
>> particular problems.
>
> In general, I'd agree. However, there is something to be said for the
> underlying question: is there a way to get at the iteration index from the
> lambda in a series? It seems like that's something that it's not
> unreasonable to want.
>
> I also think it's doable without a special tool:
>
>  0, { state $i = 1; $^a + $i++ } ... *
>
> That should work, no? Granted, state doesn't seem to work in Rakudo, unless
> I'm mis-understanding how to use it, but that's the idea.

Kludgey; but possibly doable.

Another possibility that might work would be to use the default list
parameter to count the previous elements: +...@_.  That would be
notationally more compact, but would also potentially wreak havoc on
the computational efficiency of the model; and while you could get the
index number from it, it wouldn't always be quite as simple as
counting its elements.

But what I'd really like to see would be for the index to be passed
into the step function via a named parameter.  Yes, it would be a
special tool; but it would be much more in keeping with the "keep
simple things easy" philosophy that Perl 6 tends to promote:

0, { $^a + $:i } ... * # series of triangle numbers
0, { $^a + (2 * $:i - 1)  } ... * # series of square numbers
{ $:i ** 2 } ... * # series of square numbers
1, { $^a * $:i } ... * # series of factorials

-- 
Jonathan "Dataweaver" Lang


series operator issues

2010-07-22 Thread Jon Lang
When I last reviewed the writeup for the series operators, I noticed two issues:

First, why is the RHS argument a list?  You only ever use the first
element of it; so why don't you just reference a single value?

Second, I'm trying to think of a simple and intuitive way to write up
a series expression for:

   triangle numbers: 0, 1, 3, 6, 10, 15, 21, etc.
   square numbers: 0, 1, 4, 9, 16, 25, 36, etc.
   factorials: 1, 1, 2, 6, 24, 120, 720, 5040, etc.

The difficulty that I'm running into is that there's no reasonably
straightforward way of computing a given term solely from the previous
one or two items in the list.  There _is_ a simple way to compute the
next item from the previous item and the index number, or even
strictly from the index number; but there is no way that I'm aware of
to get the index number into the step function.

-- 
Jonathan "Dataweaver" Lang


Re: multi-character ranges

2010-07-21 Thread Jon Lang
Aaron Sherman wrote:
> Darren Duncan wrote:
> 3) It seems that there are two competing multi-character approaches and both
>>> seem somewhat valid. Should we use a pragma to toggle behavior between A
>>> and
>>> B:
>>>
>>>  A: "aa" .. "bb" contains "az"
>>>  B: "aa" .. "bb" contains ONLY "aa", "ab", "ba" and "bb"
>>>
>>
>> I would find A to be the only reasonable answer.
>
> [Before I respond, let's agree that, below, I'm going to say things like
> "generates" when talking about "..". What I'm describing is the idea that a
> value exists in the range given, not that a range is actually a list.]
>
> I would find B to be the only reasonable answer, but enough people seem to
> think the other way that I understand there's a valid need to be able to get
> both behaviors.

FWIW, the reasoning behind A is that it's very much like looking up a
word in a dictionary.  Is "az" greater than, less than, or equal to
"aa"?  Greater than.  Is "az" greater than, equal to, or less than
"bb"?  Less than.  Since it is greater than "aa" and less than "bb",
it is between "aa" and "bb".  This is what infix:<..> tests for.

>> If you want B's semantics then use "..." instead; ".." should not be
>> overloaded for that.
>>
>
> I wasn't really distinguishing between ".." and "..." as I'm pretty sure
> they should have the same behavior, here. The case where I'm not sure they
> should have the same behavior is "apple" .. "orange". Frankly, I think that
> there's no right solution there. There's the one I proposed in my original
> message (treat each character index as a distinct sequence and then
> increment in a base defined by all of the sequences), but even I don't like
> that. To generate all possible strings of length 5+ that sort between those
> two is another suggestion, but then what do you expect "father-in-law" ..
> "orange" to do? Punctuation throws a whole new dimension in there, and I'm
> immediately lost. When you go to my Japanese example from many messages ago,
> which I got from a fairly typical Web site and contained 2 Scripts with 4
> different General Categories, I begin to need pharmaceuticals.

What you're asking about now isn't the range or series operators; its
the comparison operators: before, after, gt, lt, ge, le, leg, and so
on.  When comparing two strings, establishing an order between them is
generally straightforward as long as both are composed of letters from
the same alphabet and with the same case; but once you start mixing
cases, introducing non-alphabetical characters such as spaces or
punctuation, and/or introducing characters from other alphabets, the
common-sense meaning of order becomes messy.

Traditionally, this has been addressed by falling back on a comparison
of the characters' ordinals: 0x0041 comes before 0x0042, and so on.
It includes counterintuitive situations where "d" > "E", because all
capital letters come earlier in the Unicode sequencing than any
lower-case letters do.  OTOH, it's robust: if all that you want is a
way to ensure that strings can always be sorted, this will do the job.
 It won't always be an _intuitive_ ordering; but there will always be
an ordering.

> I don't see any value in having different rules for what .. and ... generate
> in these cases, however. (frankly, I'm still on the fence about ... for
> single endpoints, which I think should just devolve to .. (... with a list
> for LHS is another animal, of course))

The only area where infix:<..> and infix:<...> overlap is when you're
talking about list generation; when using them for matching purposes,
C< $x ~~ 1..3 > is equivalent to C< $x >= 1 && $x <= 3 > (that is,
it's a single value that falls somewhere between the two endpoints),
while C< $x ~~ 1...3 > is equivalent to C< $x ~~ (1, 2, 3) > (that is,
$x is a three-element list that contains the values 1, 2, and 3 in
that order) - two very different things.  There simply is not enough
similarity between the two operators for one to degenerate to the
other in anything  more than a few edge-cases.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-21 Thread Jon Lang
Smylers wrote:
> Jon Lang writes:
>> Approaching this with the notion firmly in mind that infix:<..> is
>> supposed to be used for matching ranges while infix:<...> should be
>> used to generate series:
>>
>> With series, we want C< $LHS ... $RHS > to generate a list of items
>> starting with $LHS and ending with $RHS.  If $RHS > $LHS, we want it
>> to increment one step at a time; if $RHS < $LHS, we want it to
>> decrement one step at a time.
>
> Do we?

Yes, we do.

> I'm used to generating lists and iterating over them (in Perl 5)
> with things like like:
>
>  for (1 .. $max)
>
> where the intention is that if $max is zero, the loop doesn't execute at
> all. Having the equivalent Perl 6 list generation operator, C<...>,
> start counting backwards could be confusing.
>
> Especially if Perl 6 also has a range operator, C<..>, which would Do
> The Right Thing for me in this situation, and where the Perl 6 operator
> that Does The Right Thing is spelt the same as the Perl 5 operator that
> I'm used to; that muddles the distinction you make above about matching
> ranges versus generating lists.

It does muddy the difference, which is why my own gut instinct would
have been to do away with infix:<..>'s ability to generate lists.
Fortunately, I'm not in charge here, and wiser heads than mine have
decreed that infix:<..>, when used in list context, will indeed
generate a list in a manner that closely resembles Perl 5's range
operator: start with the LHS, then increment until you equal or exceed
the RHS - and if you start out exceeding the RHS, you've got yourself
an empty list.

You can do the same thing with the infix:<...> operator, too; but
doing so will be bulkier (albeit much more intuitive).  For example,
the preferred Perl 6 approach to what you described would be:

for 1, 2 ... $x

The two-element list on the left of the series operator invokes a bit
of magic that tells it that the algorithm for generating the next step
in the series is to invoke the increment operator.  This is all
described in S03 in considerable detail; I suggest rereading the
section there concerning the series operator before passing judgment
on it.  .

--
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-20 Thread Jon Lang
Mark J. Reed wrote:
> Perhaps the syllabic kana could be the "integer" analogs, and what you
> get when you iterate over the range using ..., while the modifier kana
> would not be generated by the series  ア ... ヴ but would be considered
> in the range  ア .. ヴ?  I wouldn't object to such script-specific
> behavior, though perhaps it doesn't belong in core.

As I understand it, it wouldn't need to be script-specific behavior;
just behavior that's aware of Unicode properties.  That particular
issue doesn't come up with the English alphabet because there aren't
any modifier codepoints embedded in the middle of the standard
alphabet.  And if there were, I'd hope that they'd be filtered out
from the series generation by default.

And I'd hope that there would be a way to turn the default filtering
off when I don't want it.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-20 Thread Jon Lang
Aaron Sherman wrote:
> So, what's the intention of the range operator, then? Is it just there to
> offer backward compatibility with Perl 5? Is it a vestige that should be
> removed so that we can Huffman ... down to ..?
>
> I'm not trying to be difficult, here, I just never knew that ... could
> operate on a single item as LHS, and if it can, then .. seems to be obsolete
> and holding some prime operator real estate.

On the contrary: it is not a vestige, it is not obsolete, and it's
making good use of the prime operator real estate that it's holding.
It's just not doing what it did in Perl 5.

I strongly recommend that you reread S03 to find out exactly what each
of these operators does these days.

>> The questions definitely look different that way: for example,
>> ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz is easily and
>> clearly expressed as
>>
>>    'A' ... 'Z', 'a' ... 'z'     # don't think this works in Rakudo yet  :(
>>
>
> I still contend that this is so frequently desirable that it should have a
> simpler form, but it's still going to have problems.
>
> One example: for expressing "Katakana letters" (I use "letters" in the
> Unicode sense, here) it's still dicey. There are things interspersed in the
> Unicode sequence for Katakana that aren't the same thing at all. Unicode
> calls them lowercase, but that's not quite right. They're smaller versions
> of Katakana characters which are used more as punctuation or accents than as
> syllabic glyphs the way the rest of Katakana is.
>
> I guess you could write:
>
>  ア, イ, ウ, エ, オ, カ ... ヂ,ツ ...モ,ヤ, ユ, ヨ ... ロ, ワ ... ヴ (add quotes to taste)
>
> But that seems quite a bit more painful than:
>
>  ア .. ヴ (or ... if you prefer)
>
> Similar problems exist for many scripts (including some of Latin, we're just
> used to the parts that are odd), though I think it's possible that Katakana
> may be the worst because of the mis-use of Ll to indicate a letter when the
> truth of the matter is far more complicated.

Some of this might be addressed by filtering the list as you go -
though I don't remember the method for doing so.  Something like
.grep, I think, with a regex in it that only accepts letters:

(ア ... ヴ).«grep(/<:alpha:>/)

...or something to that effect.

Still, it's possible that we might need something that's more flexible
than that.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-20 Thread Jon Lang
Approaching this with the notion firmly in mind that infix:<..> is
supposed to be used for matching ranges while infix:<...> should be
used to generate series:

Aaron Sherman wrote:
> Walk with me a bit, and let's explore the concept of intuitive character
> ranges? This was my suggestion, which seems pretty basic to me:
>
> "x .. y", for all strings x and y, which are composed of a single, valid
> codepoint which is neither combining nor modifying, yields the range of all
> valid, non-combining/modifying codepoints between x and y, inclusive which
> share the Unicode script, general category major property and general
> category minor property of either x or y (lack of a minor property is a
> valid value).

This is indeed true for both range-matching and series-generation as
the spec is currently written.

> In general we have four problems with current specification and
> implementation on the Perl 6 and Perl 5 sides:
>
> 1) Perl 5 and Rakudo have a fundamental difference of opinion about what
> some ranges produce ("A" .. "z", "X" .. "T", etc) and yet we've never really
> articulated why we want that.
>
> 2) We deny that a range whose LHS is "larger" than its RHS makes sense, but
> we also don't provide an easy way to construct such ranges lazily otherwise.
> This would be annoying only, but then we have declared that ranges are the
> right way to construct basic loops (e.g. for (1..1e10).reverse -> $i {...}
> which is not lazy (blows up your machine) and feels awfully clunky next to
> for 1e10..1 -> $i {...} which would not blow up your machine, or even make
> it break a sweat, if it worked)

With ranges, we want C< when $LHS .. $RHS" > to always mean C<< if
$LHS <= $_ <= $RHS >>.  If $RHS < $LHS, then the range being specified
is not valid.  In this context, it makes perfect sense to me why it
doesn't generate anything.

With series, we want C< $LHS ... $RHS > to generate a list of items
starting with $LHS and ending with $RHS.  If $RHS > $LHS, we want it
to increment one step at a time; if $RHS < $LHS, we want it to
decrement one step at a time.

So: 1) we want different behavior from the Range operator in Perl 6
vs. Perl 5 because we have completely re-envisioned the range
operator.  What we have replaced it with is fundamentally more
flexible, though not necessarily perfect.

> 3) We've never had a clear-cut goal in allowing string ranges (as opposed to
> character ranges, which Perl 5 and 6 both muddy a bit), so "intuitive"
> becomes sketchy at best past the first grapheme, and ever muddier when only
> considering codepoints (thus that wing of my proposal and current behavior
> are on much shakier ground, except in so far as it asserts that we might
> want to think about it more).

I think that one notion that we're dealing with here is the idea that
C<< $X < $X.succ >> for all strings.  This seems to be a rather
intuitive assumption to make; but it is apparently not an assumption
that Stringy.succ makes.  As I understand it, "Z".succ eqv "AA".  What
benefit do we gain from this behavior?  Is it the idea that eventually
this will iterate over every possible combination of capital letters?
If so, why is that a desirable goal?


My own gut instinct would be to define the string iterator such that
it increments the final letter in the string until it gets to "Z";
then it resets that character to "A" and increments the next character
by one:

"ABE", "ABF", "ABG" ... "ABZ", "ACA", "ACB" ... "ZZZ"

This pattern ensures that for any two strings in the series, the first
one will be less than its successor.  It does not ensure that every
possible string between "ABE" and "ZZZ" will be represented; far from
it.  But then, 1...9 doesn't produce every number between 1 and 9; it
only produces integers.  Taken to an extreme: pi falls between 1 and
9; but no one in his right mind expects us to come up with a general
sequencing of numbers that increments from 1 to 9 with a guarantee
that it will hit pi before reaching 9.

Mind you, I know that the above is full of holes.  In particular, it
works well when you limit yourself to strings composed of capital
letters; do anything fancier than that, and it falls on its face.

> 4) Many ranges involving single characters on LHS and RHS result in null
> or infinite output, which is deeply non-intuitive to me, and I expect many
> others.

Again, the distinction between range-matching and series-generation
comes to the rescue.

> Solve those (and I tried in my suggestion) and I think you will be able to
> apply intuition to character ranges, but only in so far as a human being is
> likely to be able to intuit anything related to Unicode.

Of the points that you raise, #1, 2, and 4 are neatly solved already.
I'm unsure as to #3; so I'd recommend focusing some scrutiny on it.

> The current behaviour of the range operator is (if I recall correctly):
>> 1) if both sides are single characters, make a range by incrementing
>> codepoints
>>
>
> Sadly, you can't do that reasonabl

Re: Suggested magic for "a" .. "b"

2010-07-20 Thread Jon Lang
Solomon Foster wrote:
> Ranges haven't been intended to be the "right way" to construct basic
> loops for some time now.  That's what the "..." series operator is
> for.
>
>    for 1e10 ... 1 -> $i {
>         # whatever
>    }
>
> is lazy by the spec, and in fact is lazy and fully functional in
> Rakudo.  (Errr... okay, actually it just seg faulted after hitting
> 968746 in the countdown.  But that's a Rakudo bug unrelated to
> this, I'm pretty sure.)

You took the words out of my mouth.

> All the magic that one wants for handling loop indices -- going
> backwards, skipping numbers, geometric series, and more -- is present
> in the series operator.  Range is not supposed to do any of that stuff
> other than the most basic forward sequence.

Here, though, I'm not so sure: I'd like to see how many of Aaron's
issues remain unresolved once he reframes them in terms of the series
operator.

-- 
Jonathan "Dataweaver" Lang


Re: Suggested magic for "a" .. "b"

2010-07-16 Thread Jon Lang
Aaron Sherman wrote:
> Oh bother, I wrote this up last night, but forgot to send it. Here y'all
> go:
>
> I've been testing ".." recently, and it seems, in Rakudo, to behave like
> Perl 5. That is, the magic auto-increment for "a" .. "z" works very
> wonkily,
> given any range that isn't within some very strict definitions (identical
> Unicode general category, increasing, etc.) So the following:
>
> "A" .. "z"
>
> produces very odd results.

Bear in mind that ".." is no longer supposed to be used to generate
lists; for that, you should use "...".  That said, that doesn't
address the issues you're raising; it merely spreads them out over two
operators (".." when doing pattern matching, and "..." when doing list
generation).

Your restrictions and algorithms are a good start, IMHO; and at some
point when I have the time, energy, and know-how, I'll read through
them in detail and comment on them.  In the meantime, though, let me
point out a fairly obvious point: sometimes, I want my pattern
matching and list generation to be case-sensitive; other times, I
don't.  More generally, whatever algorithm you decide on should be
subject to tweaking by the user to more accurately reflect his
desires.  So perhaps ".." and "..." should have an adverb that lets
you switch case sensitivity on (if the default is "off") or off (if
the default is "on").  And if you do this, there should be function
forms of ".." and "..." for those of us who have trouble working with
the rules for applying adverbs to operators.  Likewise with other
situations where there might be more than one way to approach things.

-- 
Jonathan "Dataweaver" Lang


Re: Perl 6 in non-English languages

2010-06-23 Thread Jon Lang
Another thing to consider is that Perl 6 is symbol-heavy: that is, keywords
are often symbols (such as &&, <=>, or $_) rather than words.  AFAIK, those
symbols are not English, and I would not expect them to change under a
natural language transformation of the setting.  And to elaborate on Aaron's
point, I'd expect such things as function call syntax, operator syntax,
method call syntax, and the like to remain the same, as these things aren't
English either.

As for seeing a "natural language variant" of Perl, my own thought is that
the first such variant might be most useful if it mines a decidedly
artificial "natural language" for its keywords, such as Esperanto or
Interlingua.  Given that Perl is not English, and merely uses English loan
words whenever it needs alphanumeric keywords, I suspect that an
Interlingua-based variant might be close enough to, say, a Spanish- or
French-based variant that the latter two might possibly end up not being
worth the trouble of writing.

Not being a linguist, I could be wrong about any or all of the above.


As for Aaron's concerns about the use of alternate natural languages
complicating the use of modules: note that this really isn't any different
from any case where you change the underlying grammar.  Perl has a robust
module system that assumes that each module is written in the Perl dialect
that the module specifies rather than in the dialect that the script is
written in, and vice versa; so aside from the optional hassle of translating
English-based modules into the preferred natural language setting when you
import them (or vice versa, in the case of modules that are written in other
natural language variants), there is unlikely to be much of a problem from
Perl's perspective.

In terms of the Perl community, I suspect that we're best off assuming that
most Perl modules and scripts should be written using the default
English-based setting for the foreseeable future; the use of natural
language variants should be considered to be a niche market.  When and if
English gets supplanted by some other language as the technical language of
choice, this notion can be revisited.  Assuming that Perl is still in
reasonably wide use when that happens, it will have the flexibility to make
the transition.

-- 
Jonathan "Dataweaver" Lang


Re: r31051 -[S02] refine Blobs to simply be immutable Bufs, with similar generic characteristics

2010-06-02 Thread Jon Lang
Darren Duncan wrote:
> With the above addition, you have both Buf and Blob roles as well as Buf and
> Blob types.
>
> I think you need to make each of those just a role or a type, and then add
> another named entity which is the counterpart role or type.
>
> For example, as you have Stringy as a role with the Str type, maybe you can
> have Blobby with the Blob.
>
> And maybe Buffy with the Buf?  The Perl community already seems to like such
> puns, so why not?

I second the notion of a separate role, like Str vs. Stringy.
However, the idea here is that a Blob is an immutable Buf.  AFAICT,
the roles are agnostic concerning mutability: you have Positional,
which applies to both Arrays and Lists (IIRC).  So you'd have one of
Blobby or Buffy, but not both.  Or perhaps you'd have another name for
it that captures the essentials that Blobs abd Bufs share, without
"privileging" one over the other.  Or not.

-- 
Jonathan "Dataweaver" Lang


Re: r31054 -[S03] suggestions from dataweaver++

2010-06-02 Thread Jon Lang
 wrote:
> +Regardless of whether the dwim is forced or emergent from the shapes
> +of the arrays, once the side to dwim on has been chosen, the dwim
> +semantics on the dwimmy side are always:
> +
> +    (@dwimmyside xx *).batch(@otherside.elems)
> +
> +This produces a list the same length as the corresponding dimension
> +on the other side.  The original operator is then recursively applied
> +to each corresponding pair of elements, in case there are more dimensions
> +to handle.

Very useful; thank you.  One more request: could you provide a few
multidimensional examples?  For instance:

(1, 2, 3; 4, 5, 6) «+» (1, 2; 3, 4; 5, 6)

My gut instinct is that this would be equivalent to:

(1, 2, 3; 4, 5, 6; 1, 2, 3) «+» (1, 2; 3, 4; 5, 6) # lhs dwimmery
in the first dimension

...which in turn would be equivalent to:

(1, 2, 3; 4, 5, 6; 1, 2, 3) «+» (1, 2, 1; 3, 4, 3; 5, 6, 5) # rhs
dwimmery in the second dimension

Or:

(2, 4, 4; 7, 9, 9; 6, 8, 8)

But I'm not sure.  If I'm right, I'd like it confirmed; if I'm wrong,
I want to see what the right way to do it is.

-- 
Jonathan "Dataweaver" Lang


Re: r31050 -[S03] refine hyper dwimminess to be more like APL, with modular semantics

2010-06-02 Thread Jon Lang
Smylers wrote:
> pugs-comm...@feather.perl6.nl writes:
>
>> Author: lwall
>> Log:
>> [S03] refine hyper dwimminess to be more like APL, with modular semantics
>>
>> +    (1,2,3)   »+» 1       # 2,4,4,6     rhs dwims to (1 xx *).batch(3)
>
> I'd've expected the output to be 2,3,4; is the 2,4,4,6 copy pasta or am
> I missing something?

Likewise with:

>> +(1,2,3)   »+» (1,2)   # 2,4,4,6 rhs dwims to ((1,2) xx *).batch(3)

Wouldn't that be equivalent to:

(1,2,3) »+« (1,2,1)   # 2,4,4

?

In fact, could you show what each of the successful examples dwim to
in the form of "(1,2,3) »+« (A,B,C)"? It would make it a bit easier to
follow.

-- 
Jonathan "Dataweaver" Lang


Re: eqv and comparing buts

2010-05-27 Thread Jon Lang
Jon Lang wrote:
> Right.  Still, there are times when duck-typing, flawed as it is,
> might be exactly what is needed to resolve the problem at hand.  I
> forget who or in what context, but I vaguely recall someone posting an
> article here that proposed the use of £ in signatures as a modifier to
> mean "is like a" (i.e., accept anything that matches the given role's
> set of methods; duck-typing) rather than "is a" or "does" (which,
> respectively, check for inheritance or composition).  (Could the
> original poster please repost the link here for reference purposes?)

Found it: http://www.dlugosz.com/Perl6/polymorphism.pdf

-- 
Jonathan "Dataweaver" Lang


Re: eqv and comparing buts

2010-05-27 Thread Jon Lang
Darren Duncan wrote:
> Larry Wall wrote:
>>
>> Or going the other direction, perhaps we're missing a primitive that
>> can produce a data structure with the type information stripped, and
>> then eqv might be able to determine structural equivalence between
>> two canonicalized values.
>
> Often you still want to know the declared type, though, because while
> sometimes we want things to be equivalent if they are structurally
> equivalent, other times we don't.  A declared type implies a particular
> intended interpretation of a value.  For example, we could have two classes
> named Weight and Distance, both of which have a single Num-typed attribute
> named $v.  A structural comparison of a Weight.new(3) and a Distance.new(3)
> may consider them equal, but logically we would want those two to not
> compare equal, because no weight is a distance or vice-versa, so every
> Weight should compare as not equal to every Distance. Ignoring the declared
> type only really makes sense when the two values are subtypes of a common
> parent type.  It only makes sense for objects of two classes to be declared
> equal if you can say that a value of a type "is a" value of the other type.

Right.  Still, there are times when duck-typing, flawed as it is,
might be exactly what is needed to resolve the problem at hand.  I
forget who or in what context, but I vaguely recall someone posting an
article here that proposed the use of £ in signatures as a modifier to
mean "is like a" (i.e., accept anything that matches the given role's
set of methods; duck-typing) rather than "is a" or "does" (which,
respectively, check for inheritance or composition).  (Could the
original poster please repost the link here for reference purposes?)

To me, this seems like a rather perlish solution: allow perl to do
duck-typing, but not as the default means of type comparison; require
some additional syntax to enable it.  So looking for "Weight" only
succeeds when the test subject inherits or composes Weight; but
looking for "£ Weight" succeeds for anything that acts like a Weight.

-- 
Jonathan "Dataweaver" Lang


Re: Proposal for a new Temporal time-measurement paradigm

2010-04-24 Thread Jon Lang
Darren Duncan wrote:
> I think that the most thorough solution is to just take it for granted that
> there are multiple reference timelines/calendars and that in general it is
> impossible to reconcile them with each other.

Taking this to its logical extreme, there might be a few (admittedly
fringe) cases where someone might want a calendar that, even in
principle, cannot be reconciled with anything else: consider someone
who's writing an application that tracks events in a fantasy setting,
such as the Lord of the Rings or the Wheel of Time.  (Something like
this actually occurred with a friend of mine, who's hobby is
pen-and-paper roleplaying games; he wanted to build a database to
track the events in his campaign, but ran into the problem that
nothing allowed for the creation of a custom calendar such as the one
in his fictional setting.)

> And so, what we can do in general is simply have an Instant role and a
> Duration role, and pairs of types where each member composes one of those,
> and then all that needs to exist for temporal routines is an independent
> collection for each pair that is closed within that pair.

This is what I was trying to say.  And where you _can_ convert between
calendars, you can always write a "type-casting" routine that takes,
say, a Julian Instant as an input and produces a Gregorian Instant as
the output.

Incidently, it might be possible for two calendar systems to share the
same Duration implementation; IIRC, the Julian and Gregorian calendars
both use the same concept of seconds, minutes, hours, etc.  Likewise,
a calendar system might end up with more than one type of Duration:
it's always possible to convert between seconds, minutes, hours, days,
and weeks; and its also always possible to convert between months,
years, decades, centuries, and millenia; but it isn't always so easy
to convert between days and years.  I could see the Gregorian
implementation having two kinds of Durations: short Durations that
deal with everything from seconds to weeks, and long Durations that
deal with everything from months to millennia.

> Similarly, there would be a calendar for "I don't know what calendar", or
> varying degrees of such, which is often the case for dated historical
> records.

With this, I'm not quite following you.  Could you give an example of
what you mean?

> What calendars/timelines are supported can be implementation-defined and/or
> provided by modules.  Each Perl 6 implementation can be minimalist as far as
> composing classes go; just provide some programmatically readable way to
> discover what calendar the system uses so then modules can use that to
> decide how to make a particular calendar work on any system as possible.

We _should_ define a "default calendar", which is the one that Perl
uses when returning values from now(), etc.  That is, Perl 6.0.0
should define the Instant and Duration roles as you outlined above,
plus a set of classes that implement those roles according to the
Gregorian calendar system.  If you want to replace that with another
calendar system in your implementation of Perl, the language already
has the means of allowing you to do so (e.g., replacing &now with a
variant that returns a different type of Instant).

-- 
Jonathan "Dataweaver" Lang


Re: Proposal for a new Temporal time-measurement paradigm

2010-04-22 Thread Jon Lang
Why do I find myself thinking of roles and classes here?

IMHO, we should have a role that represents abstractly a moment in
time.  This role should, in and of itself, not be tied to any
particular calendar; its purpose is so that one can write functions
that make reference to instances in time without locking oneself into
a particular labeling scheme.  We should also have a series of classes
that compose that role, each class representing a different calendar
scheme.  For perl 6.0.0, only one such class need be defined: the one
representing the Gregorian calendar.  Later on, modules can be written
to provide additional classes representing other calendar schemes.

Fine in theory; in practice, the big question is: how much can we get
the role to do, within the "no calendar preference" constraint?  And a
corollary to this: can we get it to do enough to be worthwhile?

-- 
Jonathan "Dataweaver" Lang


Re: r30357 - docs/Perl6/Spec/S32-setting-library

2010-04-11 Thread Jon Lang
> Log:
> [Numeric] Move sqrt to Numeric. Remove incorrect return value type of roots.  
> Move cis and unpolar to Real.  Add to-radians and from-radians to Numeric.

The return value for roots should have been corrected (to List of
Numeric), not removed.

-- 
Jonathan "Dataweaver" Lang


Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-07 Thread Jon Lang
One more idea: could you implement the sort of thing being asked for
by means of a buffer?  That is, what's the difference between the
bitset being asked for and a Buf[boolean]?  And could those
differences be addressed by composing a Buf[boolean] into a more
appropriate role?

Note also that Perl 6 allows for user-defined array indices.  Since
strings and buffers borrow array syntax for the purpose of accessing
individual components, should it not be possible to define a
customized index for a boolean buffer?  Something like:

my $flags is Buf[boolean]{  };

Again, I'm not sure as to the exact syntax; but it seems to me that
something along these lines should be doable.

-- 
Jonathan "Dataweaver" Lang


Re: A common and useful thing that doesn't appear to be easy in Perl 6

2010-04-07 Thread Jon Lang
Damian Conway wrote:
> I do like the idea of being able to specify the sequence of values of an
> enumeration by using a series of some kind.
>
> And I must say the one that feels most natural is the one that plays on
> the equivalence of underlying equivalence of enums and constants, namely:
>
>    enum Perms  = 1,2,4...*;
>
> This would also mean you could think of a "normal" enum:
>
>    enum Days ;
>
> as simply defaulting to C< = 1...* >.

Wouldn't that be C< = 0...* >?

That said, don't we already have a means of assigning specific values
to individual members of an enum?  I forget the exact syntax, but I
believe that it involves an assignment operator within the
enumeration.  Mind you, this is from memory:

enum Perms { Read = 1, Write = 2, Exec = 4, Fold = 8, Spindle =
16, Mutilate = 32 }

...or something to that effect.  Clumsy, sure; but it seems to me that
this is exactly the sort of thing that hyper-operators were designed
to handle:

enum Perms { Read, Write, Exec, Fold, Spindle, Mutilate } »=« (1,
2, 4 ... 32)
enum Perms { Read, Write, Exec, Fold, Spindle, Mutilate } »=» (1,
2, 4 ... *)

...or something along those lines.  I'll check the exact syntax later,
when I have more time; but I wonder if something to this effect is
already possible with the language spec as written.

-- 
Jonathan "Dataweaver" Lang


Re: numerics, roles, and naming

2010-03-14 Thread Jon Lang
Darren Duncan wrote:
> I'm inclined to consider a "Discrete" to be broad enough to include Boolean,
> as well as every single enum type in general; it would also include Order,
> say.  So I would also then add a more specific something, say
> "DiscreteNumeric".

There are discrete things that are not ordered (such as gaussian
integers), and there are ordered things that are not discrete (such as
real numbers or strings).  As well, I was using the term "Discrete" as
shorthand for "DiscreteNumber", just as "Real" can be thought of as
shorthand for "RealNumber": the role's purpose, regardless of name, is
to mandate methods that are mostly unique to integer math (e.g.,
infix:<%>).  As such, it would be silly to apply the role to, say, an
enum of the days of the week: Thursday % Tuesday should not equal
Sunday; it should be nonsense.

And with that in mind, the role (whatever it's called) should not be
composed into Boolean, even conceptually: while Boolean values can be
mapped to numeric values, they are not inherently numeric, any more
than strings are.  Never mind the fact that there's no practical
application for such things as infix:<%> when talking about a class
with two possible values.

More generally, we need to be careful to keep anything new firmly
grounded in the practical.  If we introduce a "Discrete" role, it
should be because doing so allows us to do something more easily
(taking into account the effort involved in writing the role in the
first place), or because it makes some task possible that would
otherwise be impossible.  A role representing discrete numbers might
just meet these requirements, in that they let you write functions
that depend on being able to, say, factor numbers or find remainders
without worrying about what kind of numbers they are.  And even here
I'm leery, given the fringe status of non-Integer discrete numbers.
I'm not at all sure what practical benefit a generic "Discrete" role
would bring to the table.

Remember also: we're putting together the Perl 6 core here; we need to
show some discretion in terms of what to include vs. what gets "farmed
out" to perl 6 modules.  I suspect that gaussian integers belong
firmly in the latter camp; as such, they are germane to discussions
about core features only to the extent that the core needs to
anticipate such things.

-- 
Jonathan "Dataweaver" Lang


Re: numerics, roles, and naming

2010-03-14 Thread Jon Lang
Ruud H.G. van Tol wrote:
> Did you consider "discrete"?

I think that "Discrete" could work quite well as the role that
encapsulates the ways in which Integer and Gauss are alike.  It may
even be genralizable beyond that, although there might be some discord
between theory and practice.  (In theory, Boolean is every bit as
discrete as Integer is; but in practice, it has no use for most if not
all of the methods in Integer that pertain to discreteness (factors,
remainders, primes, etc.)

-- 
Jonathan "Dataweaver" Lang


Re: numerics, roles, and naming

2010-03-12 Thread Jon Lang
Darren Duncan wrote:
> 2.  There doesn't seem to be a role for "complex" as there is for "integer"
> or "rational" or "real" or "numeric".  So, if the boxed Perl complex number
> is called "Complex" and the machine native one is called "complex" or
> "complex128" or whatever, what would one name the role that is common to all
> of these?

I'm definitely in favor of there being a Complex role - not just for
the reasons given above, but also to have a common role that applies
to a complex number regardless of the coordinate system that's being
used to store the value (e.g. cartesian vs. polar).  Both should be
able to provide you with the real, imaginary, magnitude, and direction
components; but classes based off of the cartesian model should be
able to do the former two directly and calculate the latter two, and
vice versa.  A single role that's agnostic about the coordinate system
would allow us to use any of these in a function call.  For that
purpose, I think that the common, underlying role should be called
"Complex".

> Following the above pattern, you'd think that "Complex" would be best used
> as th role name and so something else is needed for the type, either as some
> abbreviation, or alternately with additions.
>
> Conceivably one could have a complex type defined in terms of any
> combination of the various real or rational or integer types, such as
> "NumComplex" or "RatComplex" (and "FatRatComplex") and "IntComplex" etc.

For practical purposes, I think that the component types for Complex
should be standardized as Real - that is, the Complex role should
assume that the components do the Real role.  As I indicate above, I
think that a more significant distinction should be the coordinate
system: cartesian complex numbers are essentially optimized for use
with addition and subtraction; polar complex numbers are a more
efficient choice for multiplication and division; raising a number to
a complex exponent works most efficiently if the exponent is cartesian
and the result is polar, and vice versa for logs.  And so on.

> For the integer version, my understanding is that number theory already
> provides a suitable term, "Gaussian integer", which is a complex number
> whose real and imaginary parts are both integers.
>
> So I suggest using "Gaussian" as the name option for an "IntComplex".
>
> Or maybe better yet for completion sake, make "Gaussian" a role and
> something like "Gaus" the type or something.

Hmm... true enough.  I'd rather have Gaussian be to Complex as
Integral is to Real: a separate role, not necessarily related in any
sort of role composition sense, but serving a similar purpose.  Note
that Gaussian would not have separate cartesian and polar forms; by
definition, it operates off of a cartesian coordinate system.  While a
polar version could exist in theory, it doesn't in practice; and even
if it did, it wouldn't be interchangeable with the cartesian version,
the way that they are when the components are Real.

OTOH, Gaussian definitely has analogs comparable to the differences
between Integral vs. Real, in that Gaussian and Integral have the
concept of factors and everything that goes with them (e.g., primes,
gcf, lcm, remainders, etc.)  Perhaps we need a role to encapsulate
that notion, much like we have one that encapsulates the notion of
order (e.g., before/after).  Or would that turn out to be unnecessary
clutter, seeing as how we only have two examples of roles that would
compose it (Integral and Gaussian), one of which is a highly technical
fringe case?

> Alternately, while we would still need a Complex-specific role, we could
> possibly avoid a need to explicitly declare some of the composing types if
> Complex is parameterizable, as AFAIK Rational et al are parameterizable.

I'm fine with Complex being parameterizable, as long as Real is the
default parameter.

> 3.  I notice that some roles that are longer forms of type names look like
> nouns, while others look like adjectives.  I suppose that adjectives are
> what you're going after, and the ones that look like nouns such as "Boolean"
> and "Rational" and "Real" are also adjectives.  On the other hand, lots of
> roles are surely just nouns, such as "Failure" and "Routine".
>
> So a question I have is, given the context, is "Integral" the best name for
> that role, or would "Integer" be better?

>From a layman's view of things, I keep on finding myself wanting to
say "Integer" rather than "Integral".  That said, it's not that hard
to retrain myself; and I do see some benefit to the notion that role
names are adjectives while class names are nouns, as long as it's
applied consistently to the standard roles.  That said, see below.

Still: when I first saw "Integral", the first thing that came to mind
was "a calculus operation", not "whole numbers".

> 4.  If "Integral" is better called "Integer", or regardless ...
>
> Would "Numeric" be better called "Number"?  Would there by any objection to
> renaming it such?  What 

Re: built-in roles/types routine boundary

2010-03-08 Thread Jon Lang
On Mon, Mar 8, 2010 at 12:40 PM, Darren Duncan  wrote:
> Starting with the context of this piece of Synopsis 2:
>
>  These types do (at least) the following roles:
>
>    Class       Roles
>    =       =
>    Str         Stringy
>    Bit         Numeric Boolean Integral
>    Int         Numeric Integral
>    Num         Numeric Real
>    Rat         Numeric Real Rational
>    FatRat      Numeric Real Rational
>    Complex     Numeric
>    Bool        Boolean
> 
>
> So I'm wondering how the existing and anticipated built-in
> routines/operators/methods/etc are supposed to stratify between all these
> layers of roles and composing classes.
>
> Looking at Synopsis 32 seems to provide some answers, although it looks
> rather outdated in some respects, I think predating the above table.
>
> For example, since you've got the Numeric role, which is composed by
> integers, including routines that aren't closed over integers such as "log",
> then what routines are left that are just for Integral or Real or Rational?

For Integral?  There might be "remainder"-based routines, a concept
which only exists for integer math.  Also, such things as "greatest
common factor", or even just "factors".  But these are all just
extensions of the same basic principle: Division is not closed over
integers; but instead of banning integer division because the result
won't always be an integer, we instead allow it with a "best match"
approximation when the result isn't Integral, and add routines that
let us determine which numbers will produce Integrals (e.g., factors),
or that produce some sort of Integral representation of the "rounding
error" (e.g., remainders).

Similar routines could theoretically exist for Rationals and Reals: if
I raise Rational $x to the power of Rational $y, will the result be
Rational?  If not, what's the nearest Rational value to $x where the
result _will_ be Rational?  Such routines are not as standard for
Rational and Real as they are for Integral (and thus probably aren't
suitable for implementation in the Perl library); but the principle
remains.

As well, all three of Real, Rational, and Integral have a set of
operations that Numeric lacks: the comparison operators.  Note that
Complex does Numeric; but there is no "before" or "after" for Complex,
so there cannot be a "before" or "after" for Numeric.  I believe that
infix:« are supplied by Ordered?  (I could be wrong
about that.)  Whatever it's called, infix:«('<', '<=', '>', '>=',
'<=>') are defined in Real, Rational, and Integral, but not in Numeric
or Ordered.  Likewise, Stringy defines infix:«, but
Ordered does not.

> Or actually, there is just one main thing I want to know right now ...
>
> You have roles that look like they're supposed to match one specific class
> each in particular, such as Boolean for Bool, Integral for Int, etc,
> ostensibly in case users want to declare their own classes like them.
>
> So, would Int actually have any of its own methods, or would they *all* be
> provided by Integral?  Likewise with Bool and Boolean?  And so on.

My expectation is that all of Int's methods are supplied by Integral;
all of Bool's methods are supplied by Boolean; all of Complex's
methods are supplied by Numeric; all of Num's methods are supplied by
Real; all of Rat's and FatRat's methods are supplied by Rational; and
all of Str's methods are supplied by Stringy.  Conversely, Bit's
methods are supplied by both Integral and Boolean.

Mind you, this is only in terms of "which methods must the class
implement?" - which, ultimately, is what role composition is all
about.  FatRat implements the Rational methods differently than Rat
does, and Bit might implement the Boolean methods differently than
Bool does.  I expect that Stringy, Integral, and Real supply the
appropriate default implementations for Str, Int, and Num,
respectively.  Rational might be a parametric role, with the default
implementations handed to Rat and FatRat differing only in terms of
which data types they work on; but I could be wrong about this.  I
expect that Boolean supplies the default implementations for Bool, and
I suspect that those implementations _might_ be similar enough to what
Bit needs that they can be used there, too.  OTOH, I expect that
Numeric does not provide the default implementations that are used by
Complex.

-- 
Jonathan "Dataweaver" Lang


Re: The silliness of max()

2010-03-07 Thread Jon Lang
Moritz Lenz wrote:
> Please take a look at http://rt.perl.org/rt3/Ticket/Display.html?id=73356:
>
>  rakudo: say max(1..5)
>  rakudo c05478: OUTPUT«-Inf␤»
> * masak submits rakudobug for max(1..5)
>
> The weird thing is that it is right, according to the current spec. It says
>
>  our multi max( Ordering @by, �...@values )
>  our multi max( Ordering $by, �...@values )
>
> so the range 1..5 is actually bound to @by of the first candidate,
> leaving *...@values empty, and the default value of -Inf for a max() with
> no values seems to be quite OK.
>
> Of course this is not what the casual reader suspects.
> My proposed solution is to get rid of the sub form of max() entirely.
> Any objections?

Why not just change the "by" parameter to be named instead of
positional?  Frankly, I don't understand why that isn't already the
case.

-- 
Jonathan "Dataweaver" Lang


Re: Gripes about Pod6 (S26)

2010-02-10 Thread Jon Lang
John Gabriele wrote:
> Personally, I've always thought that Perl has a very natural feel to
> it, and deserves a doc markup format that's also natural: [Markdown]
> (and [Pandoc]'s Markdown has just the right additions, IMO).
>
> [Markdown]: http://daringfireball.net/projects/markdown/
> [Pandoc]: http://johnmacfarlane.net/pandoc/

I definitely prefer Markdown's approach to "inline markup" over POD's
approach: e.g., _italic_ strikes me as much more legible than
I.

That said, Markdown doesn't go far enough in this regard, even with
the Pandoc revisions: for instance, there's nothing equivalent to C<>
or R<> in Markdown.  I'm very much in favor of revising Perl 6's
documentation system to more closely resemble Markdown; but I'd
strongly recommend going through the list of Pod 6 inline tags and
seeing how much of that can be reasonably implemented in a
Markdown-like fashion.

And Markdown gives you nothing in terms of determining how to go about
embedding documentation within a code file: for that, you'd still need
something along the lines of Pod 6's "=begin/=end", "=for", and even
"#=".  That said, if a Markdown-like syntax were to get implemented,
it might be possible to do away with documentation-specific
delimiters, relying instead on the standard comments.

I have more thoughts on this; but they'll have to wait for a bit.

-- 
Jonathan "Dataweaver" Lang


Re: One-pass parsing and forward type references

2010-02-01 Thread Jon Lang
Larry Wall wrote:
> But also note that there are several other ways to predeclare
> types implicitly.  The 'use', 'require', and 'need' declarations
> all introduce a module name that is assumed to be a type name.

Just to clarify: it's possible to define a module within a file,
rather than as a file; and in fact the usual means of defining classes
and roles is an example of this, since they are specialized kinds of
modules.  Correct?  So if I' understanding this correctly, you should
be able to say something like:

use Foo;
class Bar { ... has Foo $x ... }
class Foo { ... }

...where the dots are stand-ins for irrelevant code.  In effect, "use"
tells the compiler that Foo is a noun, so that the parser knows the
proper way to handle it.  It also looks for the definition of Foo; but
will it start screaming bloody murder if it can't find the definition
right away?  Have I failed to correctly tell it where to look for the
definition?  (i.e., do I need to say something like "use ::Foo" to let
the parser know that the definition is in this file?)

-- 
Jonathan "Dataweaver" Lang


Re: Custom errors on subsets?

2010-01-05 Thread Jon Lang
Perhaps you could create an error function that temporarily sets the
default error message (does perl 6 still have the $! variable?) and
returns false; so:

subset Filename of Str where { $_ ~~ :f or error ( "No such file: '$_'" ) }

Of course, that's a rather narrowly-defined function, as it's intended
only for use in one situation - that is, where a boolean test is
likely to be used by the parser to determine whether or not Something
Bad needs to happen.  I can't think of any case other than custom
error messages for subsets where this would happen...

Personally, I'd prefer something more along the lines of:

subset Filename of Str where { $_ ~~ :f; ERROR { "No such file: '$_'" } }

That is, have the parser look inside where blocks (or any other block
that might convert a falsehood to a failure) for an ERROR block that
is intended to be executed just as the error is about to be triggered.
 The primary purpose would be to supply a customized error message
(and for that reason, the return value should be a string that can be
used as $!); but other possibilities would exist.

-- 
Jonathan "Dataweaver" Lang


Re: r29381 - docs/Perl6/Spec

2009-12-19 Thread Jon Lang
On Sat, Dec 19, 2009 at 1:07 PM,   wrote:
>  for the most generic non-failure undefined value.  The C type,
>  derived from C, is also undefined, but excludes C so
>  that autothreading may be dispatched using normal multiple dispatch
> -rules.  The C type is derived from C but nothing else
> +rules.  All user-defined classes derive from the C class by default.
> +The C type is derived from C but nothing else
>  is derived from it.

That's cool with me; but if you're going to introduce a default
derivation, you should also provide a means to explicitly not do it
that way.  What if I need to make a new type that, like junctions,
should not derive from Any, but isn't a junction?  Is it that
explicitly deriving from a type that's already outside of Any (such as
Mu or junction) automatically disables the implicit Any derivation?

-- 
Jonathan "Dataweaver" Lang


Re: Comments on S32/Numeric#Complex

2009-12-17 Thread Jon Lang
Dave Whipp wrote:
> Jon Lang wrote:
>>
>>  my ($num, $denom) = $num.^attr; # $num.WHAT == Ratio;
>>  my ($mag, $phase) = Complex::Polar($z).^attr;
>>  my ($re, $im) = Complex::Cartesian($z).^attr;
>>  my ($x, $y) = $vector.^attr »·« ( [1, 0], [0, 1] );
>
> If I'm reading this right, the .^attr is exposing implementation details of
> the object to get its components. To my mind that is not desirable.

The reason that HOW is spelled in allcaps is because it can be used in
undesirable ways.  In particular, whedn you introspect an object,
you're looking at its implementation details.

And really, my whole point is that the implementation details are
(conceptually) the only thing that distinguishes Complex::Polar from
Complex::Cartesian.  More on this below.

> And I think there's a Math error in the 4th line: you don't need the
> components of a vector to do a dot product with that vector -- so it is just
>
>   my ($x, $y) = $vector «·« ( [1, 0], [0, 1] );

True enough.

> Which makes me wonder if all of them are just the dot-product of an object
> with a role (i.e. it uses the .^attr of the role, not the object):

The role may not have a .^attr; in particular, I'd expect the
following to be true:

  role Complex {
...
method re() { ... }
method im() { ... }
method abs() { ... }
method arg() { ... }
  } # no "has" declarations
  class Complex::Cartesian does Complex { has $re, $im; ... }
  class Complex::Polar does Complex { has $abs, $arg; ... }

There's another problem with my proposal, namely the fact that
introspection of a package's component parts shouldn't be expected to
preserve the order of said components.  But setting that aside for the
moment: Complex.^attr ought to return an empty list, since no
attributes were declared in it; Complex::Polar.^attr ought to return a
magnitude and an argument (i.e., an angle); and
Complex::Cartesian.^attr ought to return a real value and an imaginary
value.

-- 
Jonathan "Dataweaver" Lang


Re: Comments on S32/Numeric#Complex

2009-12-17 Thread Jon Lang
Dave Whipp wrote:
> Moritz Lenz wrote:
>>
>> Dave Whipp wrote:
>>>
>>> [cut] Contrast with Rat which has both separate accessors and the "nude"
>>> method (a name that could possibly be improved to avoid adult-content
>>> filters)
>>
>> suggestions welcome.
>
> Attempting to generalize: what we want is an operator that extracts a Seq of
> values from an object based on a positive criteria. For string objects, this
> description matches the C method. Generalizing:
>
>  my @words = $line.comb( /\S+/ );
>  my ($num, $denom) = $num.comb( :Ratio );
>  my ($mag, $phase) = $z.comb( :Complex::Polar );
>  my ($re, $im) = $z.comb( :Complex::Cartesian );
>  my ($x, $y) = $vector.comb( [1,0], [0,1] );
>

I like the idea of a general mechanism for producing a list of an
object's attributes; but I don't think that .comb() is the way to go
about it.  Rather, I'd use .^attr().

  my ($num, $denom) = $num.^attr; # $num.WHAT == Ratio;
  my ($mag, $phase) = Complex::Polar($z).^attr;
  my ($re, $im) = Complex::Cartesian($z).^attr;
  my ($x, $y) = $vector.^attr »·« ( [1, 0], [0, 1] );

-- 
Jonathan "Dataweaver" Lang


Re: Comments on S32/Numeric#Complex

2009-12-16 Thread Jon Lang
On Wed, Dec 16, 2009 at 2:10 PM, Dave Whipp  wrote:
> The definition of the Complex type seems a little weak. A few things:
>
> To get the Cartesian components of the value there are two methods ("re" and
> "im"). In contrast there is just one method "polar" to return the polar
> components of the value I'm not sure that this asymmetry is a good thing.
> Contrast with Rat which has both separate accessors and the "nude" method (a
> name that could possibly be improved to avoid adult-content filters)
>
> The next thing I notice is that the return value of "polar" is defined as a
> "Seq" (as is the return value of "nude"), with an English-language
> definition of that the (exactly) two members of the sequence are. Surely it
> is possible in a perl6 signature to define the return value more formally,
> something like:
>
>  our multi method polar (Complex $nim: --> [ Real $mag where 0..Inf, Real
> $angle where -π ..^ π ]) is export { ... }
>
> Finally, anyone using complex numbers probably wants a "conjugate" method
> and/or operator postfix:<*> almost as much as they want unary-minus:
>
>  $mag = sqrt( $z * $z* );

All good points.

IMHO, what we want is a role that defines four separate accessors (two
for cartesian coordinates and two for polar coordinates); a "coercion
constructor" (i.e., it accepts any object that does the role, and
returns an object using an implementation to be defined by the class);
a postfix:<*> method; and the usual stuff.  And we want a pair of
classes, one of which implements the role using cartesian coordinates
and another that implements it using polar coordinates.  I forget if
Perl still allows you to use a fully-defined role as a class; if so,
handle the cartesian implementation within the Complex role, with the
ComplexPolar class overriding enough of that definition to make it
polar instead of cartesian.

-- 
Jonathan "Dataweaver" Lang


Re: But vs. With

2009-12-03 Thread Jon Lang
On Thu, Dec 3, 2009 at 6:38 PM, David Green  wrote:
> I'm wondering whether we can make use of the contrary sense implied by the
> word "but", and have it apply specifically to cases where something is being
> overridden.  In cases where there isn't something to override we could use a
> different word, such as "with".

Don't restrict "but".  Instead, I could see a "with" infix op that
works like "but", but with the additional restriction that it cannot
change existing behavior; conversely, "but" _can_ change existing
behavior, but doesn't have to.  So "with" becomes the safe version of
run-time composition, guaranteeing that whatever you mix in won't
disturb existing behavior, and "but" becomes the unsafe version that
you can fall back on when you need to change said behavior.

I do wonder, though, whether "with" should fail if it detects a
conflict, or if it should silently resolve any such conflicts in favor
of the pre-existing methods.  I suppose you could allow for both, with
the default being "fail on conflict" and an adverb being available to
force it to quietly resolve the dispute.

-- 
Jonathan "Dataweaver" Lang


Re: r29111 - docs/Perl6/Spec

2009-11-18 Thread Jon Lang
Moritz Lenz wrote:
>> Given the above, if one wants to construct a full-precision rational
>> value in terms of 3 Int values analogous to a mantissa and radix and
>> exponent, what is the best way to write it in Perl 6?
>>
>> For example, say I want the following expression to result in a FatRat
>> because presumably that's the only type which will represent the result
>> value exactly:
>>
>>   45207196 * 10 ** -37
>>
>> How should that be spelled out in terms of 3 integers?
>
> why 3?

Because three attributes let you define them all as the same kind of
int, instead of one having twice as many bits in it as the other:

has int128 $whole, int128 $numerator, int128 $denominator

vs.

has int256 $numerator, int128 $denominator

This matters when you reach the upper end of the low-level integer
types, such that there is no longer an available integer type that has
twice as many bits as the denominator type.  But as you say, this is
an implementation detail.  The important thing for the Spec to note is
that user expectations require Rational types to be able to handle a
whole number part that's at least as large as the denominator part.
Right now, the spec is addressing this in terms of implementation
details: it assumes that a Rational will store exactly two numbers,
representing the numerator and the denominator, and that the numerator
must have twice as much storage space reserved for it as the
denominator has.  Why twice as much?  So that no matter how large the
denominator is, the numerator will be large enough to store a whole
number part that's at least as large.  The doubled bits isn't an end
to itself, but merely a means to a more fundamental end.

-- 
Jonathan "Dataweaver" Lang


Re: unusual invocants

2009-10-21 Thread Jon Lang
TSa wrote:
> Jon Lang wrote:
>>
>> I have some more thoughts on this; but I'm on a time crunch at the
>> moment, and would really like to get some feedback on the above before
>> proceeding further: have I missed anything in my reasoning?
>
> I fully understand what you mean, I hope. But note that all instances
> of the class that does the two roles do both roles. So the object at
> hand can't select the dispatch target. So it has to come from the
> *environment* of the call. I consider this as very problematic because
> essentially you have to import that into the object so that it can be
> carried for a while---this is what you call wearing a role hat. We
> should keep the class dispatch as simple as possible and not mix in
> the environment of the call into the meaning of an object!

Usually, I'd agree with you - and even here, I'd say that if you can
somehow resolve the dilemma without reference to the environment, that
would be preferable.  However, the only options that appear to be
available without it are the two that Ovid outlined: rewrite one of
the roles, or omit one of them.  Both of these options become
impractical once you account for the likes of CPAN:

* Rewriting one of the roles may not be possible if the programmer
doesn't own either of the offending roles; and even if it is possible,
it likely involves a massive search-and-replace operation that isn't
easily automated.

* Omitting one of the roles is reasonable as long as you can guarantee
that the overall concepts that the roles represent shouldn't be mixed
(as is arguably the case for the traditional Dogwood example); but
it's less than satisfactory when the only reason they can't be mixed
is that each role's author made an unfortunate naming choice for one
of the methods.

My proposal isn't perfect, either: if an established routine fails to
place the appropriate hat on the schizophrenic object, the
environment-based disambiguation won't DWIM and the programmer will be
forced to explicitly resolve the conflict before passing the object
into that routine.  Still, I don't get the same sense of it being a
potential show-stopper the way that I get from the alternatives.

But, as always, the devil's in the details.  Perhaps someone _can_
provide a means of rewriting one of the roles in a way that won't
break anything (the interface, the compiler's back, or the
programmer's mind).  And it may turn out that my proposal is
unworkable once we start looking into the details of how it would be
implemented.

You mentioned that my approach involves importing a bit of the
environment into the object for a while.  How might this be done in a
way that won't wreak havoc?  One possibility would be to hide it away
as a trait of WHAT, and then look for that trait when it comes time to
disambiguate the schizo invocants:

sub party(Drinking $x) { # $x.WHAT:role = Drinking
... $x.go_to_bar; ... # same as $x.go_to_bar:(Drinking:)
}

sub compete(Gymnast $x) { # $x.WHAT:role = Gymnast
... $x.go_to_bar; ... # same as $x.go_to_bar:(Gymnast:)
}

sub joke($x) { $x.WHAT:role is not set
... $x.go_to_bar; ... # can't be resolved without more information

given Gymnast $x { # $x.WHAT:role = Gymnast
... joke($x); ... # the joke is about a Gymnast's bar.
}

Likewise, a method that originated in Drinking (such as .buy_beer)
would set self.WHAT:role to Drinking, thus resulting in any call to
.go_to_bar getting the right method from the class. (Thanks for the
example, Jonathan; I hadn't thought of that rather obvious case.)  If
DrunkGymnast replaces .buy_beer or adds a new method that calls
.go_to_bar, it won't automatically have knowledge of which hat it
should be wearing; but that's OK, because it's expected to know about
both hats, and can explicitly don the right one before (or when)
calling the conflicted method.  It's only those environments that
can't be expected to know about the dual possibilities that concern
me.

What other problems might arise, and how might they be solved?

-- 
Jonathan "Dataweaver" Lang


Re: unusual invocants

2009-10-21 Thread Jon Lang
Jonathan Worthington wrote:
> Ovid wrote:
>>
>> I was asking the special case where:
>>
>> 1. A class consumes two (or more) roles
>> 2. Each roles provides a method with an identical signature
>> 3. The methods are not equivalent and neither role can rely on the other's
>> method
>>
>>  With that, you have roles which cannot be composed. You must rewrite one
>> (bad if you don't own it), or omit one..
>
> When a role is composed into a class, it does quite literally become as if
> it were declared within the class itself (appears directly in the methods
> list), but equally does not lose its lexical scoping relationship with the
> role it was declared in either. Would it help to say that when a method
> declared within a role invokes another method, then we first search the
> methods within that role's lexical scope? Therefore:
>
> role Drinking {
>   method buy_beer() {
>       self.go_to_bar();
>       ...
>   }
>   method go_to_bar() {
>       ...
>   }
> }
>
> role Gymnastics {
>   method go_to_bar() {
>   }
> }
>
> class DrunkGymnast does Drinking does Gymnastics {
>   method go_to_bar() {
>       # something to resolve the conflict here
>   }
> }
>
> This way, the method "buy_beer" will always consider methods in its lexical
> scope first and thus find the role's "go_to_bar" rather than the one in the
> class. Of course, if the role's lexical scope had no methods of that name
> declared within it we'd go elsewhere.

This is close to what I've been suggesting in terms of checking which
hat the object is wearing (or, alternately, which role it is
performing).  The main difference is that the final say _must_ be
given to the class, because only the class knows enough about the
implementation to be sure to do the right thing.  For instance, what
if you want the DrunkGymnast who goes to the bar in the Drinking sense
to automatically be given a citation for doing so?  class DrunkGymnast
is the place where this issue must be addressed.  Or worse: if you
have her go_to_bar in the Drinking sense, you set a flag that
indicates that she's drunk; and if you have her go_to_bar in the
Gymnastics sense while she's drunk, the call should fail.  This can
only be done if you can define two distinct go_to_bar methods within
the class, because Perl no longer has a "want" mechanism that would
allow one method to handle both cases.

This is where my proposal for disambiguating the two of them according
to the invocant comes in.  Ovid need not be right about his statement
#2: while the two methods have the same short names (e.g.,
"go_to_bar") and accept the same arguments (e.g., none), they don't
necessarily have the same signatures, because they can use the
invocant's type to address the "in the Drinking sense" and "in the
Gymnastics sense" concept that I was using in the previous paragraph.
As such, the two methods can have the same names and the same
parameter lists, but still have different signatures (and thus
different long-names): "go_to_bar:(Drinking:)" and
"go_to_bar:(Gymnastics:)".

The trick would lie in making the compiler smart enough to DWIM in
most cases (by figuring out for itself which sense you mean), and in
providing an easy-to-use means of explicitly choosing a sense to cover
the remaining cases.

I have some more thoughts on this; but I'm on a time crunch at the
moment, and would really like to get some feedback on the above before
proceeding further: have I missed anything in my reasoning?

-- 
Jonathan "Dataweaver" Lang


lvalue methods

2009-10-20 Thread Jon Lang
I recently attempted to write a sample mutable role that made use of a
number of lvalue methods, and I had a bear of a time getting it to
work.  Could we arrange for a more intuitive option to be available?
For example, allow the programmer to pass a writer code block in
through the rw trait, and assume that the default codeblock is a
reader codeblock.  Something like:

method x() is rw( { $.x = $_ } ) { return $.x }

The idea is that if this is being called as an rvalue, the { return .x
} block would be called, but if it's being called as an lvalue, the {
.x = $_ } block would be called.

The above example is of course trivial.  A more serious example might
be one based off of a coordinate system:

role point {
has Num $x, Num $y;
method angle() is rw( { $.x = .r * cos($_); $.y = .r * sin($_)
} ) { return atn($.y/$.x) }
method r() is rw( { $.x = $_ * cos(.angle); $.y = $_ *
sin(.angle) } ) { return sqrt($.x * $.x + $.y * $.y ) }
}

This strikes me as being much more readable than the current approach
of explicitly returning a proxy object.  I'd even be fine if the above
were treated as syntactic sugar for the creation of a proxy object -
that is, have:

method x() is rw( { $.x = $_ } ) { return $.x }

be exactly equivalent to something like:

method x($val) is rw { return new Proxy:
FETCH => method { return $.x },
STORE => method { $.x = $_ }
}

...but without the programmer having to worry about how to access the
role's attributes from within the proxy object.

-- 
Jonathan "Dataweaver" Lang


Re: unusual invocants

2009-10-19 Thread Jon Lang
David Green wrote:
> Jon Lang wrote:
>> In "Aiasing methods in CPAN roles", David Green wrote:
>>>
>>> I don't want my special log() method to work only for other types that
>>> explicitly do NumLog; I want it to work for any type that directly "does
>>> Numeric does Logging".
>>
>> But if Logging doesn't do Numeric, why should it be expected to
>> provide a method that assumes that it does?
>
> Well, I don't want all objects that do Logging to do Numeric; I just want to
> have custom methods for those that do happen to do both.

...which strikes me as a perfect argument for putting those methods in
a role that does both.

> If I can put ad hoc compound types into a signature, e.g. foo(Numeric
> Logging) instead of foo(NumLog), then why shouldn't it be possible to define
> a method that way?  Or conversely, should compound types in signatures be
> disallowed, and forced to use "NumLog"/whatever also?

Because a method is part of a role, and ought to abide by the same
terms by which the role abides.  If Logging doesn't do Numeric, it
shouldn't have any methods in it that won't work unless it does.

-- 
Jonathan "Dataweaver" Lang


Re: Aliasing methods in CPAN roles

2009-10-19 Thread Jon Lang
Raphael Descamps wrote:
> In the original traits paper the aliasing is not "deep": to respect the
> flattening property, the semantic of the role must not change, so
> aliasing a recursive method will call the original method. It's a known
> theoretical weakness of the traits paper and "freezing roles" try to
> solve this problem.

It's a problem that doesn't exist if you don't alias.  However, you
run into another problem; namely, what to do if two roles provide
semantically incompatible definitions for the same method.  To be
fair, ailasing doesn't solve the problem either, for the reasons that
I outlined in my last post (i.e., aliasing breaks the interface).  And
"freezing roles" doesn't solve the problem either; it just specifies
which role is broken in the combined interface.  As far as I can tell,
there are only two solutions that actually solve the problem: don't
compose two roles that have incompatible methods, or find a way for
the incompatible definitions to coexist under the same name.

The former approach works off of the theory that if the names are the
same, the semantics ought to be compatible; and thus incompatible
semantics are a sign of poor design of the base roles.  In an
environment where the programmer has the ability to rewrite everything
with which he's dealing, this makes a great deal of sense.  But as
Richard pointed out, CPAN is a counterexample to this: it is
unreasonable to assume that two modules imported from CPAN, written in
isolation by different authors, will never provide conflicting roles
due to nothing more than conflicting naming conventions - roles that,
in concept, ought to be able to be used together.

As I understand things, Richard's proposed solution is to alias one of
the offending methods during the import, effectively rewriting the
source module to use a different name for the offending method, for
the sole purpose of exporting to the target application.  IMHO, this
only works if you follow the chain of compositions all the way and
alias everything.  That is:

   role Foo { method x; }
   role Bar does Foo { method x; }
   role Baz does Foo { method x; }

If you want to alias Bar.x on import, there should be an implicit
aliasing of Foo.x as well, which would lead to the implicit aliasing
of Baz.x too.  It's the only way to avoid broken interfaces: you need
to change all related interfaces to remain compatible with the one
that you change, both up and down the composition chain.  Needless to
say, this strikes me as impractical, due to the effort involved in
figuring out what needs to be aliased and what doesn't.


Another possibility would be to borrow a page from XML Namespaces,
which addressed a similar problem: allow the programmer to require
imported elements to be referenced in terms of the module from which
they were imported.  E.g.:

use Kennel prefix Foo; # imports role Dog
use Forest prefix Bar; # imports role Tree
class Dogwood does Foo-Dog does Bar-Tree  { ... }
my $dogwood is Dogwood;
$dogwood.Foo-bark;
$dogwood.Bar-bark;

The idea here is that "prefix Foo" and "prefix Bar" cause every name
that gets imported from that module to be prefixed with that string.
So class Dogwood wouldn't have a "bark" method: it would have a
"Foo-bark" method and a "Bar-bark" method.  IOW, the above would be
equivalent to:

role Foo-Dog { ... method Foo-bark { ... } ... }
role Bar-Tree { ... method Bar-bark { ... } ... }
class Dogwood does Foo-Dog does Bar-Tree  { ... }
my $dogwood is Dogwood;
$dogwood.Foo-bark;
$dogwood.Bar-bark;

-- 
Jonathan "Dataweaver" Lang


unusual invocants

2009-10-19 Thread Jon Lang
In "Aiasing methods in CPAN roles", David Green wrote:
> Jon Lang wrote:
>> David Green wrote:
>>>
>>> I would expect that "role Logging { method log(Numeric $x:) {...} }"
>>> means the invocant is really of type Numeric & Logging, without Logging
>>> having to do Numeric.  On the other hand, I can see that strictly that might
>>> not make sense, so perhaps I really do need to create a compound NumLog type
>>> first, so I can have method log(NumLog:)?
>>
>> I think you should need to do this.
>
> That's cumbersome, though.  I don't want to create some new type, that
> happens to do Numeric and Logging (in addition to other stuff it might do);
> I want to affect everything else that does both roles.  That is, I don't
> want my special log() method to work only for other types that explicitly do
> NumLog; I want it to work for any type that directly "does Numeric does
> Logging".

But if Logging doesn't do Numeric, why should it be expected to
provide a method that assumes that it does?

-- 
Jonathan "Dataweaver" Lang


Re: Aliasing methods in CPAN roles

2009-10-19 Thread Jon Lang
Raphael Descamps wrote:
> I personally don't understand why we don't have a exclude and alias
> operator in Perl 6 but I have not read all the synopses and don't have
> an overview.

I don't think that it's explicitly spelled out anywhere; but the
reason is fairly straightforward: exclude and alias would break the
interface.

Take Stringy as an example: when a class says "does Stringy", it's
making certain promises about its syntax and semantics: e.g., it will
have a "method say", and "method say" should result in sending a
string of text to an output stream.  Thus, any routine that asks for
"Stringy $x" as one of its parameters should be able to put "$x.say"
in its code and get the expected results.

But if Foo does Stringy but excludes or aliases .say, a routine that
asks for a Stringy $x but receives a Foo $x will run into problems the
moment "$x.say" shows up in its code.  If .say was excluded, the
semantics are no longer available at all.  If it was aliased, the
semantics are still available under another name; but that does the
routine no good, because it has no idea what the new name is, or even
that it exists.  Either way, "$x.say" will not do what the routine
intended it to do.  The interface is broken.

--
Jonathan "Dataweaver" Lang


Re: Aliasing methods in CPAN roles

2009-10-18 Thread Jon Lang
David Green wrote:
> Jon Lang wrote:
>>
>> This implies that both Logging and Math do Numeric, since the invocant
>> ought to be of a type that the class does.
>
> I would expect that
>    role Logging { method log(Numeric $x:) {...} }
> means the invocant is really of type Numeric & Logging, without Logging
> having to do Numeric.  On the other hand, I can see that strictly that might
> not make sense, so perhaps I really do need to create a compound NumLog type
> first, so I can have method log(NumLog:)?

I think you should need to do this.

> Or can I create a method outside of any role:
>    role Numeric {...}
>    role Logging {...}
>    method log(Numeric Logging $x:) {...}
>
> (of course, that might be implicitly creating an anonymous compound type for
> me...)

Last I checked, all methods must be members of a class or role.

>> I think that what you're actually looking for (for the purpose of
>> illustration) is Logging::log:(Numeric $x:) and Numeric::log:(Numeric $x:).
>
> Oh, yes!
>
>> If $x does Numeric and $x does Logging, then it has a class that has
>> already encountered the potential conflict and resolved it in some way.  For
>> example:
>>
>>   class Baz does Numeric does Logging {
>>       method log(Numeric $x:) {$x.Numeric::log;}
>>       method log(Logging $x:) {$x.Logging::log;}
>>   } #`> asked to play: Numeric or Logging.>
>>
>> Baz illustrates my proposal: if $x is a Baz, it will need to check the
>> context to see if it's supposed to be acting like a Numeric or like a
>> Logging, and will act accordingly - or it will complain about ambiguity if
>> it can't figure out which role to play.  And the definition for Baz works
>> because Logging does Numeric.
>
> I suppose given that I want Logging's method log(Numeric Logging:) rather
> than its log(Any Logging:), the second method there should really be:
>    method log(Numeric Logging $x:) {$x.Logging::log;}

I suppose that that would work, too.

> (The only way to have the same sig twice would be something like if Logging
> defined a special version of log() for Numeric objects, while Numeric
> defined a special log() for Logging objects -- but semantically that ought
> to mean the same thing in both cases, so we do want a single method to
> handle that.)

And if you limit yourself to referencing types that the method's role
does, this won't be an issue.

>> If you can't tell by the routine's signature, my own preference would be
>> to make it explicit by means of a "given" block:
>>
>>   given Logging $x { .log } # logs like a Logging
>>   given Numeric $x { .log } # logs like a Numeric
>
> I also thought "given" sounded good for this, but it would have to work
> differently from a normal "given": if $x doesn't do Logging, then it needs
> to skip the block.  (Also, it looks very close to casting: "given
> Logging($x)".  Maybe something a bit more visually distinctive would be
> helpful, something like "given $x as Logging", etc.?)

IMHO, "given $x { ... }" is effectively syntactic sugar for "$x -> $_
{ ... }", and "given Numeric $x { ... }" would be syntactic sugar for
"$x -> Numeric $_ { ... }".  If $x doesn't do Numeric, the default
behavior should be a fail.

>>   $x -> Numeric $n { ... ; $n.log ; ... }
>
> What I like about this is using a sig to apply the context, so no new syntax
> is needed.
>
> (But I'll suggest something new for -> in general: what if "$x -> Numeric"
> with no "$n" variable were shorthand for "$x -> Numeric $x is rw", i.e. a
> shorthand that used the same variable name inside the block as the one being
> passed in?  That would be useful in cases like this where we don't
> particularly want to rename $x.)

It wouldn't always be workable; for instance, "@a -> Numeric, Stringy
{ ... } would grab the first two element of @a and would put them into
parameters; but there would be no obvious names to assign to those
parameters.

-- 
Jonathan "Dataweaver" Lang


Re: Aliasing methods in CPAN roles

2009-10-17 Thread Jon Lang
David Green wrote:
> Aha, so the bark:(Dog:) syntax identifies the method by its signature as
> well, thus distinguishing it from the .bark:(Tree:) method.  This works fine
> when the sigs can distinguish the invocants, which is very common.  However,
> I could have ambiguous methods even including the signatures.  Suppose I
> have a Logging role that provides a log() method for printing some info
> about a variable.  In particular, I have method log(Numeric $x:) { ... }
> because I want to handle Nums specially (say, round them off before
> printing).  Meanwhile, suppose I also have Math::log(Numeric $x:).

So you have Logging::log:(Numeric $x:), and you have
Math::log:(Numeric $x:).  This implies that both Logging and Math do
Numeric, since the invocant ought to be of a type that the class does.
 (And incidentally, this brings up another issue: as written, Math
isn't a class; it's a module.  Modules generally don't do roles,
assuming that they even can.)

Note further that in the setting, you actually have Math::log:(Numeric
$x).  Modules usually don't have methods, and so their routines
generally don't have invocants.

I think that what you're actually looking for (for the purpose of
illustration) is Logging::log:(Numeric $x:) and Numeric::log:(Numeric
$x:).  Continuing on with that:

> If $x does Numeric and does Logging, then $x.log won't be able to decide
> which method to call, unless maybe it's in a sub like foo(Numeric $x) that
> can know to provide "Numeric" context to $x.

If $x does Numeric and $x does Logging, then it has a class that has
already encountered the potential conflict and resolved it in some
way.  For example:

class Foo does Numeric does Logging {
method log(Numeric $x:) {$x.Numeric::log;}
} # Foo picks out the method from Numeric.

class Bar does Numeric does Logging {
method log(Numeric $x:) {$x.Logging::log;}
} # Bar picks out the method from Logging.

class Baz does Numeric does Logging {
method log(Numeric $x:) {$x.Numeric::log;}
method log(Logging $x:) {$x.Logging::log;}
} #`

If $x is a Foo, then $x.log will always behave like Numeric::log; if
$x is a Bar, then $x.log will always behave like Logging::log.

Baz illustrates my proposal: if $x is a Baz, it will need to check the
context to see if it's supposed to be acting like a Numeric or like a
Logging, and will act accordingly - or it will complain about
ambiguity if it can't figure out which role to play.  And the
definition for Baz works because Logging does Numeric.

You cannot define a class that does Logging and does Numeric without
defining at least one log method, because they conflict; and a class
must somehow resolve all such conflicts.

> Outside foo, or inside a sub
> like bar(Any $x), I need some other way to indicate which "log" method I
> mean.  $x.log:(Numeric:) won't work here, because both roles provide a
> method with that name and signature.

As I indicated above, it will work, because $x.WHAT will have
addressed the matter already.  In the Foo and Bar cases, it addresses
the matter by picking one or the other and preventing access to the
one it doesn't pick; this is a viable stratagem if Logging and Numeric
are semantically similar (and, seeing as how Logging does Numeric,
they probably are).  In the Baz case, it addresses the matter by
making two options available according to the role being played:
Numeric or Logging.  All you have to do then is to somehow indicate
which role is being played.

If you can't tell by the routine's signature, my own preference would
be to make it explicit by means of a "given" block:

given Logging $x { .log } # logs like a Logging
given Numeric $x { .log } # logs like a Numeric

But I could see other alternatives:

.log given Logging $x; # assumes the inclusion of a "given"
statement modifier.
$x -> Numeric $n { ... ; $n.log ; ... }
$x.log:(Logging:);

The point is that you're never going to have two different
&log:(Numeric:) methods in the same class.

-- 
Jonathan "Dataweaver" Lang


Re: Freezing role methods

2009-10-14 Thread Jon Lang
Darren Duncan wrote:
> Jon Lang wrote:
>> Here, we need a bit of a clarification: are we talking roles or
>> classes?  Real example: Numeric is a role; Num is a class.  Both can
>> be used in signatures; but only classes can be used to create objects.
>>  That is, "my Num $x;" works; but "my Numeric $x;" doesn't.  As such,
>> you cannot coerce an object to a role; you can only coerce it to a
>> class that does that role.
>
> Bad example.  Both of those would work.  Otherwise one of the main reasons
> for roles to exist, which is to be able to declare a container $x and say
> that it may hold anything that does role Y, wouldn't be possible.  Perhaps a
> better example is "Num.new(...)" works but "Numeric.new(...)" doesn't. --

You are, of course, correct.  I think that what I meant to say was "my
$x is Num" vs. "my $x is Numeric".


-- 
Jonathan "Dataweaver" Lang


Re: Freezing role methods

2009-10-14 Thread Jon Lang
David Green wrote:
> Jon Lang wrote:
>> David Green wrote:
>>> On the other hand, $dogwood.Dog::bark cannot be simplified by leaving out
>>> the "Dog::" because then it would be ambiguous.
>>
>> On the gripping hand, if we have a function "train(Dog $d)", then we can
>> safely assume that within the lexical scope of train, $d is supposed to be
>> treated as a Dog.  So within that lexical scope, it should be safe to leave
>> off the "Dog::".
>
> Yes; and then my question from last time is whether the sig (Dog $d)
> "soft-casts" the arg such that the non-doggy bits of $d still remain, e.g.
> if inside train() we call a function chop(Tree $t), chop() will
> unambiguously see the Tree-half of the original Dogwood object.  Or will it
> be "hard-cast" such that the non-doggy bits are simply lost?  (And if so,
> does an ordinary cast Foo($d) do the same thing, or is one "hard" and one
> "soft", etc.?)

Here, we need a bit of a clarification: are we talking roles or
classes?  Real example: Numeric is a role; Num is a class.  Both can
be used in signatures; but only classes can be used to create objects.
 That is, "my Num $x;" works; but "my Numeric $x;" doesn't.  As such,
you cannot coerce an object to a role; you can only coerce it to a
class that does that role.

And when passing parameters, you don't coerce the object at all.  You
smart-match the prospective object against the criteria provided by
the signature to determine whether or not it's acceptable.

...which is a long-winded way of saying that it would be like a "soft
cast": all of the object's capabilities remain intact after being
passed as a parameter; the only thing that would change would be that
the lexical scope inside the routine would show a preference for the
Dog-like features of the object.  If you asked for a Dog, it's
reasonable to assume that you were given a Dog.

And the way I see it working, this preference would only show up in
one very specific circumstance: namely, when the object in question
has multiple methods that are distinguished from each other by their
invocant types.  When in a lexical scope that shows a preference for
$dogwood to play the role of a Dog, a call to $dogwood.bark() would
result in MMD looking at &bark:(Dog $dogwood:) and &bark:(Tree
$dogwood:) and choosing the former.  When in a lexical scope where the
preference is for $dogwood as a Tree, it would resolve the decision in
favor of the latter.  And if neither or both are preferred roles for
$dogwood, it would fail on account of too much ambiguity.

Another clarification: there's a subtle but important difference
between "$dogwood.bark:(Dog:).()" and "$dogwood.Dog::bark()".  The
former calls a Dogwood method that has an invocant that does Dog; the
latter calls a Dog method.  That is:

$dogwood.bark:(Dog:).(); # calls &Dogwood::bark:(Dog:)
$dogwood.Dog::bark();# calls &Dog::bark:()

And because of the flattening nature of role composition, the latter
doesn't work: after you have composed Dog and Tree into Dogwood,
objects that are based on Dogwood no longer have access to the methods
provided by Dog or Tree; they only have access to the methods that
Dogwood provides.  (Caveat: if Dogwood doesn't explicitly provide a
method corresponding to something found in Dog or Tree, it does so
implicitly.)  This is perhaps the most crucial difference between role
composition and class inheritance: once role composition is complete,
you can ignore the implementation details of the roles that were
composed; all that matters is the implementation of the role or class
into which they were composed.

> However, I expect that "my Dog $d = $dogwood" would strip out everything
> else, on the grounds that you explicitly requested a pure Dog object.
>  Otherwise you could have said "my $d = Dog($dogwood)" or maybe "my
> $dogwood.^WHAT $d = $dogwood" instead.

With "my Dog $d = $dogwood", $d is a Dog that was initialized using
values gleaned from $dogwood.

-- 
Jonathan "Dataweaver" Lang


Re: Freezing role methods

2009-10-14 Thread Jon Lang
David Green wrote:
> Or to look at it the other way around:  Since we refer to things by name,
> those names have to be unique everywhere; so let's start out with long,
> "fully-qualified" names everywhere: $dog.Dog::bark(), $tree.Tree::bark(),
> $i.Int::succ, etc.  Now everything's fine -- except that our fingers are
> getting tired from all that typing.  We want to use shortcuts to say things
> like $dog.bark, because there's only one place that $dog can legitimately
> find a bark() method, and that's in the Dog class, so both we and Perl can
> easily figure out what is meant.
>
> On the other hand, $dogwood.Dog::bark cannot be simplified by leaving out
> the "Dog::" because then it would be ambiguous.  But if we look at it as
> starting with full names everywhere, and seeing what we can leave out
> (rather that starting with short names and having to add stuff in), I think
> it's not surprising.

On the gripping hand, if we have a function "train(Dog $d)", then we
can safely assume that within the lexical scope of train, $d is
supposed to be treated as a Dog.  So within that lexical scope, it
should be safe to leave off the "Dog::".  If you pass $dogwood into
this method, the ambiguity between Dog::bark and Tree::bark gets
resolved in favor of the former; so $d.bark _still_ barks like a Dog,
even though $d is actually a Dogwood.  That's what I was meaning when
I talked about wearing hats: while it's within the train() sub,
$dogwood is wearing its Dog hat and barks like a Dog.

>> I really don't think that deferring the decision works.  The "freezing"
>> technique described in the paper allows the consumer, C, to statically bind
>> the method foo() in the methods in the appropriate role which call it.
>
> The problem with "freezing" some methods into private ones is that those
> methods weren't meant to be private; if my role provides a .bark method, I
> need to be able to call it.

And more to the point, subs that aren't expecting a Dogwood should
still be able to accept it in its role as a Dog, call .bark, and
expect it to bark like a Dog.

-- 
Jonathan "Dataweaver" Lang


Re: Freezing role methods

2009-10-14 Thread Jon Lang
Ovid wrote:
> The only way to handle this appears to be renaming one of the x()
> methods and trying to track down all code which relies on it and
> changing it.  This essentially violates the problem we're trying to
> solve with traits, er, roles.
>
> In short, under the original traits model, you have roles you can't
> compose together.  The paper argues that in languages which have
> "public" and "private" methods, that the composing class is allowed to
> decide which x() method it needs (if any) and that it can *freeze* the
> other x() method.  That is to say, the x() in question would become
> private and statically bound to the invocants to ensure that they're
> always calling the correct x().
>
> How would Perl 6 approach this issue?

The fundamental problem is that there are times when you need both
versions of a given method to be available, but you don't want to
rename either of them.  This leads to a namespace clash.

The initial possibility that springs to mind would be to use longnames
to disambiguate between the two options - specifically, by means of
the invocant:

role T1 { method foo() }
role T2 { method foo() }
class C does T1 does T2 {
method foo(T1 $self:) { $self.T1::foo() }
method foo(T2 $self:) { $self.T2::foo() }
}

...or something to that effect.  You'd still have a disambiguation
issue, in that you'd somehow need to specify which "hat" an object of
class C is wearing when you try to call the method.  (I like this
approach because it requires you to explicitly identify that the class
is deferring the disambiguation, rather than having it silently occur
behind the scenes.)

Much of this could be handled implicitly, by means of which role was
requested when the object was passed into the current block:

sub bar (T1 $x) { ... }
sub baz (T2 $x) { ... }
my C $x;

bar $x;

Since "bar" is expecting an object that does T1, code within bar
should resolve the ambiguity involving foo in favor of foo:(T1:) -
that is, within the lexical scope of sub bar, $x is wearing its T1
hat.  Ditto with baz and T2.

In other cases, there may be no way to implicitly disambiguate.  In
those cases, there would need to be an explicit way to decide which
hat the object is wearing.  My gut instinct would be to use the same
syntax as is used to coerce an object into a particular class, but
with a role name instead of a class name.  It differs from coercion in
that it wouldn't actually change the underlying object; all it would
do would be to decide which role to favor when resolving disputes of
this sort.

In short, resolve the dilemma by allowing the class the option of
deferring the disambiguation until the method is called, and then to
try to resolve it first by means of the overall context in which the
call is made.

This "Schrodinger's method" approach doesn't fix everything; but I
suspect that it should usefully handle the majority of problems that
arise.

--
Jonathan "Dataweaver" Lang


Overloading Roles

2009-10-05 Thread Jon Lang
Consider a Range role that is parameterized (i.e., "Range of T" is a
perfectly valid thing to do).  According to the spec, the definition of
Range depends on the nature of T:

* If the lower bound is Numeric, certain coercion rules are attempted on the
upper bound; otherwise, the two boundaries must have the same type.
** Speculation: if the lower bound is a Whatever, the boundary type should
be determined by the upper bound; if both are Whatever, treat it as Numeric?
* if the boundary type has a .succ method, then the Range can provide a
RangeIterator; otherwise, it can't.

Concerning that last one: would it be reasonable to have a Discrete role
that provides a .succ method, and then overload the Range role?  E.g.:

role Range[Ordered ::T] { ... }

role Range[Ordered Discrete ::T] {
...
method iterator ( -> RangeIterator ) { ... }
}

If so, then this approach might also be used to handle the special behavior
that comes with Numeric types:

role Range[Ordered Numeric ::T] { ... }

-- 
Jonathan "Dataweaver" Lang


Re: r28597 - docs/Perl6/Spec/S32-setting-library

2009-10-04 Thread Jon Lang
Moritz Lenz wrote:
> Jon Lang wrote:
>> typos: s[Nuermic] = "Numeric"
>
> You do have a pugs commit bit, don't you?

A what?  AFAICT, I don't have any way of editing the Synopses; all I
can do is to comment on what I find.

-- 
Jonathan "Dataweaver" Lang


Re: r28597 - docs/Perl6/Spec/S32-setting-library

2009-10-04 Thread Jon Lang
How do pred and succ work when given Complex values?

More generally: if Complex does Numeric, then Numeric doesn't include
Ordered (or whatever it's called), because Complex doesn't do Ordered.
 As such, you can't used Numeric for any function that depends on the
value being Ordered.

On Sun, Oct 4, 2009 at 10:15 AM,   wrote:
> @@ -255,7 +284,7 @@
>
>  =item I
>
> - Num multi method func ( Num  $x: TrigBase $base = $?TRIGBASE ) is export
> + Nuermic multi method func ( Nuermic  $x: TrigBase $base = $?TRIGBASE ) is 
> export

typos: s[Nuermic] = "Numeric"

>  where I is one of:
>  sin, cos, tan, asin, acos, atan, sec, cosec, cotan, asec, acosec,
> @@ -281,14 +310,58 @@
>
>  =item atan2
>
> - our Num multi method atan2 ( Num $y: Num $x = 1 )
> - our Num multi atan2 ( Num $y, Num $x = 1 )
> + our Nuermic multi method atan2 ( Nuermic $y: Nuermic $x = 1 )
> + our Nuermic multi atan2 ( Nuermic $y, Nuermic $x = 1 )

More typos: s[Nuermic] = "Numeric"


-- 
Jonathan "Dataweaver" Lang


Re: generality of Range

2009-10-04 Thread Jon Lang
yary wrote:
> I'm confused between using ranges to generate a lazy list and using
> them as criteria to match against.

Indeed.  It was my understanding that there was a recent change to
Ranges so that they now exist primarily to be used as matching
criteria.  If you wish to generate a list, the preferred approach
these days is the ... infix operator:

1 .. 100 # the range of values between 1 and 100, inclusive.
1, 2 ... 100 # a list of integers.

The ability to generate a lazy list using a Range object is now of
secondary importance, and should not be a required feature anymore.
In particular, :by was removed from Range.

-- 
Jonathan "Dataweaver" Lang


Re: r28528 - in docs/Perl6/Spec: . S32-setting-library

2009-10-01 Thread Jon Lang
On Thu, Oct 1, 2009 at 9:53 AM,   wrote:
>  The Perl 6 equivalent to Perl 5's C is C.
>  (Perl 6's C function only evaluates strings, not blocks.)
> -A C block by default has a C block that handles all
> +A C block by default has a C block that handles all fatal
>  exceptions by ignoring them.  If you define a C block within
>  the C, it replaces the default C.  It also makes the C
>  keyword redundant, because any block can function as a C block

OK; so any block with a CATCH block in it is effectively a 'try' block...

>  our multi method warn ( Object $o: ) is export
>
> -Prints a warning to C<$*ERR>, which is usually finds C<$PROCESS::ERR>. See
> -C for details.
> +Throws a resumable warning exception, which is considered a control
> +exception, and hence is invisible to most normal exception handlers.
> +The outermost control handler will print the warning to C<$*ERR>
> +(which is usually finds C<$PROCESS::ERR>; see C +IO / Signals> for details).  After printing the warning, the exception
> +is resumed where it was thrown.  To override this behavior, catch the
> +exception in a CONTROL block.  A quietly {...} block is the opposite of a
> +try {...} block in that it will suppress any warnings but pass fatal
> +exceptions through.

...while any block with a CONTROL block in it is effectively a
'quietly' block.  Right?  If so, could this be spelled out in S04,
immediately after the discussion about 'try'?

-- 
Jonathan "Dataweaver" Lang


Re: object possible representations (was Re: r28523 - ...)

2009-10-01 Thread Jon Lang
Some further thoughts:

Essentially, this could be done as an extension of the versioning
system.  The difference between "possrep" versioning and normal
versioning would lie in the means by which the possrep dimension would
be resolved if not specified.  Namely, the compiler would make the
decision based on the natures of the various classes and the
preferences of the various function calls.  To illustrate, let's say
that we have two implementations for Complex: one that's optimized for
rectilinear coordinates, and another that's optimized for polar
coordinates.

class Complex:opt { ... }
class Complex:opt { ... }

...where "opt" is short for "optimized implementation".  Both
implementations of Complex would be able to use rectilinear and polar
accessors; indeed, the assumption is that both are capable of handling
the exact same interfaces, differing only in terms of how well they
handle various aspects thereof.

A routine's signature could then include a request for one or the
other - say, something like:

sub foo(Complex:opt) { ... }

This would not _require_ that a Complex:opt be provided; only
that a Complex be provided.  But if I were to say "my Complex $x;",
followed by a large number of "foo $x" calls, the compiler might
choose to implement $x as a Complex:opt.

More radically, the sig might be able to provide a priority number as
well as an "option name": e.g., 0 for "this is just a suggestion"; 1
for "it's strongly recommended that you supply this implementation";
and 2 for "do whatever it takes to supply this implementation".  So:

sub foo(Complex:opt) { ... }
sub bar(Complex:opt) { ... }

...Would mean that if you try to hand foo a Complex:opt, foo
will coerce it into a Complex:opt before using it; whereas bar
would accept it as is.  But if the compiler sees that a lot of bar $x
calls are coming up, and $x is currently a Complex:opt (or it's
at the declarator and no implementation preference has been given), it
might convert $x to a Complex:opt before it gets to the first of
them, just to smooth the way.

-- 
Jonathan "Dataweaver" Lang


Re: object possible representations (was Re: r28523 - ...)

2009-10-01 Thread Jon Lang
Darren Duncan wrote:
> Jon Lang wrote:
>> I'm not sure that I feel comfortable locking C into
>> rectilinear coordinates as its internal storage method, as there will
>> be cases where the code operates more smoothly if you're using polar
>> coordinates to store the numbers: we should leave the inner workings
>> up to the Parrots to decide.  But whichever approach gets used, if
>> either component is NaN, then the complex number should also be NaN.
>
> I'm not sure if the idea is applicable to Perl 6 because Perl 6 already has
> an alternative but ...
>
> One of the features of my Muldis D language is called possreps (possible
> representations) where you may define more than one alternative set of
> attributes for a data type (and if more than one, you also define functions
> to map between each attribute set) and then the implementation can choose
> for itself which of those representations (or it can pick yet another one of
> its own) is the actual one used physically behind the scenes and which is
> virtual, and the user could use either as if it were the real one.
>
> What Perl 6 could do with this concept is for example it can define for some
> classes multiple possible object attribute sets, so users know they can use
> any of those, and then each Perl 6 implementation can choose what to do
> natively.
>
> So the Perl 6 spec can and should enumerate the various reasonable
> alternative sets of attributes that a Complex object could have, and the
> Parrots can choose which to use internally, or could use more than one on a
> case-by-case basis.
>
> Note that ideally this would be a feature that user-defined classes can use,
> and not just language built-in ones.

This sounds a bit like how the "multi" keyword applies to Perl 6
routines to define several routines that share one name.  Perhaps
there's a way to say "multi class", letting you define several
"classes" that are different implementations of the same thing, with
each class definition within the multi class being a "possrep".  I'm
not exactly sure how this would work (you'd need some way to
distinguish between the different class definitions, much like multi
routines each have a unique long name even though they share the same
short name); but it strikes me as being more in keeping with the
nature of Perl than nesting several possrep blocks within a single
class definition.  Perhaps a multi class would involve some sort of
implicit version control, with each class definition being given a
slightly different version?  (Do we still have proto routines to go
along with multi routines?  If so, you could use a proto class to
define common features shared by all of the implementations, such as
identifying which roles the multi class does.)

Whatever mechanism gets established, the basics would involve being
able to establish more than one possible implementation for a class,
combined with an ability to identify each implementation's relative
strengths and weaknesses so that the compiler has a way to choose
which one to use.

> Now in Muldis D this system is strict and requires that one can round-trip
> between any 2 possreps and have identical attribute values to what one
> started with, so the Complex example where conversion would by nature be
> approximate wouldn't work there; but in Perl or a language where
> nonidentical round-trips are allowed, this may work for Complex too.  But
> then the implementation would have to always use the same physical
> representation for all objects of the same class, or else it wouldn't always
> DWIM when some one tries an exact equality test with objects.

If only there was a way for Perl to track exact values for irrational
numbers like it does for rationals, rather than trying to approximate
them with Num; then one _could_ set up a round trip between
rectilinear and polar coordinates that preserves the original values
(in theory, at least; you'd still have to figure out how to address
the "0 = 2 * pi" problem).

-- 
Jonathan "Dataweaver" Lang


Re: r28523 - docs/Perl6/Spec/S32-setting-library

2009-10-01 Thread Jon Lang
On Wed, Sep 30, 2009 at 11:58 PM,  wrote:
>
> Author: moritz
> Date: 2009-10-01 08:58:00 +0200 (Thu, 01 Oct 2009)
> New Revision: 28523
>
> Modified:
>   docs/Perl6/Spec/S32-setting-library/Numeric.pod
> Log:
> [S32::Num] More thoughts on Inf/NaN Complex, and on comparing Complex and 
> Real numbers
>
> Also bring the goodness of the newly defined Numeric and Real roles to some of
> the signatures.
>
> Modified: docs/Perl6/Spec/S32-setting-library/Numeric.pod
> ===
> --- docs/Perl6/Spec/S32-setting-library/Numeric.pod     2009-10-01 02:34:54 
> UTC (rev 28522)
> +++ docs/Perl6/Spec/S32-setting-library/Numeric.pod     2009-10-01 06:58:00 
> UTC (rev 28523)
> @@ -175,9 +175,12 @@
>
>  =item roots
>
> -  (in Num) method roots (Num $x: Int $n --> List of Num) is export
> +  (in Num) method roots (Numeric $x: Int $n --> List of Num) is export
>
> -Returns a list of all C<$n>th (complex) roots of C<$x>
> +Returns a list of all C<$n>th (complex) roots of C<$x>. Returns C if
> +C<< $n <= 0 >>, itself if C<$n == 0>,  and is free to return a single C

Shouldn't this be "C<< $n < 0 >>"?  Also, I'm not sold that this
should return List of Num; I'd expect it to return a List of Numeric,
with the possibility (and, indeed, likelihood) that subsequent roots
will be Complex.

> +if C<$x> is C or C, or in case of complex numbers if one of the
> +components is.

Ideally, the complex numbers case should be a moot point: if one of a
complex number's components is NaN or Inf, then the complex number
should be, too (with NaN taking precedence over Inf in the two cases
where one component is NaN and the other is Inf).  Exception: when a
complex number's arg is Inf, the complex number should be NaN: the
magnitude may be known, but the direction is completely indeterminate.

>  =item cis
>
> @@ -207,6 +210,16 @@
>
>  =head2 Complex
>
> +C is an immutable type. Each C object stores two numbers,
> +the real and imaginary part. For all practical purposes a C with
> +a C in real or imaginary part may be considered a C itself (and
> +C<(NaN + 1i) ~~ NaN> is C).

I'm not sure that I feel comfortable locking C into
rectilinear coordinates as its internal storage method, as there will
be cases where the code operates more smoothly if you're using polar
coordinates to store the numbers: we should leave the inner workings
up to the Parrots to decide.  But whichever approach gets used, if
either component is NaN, then the complex number should also be NaN.

--
Jonathan "Dataweaver" Lang


Re: updated num/str/etc roles/types (was Re: r28502 ...)

2009-09-29 Thread Jon Lang
Darren Duncan wrote:
> Jon Lang wrote:
>> So what about custom delimiters?
>>
>> q:2<1100100101>
>> q:8[57013]
>> q:16~DEADBEEF~
>
> Well, sure, if its useful; the idea is to amalgam numeric and Str syntax.
> However, because a Blob literal presumably just has 0..9,A-Z,_ characters in
> its payload, one of the main uses of custom delimiter flexibility, which is
> avoiding conflicts with payload elements, isn't necessary.

True enough.  OTOH, I've also used custom delimiters for visual distinction.

>>>> -As with C types, C and C are mutable in their
>>>> +As with C types, C and C are mutable in their
>>>>  values but not in their keys.  (A key can be a reference to a mutable
>>>>  object, but cannot change its C<.WHICH> identity.  In contrast,
>>>>  the value may be rebound to a different object, just as a hash
>>>>  element may.)
>>>
>>> So given that PairSet is mutable as a whole (while PairValSet is
>>> immutable),
>>> can you please clarify the difference between PairSet and Hash, both of
>>> which have immutable keys and mutable values?
>>
>> Back when it was Mapping, I was under the impression that the
>> difference involved whether or not the component Pairs were ordered -
>> that is, a Mapping was Positional as well as Associative.  I could be
>> wrong.
>
> I was never under the assumption that Mapping was Positional; it was an
> immutable Hash essentially, and both were associative not ordered.  So
> Mapping was renamed to PairValSet, and PairSet was added as a mutable
> alternative, hence how the latter differs from Hash is the question.  I
> think only Capture et al are both associative and ordered.  If you want an
> ordered list of Pair, I don't think that has its own type otherwise, but you
> can parameterize one from Seq/Array/etc.

Note that before this most recent change, the document read as "As
with C types, C and C are mutable in their values
but not in their keys."  Now it reads as "As with C types,
C and C are mutable in their values but not in their
keys."  I may be wrong about what the difference between a Mapping and
a Hash used to be; but the above says that Mapping was mutable in its
values, not immutable; and that it was replaced by PairSet, not Pair.
Presumably, there was already something in place to differentiate a
Mapping from a Hash; and whatever that difference was, it still
applies to PairSet vs. Hash (which would possibly make PairSet a poor
choice of names, depending on the difference).

-- 
Jonathan "Dataweaver" Lang


Re: updated num/str/etc roles/types (was Re: r28502 ...)

2009-09-29 Thread Jon Lang
Darren Duncan wrote:
> These generally look like good changes, but I have a few points on which I'd
> like clarification or to make suggestions.
>
>> +Perl supports generic types through what are called "roles"
>> +which represent capabilities or interfaces.  These roles
>> +are generally not used directly as object types.  For instance
>> +all the numeric types perform the C role, and all
>> +string types perform the C role, but there's no
>> +such thing as a "Numeric" object.  Common roles include:
>> +
>> +    Stringy
>
> Please clarify; does "Stringy" mean a dense homogeneous sequence of
> primitives in general, meaning that both strings of characters and strings
> of integers are covered (as with a Perl 5 string) or does it just mean
> characters?

It's a role, which means to me that it's form over function; interface
rather than implementation.  As such, I'd expect to make Stringy
things that are built out of stuff other than characters.  If need be,
consider making it a parametric role, with a type that defaults to
characters.

> Therefore I recommend that you add Blob to the list of types that does
> Stringy.  In general, a Blob would be a string of bits but it could also be
> used as a string of bytes etc when its length in bits is an appropriate
> multiple of 8 say.
>
> Stringy operations like the "~" infix should work on Blob too as those
> aren't specific to characters.  (For that matter, maybe infix "~" should
> also work on arrays or other Positional-doers to mean list-stitching, eg
> "$ary3 = $ary1 ~ $ary2", unless you have another better way to do that or it
> would confuse people.)  Likewise, an analogy to substr() should work on
> Blob.

I'd rather keep infix:<~> out of Positional, as you can already do
that using infix:<,>.  But I agree about the Blob.

>> +    Numeric
>> +    Real
>> +    Integral
>> +    Callable
>> +    Positional
>> +    Associative
>
>> +C and C both do the C role.
>
> You should add C to this list of things that do C.

No; you should note that C does C.  Likewise, you
should note that C does C.

>> +    Str         Perl string (finite sequence of Unicode characters)
>>     Bit         Perl single bit (allows traits, aliasing, undef, etc.)
>>     Int         Perl integer (allows Inf/NaN, arbitrary precision, etc.)
>> +    Num         Perl number (approximate Real)
>> +    Rat         Perl rational (exact Real)
>>     Complex     Perl complex number
>
> So, now that we have the Numeric role (or the Real role) to be a catch-all
> label for things that are numeric, does this mean that the Num type now
> consists specifically of approximate real numbers, conceptually meaning that
> all Num are floating-point now, rather than Num being "Rat plus extra" as it
> seemed before?
>
> I think it would be useful for Num to be specifically float semantics all
> the time, just as Rat is the opposite, as this would help with some
> predictability.
>
> And users who don't care what they get can now use Real in their routine
> signatures etc rather than Num as the catch-all for real numbers.

As well, both Num and Complex should be Numeric, solving the
long-standing dilemma concerning Real and Complex numbers in Perl.

You might also want to note Ordered (or whatever it's called) as a
common role in Perl; Real does Ordered, but Numeric and Complex do
not.

> On a tangent, I suggest renaming S32/Str.pod to S32/Stringy.pod as we now
> have a name of what Str and Buf both are (and Blob could go in there too).
>
> On another tangent, since I'm not sure that Blob literals have been defined
> in Perl 6 yet, I suggest something that combines aspects of numeric and
> character string literals, meaning a radix prefix plus string quotes; for
> example:
>
>  0b'1100100101'
>  0o'57013'
>  0x'DEADBEEF'
>
>  :2'1100100101'
>  :8'57013'
>  :16'DEADBEEF'

So what about custom delimiters?

q:2<1100100101>
q:8[57013]
q:16~DEADBEEF~

>> -As with C types, C and C are mutable in their
>> +As with C types, C and C are mutable in their
>>  values but not in their keys.  (A key can be a reference to a mutable
>>  object, but cannot change its C<.WHICH> identity.  In contrast,
>>  the value may be rebound to a different object, just as a hash
>>  element may.)
>
> So given that PairSet is mutable as a whole (while PairValSet is immutable),
> can you please clarify the difference between PairSet and Hash, both of
> which have immutable keys and mutable values?

Back when it was Mapping, I was under the impression that the
difference involved whether or not the component Pairs were ordered -
that is, a Mapping was Positional as well as Associative.  I could be
wrong.

-- 
Jonathan "Dataweaver" Lang


Re: r28339 - docs/Perl6/Spec

2009-09-21 Thread Jon Lang
On Mon, Sep 21, 2009 at 12:01 PM,  wrote:
> @@ -65,9 +65,9 @@
>
>  The basic underlying concept is that a Parcel behaves much like a
>  list, but it doesn't enforce any context, in a way that no flattening
> -or coercion is made. When you use the Positional API on a Parcel, it
> -will include all the listed items, no matter they look like named
> -arguments or positional arguments. In example:
> +or coercion is done. When you use the Positional API on a Parcel, it
> +will include all the listed items, wether they look like named
> +arguments or positional arguments. For example:
>
>   1, 2, :a
>

the second line should be:

will include all of the listed items, whether they look like named

--
Jonathan "Dataweaver" Lang


Re: S26 - The Next Generation

2009-09-17 Thread Jon Lang
Not actually S26; but closely related: should $=POD and .WHY be
read-only?  Also, should there be other Pod variables besides $=POD?
If so, which ones?

Back on the subject of S26: should declarator blocks and aliases be
able to introspect the object with which they're associated?  That is,
should you be able to say things like A<.WHAT> or A<.^methods>?  (If
so, be sure never to say A<.WHY>.)

-- 
Jonathan "Dataweaver" Lang


Re: S26 - The Next Generation

2009-09-07 Thread Jon Lang
Damian Conway wrote:
> Jon Lang kept his promise:
>
>> I promised some further thoughts; here they are:
>
> Much appreciated.

You're welcome.

>> As written, declarator aliasing attaches the alias to a piece of code,
>> and draws both the name and the alias from that.  What about using a
>> special case of the declarator block for this?  That is:
>>
>>    class Database::Handle { #=alias
>>        has IO $!handle; #=alias
>>        my Bool method open ($filename) {...} #=alias
>>
>>        =for para
>>            Note that the A method of class A
>>            stores the resulting low-level database handle
>>            in its private A attribute.
>>
>>    }
>>
>
> or:
>
>>   class Database::Handle { #=>
>>       has IO $!handle; #=>
>>       my Bool method open ($filename) {...} #=>
>>
>>       =for para
>>           Note that the A method of class A
>>           stores the resulting low-level database handle
>>           in its private A attribute.
>>
>>   }
>
> Definitely interesting ideas, especially the second one. My concern
> would be that they compete
> with the #= blocks which might also be needed on such declarations.

I don't think that there will be a problem.  First, #=> is easy enough
to distinguish from #=; I don't foresee any confusion.  Second, your
existing rules for #= already allow for multiple such blocks to be
attached to one thing, with the rule being that you append the latter
ones to the former ones:

#= Class Foo
class Foo {
#= a sample class used to illustrate.
#= This particular class has nothing in it.
}

...results in the equivalent of:

=for pod
Class Foo
a sample class used to illustrate.
This particular class has nothing in it.

With the ability to attach multiple declarator blocks to a single
declarator, it should be trivial to replace any one of them with a
declarator alias:

#=>
class Foo {
#= Class Foo
#= a sample class used to illustrate.
#= This particular class has nothing in it.
}

There _is_ a question about when the alias becomes available:

#= Class A
class Foo {
#= a sample class used to illustrate.
#= This particular class has nothing in it.
#=> X

Would A in the first line become 'Foo', or would it be whatever
A was before that line?  My later suggestion of an empty A<>
mitigates this problem by making such references less frequent in
practice; but it doesn't eliminate it.  My personal preference would
be for it to refer to 'Foo'; but that would involve postponing the
evaluation of Foo's WHY block until all possible relevant data has
been collected.

>> Regardless of what syntax you use for declarator aliasing, I'd also
>> recommend some sort of numbering scheme if you alias more than one
>> declarator of the same type in the same lexical scope:
>
> It's definitely an issue I hadn't considered properly. However, I
> think the correct
> solution is not numbering (which is always fraught with problems when 
> subsequent
> maintenance adds an extra declarator in the middle), but rather naming. Like 
> so:

I tend to agree.  I only proposed numbering as a way of being able to
access different declarators without having to explicitly label them.
I can definitely understand if this option gets dropped as being too
error-prone with regard to maintenance.

>    =alias
>    class Database::Handle {
>        =alias
>        has IO $!handle;
>
>        =alias open
>        my Bool method open ($filename) {...}
>
>        =alias close
>        my Bool method close() {...}
>
>        =for para
>            Note that the A method of class A
>            stores the resulting low-level database handle
>            in its private A attribute, while the A
>            method closes that handle.
>    }

The problem with this example is that '=alias name' isn't a declarator
alias; it's a block alias.  (I don't have a problem with the
underlying concept that you're trying to illustrate.)  So A
would be 'my Bool method open($filename) {...}', when what you'd be
looking for in a named declarator alias would be 'open'.  (And it
might not even be that, unless you loosen the syntactic requirements
for a block alias: there are no subsequent curly braces to define how
much gets aliased.)  Which brings me to:

>> If you adopt the declarator block basis for declarator aliasing, you
>> could even let the documenter choose his own names:
>>
>>    class Database::Handle { #=>
>>        has IO $!handle; #=>
>>
>>       

Re: S26 - The Next Generation

2009-09-07 Thread Jon Lang
Damian Conway wrote:
> Raiph elucidated:
>> I was thinking it would be possible to reference (compiler) variables
>> representing eg. the name and sig of a block being parsed, or a block
>> or declaration which has just been parsed, or which is just about to be
>> parsed, and that simply referencing these variables would be ok and
>> would save the need to create explicit named anchors.
>
> Well, that certainly *is* possible in Pod, which will definitely have
> access to any compile-time
> Perl variables, including the following usually bits of information:
>
>    $?FILE      Which file am I in?
>    $?LINE      Which line am I at?
>    &?ROUTINE   Which routine am I in?
>    &?BLOCK     Which block am I in?
>    $?SCOPE     Which lexical scope am I in?
>    $?PACKAGE   Which package am I in?
>    $?MODULE    Which module am I in?
>    $?CLASS     Which class am I in? (as variable)
>    $?ROLE      Which role am I in? (as variable)
>    $?GRAMMAR   Which grammar am I in?

Huh.  Would you be able to do something like:

=begin pod
Welcome to $?FILE.

...and have it interpolate the file's name?  Or would you need some
special markup for this, such as:

=begin pod
Welcome to A<$?FILE>.

Or would you have to alias the variable and then refer to it?

-- 
Jonathan "Dataweaver" Lang


Re: Synopsis 02: Range objects

2009-08-31 Thread Jon Lang
On Mon, Aug 31, 2009 at 12:42 AM, TSa  wrote:
>
> HaloO,
>
> Jon Lang wrote:
>>
>> '<' and '<=' numify their arguments before comparing them.
>> 'lt' and 'le' stringify their arguments before comparing them.
>> 'before' compares its arguments without any coercion.  Note that
>> there's no equivalent to '<='.
>
> This last one is !after and !before is '>='.

Only when total ordering is involved.

--
Jonathan "Dataweaver" Lang


Re: Synopsis 02: Range objects

2009-08-27 Thread Jon Lang
On Thu, Aug 27, 2009 at 2:34 PM, Larry Wall wrote:
> On Thu, Aug 27, 2009 at 02:21:12PM -0700, Jon Lang wrote:
> :     2.5 ~~ 1..5 # true: equivalent to "2.5 ~~ 1 <= $_ <= 5".
>
> Current specced behavior for Range objects.
>
> :     2.5 ~~ @(1..5) # false: equivalent to "2.5 ~~ (1, 2, 3, 4, 5)".
>
> Not by current rules; which say the left side matches the list 1..5
> as a whole.  We don't do implicit junctifying of lists anymore, and haven't
> for several years.  Which points to the correct Perl 6 utterance for that:
>
>    2.5 ~~ any(1..5)    # false
>
> Wherein, as you suggest, the 1..5 in list context does in fact iterate the
> range to produce individual values.

You're right, of course.  I keep getting tripped up on those details...

-- 
Jonathan "Dataweaver" Lang


Re: Synopsis 02: Range objects

2009-08-27 Thread Jon Lang
smuj wrote:
> So you're saying you'd like things to stay exactly as they are at the
> moment!? :-)

Not quite.  I'd like to see the effects of context spelled out more
clearly than they are; and I'd like a revision so that '..' numifies
its endpoints while a new 'to' operator doesn't.  That is, restrict
'..' to cases when you're defining a range of numbers, and use 'to' to
handle all other cases.

It might also be nice to have a stringifying version; perhaps 'be',
using the same "everything's an acronym" naming convention used by
other stringifying operators (e.g., 'lt' is "less than", 'le' is 'less
than or equal to', 'leg' is "less than, equal to, greater than") - in
this case, 'be' would be 'beginning to end'.  At the very least, this
would avoid the inevitable questions about why there isn't a
stringifying version. :)  That said, it may not be good for much more
than that.

-- 
Jonathan "Dataweaver" Lang


Re: Synopsis 02: Range objects

2009-08-27 Thread Jon Lang
On Thu, Aug 27, 2009 at 2:36 PM, Mark J. Reed wrote:
> I think $a <= $^x <= $b is short enough, and lets you choose between <
> and <= on both ends and without having to remember how many dots each
> maps to.

"How many dots"?

Note that there are three sets of comparison operators:

'<' and '<=' numify their arguments before comparing them.
'lt' and 'le' stringify their arguments before comparing them.
'before' compares its arguments without any coercion.  Note that
there's no equivalent to '<='.

I'm unclear as to which of these cases '..' is currently like, if any;
it may be an unholy hybrid of all three.  But for the sake of
argument, I'll assume that it's currently like '<' and '<='.

$a ~~ 1..5   # $a ~~ 1 <= $_ <= 5
$a ~~ 1^..5  # $a ~~ 1 < $_ <= 5
$a ~~ 1..^5  # $a ~~ 1 <= $_ < 5
$a ~~ 1^..^5 # $a ~~ 1 < $_ < 5

What's so hard about that?  And if '..' is like 'before', it can do
things that can't easily be done otherwise:

$a ~~ 1..5 # 1 before $_ before 5 || $_ === 1 | 5

-- 
Jonathan "Dataweaver" Lang


Re: Synopsis 02: Range objects

2009-08-27 Thread Jon Lang
smuj wrote:
> TSa wrote:
>>
>> HaloO,
>>
>> David Green wrote:
>>>
>>> For certain discrete ordered types, like Int, both ways work out the
>>> same, and since Ints are the most common and most obvious use for Ranges,
>>> it's easy to overlook the confusion.  The case with strings is a good
>>> example: it really doesn't make sense that a value not produced by a range
>>> nevertheless lies between its endpoints.  Why not have a separate Interval
>>> type?
>>
>> I see no problem when a Range matches for values which are not produced
>> by a RangeIterator. I expect 2.5 ~~ 1..5 to be true even though 2.5 is
>> not in 1,2,3,4,5.
>
> I suspect that the double meaning of Ranges is going to confuse some people
> and bite others. If things stay as they are, I hope that the use of :by will
> be flagged as a syntax error if used in literal Range smart matching. Of
> course, that doesn't help the unsuspecting when variables are being used,
> ala 2.5 ~~ $myrange.

Another possibility is that literal Range smartmatching works as is in
the absence of :by (that is, with a Range), but becomes a set
membership test in its presence (i.e., with a RangeIterator).  Or not;
see below.

> (For the record, 2.5 ~~ '!'..5 is also true on my system, although I don't
> know why! I certainly wouldn't expect it though :)

One explanation would be that it's comparing the String "2.5" to the
String-terminated Range "!".."5".  Since "2" falls between "!" and
"5", so does "2.5".

>> The same applies for 'aaa' ~~ 'aa'..'az'. I find this
>> quite natural.
>
> Not sure if you're saying that's something you'd like or if you think that
> that's something already there. It doesn't match for me using recent(ish)
> Rakudo. Of course, that could just be me! :)
>
> I'd personally prefer it if Ranges just did lists, including when smart
> matching, but had an interval method or such like for explicit matching
> against the endpoints, e.g.
>
> 2.5 ~~ interval(1..5)   # or
> 2.5 ~~ $myrange.interval

I don't like the Huffman encoding: "does $x come after $a and before
$b?" is a common test, and so should be short.  I'd rather require you
to force it into list context if your goal is to test for set
membership.  In fact, that might be a clean way of handling its dual
nature: in item context, it behaves as a Range object; in list
context, it behaves as the RangeIterator.  So:

2.5 ~~ 1..5 # true: equivalent to "2.5 ~~ 1 <= $_ <= 5".
2.5 ~~ @(1..5) # false: equivalent to "2.5 ~~ (1, 2, 3, 4, 5)".

Incidently, this first example is why I think that Range is intimately
related to the various order-related operators, and in particular
before and after: its most common use outside of generating sequential
lists is to provide a shorthand for "$min before $_ before $max" and
similar range-testing expressions.

-- 
Jonathan "Dataweaver" Lang


  1   2   3   4   >