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" <allber...@gmail.com> 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 <datawea...@gmail.com> 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" <allber...@gmail.com> wrote:
>>
>>>
>>> On Mon, Nov 14, 2016 at 3:42 PM, Aaron Sherman <a...@ajs.com> 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 not@gmail.com 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 bruce.g...@acm.org 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_precedencehttp://perlcabal.org/syn/S03.html#List_infix_precedence
 Buried in its definition is this gem:
   
 http://perlcabal.org/syn/S03.**html#line_1884http://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


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 unitssecond.  Otherwise, Instant and
Duration remain unchanged.

Thoughts?

-- 
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 cma...@gmail.com 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:

  http://strangelyconsistent.org/blog/6-builtins-in-perl-6-that-you-never-knew-you-needed

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

-- 
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: 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: 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: Packed arrays and assignment vs binding

2010-11-14 Thread Jon Lang
On Sun, Nov 14, 2010 at 2:54 AM, Moritz Lenz mor...@faui2k3.org 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: 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-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: 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
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)

 snip

 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

  {:a1, :a2}  # 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(:a1)  # 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-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-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-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: 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 datawea...@gmail.com 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: 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
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: 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-29 Thread Jon Lang
On Wed, Jul 28, 2010 at 10:35 PM, Brandon S Allbery KF8NH
allb...@ece.cmu.edu 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
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-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
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
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
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-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 9:25 AM, Aaron Sherman a...@ajs.com wrote:
 On Thu, Jul 22, 2010 at 11:41 AM, Moritz Lenz mor...@faui2k3.org 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


Re: series operator issues

2010-07-22 Thread Jon Lang
On Thu, Jul 22, 2010 at 11:35 AM, Aaron Sherman a...@ajs.com wrote:
 On Thu, Jul 22, 2010 at 1:13 PM, Jon Lang datawea...@gmail.com 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: 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: 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-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-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 reasonably. Here are some examples of why, using
 only Latin and Greek as examples (not the most convoluted Unicode 

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
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-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: 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: r31054 -[S03] suggestions from dataweaver++

2010-06-02 Thread Jon Lang
pugs-comm...@feather.perl6.nl 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: 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: 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
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 Read Write Exec Fold Spindle Mutilate = 1,2,4...*;

 This would also mean you could think of a normal enum:

    enum Days Sun Mon Tue Wed Thu Fri Sat;

 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: 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]{ Read Write Execute Fold Spindle Mutilate };

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: 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-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-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 are advantages of the former over the latter?

 Basically, same idea, if we're going more for nouns or 

Re: built-in roles/types routine boundary

2010-03-08 Thread Jon Lang
On Mon, Mar 8, 2010 at 12:40 PM, Darren Duncan dar...@darrenduncan.net 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
 snip

 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:«before after cmp 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:«lt le gt ge leg, 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:

 moritz_ rakudo: say max(1..5)
 p6eval 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
Iitalic.

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,  pugs-comm...@feather.perl6.nl wrote:
  for the most generic non-failure undefined value.  The CAny type,
  derived from CMu, is also undefined, but excludes Cjunctions so
  that autothreading may be dispatched using normal multiple dispatch
 -rules.  The CWhatever type is derived from CAny but nothing else
 +rules.  All user-defined classes derive from the CAny class by default.
 +The CWhatever type is derived from CAny 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:
 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 Ccomb 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-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-16 Thread Jon Lang
On Wed, Dec 16, 2009 at 2:10 PM, Dave Whipp d...@dave.whipp.name 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 david.gr...@telus.net 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
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


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


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: 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


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:
 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


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-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;}
   } #`Baz postpones the decision until it knows which role it's being
 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;}
} #`Baz postpones the decision until it knows which role it's
being asked to play: Numeric or Logging.

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


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


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: 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: 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,  pugs-comm...@feather.perl6.nl wrote:
 @@ -255,7 +284,7 @@

  =item IStandard Trig Functions

 - 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 Ifunc 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: 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: r28523 - docs/Perl6/Spec/S32-setting-library

2009-10-01 Thread Jon Lang
On Wed, Sep 30, 2009 at 11:58 PM, pugs-comm...@feather.perl6.nl 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$nth (complex) roots of C$x
 +Returns a list of all C$nth (complex) roots of C$x. Returns CNaN if
 +C $n = 0 , itself if C$n == 0,  and is free to return a single CNaN

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 CNaN or CInf, 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

 +CComplex is an immutable type. Each CComplex object stores two numbers,
 +the real and imaginary part. For all practical purposes a CComplex with
 +a CNaN in real or imaginary part may be considered a CNaN itself (and
 +C(NaN + 1i) ~~ NaN is CTrue).

I'm not sure that I feel comfortable locking CComplex 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: 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 CComplex 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: 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:optrect { ... }
class Complex:optpolar { ... }

...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:optpolar) { ... }

This would not _require_ that a Complex:optpolar 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:optpolar.

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:optrect 1) { ... }
sub bar(Complex:optrect 0) { ... }

...Would mean that if you try to hand foo a Complex:optpolar, foo
will coerce it into a Complex:optrect 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:optpolar (or it's
at the declarator and no implementation preference has been given), it
might convert $x to a Complex:optrect before it gets to the first of
them, just to smooth the way.

-- 
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,  pugs-comm...@feather.perl6.nl wrote:
  The Perl 6 equivalent to Perl 5's Ceval {...} is Ctry {...}.
  (Perl 6's Ceval function only evaluates strings, not blocks.)
 -A Ctry block by default has a CCATCH block that handles all
 +A Ctry block by default has a CCATCH block that handles all fatal
  exceptions by ignoring them.  If you define a CCATCH block within
  the Ctry, it replaces the default CCATCH.  It also makes the Ctry
  keyword redundant, because any block can function as a Ctry 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
 -CSynopsis 16: IPC / IO / Signals 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 CSynopsis 16: IPC /
 +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: 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 CNumeric role, and all
 +string types perform the CStringy 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

 +CRat and CNum both do the CReal role.

 You should add CInt to this list of things that do CReal.

No; you should note that CIntegral does CReal.  Likewise, you
should note that CReal does CNumeric.

 +    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:21100100101
q:8[57013]
q:16~DEADBEEF~

 -As with CHash types, CPair and CMapping are mutable in their
 +As with CHash types, CPair and CPairSet 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: 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:21100100101
 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 CHash types, CPair and CMapping are mutable in their
 +As with CHash types, CPair and CPairSet 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 CHash types, CPair and CMapping are mutable in their values
but not in their keys.  Now it reads as As with CHash types,
CPair and CPairSet 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: r28339 - docs/Perl6/Spec

2009-09-21 Thread Jon Lang
On Mon, Sep 21, 2009 at 12:01 PM, pugs-comm...@feather.perl6.nl 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, :ab


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:
 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: 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 Amethod method of class Aclass
            stores the resulting low-level database handle
            in its private Ahas attribute.

    }


 or:

   class Database::Handle { #=
       has IO $!handle; #=
       my Bool method open ($filename) {...} #=

       =for para
           Note that the Amethod method of class Aclass
           stores the resulting low-level database handle
           in its private Ahas 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 Aclass
class Foo {
#= a sample class used to illustrate.
#= This particular class has nothing in it.
#= Xthis assigns to the 'class' declarator alias.

Would Aclass in the first line become 'Foo', or would it be whatever
Aclass 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 Aopen method of class Aclass
            stores the resulting low-level database handle
            in its private Ahas attribute, while the Aclose
            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 Aopen
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; #=

        my Bool method open ($filename) {...} #=m1
        my Bool method close () {...} #=m2

This would be a way to do a named declarator alias, for distinguishing
between multiple aliases to the same type of declarator.

Indeed, you might end up making extensive use of embedded named
declarator aliases (ENDAs? :P ), since as soon as you reach the
close-bracket, you have the rest of the line available for other uses
(such as declarator blocks):

class Database::Handle

Re: Synopsis 02: Range objects

2009-08-31 Thread Jon Lang
On Mon, Aug 31, 2009 at 12:42 AM, TSa thomas.sandl...@vts-systems.de 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 [recap]

2009-08-27 Thread Jon Lang
On Thu, Aug 27, 2009 at 2:59 AM, Jon Langdatawea...@gmail.com wrote:
 Michael Zedeler wrote:
 Jon Lang wrote:
 As for Str, I'm not sure that we should go so far as to say that you
 _can't_ create RangeIterators over them, so much as to say that the
 default step algorithm is defined only for single-character strings,
 and fails if you give it anything else.  In particular, the programmer
 should be allowed to enable Str-based RangeIterators by explicitly
 supplying his own step algorithm.  That is:

 'aa' .. 'zz' # Error in list context: default stepper rejects
 multi-character endpoints
 'aa' .. 'zz' :by(stepper) # custom stepper overrides default concerns


 The difference between this and the triple dot-operator is that we provide
 an upper bound (and are forced to use the :by-adverb). Is it worth the
 while?

 It _does_ give you an upper bound, which ... doesn't do.

 This is only a half-formed thought at the moment, so please bear with
 me: maybe Ranges should extend the triptych that exists with
 comparison operators.  That is, you have before and after, lt
 and gt, and  and ; you also have cmp, leg, and =.
 Perhaps .. should be treated as the numeric operator, and equivalent
 Str and generic operators should be supplied separately.  I'd be
 inclined to spell the generic Range operator - the one corresponding
 to before/after/cmp - as to.  I'm not sure how the Str-based
 one ought to be spelled.

 With .., there should be automatic coercion of both endpoints to
 numbers, just as there is with  and .  With to, there should
 be no coercion at all, just like before after, and cmp.

 And just like .. should nummify, the to operator should stringify?

 Sounds nice.

 No.  Technically, there should be three versions: a generic version
 that does no coercion; the version that nummifies; and the version
 that stringifies.  I can only think of two names to use; so unless
 someone else can come up with a viable third name, we have to do
 without one of the three.  The one that stringifies is the most
 expendible, since one can always explicitly stringify when no coercion
 is implicitly done, but there's no way _not_ to stringify if it _is_
 implicitly done.  And stringified ranges aren't nearly as important to
 have as numified ones are.

 --
 Jonathan Dataweaver Lang




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


Re: Synopsis 02: Range objects

2009-08-27 Thread Jon Lang
On Thu, Aug 27, 2009 at 2:36 PM, Mark J. Reedmarkjr...@gmail.com 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:
 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:34 PM, Larry Wallla...@wall.org 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 [recap]

2009-08-26 Thread Jon Lang
Michael Zedeler wrote:
 Proposed changes:

 It shouldn't be possible to construct RangeIterators over Str (apart from
 single length strings) or Complex using the Range operator (..).

I'd go one step further with Complex, to say that Range isn't a useful
concept at all so long as before and after are undefined.

As for Str, I'm not sure that we should go so far as to say that you
_can't_ create RangeIterators over them, so much as to say that the
default step algorithm is defined only for single-character strings,
and fails if you give it anything else.  In particular, the programmer
should be allowed to enable Str-based RangeIterators by explicitly
supplying his own step algorithm.  That is:

'aa' .. 'zz' # Error in list context: default stepper rejects
multi-character endpoints
'aa' .. 'zz' :by(stepper) # custom stepper overrides default concerns

 Next open question:

 What about Ranges using different types in each endpoint?

 1.5 .. 10 :by(0.5)
 (Rat .. Int)

 0 .. 7

 Should they be coerced - and in that case to what? If we don't coerce them,
 what should be returned?

This is only a half-formed thought at the moment, so please bear with
me: maybe Ranges should extend the triptych that exists with
comparison operators.  That is, you have before and after, lt
and gt, and  and ; you also have cmp, leg, and =.
Perhaps .. should be treated as the numeric operator, and equivalent
Str and generic operators should be supplied separately.  I'd be
inclined to spell the generic Range operator - the one corresponding
to before/after/cmp - as to.  I'm not sure how the Str-based
one ought to be spelled.

With .., there should be automatic coercion of both endpoints to
numbers, just as there is with  and .  With to, there should
be no coercion at all, just like before after, and cmp.

-- 
Jonathan Dataweaver Lang


Re: S26 - The Next Generation

2009-08-25 Thread Jon Lang
I promised some further thoughts; here they are:

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 Amethod method of class Aclass
           stores the resulting low-level database handle
           in its private Ahas attribute.

   }

The rules for what gets aliased would be the same as the rules for
what gets annotated.  This is more compact than the =alias directive
sans arguments approach, as you can put the alias on the same line as
the declarator to which it is bound.

The downside is that it runs opposite to what declarator blocks
usually do: instead of attaching some Pod to the ambient code, it
attaches a piece of the ambient code to Pod.  That, and alias is
appearing in the declarator block where the Pod parser would be
expecting content.  Perhaps you could use some other symbol to
distinguish a declarator alias from a declarator block: e.g., #=
represents a declarator alias, while #= represents a declarator block.
 So:

   class Database::Handle { #=
   has IO $!handle; #=
   my Bool method open ($filename) {...} #=

   =for para
   Note that the Amethod method of class Aclass
   stores the resulting low-level database handle
   in its private Ahas attribute.

   }

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:

   =alias
   class Database::Handle {
       =alias
       has IO $!handle;

       =alias
       my Bool method open ($filename) {...}

       =alias
       my Bool method close() {...}

       =for para
           Note that the Amethod1 method of class Aclass
           stores the resulting low-level database handle
           in its private Ahas attribute, while the Amethod2
           method closes that handle.

   }

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; #=

       my Bool method open ($filename) {...} #=m1
       my Bool method close () {...} #=m2

       =for para
           Note that the Am1 method of class Aclass
           stores the resulting low-level database handle
           in its private Ahas attribute, while the Am2
           method closes that handle.

   }

This would be more robust, in that you could rearrange the components
of the block without getting the aliases mixed up.  It might even be
worthwhile to make the names mandatory.

You might even allow a second parameter which could (for example) be
used to engage in introspection of the attached thing, thus allowing
you to alias aspects of it other than its name.  But I'd consider this
to be part of the Pod extensibility, rather than a core feature.  An
example:

my Bool method open ($filename) {...} #=m1
#=m1-type Type

=para Am1 is a Am1-type.

Result:

Copen is a Cmethod.

--

An unrelated possibility would be to allow empty A tags in a
declarator block, with 'A' being replaced with the name of the
declarator to which the block is attached:

   class Database::Handle { #=[the A class handles a database.]
   has IO $!handle; #=[the A attribute identifies the database
to be handled.]
   my Bool method open ($filename) {...} #=[the A method opens
the database.]
   }

This would attach the CDatabase::Handle class handles the
database. to class Database::Handle, the C$!handle attribute
identifies the database to be handled. to $!handle, and the Copen
method opens the database. to method open.

--
Jonathan Dataweaver Lang


Re: Synopsis 02: Range objects

2009-08-25 Thread Jon Lang
Michael Zedeler wrote:
 The obvious (default) choice for a step size would be the precision of
 the more precise of the two values.  So 0.0001 in your example above.


 Well... maybe. How do you specify the intended precision, then? If I want
 the values from 1 to 2 with step size 0.01, I guess that writing

 1.00 .. 2.00

 won't be sufficient. Trying to work out the step size by looking at the
 precision of things that are double or floats doesn't really sound so
 feasible, since there are a lot of holes in the actual representation, so
 1.0001 may become 1.0, yielding very different results.

 It could be really nice to come up with something dwimmy, but I can't really
 se any really good candidates, when it comes to floating point numbers and
 strings.

For floating point numbers, assume a default step size of 1, just like
integers; use the :by adverb to specify a different step size, either
by supplying a floating point number to be added in or by supplying a
block that generates the next step when fed the current one.  So:

1.00 .. 2.00 # 1.00, 2.00
1.00 .. 2.00 :by .01 # 1.00, 1.01, 1.02, ..., 1.98, 1.99, 2.00

Also, I want to second David Green's point: we're not talking Range
and Interval here; we're talking Range and Series.  A Series
would be a kind of Range that has the additional ability of generating
a list.  The :by adverb would be a property of a Series, but not a
Range.  Using Num for your endpoints would result in a Series; using
Complex for your endpoints should result in an error: Complex numbers
don't have a viable definition of before or after, let alone
between.

-- 
Jonathan Dataweaver Lang


Re: Synopsis 02: Range objects

2009-08-25 Thread Jon Lang
Mark J. Reed wrote:
 On Tue, Aug 25, 2009 at 5:58 PM, Jon Langdatawea...@gmail.com wrote:
 Also, I want to second David Green's point: we're not talking Range
 and Interval here; we're talking Range and Series.

 But a series refers to a more general concept than a discrete range.
  I still think Range and Interval fit better.

IME, range and interval are largely interchangeable terms.  The
only time that they aren't is when range is used in contrast to
domain; and even there, it still doesn't refer to a list of discrete
values.  That's generally referred to as a sequence; unfortunately,
that's a term that Perl has already co-opted.

 using Complex for your endpoints should result in an error: Complex numbers
 don't have a viable definition of before or after, let alone between.

 Slight overstatement, IMO. Sure, complex numbers don't form an ordered
 field: given three numbers, z0, z1, and z2, you can't ask if z0  z1
 or z0  z2, at least not without imposing some artificial ordering
 rule. Even without defining an ordering, though, you can meaningfully
 ask whether z0 lies within or outside  the rectangle formed by z1 and
 z2, which is a viable (if nonlinear) definition of between. You can
 only get a Boolean answer, but it's a valid question.

It's also every bit as artificial as the ordering rules that can be
imposed.  It would be just as valid to ask whether z0 lies on the line
segment that runs between z1 and z2, or within the smallest circle
that includes z1 and z2.  And if you _do_ establish an artificial
ordering rule, it's also perfectly valid to ask if z0 is after z1 and
before z2 (or vice versa, if z2 is before z1).

 That's just nitpicking, though.  It's perfectly reasonable to fail()
 if someone tries to construct a Range/Series/Interval out of Complex
 numbers.  We can use a different class for complex rectangles if we
 need them.

Agreed.

-- 
Jonathan Dataweaver Lang


  1   2   3   4   >