Re: S02 mistake re Blob?

2015-02-21 Thread Jonathan Lang




On Feb 21, 2015, at 2:45 AM, Moritz Lenz mor...@faui2k3.org wrote:

 Hi Darren,
 
 On 21.02.2015 08:51, Darren Duncan wrote:
 I notice from looking at http://design.perl6.org/S02.html that Blob is 
 listed 
 both as being a role and as a type.  See 
 http://design.perl6.org/S02.html#Roles 
 for an example of the former, and 
 http://design.perl6.org/S02.html#Immutable_types for an example of the 
 latter. 
 -- Darren Duncan
 
 so, you think roles aren't types?
 
 (Also, roles auto-pun into classes upon usage).
 
 Cheers,
 Moritz

You gotta love a language that “auto-puns” things.  :)

Re: Unexpected expansion of string with xx

2013-12-21 Thread Jonathan Lang
On Dec 21, 2013, at 12:00 AM, Moritz Lenz mor...@faui2k3.org wrote:

 On 12/20/2013 04:52 AM, Richard Hainsworth wrote:
 OK x not xx.
 
 The doubling of operators is confusing.
 
 OTOH having a single operator which two different meanings is also confusing 
 (and very un-perlish).

Sometimes, yeah.  On a related note, I sometimes wish that qw«=  » and the 
like were general-purpose comparison operators rather than explicitly numeric 
comparators.  I understand why Perl uses them in the way that it does (mainly, 
it’s a legacy thing from Perl 5, when there weren’t any data types and the 
distinction between “number” and “string” had to be built into the operator); 
but it takes a lot of getting used to, and there are times that I wish that the 
language would use some argument-based magic to let me sort arbitrary objects 
using “” instead of “before”.  

If it wasn’t for the need for backward compatibility, I’d want something like 
the following:

  $a  $b :as(Num) #[coerce $a and $b to Num.  Same as “$a  $b” now.]
  $a  $b :as(Str) #[coerce $a and $b to Str.  Same as “$a lt $b” now.]
  $a  $b :as(*) #[don’t coerce anything.  Same as “$a before $b” now.]
  $a  $b #[coerce $b to whatever type $a is for the comparison.  No simple 
equivalent now.]

That strikes me as better “principle of least surprise” than the current 
approach.  Alas, I suspect that the ship has long since sailed on this idea.  

Re: [perl6/specs] 9c428a: /.sleep/.alarm/

2013-11-04 Thread Jonathan Lang




On Nov 4, 2013, at 12:19 AM, GitHub nore...@github.com wrote:

  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: 9c428a98d060811fa086d3168321cfe437be695a
  
 https://github.com/perl6/specs/commit/9c428a98d060811fa086d3168321cfe437be695a
  Author: Elizabeth Mattijsen l...@dijkmat.nl
  Date:   2013-11-04 (Mon, 04 Nov 2013)
 
  Changed paths:
M S17-concurrency.pod
 
  Log Message:
  ---
  /.sleep/.alarm/
 
 I think .sleep is confusing, as its functionality does not match sleep().
 And from this, we could spec an alarm() function, which would just create a
 subscribable with an .alarm and code to be executed when the alarm arrives.

This sounds a lot like WHEN (i.e., the hook that exists for the eventual 
implementation of an event-driven programming paradigm) should be involved 
somehow.  

Re: Commensurability as Key

2013-08-23 Thread Jonathan Lang
On Aug 23, 2013, at 2:41 AM, Steve Pitchford steve.pitchf...@gmail.com wrote:

 How would you implement, in a robust way, the following things:
 
 1 kg + 1 kg = 2 kg
 2 m * 3 m = 6 m^2
 5 kg * (3 m/s)^2 = 45 J
 
 The answer is that you wouldn't - the problem domain is so vague as to be 
 meaningless. 1kg or 1m of what?

Understood; but it misses the point I was trying to make.  Bringing a measuring 
system into play needs to be more robust than merely addition and subtraction 
of common units; it also needs to be able to transform those units into related 
ones.  Let's do a little rocket science:

DeltaV = Ve * ln ( m0 / m1 )

Where DeltaV is the total amount your velocity can change, Ve is the velocity 
of your rocket propellant, m0 is your initial mass, and m1 is your final mass.  
Simple enough: as long as m0 and m1 are both measured using the same units, 
they cancel out with each other, letting us take the natural log of a unitless 
number — which is fortunate, because I don't have a clue how you'd take the 
logarithm of a number that has units of measure.  You then multiply that 
unitless number by a velocity (measured in units of distance over units of 
time) to get another velocity (measured in the same units).  

In this problem, the question of what? is largely irrelevant; the rocket 
formula will work equally well whether you're shooting a jet of hydrogen out 
the back of your spacecraft or if you're throwing rocks.  Likewise, the number 
of things that you use as propellant is largely irrelevant.  It doesn't hurt to 
keep track of that information, as long as doing so doesn't interfere with your 
calculations; but you don't really need it.  

A related formula is the thrust formula:

F = Isp * m' * g0

Where F is the thrust generated, Isp, is the specific impulse of the fuel (a 
measure of how efficient the fuel is), m' is the mass flow: the rate 
(measured in mass per unit of time) that the fuel is being expelled, and g0 is 
the gravitational acceleration at Earth's surface.  The reason why g0 is in 
there is because of a conflation between two very different kinds of units in 
the early days of rocket science, before metric became the standard in 
rocketry; namely, pounds (of force) and pounds (of mass).  

Originally, the formula was simply C F = Isp * m' , with F measured in pounds 
and m' measured in pounds per second; as such, Isp was assigned units of 
seconds to make these measurements balance out.  When the formula was 
converted over to metric, it became blatantly obvious that things had been 
improperly conflated, since force is measured in Newtons and mass flow is 
measured in kilograms per second.  When that's done, it becomes obvious that 
the Specific Impulse ought to be measured in units of speed (meters per second, 
in this case) rather than in units of time.  But by then, the convention of 
measuring Specific Impulse in seconds was firmly rooted in the rocket 
engineering community; so the surface gravity of Earth was brought in as a 
fudge factor, since that is the ratio of one pound of force to one pound of 
mass.  

 Going back to apples - The value of 1kg of apples in terms of representation 
 depends on context. 
 
 For example, it would be a chore to try to arrange a group of apples to make 
 an exact kilogram. On an individual basis you may have 6 apples. In some 
 cases you may represent that as 6 instances. In another context, you may 
 represent a collection of apples in their tray form - which may have a 
 notional weight with a tolerance. Now, if one were writing a checkout system, 
 it may be sufficient for one to have a fruit class, of which apples and 
 oranges are instances, and both are charged in weight - and their may be 
 additional algorithms to predict stocking levels and re-ordering thresholds, 
 but from personal experience, these algorithms often require the backup of 
 business process such as stock takes to ensure that waste, theft, and 
 approximation errors are taken for granted, and we don't end up with a 
 backlog of rotten apples or empty shelves.

Some relevant tools:

There's a repetition operator infix:xx that's currently set up to take a 
string and construct a longer one made up of multiple consecutive copies of the 
original string.  e.g., C 5 xx ab eq ababababab .  That might be 
leveraged into a general-purpose assign a count to an object operator: e.g., 
C 5 xx apple  means that you have five apples; C 5 xx kg of apple  (would 
that parse correctly? I'm not sure off the top of my head; but I hope so) means 
that you have 5 kilograms of apples; and so on.  

Turning that around, the infix:xx operator could be used to assign a 
measure (defined by whatever is on the right-hand side) to an 
otherwise-unitless value (defined by whatever numeric value is on the 
left-hand side) to get a quantity.   You could then do things like 
multiplying a quantity measured in kg of apple by a quantity measured in 
dollars / kg of apple to get a quantity 

Re: How to make a new operator.

2012-03-21 Thread Jonathan Lang
My understanding is if you want to count by threes, starting at 2 and ending at 
14, you should be able to write:

   2, 5 ... 14

That is, the list-building operator looks at the previous two or three terms 
preceding it to determine where to start and what step function to use, and 
then looks at the first term following it to determine where to stop.  The use 
of lambda functions in the immediately preceding and following terms provides a 
means to explicitly define the step function and the test condition, 
respectively; but Perl 6 is supposed to be smart enough to intuit linear step 
functions from two strictly numeric prior terms, geometric step functions from 
three such terms, and a test condition that stops the series at ' $n' from a 
numeric right term.  

So: 

1, 3 ... 13 # same as 1,3,5,7,9,11,13
1 ... 10 # same as 1,2,3,4,5,6,7,8,9,10
1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64

and

2, 5 ... 14 # same as 2,5,8,11,14

Meanwhile, using Whatever for the test condition means keep the series going 
indefinitely:

1, 3 ... * # every positive odd number.  
1 ... * # all counting numbers.
1, 2, 4 ... * # all powers of 2.

And using '...^' instead of '...' changes the default final test condition from 
' $n' to '= $n':

1, 3 ...^ 13 # same as 1,3,5,7,9,11
1 ...^ 10 # same as 1,2,3,4,5,6,7,8,9
1, 2, 4 ...^ 100 # same as 1,2,4,8,16,32,64

In short, what Damian is talking about is the more powerful and reliable use of 
the syntax; but the above approach (assuming it has been properly implemented) 
is a more intuitive use that covers the most common cases.  Make common things 
easy, and make uncommon things possible. 

Likewise, using Whatever in conjunction with operators is there to provide an 
intuitive way to calculate the next term from the previous one(s):

1, *+2 ... 13 # start at 1, step by 2s, stop at 13.
1, 1, *+* ... * # each new term is the sum of the previous two.
1, 1, infix:+ ... * # same as last one.

Re: How to make a new operator.

2012-03-21 Thread Jonathan Lang
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?

Re: Setting private attributes during object build

2012-02-01 Thread Jonathan Lang
Why must we use 'submethod BUILD' instead of 'method BUILD'?  Is it some sort 
of chicken-and-egg dilemma?  


Re: Musings on operator overloading (was: File-Fu overloading)

2008-02-24 Thread Jonathan Lang
Aristotle Pagaltzis wrote:
  And this contradiction – that being able to declare sugar is
  good, but the way that languages have permitted that so far leads
  to insanity – is what sent me thinking along the lines that there
  has to be some way to make overloading sane. And we all know that
  all is fair if you predeclare. And that led me to the flash of
  inspiration: why not make overloading a property of the source
  (lexical, early-bound) rather than of the values (temporal, late-
  bound)? And what we need to do that is a way to say this scope
  is special in that the operators herein follow rules that differ
  from the normal semantics. There you have it.

So if I'm understanding you correctly, the following would be an
example of what you're talking about:

  { use text; if $a  49 { say $a } }

...with the result being the same as Perl5's 'if $a gt 49 { say $a
}' (so if $a equals '5', it says '5').  Am I following you?  If so,
I'm not seeing what's so exciting about the concept; all it is is a
package that redefines a set of operators for whatever scopes use it.
If I'm not following you, I'm totally lost.

-- 
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14510 - doc/trunk/design/syn

2008-02-15 Thread Jonathan Lang
  +Despite the appearance as a subscripting form, these names are resolved
  +not at run time but at compile time.  The pseudo-subscripts need not
  +be simple scalars.  These are extended with the same two-element list:
  +
  +infix:?? !!
  +infix:['??','!!']

Huh.  I thought that multiple elements were only permitted in
circumfix and postcircumfix, and that even there you had to use
precisely two.  Not that I'm complaining; but if this is a change of
policy, we should consider the ramifications:

An infix operator with multiple delimiters must be list-associative;
it must use the delimiters in order; and it must have one fewer
delimiter than the number of positional parameters in the signature.
Exception: if the signature includes a slurpy array, one more
delimiter can be added to separate the slurped arguments.  An infix
operator with one delimiter is under none of these restrictions.

A circumfix or postcircumfix operator can have three or more
delimiters.  In this case, the first and last delimiters get treated
as the bracketing characters, and the bracketed contents get parsed
using the remaining delimiter(s) as per the rules for infix operators
(trimming off the leading parameter, in the case of postcircumfix
operators).

The only catch with this is that Conditional Operator Precedence is
left-associative, not list associative.  List-associativity would
probably work as well or better for infix:?? !!; but this precedence
level also includes ff and fff.

-- 
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14501 - doc/trunk/design/syn

2008-02-05 Thread Jonathan Lang
 +++ doc/trunk/design/syn/S03.podTue Feb  5 09:55:29 2008
 @@ -2791,7 +2791,7 @@
  are insufficient for defining the pecking order of code.  Note that
  you can bind to either a bare block or a pointy block.  Binding to a
  bare block conveniently leaves the topic in C$_, so the final form
 -above is equivalent to a Cdefault.  (Placeholders parameters may
 +above is equivalent to a Cdefault.  (Placeholder parameters may
  also be used in the bare block form, though of course their types
  cannot be specified that way.)

Is it forbidden to use placeholder parameters in conjunction with
my?  Or would it simply not do anything useful?  I ask because Do
what I mean would seem to imply that 'my Dog $^foo' would specify
$^foo's type as 'Dog'.  Though if you start doing too much of that,
you're almost certainly better off explicitly defining a signature.

Also, how much trouble would we get in if we spelled the ubiquitous
alias for a method's invocant as C $^_  instead of C $self ?

-- 
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14501 - doc/trunk/design/syn

2008-02-05 Thread Jonathan Lang
Larry Wall wrote:
 : Is it forbidden to use placeholder parameters in conjunction with
 : my?  Or would it simply not do anything useful?  I ask because Do
 : what I mean would seem to imply that 'my Dog $^foo' would specify
 : $^foo's type as 'Dog'.  Though if you start doing too much of that,
 : you're almost certainly better off explicitly defining a signature.

 Indeed.

So we're agreed that it could be abused if permitted.  Still, is it permitted?

 : Also, how much trouble would we get in if we spelled the ubiquitous
 : alias for a method's invocant as C $^_  instead of C $self ?

 Then we're back to confusing people over the difference between the
 object and the topic, and the topic-as-self breaks as soon as you
 topicalize some other way.  And you can always throw in a $_ := self
 or a given self if you really want it.  Plus $.foo is still only
 one character longer than .foo so it doesn't really get you much most
 of the time.

Huh.  My intention was not to topicalize the invocant.  Rather, I
thought that $_ and $^_ would be treated as two separate variables: $_
would be the topic, while $^_ would be the invocant.  I'm trying to
think of why this distinction might not be.

Unless I'm missing something, it would be very much like what we have
now, except that '$self' would be spelled '$^_' (shorter and not tied
to English, but instead evocative of I'm using a parameter that I may
not have declared in the signature, sort of like what placeholder
parameters do and I'm using the parameter that defines what this
routine is talking about, sort of like what the topic variable does).

-- 
Jonathan Dataweaver Lang


Re: pluralization idea that keeps bugging me

2008-01-26 Thread Jonathan Lang
Larry Wall wrote:
 Any other cute ideas?

If you have '\s', you'll also want '\S':

$n cat\s fight\S # 1 cat fights; 2 cats fight

I'm not fond of the 'ox\soxen' idea; but I could get behind something
like '\sox oxen' or 'ox\sen'.

'\sa b' would mean 'a is singular; b is plural'
'\sa' would be short for '\s a'
'\s' would be short for '\s s'
\Sa b' would reverse this.

Sometimes, you won't want the pluralization variable in the string
itself, or you won't know which one to use.  You could use an adverb
for this:

:s$nthe cat\s \sis are fighting.

and/or find a way to tag a variable in the string:

$owner's \s=$count cat\s

'\s=$count' means set plurality based on $count, and display $count normally.

-- 
Jonathan Dataweaver Lang


Re: pluralization idea that keeps bugging me

2008-01-26 Thread Jonathan Lang
Gianni Ceccarelli wrote:
 Please don't put this in the language. The problem is harder than it
 seems (there are European languages that pluralize differently on $X %
 10, IIRC; 0 is singular or plural depending on the language, etc etc).

-snip-

 I know Perl is not minimal, but sometimes I feel that it will end up
 being maximal... and the more you put in the core, the less
 flexibility you get in the long term.

This _does_ appear to be something more suitable for a Locale::
module.  I just wonder if there are enough hooks in the core to allow
for an appropriately brief syntax to be introduced in a module: can
one roll one's own string interpolations as things stand?  E.g., is
there a way to add meaning to backslashed characters in a string that
would normally lack meaning?

Do we have the tools to build $m tool\s?

-- 
Jonathan Dataweaver Lang


Re: pluralization idea that keeps bugging me

2008-01-26 Thread Jonathan Lang
Yuval Kogman wrote:
 You can subclass the grammar and change everything.

 Theoretically that's a yes =)

Right.  One last question: is this (i.e., extending a string's
grammar) a keep simple things simple thing, or a keep difficult
things doable thing?

-- 
Jonathan Dataweaver Lang


Re: Definition of Order in S29

2008-01-24 Thread Jonathan Lang
Thom Boyer wrote:
 The enumerations and the numerical values are both in correct order.
 Since abc is less than xyz,  abc cmp xyz is being invoked with
 its arguments in increasing order, So it returns Order::Increase. That
 numifies to -1 because that's how less-than is usually encoded.

Others have pointed out Joe's actual intent in asking the question; so
I won't belabor the point.

Instead, I'll say that the idea that Order::Increase numifies to -1 is
going to take some getting used to.  While I understand the reasoning
behind it, my intuition would have been to numify it to +1 for an
increase and -1 for a decrease.

If Cabc cmp xyz must numify to -1, could we please choose
something like 'Order::Before' and 'Order::After' instead of
'Order::Increase' and 'Order::Decrease'?  Not only does this make more
intuitive sense, but it also pairs the Order values more closely with
the type-neutral comparison operators ('before' and 'after').

(Which brings up another point, which I'll freely admit I'm too lazy
to look up at the moment: do we already have a type-neutral operator
that corresponds to 'Order::Same'?  I suspect that '===' is it; but my
grasp of the plethora of equivalence operators is somewhat shaky.  If
not - and possibly even if so, depending on which paradigm is the most
important one to reinforce - I might recommend using 'same' to
complete the 'before'/'after' set of operators.)

-- 
Jonathan Dataweaver Lang


Re: Instance and Class disambiguation?

2008-01-20 Thread Jonathan Lang
Ovid wrote:
 If I call this:

   if $class.^can('wibble') { ... }

 Does Perl 6 return false if that's only an instance method?  Will the
 WALK iterator returned by .^can return references to instance methods?

As I understand it, Perl 6 generally doesn't bother with the
class-vs-instance distinction.  Instead, it uses an objects and
prototypes paradigm, much like the distinction between proper nouns
and common nouns.

-- 
Jonathan Dataweaver Lang


Re: S02 interpolation of entire hashes

2008-01-07 Thread Jonathan Lang
Dave Whipp wrote:
 The tests in S02 LS02/Literal/In order to interpolate an entire hash
 appear to assume that an interpolated hash renders its keys in a sorted
 order. But this property doesn't seem to be stated in the text. Is it
 true that the keys are always sorted for interpolation? (is it possible,
 in P6, for hash keys to not be comparable?)

I don't know if it's stated anywhere; but ISTR something about %h.keys
returning a Set instead of a List, and %h.vals returning a Bag.  In
fact, I believe that this sort of thing was part of the motivation
behind adding Sets and Bags to the core language: hash keys are not
inherently sorted; and if you're using something other than strings as
your hash keys, the keys may not be sortable.

-- 
Jonathan Dataweaver Lang


Re: Sequential bias in S04 (and Perl6 in general)

2008-01-04 Thread Jonathan Lang
Joe Gottman wrote:
On the other hand, this being Perl, I do believe it should be easy to
 specify the concurrent case.  I think that a forall keyword (and a
 givenall keyword corresponding to given) would be a good idea.
 These would not be quite parallel to for and given because there
 would be some subtle differences arising from the concurrent
 processing.  For instance, forall probably should not be used with
 last, because last should stop subsequent iterations and the
 subsequent iterations could already have occurred when it is called.
 Similarly, givenall should not be used with continue, because the
 next case might already have been checked when continue is called.

I don't think that there's need for a 'forall' keyword.  Note that
Perl 6 has both Lists and Bags, the difference being that a List is
ordered while a Bag isn't.  So what happens when you feed a Bag into a
for statement?  Conceptually, you'd expect to get evaluation across
its members with no promises concerning the order of evaluation.

Likewise, I wonder if there might be a more general way to handle the
'givenall' concept.  Say, by marking a block as being concurrent
(i.e., parallel) in nature rather than sequential (i.e., series).
That is, you normally evaluate a block's statements in order from the
first to the last; marking the block as concurrent would tell the
parser that the order of evaluation within this block isn't important.
 If a block of when statements is parallelized in this manner, you
get the effect of the proposed 'givenall' keyword without the inherent
restrictions that requiring the keyword would impose.

-- 
Jonathan Dataweaver Lang


Re: Sequential bias in S04 (and Perl6 in general)

2008-01-04 Thread Jonathan Lang
Dave Whipp wrote:
 No, you're not the only person thinking Occam ... though I should point
 out that none of my suggestions are par blocks -- a par block made
 every statement within the block execute in parallel with the other
 statements in that block (much like a Verilog fork/join pair).

No; that was me.  Although, as Luke pointed out, I wasn't thinking
parallel execution so much as arbitrarily ordered execution
(which, as Dave points out, is a prerequisite for true parallel
execution).

Paul Seamons wrote:
  I disagree with the idea that humans don't think concurrently (though
  more often they think in terms of data dependencies).

 I think this is more analogous to event based programming rather than parallel
 programming.  Event based and parallel based have some similarities but the
 are fundamentally different.  Humans typically interact with events and only
 occasionally are able to walk and chew gum at the same time.

As a human (as opposed to that weird creature known as a professional
programmer), I tend to do one thing at a time, though I'm more than
capable of prioritizing a set of tasks that are handed to me, even if
new tasks are added to my workload while I'm still working on others.
And if I'm working as part of a team, I know how to delegate tasks to
others.  As Dave points out, it isn't parallelism that's hard so much
as it is coordination with the rest of the team in order to prevent
conflicts involving shared resources.

-- 
Jonathan Dataweaver Lang


Re: Sequential bias in S04 (and Perl6 in general)

2008-01-04 Thread Jonathan Lang
Larry Wall wrote:
 I (impersonally) believe that hyper context is the right solution to
 this because context can propagate to where it needs to dynamically.
 As for the fact that it's not the default list context for for,
 that could easily be changed with a pragma.  Maybe that could even
 be the default someday, but we have to educate people to think about
 hyper first.

As I just indicated, I'm a mere mortal; so some of the terminology
you're using here is throwing me.  When I hear hyper context, my gut
instinct is to think he's advocating some sort of application of the
hyperoperator.  Is that what you mean, or would the substitution of a
bag for a list in a for statement qualify as hyper context?

Or maybe you mean something like the use of a junction in a given
statement as the parallelized equivalent of a for statement?

  for @x { ... } # executes the block for each element of @x in series
  given all(@x) { ... } # executes the block for each element of @x in parallel

 As for the other part of the proposal, a parallel smartmatch would
 need new comb syntax for the compound pattern--I wouldn't overload
 given/when for that.  Or maybe just make a way to attach a mapreduce
 action to any leg of a junction or hyperoperator.

Again, I'm not up on the terminology being used here.  But if I'm
getting the gist of it right, the following is in the spirit of what
you're suggesting:

Introduce a function that does given/when-type smart-matching, but
geared around pattern/code Pairs: e.g.,

  match $x: 1..3 = { dothis() }, 4..6 = { dothat() }

  # equivalent to:

  given $x {
when 1..3 { dothis() }
when 4..6 { dothat() }
  }

Then you could use a junction of Pairs in place of a single Pair to
smart-match the patterns in parallel:

  match $x: 1..3 = { dothis() }  2..4 = { dothat() }

  # smart-matches 1..3 and 2..4 in parallel

 In any case, we need
 to make sure it's easy to place such a parallel comb of matchers at the
 pointy end of a feed, and if the source of the feed is also executing
 in parallel, make sure the feed can be optimized to a full crossbar
 based on packet destination.

In the above example, you might say:

  @x».match 1..3 = { dothis() }  2..4 = { dothat() }

or

  match any(@x): 1..3 = { dothis() }  2..4 = { dothat() }

in order to get a full crossbar.

 It's also possible that we should discourage syntactic parallel
 matching in favor of parallel polymorphic dispatch, given that
 signatures can also express patterns.  Might need to tweak the current
 multiple dispatch rules a bit though if we want dispatch ambiguity
 to express nondeterminism.  In any case, real mapreduce situations
 are often generated dynamically, and cannot easily be expressed in
 a syntactically fixed set of options.

No idea what you're talking about here.

-- 
Jonathan Dataweaver Lang


Re: Multiline comments in Perl6

2008-01-02 Thread Jonathan Lang
Paul Hodges wrote:
 http://perl6.org/doc/design/syn/S02.html still says:
  Intra-line comments will not be supported in standard Perl

This is wrong, since S02 also defines intra-line comments, under
Whitespace and Comments.  It calls them 'embedded comments'.  You
don't need a 'use' statement.

 Is there any restriction of the whitespace *inside* the comment?

Not from my reading of it, no.

 And is / a valid bracketer?

No.  The valid bracketers are defined under Lexical Conventions - in
layman's terms, bracketing characters are matching pairs of
characters: so '(' and ')' are bracketing characters, but '/' is not.
Likewise, the matches are based on individual characters, so if you
use -- at the start of a bracketed segment, only the  counts as
a bracketing character.

 or should I stick to things like

$x = #-- comment  -- 1;
$x = #{   comment   #} 1;
$x = #(   comment   +) 1;
$x = #[   comment  =o] 1;

 Or will any of these not work?

All four of those work as written.

In addition, S06 demonstrates how you can use macros to create custom
embedded comments:

macro circumfix:«!-- --» ($text) is parsed / .*? / {  }
!-- this is now a comment --

-- 
Jonathan Dataweaver Lang


Re: Multiline comments in Perl6

2008-01-02 Thread Jonathan Lang
I've been putting a fair amount of thought into this.  Here's what
I've come up with:

Perl 6 has several instances where whitespace is required or forbidden
in order to better facilitate Do What I Mean programming: for
instance, by having the presence or absence of whitespace before curly
braces affect their meaning, you're allowed to omit the parentheses
around the parameters of the various control structures: e.g., 'if $x
{ ... }' is now valid, whereas in Perl 5 you would have had to say 'if
($x) { ... }'.  Likewise, the same technique lets you provide an
unambiguous distinction between an infix operator and a postfix
operator (IIRC).  So it isn't much of a stretch to require the use of
whitespace in order to distinguish between a standard line comment
and an embedded comment.

Except that that isn't what Perl 6 is doing.  All that it does is to
say there's this one case where there's some ambiguity between line
comments and embedded comments; it's up to the programmer to remove
the ambiguity, through whatever means he sees fit.  In many ways,
this is the opposite of the above cases, and is more akin to how role
composition must be explicitly disambiguated by the programmer,
instead of having the compiler take a best guess.

I must admit: as nice as it is to be able to create an embedded
comment by wrapping the actual comment in brackets, the existence of
that one point of ambiguity is troubling.

--

What I like about the current embedded comments:

1. They're short.  You need a single leading character (the '#'),
followed by content wrapped in as little as a pair of bracketing
characters.  That's three characters in addition to the content
itself.

2. They're flexible.  By going with user-specified bracketing
characters, the programmer can choose an intuitive closing sequence
that won't conflict with content that he's commenting out.

Of the two features, the second one is the more important one.

Likewise, the central most important feature concerning line comments
is that you can initiate them using a single character, allowing you
to reliably comment out a set of lines through a straightforward - and
short - sequence of keystrokes.

The problem arises from the fact that embedded comments start with the
same character that line comments start with.  This means that the
second character is the one that gets used to distinguish between line
comments and embedded comments, which at best interferes with the main
benefit of line comments described above, and at worst leads to an
extra round of debugging as the programmer is forced to go through and
add whitespace (or other characters) to disambiguate the two.

--

The solution, then, would be to change embedded comments so that
they're initiated by something that doesn't begin with a '#'.

Ideally, you'd still use a single character (plus the brackets) to
define an embedded comment.  Unfortunately, I'm pretty sure that we've
got a severe shortage of such characters available for use.  Assume,
then, that a two-character initializer is going to be needed, and that
the first character cannot be a '#'.

--

I'm leery about making the first character be a '=', as there's the
potential for conflict with POD sections.  IIRC, there's a (currently
unspoken?) design goal involving POD sections that says that any line
beginning with a '=' ought to be able to be stripped out of the
program without affecting the code.  Those with more familiarity with
POD design philosophy can please speak up?

OTOH, it might be possible that '=#[ ... ]' could be used to add
versatility to the POD syntax.  Consider the possibility of saying
that '=#[blah blah blah]' at the start of a line is equivalent to
'=blah blah blah', except that the POD header ends at the ']' instead
of the first '\n'.  This could be used to wrap a POD header over
several lines, and/or to put the first line of POD content on the same
line as a short POD header.  So:

  =#[for comment
  params] text

  foo;

would be equivalent to:

  =for comment params
  text

  foo;

...or not; this could lead to the same sort of trouble that we
currently have with line comments vs. embedded comments.  If we were
to go this route, I'd be inclined to say that '=#[ ... ]' isn't just
an embedded comment; it's an embedded POD header.  This removes all
ambiguity regarding what it is, at the expense of forcing the POD
Parser to look at more than just the first character of each line to
determine whether or not it's meaningful.  The expense may be too
great.  At the very least, it opens up a whole new can of worms.

--

OK; so let's assume a two-character sequence prior to the opening
bracket of an embedded comment, with the first character being
something other than '#' or '='.  It's perfectly acceptable (and,
IMHO, desirable) for the second character to be a '#'.

How about '~#', meaning something along the lines of string-like
comment?  The idea is that the syntax that follows this would conform
closely to that of string 

Re: Multiline comments in Perl6

2008-01-02 Thread Jonathan Lang
Jonathan Lang wrote:
 How about '~#', meaning something along the lines of string-like
 comment?  The idea is that the syntax that follows this would conform
 closely to that of string literals (i.e., quotes).  We might even
 consider loosening the restrictions on delimiter characters, allowing
 the full versatility of quoting delimiters, since there'd no longer be
 any danger of confusing this with a line comment.  So:

For the record: if this gets implemented as I'm describing above, I
will personally restrict myself to using bracketing characters as the
delimiters.  Non-bracketing delimiters have issues that, as a
programmer, I don't want to have to deal with: e.g., if I were to use
'~#/ ... /' to comment out a block of code, I'd have to be very sure
that said code doesn't do any division.  This is still a problem with
brackets, but less so - especially with the ability to double up (or
more) on the brackets.  E.g., '~#[[ ... ]]' pretty much guarantees
that I'll comment out exactly what I want to comment out on the first
try.

Oh, and I just realized: '~#( ... )' looks a bit like an
ascii-graphics thought bubble, as used in old text-based MUXs.  If
'~#' gets nixed, perhaps 'oO' would be a viable alternative?

  $x = oO(here's a comment) 5;

-- 
Jonathan Dataweaver Lang


Re: Multiline comments in Perl6

2007-12-30 Thread Jonathan Lang
Amir E. Aharoni wrote:
 On 30/12/2007, Jonathan Lang [EMAIL PROTECTED] wrote:
  The only wart
  is that '#( ... )' cannot begin at the very start of a line; but it's
  easy enough to get around that restriction - say, with some leading
  whitespace.

 Thanks for the reply - can you please what is the problem with having
 it in the beginning of the line?

Short answer: the compiler has no way of knowing whether the
programmer wants an embedded comment or a line comment; so instead of
guessing, it requires the programmer to disambiguate.

Long answer: a standard method of commenting out code is to manually
prefix each line with a '#'.  If embedded comments were allowed at the
beginning of a line, then people using this technique would
occasionally get some nasty surprises.  For example:

  if ($test)
  {
.say;
  } else {
.doit;
  }

Let's say that the programmer in question wants to comment out all but
the third line; so he prefixes everything else with '#':

  #if ($test)
  #{
.say;
  #} else {
  #  .doit;
  #}

What the writer _wants_ this to do is the equivalent of:

.say;

What he'd get with embedded comments would be the equivalent of:

else {

--

Initially, the rule was that any line beginning with a '#' would be
considered a line comment, regardless of what the second character is.
 The result was that the above code worked as expected.  However, it
lead to the possibility of someone putting a '#{' at the start of a
line, expecting an embedded comment, and getting a line comment
instead:

  #{ start here } if ($test)
  {
.say;
  } else {
.doit;
  }

There's no way for the compiler to reliably guess which semantics the
programmer intended, so it complains.  The easiest way to keep it from
complaining is to add some whitespace:

  # if ($test)
  # {
.say;
  # } else {
  #   .doit;
  # }

or

   #{ start here } if ($test)
  {
.say;
  } else {
.doit;
  }

-- 
Jonathan Dataweaver Lang


Re: Multiline comments in Perl6

2007-12-30 Thread Jonathan Lang
Offer Kaye wrote:
  #(  commenting out a large code section, yey for Perl6 multi-line comments...
if ($foo) {
   print ...or not :(\n
}
 ) # this should have been the end of the embedded comment

...and since it wasn't, you probably should have chosen other brackets such as:

 #[[  commenting out a large code section, yey for Perl6 multi-line comments...
   if ($foo) {
  print ...or not :(\n
   }
]]

or just used POD sections:

=begin comment
   if ($foo) {
  print ...or not :(\n
   }
=end comment

 Comments are a some of the most commonly used constructs in code.
 Every code has them, even the simplest script. If you have to get
 around a limitation whenever using them (your words - but it's easy
 enough to get around that restriction) you're doing something wrong
 with their design.

My words; not the designer's.

 Where is the sense in making the closing of the
 embedded comment a single bracket only?

It seems so natural to me that I find myself wondering how it can be
thought of as nonsense.

 I think the Perl 5 method of having just # for single-line and =pod
 for multi-line was better.

IMHO, the _only_ problem with the current commenting system is that
there's potential ambiguity when you start a line with '#('.  Many of
us find that the benefits of having embedded comments outweigh this
one flaw.

 Yes simple Perl users I know didn't use
 =pod but it was there if they needed it.

It still is.  Embedded comments do not replace POD sections any more
than they replace traditional line comments.

-- 
Jonathan Dataweaver Lang


Factoring Arguments

2007-12-21 Thread Jonathan Lang
I'm thinking aloud here, so please bear with me.

A number of languages have a with ... construct that's intended to
cut down on repetitive typing, by factoring the invocant out of every
method call.  Perl 6 also has this, in the form of given ...:

  given $foo.bar.baz {
.dothis();
.dothat();
.doanother();
  }

(same as)

  $foo.bar.baz.dothis();
  $foo.bar.baz.dothat();
  $foo.bar.baz.doanother();

I'm wondering if something similar could be done for optional
arguments - something along the lines of within the following block,
assign value V to argument X of routine R by default.  This would
allow for a similar factoring out of repetitive flags.  So instead
of:

  say qq:!c ... { ... } ...;
  say qq:!c ... { ... } ...;
  say qq:!c ... { ... } ...;

and so on, you might do something like:

  with qq :(c = false) {
say ... { ... } ...;
say ... { ... } ...;
say ... { ... } ...;
  }

Or maybe it could be a pragma (which, by definition, lasts only until
the end of the current scope):

  {
use defaults { qq = :!c }
say ... { ... } ...;
say ... { ... } ...;
say ... { ... } ...;
  }

The core concept here is to allow the programmer to easily change the
default behavior of a routine within a given scope so that he doesn't
have to repeatedly override the default behavior every time it comes
up.

--

Is this reasonable, or is this too much of a corner case to be worth the effort?

-- 
Jonathan Dataweaver Lang


Re: Concerns about {...code...}

2007-12-21 Thread Jonathan Lang
Dave Whipp wrote:
 If the construct is used only rarely then it should have a longer name,

Actually, Huffman coding implies that if the construct is used
regularly then it should have a short name.  It does not mandate a
long name for rare constructs; it merely says that if a given short
name is suitable for both a common construct and a rare construct, the
common construct should get it.  If there's no such conflict, there's
no reason not to give the short name to a rarely used construct.

-- 
Jonathan Dataweaver Lang


Re: Factoring Arguments

2007-12-21 Thread Jonathan Lang
Ryan Richter wrote:
 Jonathan Lang wrote:
  and so on, you might do something like:
 
with qq :(c = false) {

 I think this can be done with normal currying, something like

 temp circumfix:  := quote:qq.assuming(:!c);

That handles the specific example that I had in mind, but does so in a
rather brittle way.  First, the programmer is forced to use
double-quotes to make use of the currying; he cannot switch to another
quoting character if one of the strings that he's dealing with has a
number of double-quote characters in it.  This being a
quoting-specific issue, it should be no surprise that it comes with a
quoting-specific solution, e.g., use 'qs' instead of 'qq:!c') - but
that still leaves you with having to prefix every string in the target
scope: cqs ...  instead of c ... .  Still, that isn't my main
concern here.

There's no way that I know of to override the currying: every
.assuming that you use removes one parameter from the signature (if I
understand currying correctly).  This means that you don't get to set
assumed values for three different parameters at the start of the
block and then override just one of them for a single use of the
function in the middle of the block.  This concern could probably be
addressed if currying doesn't remove arguments from a signature, but
instead forces them to be optional and assigns default values to them;
but this can lead to its own problems, such as what happens when you
curry the second of three required positional parameters.

What I was thinking of would be somewhat more modest: it would be a
variation on the currying mechanic, but would only apply to optional
parameters.  It wouldn't remove them from the signature at all; it
would merely change the default values assigned to them.

-- 
Jonathan Dataweaver Lang


Re: perl 6 grammar

2007-12-04 Thread Jonathan Lang
Another thing to note about given ... when: you don't have to use them
together.  All that given does is to set $_ to the variable
provided; this can be used in a manner similar to with statements in
other languages.  And when doesn't have to be inside a given
block, either: it can be used in any block that sets $_.  For example:

  for @list {
when *..^0 { say $_ is negative }
when 0 {say $_ is zero }
when 0^..* { say $_ is positive }
default { say $_ is something else }
  }

or (I think):

  method test ($value) {
setup();
when $value { doit() } #[smart-match the calling object $_ against $value.]
  }

(Question: assuming that the above is valid, would breaking out of the
when block be the same as returning from the method?  Or would it
qualify as an abnormal termination of the method?)

-- 
Jonathan Dataweaver Lang


Re: , , and backtracking.

2007-09-06 Thread Jonathan Lang
Jonathan Scott Duff wrote:
 How do C and C differ with respect to backtracking?  For instance,

 foobar ~~ / [a..z]+  [ ... ] /;

 Both sides of the C happen in parallel, so I would guess that they
 both match foo then stop. Please correct me if that's wrong.

As written, this match would fail, since '[a..z]+' would match
foobar while '[ ... ]' would match foo.  '' requires that both
sides match the same start and end points.  I suppose that it might be
worth considering requiring only the start points to match, and having
the conjoined match use the earliest end point; so that the above
match would then match foo instead of failing.  But it's entirely
possible that there's something faulty with this approach.

The difference between '' and '' is that '' evaluates the two
sides in an arbitrary order, possibly even in parallel; '' always
evaluates the left side first, and only bothers with the right side if
the left side matched.

-- 
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14447 - doc/trunk/design/syn

2007-09-06 Thread Jonathan Lang
So 'orelse' is exactly like '//', except that the result of the left
side gets passed to the right side as an error message.  Is there a
reason to make this exception, as opposed to altering '//' to behave
exactly like 'orelse' does?

-- 
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14447 - doc/trunk/design/syn

2007-09-06 Thread Jonathan Lang
Larry Wall wrote:
 Jonathan Lang wrote:
 : So 'orelse' is exactly like '//', except that the result of the left
 : side gets passed to the right side as an error message.  Is there a
 : reason to make this exception, as opposed to altering '//' to behave
 : exactly like 'orelse' does?

 How 'bout, it's convenient to have the simpler defaulting semantics
 when you don't care what kind of undefined value is on the left.

If you don't care what kind of undefined value is on the left, you
probably won't notice if it's passed to the right; and the optimizer
may very well end up implementing the simpler semantics in this case,
even if you use 'orelse'.  And if you explicitly want to use the
simpler semantics, you can come very close by blocking the right side
in a block that takes no arguments.

Conversely: if you do care about the undefined value, the subtle
distinction between '//' and 'orelse' (beyond the implied difference
in precedence) will be yet another language quirk that you'll have to
remember.  Very inconvenient.

--
Jonathan Dataweaver Lang


Re: A problem about IPC::Open2

2007-07-01 Thread Jonathan Lang

Admittedly, that wasn't particularly germane to the perl6 mailing
list; but it did bring up an issue that's been bothering me for a
while.

I would like to see Perl6 handle the equivalent of IPC::Open2 using
the same sort of syntax and semantics that it uses for sockets, by
default.  That is, I'd like to be able to say something like:

 $fh = filename.open :rw; # same as open2 filename, $in, $out;

 $line = =$fh; # same as $line = =$in;

 $fh.say rewrite!; # same as $out.say rewrite!;

--
Jonathan Dataweaver Lang


Re: Referring to source code within Perldoc

2007-06-25 Thread Jonathan Lang

David Green wrote:

(Unless I'm missing something, which is always possible; you can put
a piece of POD geographically next to a Perl declaration, but I'm not
sure that's unambiguous enough.  Hm, why not?  POD doesn't know
what's going on around it, but Perl does, and could say, I've just
declared $size, and the next line starts a chunk of POD, so I'll
simply copy it into $size's 'documented' trait... would that work??)


It is doable: say that any Pod section that appears within or after a
class definition is considered by perldoc to refer to that class.

The problem with this is that you're forcing the Pod author to
organize his documentation in a manner that precisely mirrors the
organization used by the Perl programmer, and to scatter it throughout
the module.  This isn't necessarily a deal-breaker because the Pod
author is usually(?) going to _be_ the Perl programmer (thus letting
him reorganize the classes to match the preferred documentation
sequence or vice versa), and because the Pod author may _prefer_ to
place the documentation in close proximity to the source code being
documented.  But it would be nice to have more freedom of placement of
documentation for those with other preferences.

There's the new 'A' tag, which specifically refers to a word or
phrase in the source code.  But that's a single inline tag; so it's
questionable as to how useful it would be for the purpose of
associating an entire Pod section to a piece of source code.  In
addition, the 'A' tag, as written, makes explicit use of exactly the
geographic positioning that we're trying to get around.

--

Then there's the suggestion that I made about providing a Pod rule (or
Pod rules) for the purpose of identifying points in or sections of the
source code for more robust referencing.  In my proposal, I suggested
being able to say something like '=code Foo' to identify the start of
a section of source code that abstractly relates to the label 'Foo',
coupled with the ability to tell a Pod section elsewhere that it is
associated with the source code identified by 'Foo' (using something
like '=begin pod :AFoo' to do so).

At the time, I was thinking in terms of allowing more freedom of
placement of 'A' tags; but it also works for giving entire pod
sections freedom of placement while still maintaining ties to specific
source code: for example, perldoc could look for the '=code' rule that
precedes or encompasses a given class definition and then associate
any Pod sections that attach themselves to that rule with that class.
So while the '=code' rule would have to maintain a close geographic
relationship to the source code in question, the documentation itself
would not.

Ideally, this wouldn't replace the proximity-based bindings, but would
supplement it, with the idea that Pod sections with :A... traits
would be bound to whatever follows the associated '=code' rule, while
those without :A... traits would be bound to whatever they follow.

Best of all, none of these bindings would be Pod's responsibility.  As
far as Pod is concerned, the only use that '=code' rules would have
would be in service to 'A' tags, and could maintain ignorance about
what the source code speaks of.  Perldoc would have the final
responsibility of binding documentation to definitions.

--

The other way to go about it would be to have the source code refer to
Pod sections:

 class Foo is documented(Bar) {
   has $.x is documented(Baz);
 }

 ...

 =begin Bar
 ...

 =begin Baz
 ...

This places the responsibility of bindings on the language (in this
case, Perl) - each of which would have to come up with its own syntax
for referencing documentation.  This is fine as far as Perldoc is
concerned, but does raise issues if you decide that you want to do
something similar with, say, C++ or HTML.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-22 Thread Jonathan Lang

Mark Overmeer wrote:

* Damian Conway ([EMAIL PROTECTED]) [070622 09:02]:
 Mark Overmeer wrote:
 Then, when you want to add some docs to the method, to help the
 correct use, add it, for instance like:
 
   method isValidPostalCode(str $postalcode) returns bool {...}
  ` Check wether the postal code confirms to the standards
  `$postalcode: a string with blanks trimmed.
  `return: the string is not cleaned-up.
 
 or maybe (exact syntax open to discussion)
 
   method isValidPostalCode(str $postalcode) returns bool {...}
   #=  Check wether the postal code confirms to the standards
   #=$postalcode
   #=  a string with blanks trimmed.
   #=return
   #=  the string is not cleaned-up.

 Would the following syntax suffice?

method isValidPostalCode(str $postalcode) returns bool {...}
=PURPOSE  Check weather the postal code confirms to the standards
=ARG $postalcode
a string with blanks trimmed.
=RETURN
the string is not cleaned-up.

 Because you can already do precisely that in the current design of Pod 6.

This is syntactically what can be done with the current design,
but is semantically very different.


For the record, I find Damian's example to be considerably more readable.


The needs for my kind of documentation generators are very simple: the
Perl6 parser needs to collect all lines of docs which follow a certain
line with code into the AST node of that line or item.  The Perl6
parser itself doesn't need to do anything more than that.  Tools doing
introspection on the AST do the rest.


Please forgive my ignorance: what does AST stand for?

--
Jonathan Dataweaver Lang


Re: Referring to source code within Perldoc: the new A code

2007-06-22 Thread Jonathan Lang

OK.  After much thinking on the subject, here are my recommendations:

First: give Pod the ability to delimit blocks of ambient text, e.g.:

 =text
 class Foo {
   has $bar;
 }
 =stop

'=text' and '=stop' would be considered to be separate but related
single-line Pod Sections, so Pod-stripping utilities would remove them
while leaving the lines between them intact.  (I'm not sold on the
specific names for these tags; just the principles behind them.)

By default, 'A' searches backward from its current position within
the scope of the current ambient text block.  This helps you catch
gotchas such as removing a piece of code and failing to remove the
documentation that was referencing it.  Consider, for example,
documenting the first attribute of a class that follows another class.
The coder removes the attribute, but fails to remove the
documentation that references it.  Suddenly, that documentation is
referencing the last attribute of the previous class.  If each class
were encapsulated in a separate ambient text section, Pod would then
know to complain that there is no attribute to reference anymore.

--

Allow ambient text blocks to be named, and allow 'A' to choose a
named ambient text block to search.  When you do this, the position of
the A tag relative to the ambient text block becomes irrelevant.
Example:

 =begin pod
 AFoo.has
 =end pod

 =text Foo
 class Foo {
   has $bar;
 }
 =stop Foo

You might also consider changing the rules when searching ambient text
blocks in this way, so that it searches for the first instance of the
prefix in the block instead of searching for the last one.

--

Let a pod section specify a default ambient code block, causing all
ambient references within its scope to automatically reference that
block:

 =begin pod :AFoo
 Ahas
 =end pod

 =text Foo
 class Foo {
   has $bar;
 }
 =stop Foo

--

Allow ambient text blocks to be nested:

 =begin pod :AFoo
   =ATTRIBUTE Ahas
   =METHOD Amethod :Abaz
 =NAME Aname
 =RETURNS Areturn

 =end pod

 =text Foo
 class Foo {
   has $bar;

 =text baz
   method baz () returns Number { ... }
 =stop baz
 }
 =stop Foo

--

Allow an optional array index for the prefix so that you can skip
over a given number of matches, rather than being limited to the first
one you find:

 =begin pod :AFoo
 Ahas[0]
 Ahas[1]
 =end pod

 =text Foo
 class Foo {
   has $bar;
   has $baz;
 }
 =stop Foo

--

Finally, there are cases where prefix handles won't be readily
available.  Consider what happens when you try to document a C++
function:

 extern void swap(int*, int*);
 =NAME Avoid
 =RETURN Aextern

How do you reference the 'extern' in that function definition?

Now let's say that the C++ programmer decides that he wants this
function to return a success flag:

 extern int swap(int*, int*);
 =NAME Aint
 =RETURN Aextern

Note that he had to change 'void' to 'int' in two places: once in the
code, and once in the documentation.  This, combined with the
distinctly unintuitive prefixes being used in the ambient references,
can lead to a real mess.

In cases such as these, it might be best to have Pod punt to an
'assistant parser' that returns the equivalent of a list of '=alias'
tags.  I see this as being a case of All's fair if you predeclare,
and I was inspired by XML's Processor Instructions (conceptually) and
namespaces (syntactically).  Using this, the above might be handled
as:

 =parser C++ uri

 ...

 =text swap :parsedC++
 extern void swap(int*, int*);
 =stop text
 =for pod :Aswap
 =NAME Aname
 =RETURN Areturn

The '=parser' line tells Pod that some later ambient text sections
will be parsed using a C++ helper utility.  It's assumed that Pod will
search for said helper utility, and will complain if it can't find it.

I'm assuming that the helper utility would return the equivalent of:

 =alias name swap
 =alias return void

when given the ambient text section in question.  I'm also figuring
that these parser-generated aliases would take precedence over
prefix-based referencing, but that explicit '=alias' tags would take
precedence over them.

--

One ramification of Larry's earlier suggestion that Perl not handle
Pod sections exactly the same way that Pod does is that it's possible
for certain sections of Perl code to not register as ambient text in a
Pod Parser:

 say qq:to(END)
 =begin pod
 oops
 =end pod
 END
 =for pod
 A=begin

To a Perl Parser, the code is as follows:

 say qq:to(END)
 =begin pod
 oops
 =end pod
 END

To the Pod Parser, the ambient text is this:

 say qq:to(END)
 END

This wasn't a big deal when Pod was completely ignoring the ambient
text.  But once it starts referencing ambient text, you're best off
keeping Perl code and Pod ambient text in sync with each other.

--
Jonathan Dataweaver Lang


Quirky comments

2007-06-16 Thread Jonathan Lang

In [svn:perl6-synopsis] r14421 - doc/trunk/design/syn,
Damian Conway wrote:

brian wrote:
 So, if this is the case, how will a new Perl 6 user debug a program
 failure when part of their program mysteriously disappears because
 they just happened to have =begin at the beginning of a line?

The same way they debug it when part of their program mysteriously
disappears because they just happened to have # at the beginning of a
line: by learning to distinguish between code and commentary.

Except, of course, the Pod mysteriously vanishing will be considerably
easier to debug, because ALL lines starting with =begin vanish, whereas
only some lines beginning with # do.


By this reasoning, a case could be made for declaring that all lines
that begin with '#' are comments (either block or line, depending on
the second character), no matter what.  That way, you'll have more
consistency between block comments and Pod Sections (which, from
Perl's perspective, should be equivalent).

The price to be paid (in both cases) is that you have to finagle any
code that would normally start a line with a '#' or '=' respectively,
such as the aforementioned block quote.  Admittedly, this isn't hard
to do: starting the line with whitespace or an unspace will do the
trick.  (But ending the previous line with an unspace won't, as
comments are apparently found and turned into whitespace by the
lexer.)

There is an additional price to be paid in the case of '#': you'd have
to distinguish between end-of-line comments (which cease to be
comments if placed in quotes) and line comments (which are always
comments, no matter what).  In effect, you would have four kinds of
comments, not counting Pod sections:

bracketed?  starts line?
   yes:   no:
no: line   end-of-line
yes:block  embedded

The semantic similarities would be as follows:

* line-oriented comments (line and block) don't care about quotes;
character-oriented comments (end-of-line and embedded) do.
* block and embedded comments continue until explicitly terminated;
line and end-of-line comments are terminated by newline.

--

Another quirk concerning comments: if I'm reading S02 correctly, C\#
is an unspaced comment whenever it would normally be a comment, and is
only an escaped pound sign when it would normally be a quoted pound
sign.  This is one (possibly the only) case where backslashing a
special character does _not_ shut off its special behavior.  As a
result, you have to quote a pound sign if you want to use it in a
pattern.  If this behavior is kept (I don't care either way), it
should probably be noted in Learning Perl 6 or the like, as a
gotcha.

--

I also can't seem to find any means of starting a comment from within
a quote, aside from Pod Sections (and, if my first suggestion is
adopted, line and block comments).  Perhaps C\# should count as the
start of a comment when appearing in a quote?  This has the advantage
that almost every appearance of that pair of characters will act to
comment out what follows; the only exception would be when it appears
as part of the C\\# sequence, which is easily tested for.  It does,
however, mean that you can't start a line that's within a quote with
C\# in order to start that line with a literal pound sign.  C\ #
would work, though, as would indenting the quote in the case of a
heredoc.

--

Also from S02:

 Although we say that the unspace hides the whitespace from the
 parser, it does not hide whitespace from the lexer. As a
 result, unspace is not allowed within a token.

Technically true; but what does this mean?  If I were to say

 foo\ bar

would the lexer generate a pair of tokens ('foo' and 'bar') that don't
have any intervening whitespace (which might be important in some
cases that involve whitespace-based disambiguation), or would it
complain about finding an unspace where it doesn't belong?  I hope
that the former is true; although Larry seems to have been very
conscientious about making sure that whitespace is never forbidden
between tokens unless a dot can be placed there instead.  Still,
letting unspace split tokens provides a more general solution.

--

Finally, from S02:

 Since there is a newline before the first =, the POD form of
 comment counts as whitespace equivalent to a newline.

This rationale doesn't hold, for two reasons.  First, there is not
going to be a newline before the first = in a Pod Section if said Pod
Section starts the file.  Second, the stated behavior doesn't follow
from the premise.  Given the logic that Pod Sections are effectively
stripped out of the file before anything else happens, one would
expect:

 say qq:to'END';
 =begin comment
 END
 =end comment
 END

to be equivalent to:

 say qq:to'END';
 END

instead of:

 say qq:to'END';

 END

However, the latter is what occurs under the current rule.  I submit
that Pod Sections shouldn't be equivalent to whitespace; they should
be equivalent to empty strings.  Likewise with line and block
comments: all 

Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-16 Thread Jonathan Lang

brian d foy wrote:

 Whereas the rule you have to teach under the Integration model is:

We don't teach any rule under this model, and it's been fine for over a
decade :)

When we do teach the current Pod, the simple rule is that Pod starts:

   * when Perl is expecting a new statement
   * there is a =something at the beginning of the line

Which is considerably simpler than the long rule list you used to say
the same thing (which seems a bit of FUD, honestly).


Agreed about the parenthetical.  From my perspective, the proponents
of the Separation Model are overstating the difficulties inherent to
the Integration model.  That said:

By the rule you give above, Pod Sections cannot be embedded in the
middle of statements.  For example, given:

 if
 a = 5
 {
   say ouch!
 }

you couldn't insert a Pod Section between the first and second lines,
or between the second and third lines.   From a guy-in-the-trenches
perspective, this isn't a problem; interrupting an instruction
mid-stream in order to talk about it is very bad form.  Still, it's a
restriction that Damian's Separation model lacks.


   So, if this is the case, how will a new Perl 6 user debug a program
   failure when part of their program mysteriously disappears because
   they just happened to have =begin at the beginning of a line?

 The same way they debug it when part of their program mysteriously
 disappears because they just happened to have # at the beginning of a
 line:

 Except, of course, the Pod mysteriously vanishing will be considerably
 easier to debug, because ALL lines starting with =begin vanish, whereas
 only some lines beginning with # do.

That's not really the case. The # only affects one line, and a pound in
a literal string doesn't start a comment. People grok single line
comments very well.


With the advent of block comments, this isn't as true as it used to
be.  In fact, I expect that some people will have to take a moment to
wrap their heads around the notion that you ignore everything that
follows the closing bracket on the last line of the block quote.  That
said, I don't expect there to be much of a learning curve here.

Still, it may be worth it to state that a line that starts with '#'
followed by a closing bracket is _not_ commented out (although said
character sequence should be stripped out of the line).  Less
cognitive dissonance that way.


The start of a Pod comment now affects its line and the ones following
it.


...also not much in the way of a learning curve; in fact, I expect
that people will grok Pod Sections more readily than they will grok
block comments as currently written.


Well, easy to use Pod with other languages until they try to use the
assignment operator at the beginning of the line, or a = in a literal
string at the beginning of a line.


...or you're dealing with a language that assigns special meaning to
lines that begin with '='.

You are not going to be able to make Pod completely orthogonal to the
code that it's embedded in.  You can come close (and IMHO you come
_very_ close with the Separation model that you're discussing), but
there will always be some sort of constraint placed on the code into
which you're embedding Pod.


There are other things to consider, and to me it looks like this design
decision isn't based on what's easier for the Perl 6 programmer but
what's easier for the implementors. It's not that I don't understand
both sides, I just disagree about where the complexity should be.


Thank you, Brian.  That's exactly the sense that I've been getting
from the explanations being given.

Which is not to say that there isn't a time and place when ease of
implementation should trump ease of programming; taking an extreme
example, being able to write a program that consists of the single
line:

 attend my every wish

is the ultimate in terms of ease of programming; it's also impossible
to implement, barring the invention of mind-reading hardware and
sapient artificial intelligence software.  If a small increase in the
programmer's learning curve is the price that must be paid to achieve
a massive reduction in the implementor's workload, it may very well be
worthwhile to foist some of the complexity onto the programmer.

The question is whether or not this is one of those cases.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-16 Thread Jonathan Lang

Jonathan Lang wrote:

Which is not to say that there isn't a time and place when ease of
implementation should trump ease of programming; taking an extreme
example, being able to write a program that consists of the single
line:

  attend my every wish

is the ultimate in terms of ease of programming; it's also impossible
to implement, barring the invention of mind-reading hardware and
sapient artificial intelligence software.  If a small increase in the
programmer's learning curve is the price that must be paid to achieve
a massive reduction in the implementor's workload, it may very well be
worthwhile to foist some of the complexity onto the programmer.

The question is whether or not this is one of those cases.


Addendum: let me note that Perl has a reputation for bending over
backward to accommodate the programmer; as such, the difference in
implementation workloads for the two models that Damian referenced is
going to have to be _very_ severe for ease of implementation to win
out over ease of programming - IMHO.  Unfortunately for me, MHO
doesn't count as much as DHO.  Help, help!  I'm being oppressed!

--
Jonathan Dataweaver Lang


Re: Quirky comments

2007-06-16 Thread Jonathan Lang

Larry Wall wrote:

I have a problem with both extremes, and I want to solve it with a dose
of postmodern apathy.  It may seem a bit insane, but I think that in

print qq:to/END/

=for whatever

END

I would prefer that the =for is considered Pod by any standard Pod
parser, but is *not* considered Pod by the Perl 6 parser.  And I think
that's just fine.  If the programmer really wants to put Pod in a
string, they can just be responsible for stripping it out themselves.
And a standard Pod parser shouldn't be expected to parse full-up Perl.


Summary: Perl treats quoted Pod as quoted text, and all other Pod as
comments; Pod treats all Pod as Pod.

Effects:
1. You trade the brutally surprising behavior of whole lines of string
literal content vanishing for the much more subtle surprising behavior
of whole lines of string literal content being available via $=pod
variables (some might consider the latter to be a feature).
2. Pod Sections behave just like block comments (aside from the pod
variables thing), which is very nice.
3. There will be a few rare cases where the Perl programmer will need
to cheat to keep something that looks like Pod from registering as
Pod; this will be easy enough to do when it's needed.

Opinion: That's a significant trade up, and addresses my biggest concerns.

--

The only other thing that I'll continue to lobby for is that the line
starting with a block comment's termination tag should _not_ be
considered part of the comment, save for the termination tag itself.
Programmers are likely to be surprised when text that follows a
closing bracket is treated as being included within it.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-14 Thread Jonathan Lang

I'm going to stay away from the POD referencing Perl debate for the
time being.  Instead, a couple of thoughts:

1. It has always been my understanding that comments intimately relate
to documentation, despite being part of Perl's syntax.  As such, they
are a technical violation of this separation of Church and State,
being State-sponsored religion as it were. (Who'd have thought that
we'd be talking politics and religion on a programming language
mailing list?  Egad!)  Not that I'm advocating the removal of
comments; their sheer practical value makes up for their heathen ways.

2. Getting block comments to hide POD blocks wouldn't require the POD
parser to have a full implementation of a Perl parser.  It would
require the POD parser to have a _limited_ implementation of a Perl
parser, one that's capable of identifying block comments.  And IIRC,
you already have to do something like this with respect to block
quotes:

 say :to(END);
 =begin POD
 blah blah blah
 =end POD
 END

If I understand matters correctly, the POD code in the above example
isn't POD code at all, but rather the content of a multi-line quote.
So extending the POD parser's awareness of Perl syntax to handle block
comments as well isn't much of a stretch.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-14 Thread Jonathan Lang

Larry Wall wrote:

So I think a named reference is a good compromise, where the name in
the documentation (in some easily recognized syntactic form) refers
to the next declaration (or set of declarations) of that same name.
Hopefully the pod either knows implicitly or has been told explicitly
how to parse out such declarations for insertion into the document.
(And a positional notation could just be a degenerate case of not
specifying the name (or using a name of * maybe), so it finds the
next declaration of any name.  Maybe even some kind of wildcarding
works for hybrid situations.)

The syntax for such named forward references is open for bikeshedding.
(I've intentionally not given any examples in this message to avoid
prejudicing the matter.)


My first instinct for such a thing would be to surround the perl code
to be referenced with POD-like tags:

 =code name
 class foo
 ...
 =/code

...the idea being that a Perl parser treats the =code and =/code lines
as line comments, while a Pod parser would take the block of lines
that exists between the two and attaches it to 'name', to be rendered
as is whenever 'name' is referenced.

In short, =code and =/code would define a target which could then be
referenced as few or as many times as you want within your regular
perl code using something like

 =ref name

...where POD would substitute

 class foo
 ...

every time that it sees

 =ref name

--

Expanding on this idea:

* if you don't specify a name on a '=ref' line, you automatically
reference the next '=code' section to be found.  If you don't bother
naming a '=code' section, this is the only way that it can be
referenced.  If you give '^' as the name, then you automatically
reference the last code section that was found.  So:

 =begin pod
 =ref
 =end pod

 =code
 foo
 =/code

 =begin pod
 =ref ^
 =end pod

would render the same as

 =begin pod
 foo
 =end pod
 =begin pod
 foo
 =end pod

* Put a number instead of a name, and it counts up (if negative) or
down (if non-negative) through the code blocks, with -1 being the
previous code block and 0 being the next one.  A blank name is
equivalent to 0, and a '^' is equivalent to -1.  This should be used
sparingly.

* Add or subtract a number to/from a name, and you count up or down
from that name, with '+1' giving the first code block following the
named codeblock and '-1' giving the last code block prior to it.

* In the same way that '=code'...'=/code' is designed to mimic the
'=begin'...'=end' syntax of POD blocks, you could introduce a
variation of '=code' that mimics the '=for' syntax by grabbing the
next line or block of code (say, '=codeline' and '=codeblock'), where
a block of code is terminated by a blank line.

* the final violation of the separation of Church and State would be
to have the Church ask the State to do something for it.  Let a
'=code' line specify a parser (such as perl): Pod passes the block of
code to the specified parser; that parser then (presumably) goes
through its paces with the goal of extracting language-specific
documentation (such as the previously suggested 'is doc' traits),
formatting the result as a text block, and handing that block back to
the POD parser.  If Pod can't talk to the language parser or vice
versa, Pod simply uses the code block as is.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14421 - doc/trunk/design/syn

2007-06-13 Thread Jonathan Lang

[EMAIL PROTECTED] wrote:

+Block comments may be nested within other block comments (with the
+same or differing brackets).  POD comments may also be nested within
+block comments.  (These are still visible to the POD parser; if you
+wish to comment out a block of mixed POD and Perl 6 code, either use a
+POD comment around it all, or prefix every line with C#.)  The parser
 must report mismatched openers or closers to prevent, for example,
 unwitting use of bare C} as a closer for an opening C#{.


...or put it all in a block comment, and prefix POD's block tags with C#.

What's the rationale for keeping POD comments that are nested in block
comments visible to the POD parser?  It seems to me that the least
surprising behavior would be for the POD comment to be swallowed up by
the block comment, on the basis that a block comment ought to be
equivalent to prefixing every line from its start to end with a C# .
Conversely, I'd expect a block comment that's nested inside a POD
comment to be passed to the POD parser as ordinary POD text.  In
short, whichever kind of comment comes first should dominate.

--
Jonathan Dataweaver Lang


Re: Generalizing ?? !!

2007-06-13 Thread Jonathan Lang

Charles Bailey wrote:

I'm concerned that the relevant precedent isn't just Perl5.  The ?: spelling
of the ternary is pretty deeply embedded in programming languages -- I'm
hard pressed to think of a widely used language in the past 10-15 years that
spells it differently (though that may say more about my experience than the
universe of widely used languages).  Put more practically, I don't think
the issue is just moving people forward from Perl5; we need to think about
whether it'll help or hinder users moving back and forth among several
languages, or bringing familiarity with other languages to the process of
learning Perl6.


In short, is C:: ?? going to be Perl 6's C - ?

Again, this presupposes that C: ? is a feasible option (i.e.,
doesn't conflict with anything important) now that we have whitespace
disambiguation.  If it isn't, then this whole line of reasoning is
moot.  So: Is it feasible?

--
Jonathan Dataweaver Lang


Re: Generalizing ?? !!

2007-06-11 Thread Jonathan Lang

Audrey Tang wrote:

Jonathan Lang wrote:
 A variation of chaining associativity gets
 used, with the chaining rule being '$v1 op1 $v2 // $v1 op2 $v3'
 instead of '$v1 op1 $v2  $v2 op2 $v3', as is the case for comparison
 chaining.

But wouldn't that make:

   True ?? undef !! Moose;

evaluate to Moose, instead of undef as we wanted?


Nope; because of the short-circuiting behavior:

   True ?? undef !! Moose
-
   True ?? undef // True !! Moose

The condition evaluates to True, causing the ?? to evaluate its RHS
and then short-circuit the rest of the expression.  The fact that the
RHS evaluates to undef is irrelevant.

In a sense, ?? and !! would invert the usual short-circuiting
behavior: with normal short-circuiting operators ( and ||), the RHS
is evaluated if and only if the operator does not short-circuit; with
?? and !!, the RHS would be evaluated if and only if the operator
_does_ short-circuit.

NeonGraal wrote:

Surely if you defined !! to return undef but true and both operators
to be left associative then it all works.

 1==0 ?? True !! False - (undef) !! False which seems right to
me.

 1==1 !! False ?? True - (undef but true) ?? True also good.


...except that '1==1 !! False' would return 'undef but true' on a
failure.  I'm sure that a rationale could be provided for doing this;
but it's a potentially surprising result which could get you in
trouble.  Best to keep to a simple 'undef' result on a failure.

Hakim: I'm not familiar with Haskell, so I can't follow your code as
well as I need to to provide an informed response.

Juerd Waalboer wrote:

Zev Benjamin wrote:
 ?? and !! could always return some kind of result object that boolizes
 to true or false.

Can we *please* keep simple things simple?


Agreed.  I'm in favor of this proposal to the extent that it breaks a
simple trinary operator down into equally simple binary operators
(with the trinary form continuing to exist as an emergent property of
the interaction of the binaries); if those binary operators become
more complex than the trinary form, or if you lose the ability to
recover the trinary form from them, there's no point in pursuing this
proposal.

--
Jonathan Dataweaver Lang


Re: Generalizing ?? !!

2007-06-11 Thread Jonathan Lang

[EMAIL PROTECTED] wrote:

Besides ?? !! with out an else part is just .


No, it isn't.  While  behaves properly when the condition turns out
to be true, the result of the condition turning out to be false is
whatever the condition turned out to be.

Still, Damian has a good point - which renders the bulk of this
discussion moot.  The one thing left to consider (IMHO) is whether or
not it's worthwhile (or even possible) to go back to '$c ? $t : $f' or
to '$c ? $t ! $f'.  As I said, the primary concern originally
expressed about the Perl 5 syntax involved matters of ambiguity which
seem to have been resolved since then.  A case could be made that if
the Perl 5 syntax for this doesn't clash with the rest of Perl 6, it
should be used: anything else would be change for change's sake.

--
Jonathan Dataweaver Lang


Generalizing ?? !!

2007-06-10 Thread Jonathan Lang

Rereading A03, I ran across the original reasoning behind why Perl 5's
'?:' trinary operator became '?? ::' first, and then '?? !!'.  Three
reasons were given:

* the '?' and ':' tokens are far too broadly useful to be gobbled up
by the trinary operator.

* the doubled symbols bring to mind the short-circuiting operators
(e.g., '' and '||'), suggesting a similar short-circuiting behavior
here.

* the '!!' brings to mind evaluate this when the condition fails.

IMHO, the first point was always more about the ':' than it was about
the '?'; if you were to replace ':' with '!', I suspect that this
concern would largely go away.  That is, I don't see any infix:? or
infix:! operators in the current draft.  A case could be made that a
trinary '... ? ... ! ...' operator could work within the current state
of things without conflict.  Also, the whitespace disambiguation rules
that were later implemented go a long way to resolving the original
problem of ':' trying to do too much.

That said, the latter two points are still valid.  '... ? ... : ...'
might be perfectly workable; but so is '... ?? ... !! ...'.

However, there still may be room for improvement.  Consider the
following possibility:

Instead of being a single, inflexible trinary operator, break this
into a pair of binary operators: infix:?? and infix:!!.  Each can
be used on its own, returning the right side if the condition
evaluates as expected (i.e., true for ?? and false for !!), and
otherwise returns 'undef'.  A variation of chaining associativity gets
used, with the chaining rule being '$v1 op1 $v2 // $v1 op2 $v3'
instead of '$v1 op1 $v2  $v2 op2 $v3', as is the case for comparison
chaining.  So all of the following would be valid syntax:

 $test ?? $a !! $b  # true: $a; false: $b
 $test !! $a ?? $b  # true: $b; false: $a
 $test ?? $a   # true: $a; false: undef
 $test !! $b   # true: undef; false: $a

I suggest this mainly because it's potentially more extensible than
the current model.  I could see someone devising a fuzzy logic
module which could allow for such things as:

 $test ?? $a !! $b maybe $c likely $d unlikely $e

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14415 - doc/trunk/design/syn

2007-06-05 Thread Jonathan Lang

Larry Wall wrote:

: * In item context, a list of captures becomes a single Array object,
: and the question about whether or not it gets flattened gets deferred
: until its contents get looked at in list, slice, or hash context.

That's the intent.  $() used to assume @@ inside till this latest
change, but that seemed insufficiently lazy to me...

But it kinda means there's yet another list context that doesn't
decide yet, used explicitly by the insides of \(...) and implicitly
by the $() context.  Not sure if it needs a name yet, or whether it's
a design smell.


IMHO, no name is needed; just note that \(...) generates a variation
of the list context that is agnostic to flattening, but is otherwise
equivalent to list.


Arguably list should be non-committal and we give
@() a different name like flat, but that grates in my brain for
some reason, if only because most list contexts would in the end
be flat anyway.  And list in English already implies something
flatter than, say, an outline.


...which tends to be more akin to slice.  In fact, consider renaming
slice as outline.  Sure, it's two characters longer; but it's
_much_ more descriptive of what's going on.  Slice strikes me as
something of a holdover from its origins in array indices.

Conversely, our agnostic list _is_ flatter than a slice or outline,
just like a hardcore list is flatter than an agnostic list.  I'd tend
to agree about keeping list tied to the flattened stuff.  IMHO,
you're not going to find anything in English to represent the agnostic
list of captures.

In essence, we have: list, list-of-captures, and slice (or outline?);
also, hash and item.


: Meanwhile, 'zip' produces a list of captures - which, because list
: context is the default plural context, immediately gets flattened
: most of the time.  As I see it, then, the serial equivalent to
: 'zip(@a;@b)' would be '(@a;@b)', and 'list(@a;@b)' would be the serial
: equivalent to 'list(zip(@a;@b))'.

That doesn't make sense to me.  You seem to be thinking that semicolon
has zip semantics, when it doesn't.  All ; does is make a list of
captures.


My focus in this comparison is on what is being produced, rather than
on what is being passed in.

My understanding is that 'zip' produces a list of captures.  It's just
that the default context that zip is likely to work in is list
context, which flattens that list of captures.  Or am I wrong about
this?  The other alternative is that zip knows whether it's being
called in list or slice/outline context, and produces its output
accordingly.  I was assuming that zip wouldn't need to know; but I
could be wrong about this.

If zip _does_ tailor its return value according to the variety of list
context that it finds itself in, then 'list()' is _still_ not the
serial analog to 'zip()', any more than 'slice()' is, since both
impose a specific context on the product.  You'd need a new function
that takes a list of captures as its parameters, and produces a flat
list in list context or a slice or outline in slice/outline context.


: Or does '(@a;@b)' default to slice context?

Parentheses don't supply context.  They only group.  (@a;@b) returns
a list of captures.  It requires a binding (or other sigil) coercion
to supply context.


The parentheses weren't concerning me here; the semicolon within
brackets was.  I've been working under the assumption that a bracketed
@a;@b produces an agnostic list of captures, which then gets
flattened or structured when it hits list or slice context,
respectively; I was asking about the possibility that I was wrong
about this, and that bracket-within-semicolons produces a
slice/outline outright.

--

This does bring up another question, though: when are you in list
context, and when are you in list-of-captures context?  That is, when
do you force a list of captures to flatten, and when do you leave it
alone?

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14415 - doc/trunk/design/syn

2007-06-05 Thread Jonathan Lang

Jonathan Lang wrote:

 Arguably list should be non-committal and we give
 @() a different name like flat, but that grates in my brain for
 some reason, if only because most list contexts would in the end
 be flat anyway.  And list in English already implies something
 flatter than, say, an outline.

...which tends to be more akin to slice.  In fact, consider renaming
slice as outline.  Sure, it's two characters longer; but it's
_much_ more descriptive of what's going on.  Slice strikes me as
something of a holdover from its origins in array indices.


An even better choice might be tree: it's the same length as list
and item, and conveys the hierarchal structure inherent to that
context quite nicely.

Then again, [[['a', 'b'], ['c', 'd']], 'e', ['f', 'g']] isn't really a
tree _or_ an outline, since only the leaf nodes actually have
content.

--
Jonathan Dataweaver Lang


Re: 'x' vs. 'xx'

2007-06-03 Thread Jonathan Lang

Chas Owens wrote:

Jonathan Lang wrote:
 Chas Owens wrote:
  Jonathan Lang wrote:
   Is there any reason why we can't simply define '$a x $n' as being
   shorthand for 'cat($a xx $n)'?  In what way does the former differ
   from the latter, other than the use of a Whatever in place of $n?
 
  $a x $n is equivalent to join '', $a xx $n, but that isn't an apt
  description of its behavior.  cat($a xx *) is an attempt to provide
  an infinite string since 'a' x Inf would result in memory overflow
  (but the cat trick works since lists are evaluated lazily).

 Then it looks to me like 'cat($a xx $n)' is more flexible than join
 '', $a xx $n, and would work better as the baseline definition for
 '$a x $n'.  Is there any reason to prefer a join-based definition to a
 cat-based one?  AFAICT, the only thing that 'join' can do that 'cat'
 can't is to provide a delimiter when stitching the component strings
 together; in the case of 'x', this feature is (rightfully) not being
 used.

Okay, maybe my understanding of the cat function is flawed, but I
thought it walked through each array handed to it in a serial fashion
(as opposed to zip which walks the arrays in a parallel fashion).


Hmm... true enough.  That was an aspect of the 'cat' function that I
hadn't been aware of.  Rather, what came to mind when I saw the 'cat'
function was the following (from S29): ...a CCat in item context
emulates the CStr interface lazily.

In short, 'cat(a x 5)' effectively _is_ a scalar string value of
five characters - in item context.  And because it emulates the string
interface _lazily_, there's no danger from an infinitely long string.

Again, I was not aware that there _was_ a distinct list context result
for 'cat'; and I'm pretty sure that it was referenced as an
alternative to '$a x *' due to its behavior in scalar context, rather
than its behavior in list context.

So the question is this: is there a problem with 'a' x 5 producing
'a', 'a', 'a', 'a', 'a' in list context, and 'a' in item
context?  Or should it produce the latter in anything but void
context?

--
Jonathan Dataweaver Lang


Re: 'x' vs. 'xx'

2007-06-03 Thread Jonathan Lang

Chas Owens wrote:

I am almost certain that the following code is in list context.

pugs my @a = '-' x 5, 'foo', '-' x 5;
pugs @a
(-, foo, -)
pugs my @b = cat('-' xx 5), 'foo', cat('-' xx 5)
(-, -, -, -, -, foo, -, -, -, -, -)

However, it does seem that Pug's version of cat does not handle the
Str emulation, so that may fix it, but I don't see how it could since
(at least in my mind) the code above is in list context.


You're right; it is.


From what you're saying, I get the impression that you think that '-'

x 5 ought to produce a single string of five dashes regardless of
whether the context is item or list.  Correct?  (Note: I'm not asking
about what the spec says, since what it says is potentially up for
revision, given sufficient cause; I'm asking about what you think the
spec _should_ say.)  If so, cat($n xx *) is not an adequate
replacement for $n x *, since it produces a list of one-character
strings if used in list context.  OTOH, ~cat($n xx *) might work.

Personally, I would tend to favor the notion that infix:x always
produces a single string.  With this in mind, I'm now leaning toward
~cat($a xx $n) as the more verbose equivalent of $a x $n.  You
always produce a single string, and you do so lazily (according to the
way that 'cat' works in item context).

--
Jonathan Dataweaver Lang


Re: 'x' vs. 'xx'

2007-06-03 Thread Jonathan Lang

Mark J. Reed wrote:

Is item context what we're calling scalar these days, or something else?


According to S03, it does indeed appear that item context is the
current terminology for what perl 5 called scalar context:

 The item contextualizer

 item foo()

 The new name for Perl 5's scalar contextualizer. Equivalent to $().
We still call the
 values scalars, and talk about scalar operators, but scalar
operators are those
 that put their arguments into item context.

--
Jonathan Dataweaver Lang


Re: 'x' vs. 'xx'

2007-06-03 Thread Jonathan Lang

Chas Owens wrote:

The current Perl 5 behavior is

[EMAIL PROTECTED]:~$ perl -le 'my @a = (- x 5, foo, - x 5); print @a'
- foo -
[EMAIL PROTECTED]:~$ perl -le 'my @a = ((-) x 5, foo, (-) x 5); print 
@a'
- - - - - foo - - - - -

I am against anything other than that for x or xx without a really
compelling reason.


...with x always corresponding to the first and xx always
corresponding to the second, right?  In essence, x always produces a
string, while xx always produces a list.


Jonathan Lang wrote:
 Personally, I would tend to favor the notion that infix:x always
 produces a single string.  With this in mind, I'm now leaning toward
 ~cat($a xx $n) as the more verbose equivalent of $a x $n.  You
 always produce a single string, and you do so lazily (according to the
 way that 'cat' works in item context).

I assume it is a bug in Pugs implementation of cat, but
pugs ~cat('a' xx 5)
a a a a a


Yes, that would be a bug - probably closely tied to the fact that pugs
doesn't implement cat properly in item context.  IIRC, the original
inspiration for the 'cat' function was 'concatenate' - thus, in item
context at least, one would expect 'cat' to resemble '[~]'.


I also am having a hard time figuring out why I would want an infinite
string.  My first thought was something like

my $ten_zeros = substr(cat(0 xx *), 0, 10);

but that is more clearly written as

my $ten_zeros = 0 x 10;


I'll punt the practical usage to someone else, other than to suggest
that the goal of using an asterisk for the number of repetitions isn't
so much to produce an infinite string as a string of arbitrary
length.  Remember, '*' ne 'Inf'; '*' eq 'Whatever'.  A practical use
for '~cat($string xx *)' would most likely be one that relies on the
arbitrariness of the number of repetitions.  Hmm... how about
something like:

 if $a gt ~cat('-' xx *) { ... }

or, if 'x' is defined along the lines that I'm considering:

 if $a gt '-' x * { ... }

Bear in mind that you're not limited to single-character repetitions:

 if $a lt '142857' x * { ... }

In short, the string will get replicated exactly as many times as is
needed to resolve the comparison.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14415 - doc/trunk/design/syn

2007-06-03 Thread Jonathan Lang

[EMAIL PROTECTED] wrote:

Author: larry
Date: Sun Jun  3 17:23:15 2007
New Revision: 14415

Modified:
   doc/trunk/design/syn/S03.pod
   doc/trunk/design/syn/S04.pod
   doc/trunk/design/syn/S06.pod

Log:
typo from Aaron Crane++
s/cat/list/ for flattening captures in order
cat() now only produces pseudo-strings even in list context





Modified: doc/trunk/design/syn/S03.pod
==
--- doc/trunk/design/syn/S03.pod(original)
+++ doc/trunk/design/syn/S03.podSun Jun  3 17:23:15 2007
@@ -610,7 +610,7 @@
 $string x $count

 Evaluates the left argument in string context, replicates the resulting
-string value the number of time specified by the right argument and
+string value the number of times specified by the right argument and
 returns the result as a single concatenated string regardless of context.

 If the count is less than 1, returns the null string.
@@ -625,7 +625,7 @@
 @list xx $count

 Evaluates the left argument in list context, replicates the resulting
-CCapture value the number of time specified by the right argument and
+CCapture value the number of times specified by the right argument and
 returns the result in a context dependent fashion.  If the operator
 is being evaluated in ordinary list context, the operator returns a
 flattened list.  In slice (C@@) context, the operator converts each 
CCapture
@@ -3554,15 +3554,12 @@
 ...
 }

-To read arrays serially rather than in parallel, use Ccat(@x;@y).
-This wins a useless use of cat award in this case since you could
+To read arrays serially rather than in parallel, use Clist(@x;@y).
+This wins a useless use of list award in this case since you could
 always just write C(@x,@y) to mean the same thing.  But sometimes
 it's nice to be explicit about that:

-@foo := [[1,2,3],[4,5,6]]; say cat([;] @foo); # 1,2,3,4,5,6
-
-(The Ccat function is not entirely useless; it also provides stringy
-semantics in string context.)
+@foo := [[1,2,3],[4,5,6]]; say list([;] @foo); # 1,2,3,4,5,6


Let me see if I understand this correctly:

* In list context, a list of captures gets flattened.

* In slice context (a variant of list context), a list of captures
doesn't get flattened.

* In hash context (another variant of list context), a list of
captures gets flattened, and then grouped into Pairs.

* In item context, a list of captures becomes a single Array object,
and the question about whether or not it gets flattened gets deferred
until its contents get looked at in list, slice, or hash context.

Meanwhile, 'zip' produces a list of captures - which, because list
context is the default plural context, immediately gets flattened
most of the time.  As I see it, then, the serial equivalent to
'zip(@a;@b)' would be '(@a;@b)', and 'list(@a;@b)' would be the serial
equivalent to 'list(zip(@a;@b))'.

Or does '(@a;@b)' default to slice context?

--
Jonathan Dataweaver Lang


'x' vs. 'xx'

2007-06-02 Thread Jonathan Lang

Is there any reason why we can't simply define '$a x $n' as being
shorthand for 'cat($a xx $n)'?  In what way does the former differ
from the latter, other than the use of a Whatever in place of $n?

--
Jonathan Dataweaver Lang


Re: 'x' vs. 'xx'

2007-06-02 Thread Jonathan Lang

Chas Owens wrote:

Jonathan Lang wrote:
 Is there any reason why we can't simply define '$a x $n' as being
 shorthand for 'cat($a xx $n)'?  In what way does the former differ
 from the latter, other than the use of a Whatever in place of $n?

$a x $n is equivalent to join '', $a xx $n, but that isn't an apt
description of its behavior.  cat($a xx *) is an attempt to provide
an infinite string since 'a' x Inf would result in memory overflow
(but the cat trick works since lists are evaluated lazily).


Then it looks to me like 'cat($a xx $n)' is more flexible than join
'', $a xx $n, and would work better as the baseline definition for
'$a x $n'.  Is there any reason to prefer a join-based definition to a
cat-based one?  AFAICT, the only thing that 'join' can do that 'cat'
can't is to provide a delimiter when stitching the component strings
together; in the case of 'x', this feature is (rightfully) not being
used.

--
Jonathan Dataweaver Lang


Purging [-1]

2007-05-25 Thread Jonathan Lang

I just went through all of the synopses searching for instances where
[-1] is still being referenced in its perl5 sense; the following
patches update them to correct perl6 syntax.  I also took the liberty
of fixing up a markup glitch in S03.pod.

=begin S02

@@ -1379,7 +1379,7 @@

=item *

-The C$#foo notation is dead.  Use C@foo.end or C@foo[-1] instead.
+The C$#foo notation is dead.  Use C@foo.end or C@foo[*-1] instead.
(Or C@foo.shape[$dimension] for multidimensional arrays.)

=back
=end S02

=begin S03

--- S03.pod 2007-05-25 17:32:16.0 -0700
+++ S03a.pod2007-05-25 17:38:14.0 -0700
@@ -1606,7 +1606,7 @@

=item *

-Cqw{ ... } gets a synonym: C  ...  , and an interpolating
+Cqw{ ... } gets a synonym: C  ...  , and an interpolating
variant, C«...».
For those still living without the blessings of Unicode, that can also be
written: C  ...  .
@@ -1614,7 +1614,7 @@
=item *

In item context comma C, now constructs a CList object from its
-operands.  You have to use a C[-1] subscript to get the last one.
+operands.  You have to use a C[*-1] subscript to get the last one.

=item *

@@ -2146,7 +2146,7 @@

is short for something like:

-@[EMAIL PROTECTED], @array[-1] xx *
+@[EMAIL PROTECTED], @array[*-1] xx *

An empty Range cannot be iterated; it returns a CFailure instead.  An empty
range still has a defined min and max, but the min is greater than the max.
@@ -3050,8 +3050,8 @@

are equivalent to

-$x = @y[0] = @y[1] = @y[2] ... @y[-1] = $z = 0
-$x += @y[0] += @y[1] += @y[2] ... @y[-1] += $z += 1
+$x = @y[0] = @y[1] = @y[2] ... @y[*-1] = $z = 0
+$x += @y[0] += @y[1] += @y[2] ... @y[*-1] += $z += 1

rather than
=end S03

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14401 - doc/trunk/design/syn

2007-05-24 Thread Jonathan Lang

Darren Duncan wrote:

Jonathan Lang wrote:
I see no mention of C@@x in this section.  I would assume that
C@@x may be bound to any object that does the CMultidimensional
role, with a note to the effect that the CMultidimensional role does
the CPositional role (and thus anything that C@x may be bound to,
C@@x may also be bound to).

I would argue that multi-dimensional is too generic a name for what
you describe.  In particular, I wouldn't say that something with that
name does positional, at least in a conventional sense.


...another reason to consider my more recent suggestion of replacing
'Positional', 'Associative', etc. with 'sigil:@', 'sigil:%', and
so on.  '@@x' would then bind to any object that does 'sigil:@@'.


If we have a multidim role, don't make it do positional.  Those can
only be combined on a case by case basis.  If you do make multidim
positional, then you might as well say that every type does ordered,
because that makes as much sense.


I suggested this because anything that can be bound to '@@' can also
be bound to '@'; this implies to me that 'sigil:@@' does
'sigil:@'.  That said, you have a point, in that '@@' vs. '@' is a
strange dog; an object that is bound to '@@' behaves differently than
one that's bound to '@', which would not be the case if we relied
solely on something to the effect of 'sigil:@@ does sigil:@' to
handle matters.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14401 - doc/trunk/design/syn

2007-05-24 Thread Jonathan Lang

Perhaps it's better to think of '@' and '@@' as working with different
contexts.  S02 says that there are three main contexts (void, scalar,
and list); that scalar context has a number of sub-contexts
(boolean, integer, number, and string), and that list context has a
number of sub-contexts based on the container type.  The difference
between '@' and '@@' seems to be 'list context' vs. 'lisp context', as
it were - i.e., whether or not nested lists should be flattened.  How
this maps to required roles, I'm still not sure.

--
Jonathan Dataweaver Lang


Re: [S02] Sigils

2007-05-24 Thread Jonathan Lang

Larry Wall wrote:

Well, it's already too easy, but the problem I have with it is not
that.  My problem is that sigil:@ is the name of a very specific
syntactic notion, while Positional is the name of a very generic
semantic notion.  I don't think those levels should be confused.


Fair enough.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14401 - doc/trunk/design/syn

2007-05-23 Thread Jonathan Lang

[EMAIL PROTECTED] wrote:

 Sigils indicate overall interface, not the exact type of the bound
+object.  Different sigils imply different minimal abilities.


I see no mention of C@@x in this section.  I would assume that
C@@x may be bound to any object that does the CMultidimensional
role, with a note to the effect that the CMultidimensional role does
the CPositional role (and thus anything that C@x may be bound to,
C@@x may also be bound to).

--
Jonathan Dataweaver Lang


[S02] Sigils

2007-05-23 Thread Jonathan Lang

From S02:


--

Perl 6 includes a system of Bsigils to mark the fundamental
structural type of a variable:

   $   scalar (object)
   @   ordered array
   %   unordered hash (associative array)
  code/rule/token/regex
   ::  package/module/class/role/subset/enum/type/grammar
   @@  multislice view of @

C$x may be bound to any object, including any object that can be
bound to any other sigil.

C@x may be ... bound to any object that does the CPositional role

C%x may be bound to any object that does the CAssociative role

Cx may be bound to any object that does the CCallable role

C::x may be bound to any object that does the CAbstract role

--

IIRC, could the above section about C$x be considered equivalent to
saying that C$x may be bound to any object that does the CObject
role?

Also, a possible change in terminology:

 s/CPositional/C sigil:@ /
 s/CAssociative/C sigil:% /
 s/CCallable/C sigil: /
 s/CAbstract/C sigil::: /
 s/CObject/C sigil:$ / if every object does the Object role

This would free up more role names for programmer use.  It would also
imply that one could create a new sigil by defining a role named
'sigil:...', with the behavior of the sigil being established by the
definition of the role.  Or does this make it too easy to create new
sigils?

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14399 - doc/trunk/design/syn

2007-05-22 Thread Jonathan Lang

Some additional suggestions for S02:

--

@@ -740,9 +740,9 @@
Range   A pair of Ordered endpoints; gens immutables when iterated
Set Unordered group of values that allows no duplicates
Bag Unordered group of values that allows duplicates
-JunctionSets with additional behaviors
+JunctionSet with additional behaviors
PairTwo elements that serve as key/value in a one-element Mapping
-Mapping Pair set with no duplicate keys
+Mapping Set of Pairs with no duplicate keys
Signature   Function parameters (left-hand side of a binding)
Capture Function call arguments (right-hand side of a binding)
BlobAn undifferentiated mass of bits

--

Also, the definitions of Pair and Mapping almost seem to be circular:
what is a Pair?  A one-element Mapping.  What is a Mapping?  A Set of
Pairs.  Perhaps replace Pair with:

PairTwo elements that represent a key and its value

--
Jonathan Dataweaver Lang


Re: explicit line termination with ;: why?

2007-05-15 Thread Jonathan Lang

Larry Wall wrote:

Dave Whipp wrote:
: A slightly tangental thought: is the behavior of Cgiven with no block
: defined? I.e. is

It would be illegal syntax currently.


As I understand it, the proposal is to say that if the parser finds a
';' where it was expecting to find a control block, it treats the rest
of the current block as the expected control block - or something to
that effect.  Eh... messy, and with no substantial gain.


: given $foo { when 1 {...} };
:
: equivalent to
:
: given $foo;
: when 1 {...};

Both of these suggestions would seem to duplicate the existing construct:

$_ = $foo;

:-)


Agreed.  But I think that postfix:? is rather clean:

   $foo?
   when 1 {...}

Two catches:

1. I could easily define postfix:? myself, save for one thing: what
would I put as the parameter for the 'is equiv' trait, so that it has
terminator precedence?

2. 'when' implicitly leaves its current block after successfully being
executed (as per 'last'), since it's designed primarily for use as one
of a set of mutually-exclusive options.  I'm not sure how wise of a
decision that is, since it's easier to add a last to a block that
implicitly lacks one than it is to remove a last from a block that
implicitly includes one.  Part of me would strongly prefer that when
$x { ... } be exactly equivalent to if $_ ~~ $x { ... }, except for
the inability to append an else block to the former.


Of course, now someone will argue that unary:= should assign to $_ by
default, in which case we'd have to find a new iteration operator...


Horrors, no!  '=$filehandle' works just fine for reading an iterator,
thank you...

I _might_ flirt with the idea of postfix:= being equivalent to a
filehandle's '.say' method (i.e., writing to an iterator) - or not.
Given the mandatory whitespace that a postfix operator imposes on an
equivalent infix operator, I'd strongly suggest that good practice for
Perl 6 would be to avoid defining both forms if at all reasonable; and
infix:= definitely has the edge here.  (Rule of thumb: if you can
avoid doing something that will mandate or forbid whitespace, avoid
it.)

--
Jonathan Dataweaver Lang


Re: explicit line termination with ;: why?

2007-05-14 Thread Jonathan Lang

gabriele renzi wrote:

Hi everyone,

I don't want to argue about the design of perl6, I just wonder: why
the semicolon is still needed in the end of lines in perl6?


It isn't - sometimes.  S03 identifies a number of ways that an
expression can be terminated: the semicolon (';'), a block-final
('}'), a control block (' { ... }'), a statement modifier
('if'|'unless'|'while'|'until'|'for'|'given'|'when')^, or a feed
operator ('==', '==', '==', '==').

^ FWIW, S03 needs updating, since it doesn't list 'given' or 'when'
among the statement modifiers in the block termination section.

A couple of thoughts:

1. There's a subtlety here: termination of an expression is not always
the same as termination of a statement.  In particular, ';' is pretty
much equivalent to the '==' feed operator when used in a bracketing
construct [1]^, and feed operators in general don't appear to force
statement termination the way that control blocks, statement
modifiers, and block-finals do.  Of course, this distinction may be me
misunderstanding how expression termination works.

2. This brings up the possibility of custom-designed termination
operators.  Question: which kinds of operators can have this
precedence?  That is, prefix, postfix, infix, circumfix, or
postcircumfix?  It appears to me that our current list of termination
operators includes analogs of most of these: postfix:;,
infix:{'=='}, circumfix:{ }, and postcircumfix:«\s{ }» [2]^.

  Meanwhile, how much clarity does the parser have between postfix
and infix?  That is, if I defined both postfix:foo and infix:foo,
would the parser be able to reliably distinguish between them?  This
matters to the current topic because ';' could be thought of as
'postfix-like' when used to terminate a statement, and 'infix-like'
when being used to construct feeds; if clarity between postfix and
infix exists, you might be able to do away with the bracketed
context clause - though it might not be wise to do so, even if you
could.)

  I'm thinking about this in terms of the possibility of adding more
punctuation to the syntax: consider something akin to a postfix:?
operator that behaves exactly like postfix:;, except that it
automatically topicalizes the expression's value.  Or a postfix:.
that always behaves the way that postfix:; does at statement level
[3]^.  Borrowing from Spanish, circumfix:¿ ? might be to
circumfix:{ } as postfix:? would be to postfix:;.  And so on.

  As long as we maintain clarity between the grammatical categories,
such punctuation operators shouldn't present any difficulty; e.g.,
postfix:? will not clobber prefix:? or vice versa, even if the
former has terminator precedence and the latter has symbolic unary
precedence.

  Or is this the sort of thing that you'd rather consign to explicit
hacks of the parser?

^[1]: see S09.
^[2]: Admittedly, this last one cheats a bit by putting whitespace
into the delimiter.  But the principle is the same.
^[3]: If this were included in the core, you might even reverse things
so that ';' is defined in terms of postfix:. or infix:{'=='},
depending on the context; in this case, postfix:? would be defined
in terms of postfix:., rather than postfix:;.  In fact, the only
thing keeping postfix:. from completely replacing postfix:; as a
statement terminator and insisting that the latter always be used as a
shortcut for feeds is the long tradition that the latter has in
programming languages - much like perl 6's infix:. replaces perl 5's
'-' because that's what everyone else uses.

--
Jonathan Dataweaver Lang


Re: Sigils by example (was: Re: Is Perl 6 too late?)

2007-05-14 Thread Jonathan Lang

Good examples.  Now could you provide some to explain to me why it's
important to distinguish between '$', '@', '%', and ''?  I ask
because I've seen a lot of object-based code that has said stuff like
'$container{$key}'; it seems that there's an assumption that $foo can
be used as a list, a hash, or even a routine if the object that it's
tied to has list-, hash-, or routine-like behavior: i.e., it no longer
seems to be a scalar variable, but rather a variable.  Whereas
'@', '%', and '' still seem to promise list, hash, and routine
functionality, respectively.  In short, there no longer appears to be
a sigil that says I give my solemn promise that the contents herein
will be scalar.

--
Jonathan Dataweaver Lang


Re: explicit line termination with ;: why?

2007-05-14 Thread Jonathan Lang

Jonathan Lang wrote:

^[3]: If this were included in the core, you might even reverse things
so that ';' is defined in terms of postfix:. or infix:{'=='},
depending on the context; in this case, postfix:? would be defined
in terms of postfix:., rather than postfix:;.  In fact, the only
thing keeping postfix:. from completely replacing postfix:; as a
statement terminator and insisting that the latter always be used as a
shortcut for feeds is the long tradition that the latter has in
programming languages - much like perl 6's infix:. replaces perl 5's
'-' because that's what everyone else uses.


Umm, never mind.  I just realized that introducing a postfix:.
operator would complicate matters in unexpected ways by forcing
infix:. to require disambiguating whitespace, as per S02.  This
would be Very Bad in several ways, e.g., an infixed dot is given as
the appropriate way to separate a postfix operator from the term in
front of it when whitespace is forbidden.  Or the fact that 'foo.bar'
would no longer parse as expected.  :sigh:

--
Jonathan Dataweaver Lang


Re: Sigils by example (was: Re: Is Perl 6 too late?)

2007-05-14 Thread Jonathan Lang

Mark J. Reed wrote:

Jonathan Lang wrote:
 Good examples.  Now could you provide some to explain to me why it's
 important to distinguish between '$', '@', '%', and ''?  I ask
 because I've seen a lot of object-based code that has said stuff like
 '$container{$key}';

Well, $container{$key} is how you access elements of %container in
Perl5; in Perl6 that's %container{$key}.  But in object-based P5 code,
you'd be much more likely to see $container-{$key}, where $container
contains a reference to a hash.


True; but not at all what I was referring to.


I believe in P6 you could write that
either as $container.{$key}, $container{$key} (where the . is implied
since $container{$key} can't refer to %container anymore),  or
%$container{$key}.


_This_ is closer to what I'm referring to.  As I understand it, Hash
is a role that provides (among other things) postcircumfix:{ }.  So
any object that does Hash should be able to call the above method.
And unless I've missed something, there's nothing in perl 6 that
insists that an object that does Hash must be assigned to a variable
that uses the '%' sigil; the '$' sigil seems to work equally well.
i.e., I've seen code to the effect of:

 class Foo does Hash { ... }
 my $obj is Foo;
 $objkey = 5;
 say $objkey;

In short, it appears that there's nothing keeping you from assigning
hash-like or list-like objects to scalar variables.

And this is without bringing references into the picture.


You aren't the only person who feels this way; there was a proposal
back in the RFC process to remove sigils in favor of everything is a
scalar, dereference as needed.  I was in that camp myself.  But Larry
rejected that proposal, defending the utility of sigils, and I have
been swayed by the arguments, which I'm not going to repeat because I
can't say it as well, but I do advise you to go read - it was either
Apoc1 or Apoc2, I think.


I have never been in that camp.  In fact, I tend to see the points I
raise above as a bug, not a feature.

Perhaps the relationship between sigils and roles will be addressed in
the as-yet unwritten S14 (or whichever spec is supposed to address
tied variables)?

--
Jonathan Dataweaver Lang


Re: explicit line termination with ;: why?

2007-05-14 Thread Jonathan Lang

On 5/14/07, Daniel Hulme [EMAIL PROTECTED] wrote:

On Mon, May 14, 2007 at 02:29:11PM -0700, Jonathan Lang wrote:
 2. This brings up the possibility of custom-designed termination
 operators.

cf. Semi::Semicolons.


Close.  I'm thinking added functionality for semicolon alternatives
rather than the replace the semicolon stunt that Semi::Semicolons
pulls.  In particular, as long as there's no ambiguity between
prefix:? and postfix:?, I think that it would be quite useful for
postfix:? to act as a semicolon that additionally sets $_ equal to
the expression's value, allowing for a pseudo-Prolog style of syntax
(i.e., the code could include questions as well as declarations and
instructions).

--
Jonathan Dataweaver Lang


Re: Default filehandles, or topicalizing filehandles, or something

2007-05-01 Thread Jonathan Lang

On 5/1/07, brian d foy [EMAIL PROTECTED] wrote:

I was thinking about default filehandles yesterday. select() doesn't
seem to be around except as an Unfiled function in S16.

Then, as I was looking at

   .say( Hello World );


At various times, I have seen something to the effect of each of the
following being bandied about:

 $*OUT.say( Hello World );
 Hello World.say;

That is, both filehandles and strings have 'say' methods that do
essentially the same thing, but using subtly different syntax.  How
would I use (Hello World.say) to write to filehandle $FH?  My gut
reaction would be to use an adverb for the purpose:

 Hello World.say :to($FH);

This would also work for the sub version:

 say :to($FH) Hello World;

With this in mind, you probably could create a localized alias for
'say', if you wanted to:

 {
   my say := OUTER::say.assuming(:to($FH));
   say Hello World; # same as 'say Hello World :to($FH);'
 }

The catch with this is that you'd have to do this for each output
routine separately.

How about this: Do the output routines default to the global
filehandles directly, or do they default to lexical bindings of them?
That is, does 'say' output to $*OUT in the absence of an explicit
filehandle, or does it output to $OUT (with the latter normally being
bound to $*OUT)?  If the latter, you should be able to redirect all of
your output in the rest of the current scope by saying:

 $OUT := $*ERR;

I can understand not being able to rebind the global filehandles.
After all: once they're rebound, how would you ever find what they
were originally bound to?

--
Jonathan Dataweaver Lang


Re: S12: can(), signatures and casting

2007-04-30 Thread Jonathan Lang

Larry Wall wrote:

The fundamental problem here is that we're forcing a method name to be
represented as a string.  We're basically missing the foo equivalent
for methods.  Maybe we need to allow the  indirection on method names
too:

if $obj.fribble:(Str -- BadPoet) {


Takes a little getting used to (it isn't immediately obvious that
you're testing for the existence of a method - at least, not until
you've spent some time thinking about it); but otherwise, I like.

--
Jonathan Dataweaver Lang


Re: S12: can(), signatures and casting

2007-04-30 Thread Jonathan Lang

Larry Wall wrote:

Maybe we need to allow the  indirection on method names too:

if $obj.fribble:(Str -- BadPoet) {


-snip-


Note that we already define foo:(Int, Str) to return a list of candidates
if there's more than one, so extending this from the multi dispatcher
to the single dispatcher just seem like a SMOS (small matter of syntax).


One corollary of this is that querying an object for its available
methods should probably give you a list of coderefs instead of method
names.

What threw me initially was that I wasn't used to thinking of a
coderef as a test for existence - in particular, I couldn't see how
the method's name could be specified using such a syntax.

Another question: what about

 $obj.?fribble:(Str -- BadPoet)
 $obj.*fribble:(Str -- BadPoet)
 $obj.+fribble:(Str -- BadPoet)

As I understand it, placing a ? or * between an object and a method
results in the method only being called if it exists (although I'm not
clear on what happens if it doesn't); placing a * or + between the
object and method calls every version of the method that applies.
Couldn't you just cap one of the former two with a '' to prevent the
resulting methods from actually running?

 $obj.?fribble:(Str -- BadPoet)
 $obj.*fribble:(Str -- BadPoet)
 $obj.+fribble:(Str -- BadPoet)

Or would you have to hyperize the '' in the latter cases?

 $obj.fribble:(Str -- BadPoet) # dies if fribble doesn't work as advertised;
 $obj.?fribble:(Str -- BadPoet) # returns undef instead.
 «$obj.*fribble:(Str -- BadPoet) # returns a list of all fribbles;
 «$obj.+fribble:(Str -- BadPoet) # as above, but fails on an empty list.

Regardless, I agree: can '.can()'.

--
Jonathan Dataweaver Lang


Re: S12: can(), signatures and casting

2007-04-29 Thread Jonathan Lang

Ovid wrote:

My apologies if these have been answered.  I've been chatting with
Jonathan Worthington about some of this and any misconceptions are
mine, not his.

In reading through S12, I see that .can() returns an iterator for the
methods matched.  What I'm curious about is this:

  if $obj.can('fribble') {
my BadPoet $jibbet = $obj.fribble('repeatedly');
  }

Just because $obj.can('fribble') does not mean that the available
fribble(s) will accept a string argument or return BadPoet instances.
In chatting with Jonathan about this, he speculated that I would have
to manually walk the method objects in the iterator to find out if I
really have a suitable method.  This seems like what we really have is
$object.might($method).  Is there a simpler way of determining if
there's an appropriate method for what I need?  It seems like what we
really want is a method object where I can declare a signature and then
do this:

  if $obj.can($object_with_signature){ ... }


I suppose.  Still, an easier solution might be to allow an optional
second parameter for .can that takes a signature object:

 if $obj.can('fribble', :(string - BadPoet)) {
   my BadPoet $jibbet = $obj.fribble('repeatedly');
 }

Or you could allow signatures to be attached to strings:

 # pseudo-code:
 if $obj.can('fribble':(string - BadPoet)) {
   my BadPoet $jibbet = $obj.fribble('repeatedly');
 }

In effect, the signature gets attached as a property of the string,
and 'can()' checks for the signature property.

The only problem that I have with this idea is that I can't think of
any uses for a signatory string outside of '.can()'.


This raises my second question.  What if I have this?

  class MadHatter is BadPoet { ... }

If I get back a MadHatter instead of a BadPoet, but I really want the
superclass and not a subclass, how can I enforce that?  Do I have to do
something like this?  (pseudo-code)


What are you looking for that .is() doesn't provide?  The only thing I
can think of is that you're trying to insist that $obj's
implementation be BadPoet - not BadPoet or a class derived from it,
but BadPoet.  This strikes me as getting into the same territory as
finalized classes.


  subset ReallyABadPoet where { $^N.type eq BadPoet }
  my ReallyABadPoet = $obj.fribble('repeatedly');


I'll assume that you meant to include a variable name on the second line:

 subset ReallyABadPoet where { $^N.type eq BadPoet }
 my ReallyABadPoet $obj2 = $obj.fribble('repeatedly');

If so, I fail to see what you gain from this, as opposed to:

 my BadPoet $obj2 = $obj.fribble('repeatedly');

In this case, $obj2 won't accept the product of
$obj.fribble('repeatedly') unless that product .does('BadPoet').


That seems to fail because the you'd have to invoke every method to
guarantee that you're really getting back the exact type you want.


As I understand it, Perl 6's typing system does not do duck typing -
that is, it uses .does() as its primary means of type-checking, not
.can().  As such, you can check an object's type directly without
having to examine its set of methods - just scan the set of roles that
the object composes until you find the role that you're looking for.

Or am I misunderstanding you?


As such, it seems like we'd need return values to guarantee that the
returned type is exactly what we claimed.

  method foo(Int $bar, Int $baz) returns Int {
return $foo/$baz;
  }

Since the return value might be a Float, does it get cast to an Int,
thereby discarding information?


As I understand it, yes; a Float would be cast into an Int in this
case.  Though my understanding is that this says more about Ints and
Nums than it does about objects in general.

--
Jonathan Dataweaver Lang


Re: File test operators as Pairs

2007-04-13 Thread Jonathan Lang

Luke Palmer wrote:

These things are methods, and I'm not sure why we've crammed them into
smart match. Things like :M have nothing to do with matching. What
would it mean if smart match returned false?  This file has not been
modified ever?  :e has a bit more merit for a smart match, but the
operation has little to do with the concept of a string or the pair e
= 1.


Also, I found the following line from S03 to be jolting:

   Any   Pair  test object .STATUS(X) (Str,IO do filetest)

It struck me as a rather specific application for such a generic data type.


I'm inclined to say that the best solution for filetests is to throw
out our dwimmery altogether.  Back in Perl 4 days, using stat
explicitly was awkward, because you had to use it as a list and
memorize the positions of all the returns.  -s $file beats the heck
out of (stat $file)[7], for sure.  It also had the benefit that shell
people would instantly recognize what's going on.

However, now we have stat($file).size.  With that, every programmer
will recognize what's going on, not just people with shell background.
 And I don't think even people with a shell background will know what
($file ~~ :s) means (their guess could be right, but they'd have to
look it up to confirm, and they would never think to *write* such a
thing).

I can never remember whether mtime is -m or -M anyway...

Let's get rid of all the filetest magic, in favor of using stat explicitly.


I tend to agree that the magic should go away.  However, I already
miss the filetest operators.  Given the way that prefix operators
work, wasn't it already possible to say something like the following?

   given $handle {
   when .'-r'  .'-w'  .'-x' { ... }
   when !.'-w' | !.'-x' { ... }
   when * { ... }
   }

   sort { $^a.'-M' = $^b.'-M' }, @files
   sort { .'-M' }, @files

What does pair notation buy us that quoted-postfix notation doesn't
already cover?

--
Jonathan Dataweaver Lang


Re: Should a dirhandle be a filehandle-like iterator?

2007-04-13 Thread Jonathan Lang

brian d foy wrote:

As I was playing around with dirhandles, I thought What if... (which
is actualy sorta fun to do in Pugs, where Perl 5 has everything
documented somewhere even if nobody has read it).

My goal is modest: explain fewer things in the Llama. If dirhandles
were like filehandles, there's a couple of pages of explanation I don't
need to go through.

Witness:

I can iterate through the elements of a named array with [EMAIL PROTECTED]:

   my @a =  1 2 3 4 5 ;
   for [EMAIL PROTECTED] { .say }   # but not = 1 2 3 4 5  :(

and I can read lines from a file:

   for =$fh { .say }

Should I be able to go through a directory handle that way too? A yes
answer would be very pleasing :)

   my $dh = doc.opendir;
   for =$dh { .say }# doesn't work in pugs

And, since we're using objects now, .closedir can really just be
.close, right?


Please.  I've always found the opendir ... readdir ... closedir set
to be clunky.

Also: why distinguish between open and opendir?  If the string is
the name of a file, 'open' means open the file; if it is the name of
a directory, 'open' means open the directory.  If it's the name of a
pipe, it opens the pipe.  And so on.

Note that the above could be further shorthanded, as long as you don't
need the directory handle after the loop:

   for =doc.open { .say }

--
Jonathan Dataweaver Lang


Re: Should a dirhandle be a filehandle-like iterator?

2007-04-13 Thread Jonathan Lang

Geoffrey Broadwell wrote:

Jonathan Lang wrote:
 Also: why distinguish between open and opendir?  If the string is
 the name of a file, 'open' means open the file; if it is the name of
 a directory, 'open' means open the directory.  If it's the name of a
 pipe, it opens the pipe.  And so on.

As long as you still have some way to reach the low-level opens --
though it's an odd thing to do (except perhaps in a disk integrity
checker), there's no fundamental reason why you shouldn't be able to
actually look at the bytes that happen to represent a directory
structure on disk.


It wouldn't be hard to allow .openfile, .opendir, and .openpipe as
well as .open.

--
Jonathan Dataweaver Lang


Re: Should a dirhandle be a filehandle-like iterator?

2007-04-13 Thread Jonathan Lang

Uri Guttman wrote:

 JL == Jonathan Lang [EMAIL PROTECTED] writes:


  JL Please.  I've always found the opendir ... readdir ... closedir set
  JL to be clunky.

  JL Also: why distinguish between open and opendir?  If the string is
  JL the name of a file, 'open' means open the file; if it is the name of
  JL a directory, 'open' means open the directory.  If it's the name of a
  JL pipe, it opens the pipe.  And so on.

maybe this won't help you but if you did open on a dir in perl5 you can
read the raw directory data which is pretty useless in most cases. so
with open working as opendir on directories, what is the op/method to
get the next directory entry? that isn't the same as reading a
line. there won't be any trailing newlines to chomp. marking a location
is not the same with tell and telldir (one is a byte offset, the other a
directory entry index). and since dirs can reorder their entries
(especially hash based dirs) the ordering and seek points may move. not
gonna happen on text files. there are many differences and the only one
you seem to see is a linear scan of them (which is just the most common
access style).


Well, I did suggest that openfile and opendir exist alongside
open, with openfile being more akin to Perl 5's open or
sysopen, and open being a bit more dwimmy.

But in general, most of the differences that you mention are things
that ought to be addressed in the resulting iterators, not in the
creating statement.  No, a directory handle will not behave exactly
like a file handle.  But then, a file handle doesn't behave exactly
like standard in or standard out, either (last I checked, Perl 5
won't do anything useful if you say seek STDIN, 0, SEEK_END).

--
Jonathan Dataweaver Lang


[S03] Negation metaoperator

2007-04-06 Thread Jonathan Lang

Generalize the negated relational operators to apply to any infix
operator that returns a boolean.  In terms of the standard operators,
this will add  || ^^ // and or xor err to the family that is
implicitly equipped with logical negations.

For consistency's sake, you may also want to define junctive operators
! !| !^.  '!|' corresponds with the list-op 'none', although I can
think of no intuitive list-ops for the other two; we might have to
settle for '!all' and '!one'.  If so, consider '!any' as a synonym for
'none', much like '!eq' and 'ne' are synonyms for each other.

Or just reduce the operators: [!] and [!^].  Personally, I find
'!all' and '!one' to be more legible; but YMMV.

--
Jonathan Dataweaver Lang


[S03] Range Semantics

2007-04-05 Thread Jonathan Lang

Inspired by the new array indexing syntax from S09.

Modify S03 (under Range Semantics) so that if a Range is operating
in a bounded space, a 'whatever' star as the starting or ending point
maps to the lower or upper bound:

   my enum Months «:Jan(1) Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec»
   Mar..*# same as Mar..Dec
   *..Mar# same as Jan..Mar

This makes Ranges in an array index a natural outgrowth of the
standard Range semantics, rather than being an exceptional case.

--
Jonathan Dataweaver Lang


Re: [svn:perl6-synopsis] r14359 - doc/trunk/design/syn

2007-04-04 Thread Jonathan Lang

[EMAIL PROTECTED] wrote:

+Arrays may also be defined with a mixture of fixed and autoextending
+dimensions:
+
+my @calendar[12;*;24]; # Month dimension unlimited
+
+


Move this out of the section on fixed-length arrays and into the
section on multidimensional arrays; it fits most naturally as the
second paragraph of the latter section.

--
Jonathan Dataweaver Lang


Enhanced enumerations

2007-03-19 Thread Jonathan Lang

Some (many?) enumerations represent cycles, where incrementing from
the last element takes you back to the first: the seasons, the months,
the days of the week, the hues, etc.  How hard would it be to write a
module that lets you say something like:

 enum weekdays is cycle Sun Mon Tue Wed Thu Fri Sat

So that Sat++ eqv Sun (and a resumable control exception is thrown so
that you can do something fancy whenever you return to the start of
the cycle)?


Likewise, how would one be able to legally say:

 enum seasons spring summer autumn|fall winter

That is, to use a junction in the definition in order to provide
synonyms for one of the enumerated values?

--
Jonathan Dataweaver Lang


Re: [S09] Whatever indices and shaped arrays

2007-03-07 Thread Jonathan Lang

OK: before I submit a patch, let me make sure that I've got the
concepts straight:

@x[0] always means the first element of the array; @x[-1] always
means the last element of the array; @x[*+0] always means the
first element after the end of the array; @x[*-1] always means the
first element before the beginning of the array.  That is, the
indices go:

..., *-3, *-2, *-1, 0, 1, 2, ..., -3, -2, -1, *+0, *+1, *+2, ...
   ^  ^
   |  |
 first   last

As well, a Whatever in square braces is treated as an array of the
valid positions; so @x[*] is equivalent to @x[0..-1].

If you want to use sparse indices and/or indices that begin somewhere
other than zero, access them using curly braces.  Consider an array
with valid indices ranging from -2 to +2: @x{-2} means element -2,
which would be equivalent to @x[0]; @x{+2} means element 2, which
would be equivalent to @x[-1].  Likewise, @x{0} is the same as @x[2],
@x{-3} is the same as @x[*-1], @x{+3} is the same as @x[*+0], and so
on.  If @y has a series of five indices that start at 1 and double
with each step, then @y{1} will be the same as @y[0]; @y{4} will be
the same as @y[2], and so on.

A Whatever in curly braces is treated as an array of the valid index
names; so @x{*} means @x{-2..+2}, and @y{*} means @y{1, 2, 4, 8, 16}.
Because it is treated as an array, individual index names can be
accessed by position: @x{*[0]} is a rather verbose way of saying
@x[0].  This lets you embed ordinal indices into slices involving
named indices.  Conversely, using *{...} inside square braces lets you
embed named indices into slices involving ordinal indices: @x[*{-2}]
is the same as @x{-2}.

Multidimensional arrays follow the above conventions for each of their
dimensions; so a single-splat provide a list of every index in a given
dimension, a 0 refers to the first index in that dimension, and so on.
A double-splat extends the concept to a multidimensional list that
handles an arbitrary number of dimensions at once.

--

Commentary: I find the sequence of ordinals outlined above to be a bit
messy, especially when you start using ranges of indices: you need to
make sure that @x[0..-1] dwims, that @x[-1..(*+0)] dwims, that
@x[(*-2)..(*+3)] dwims, and so on.  This is a potentially very ugly
process.  As well, the fact that @x[-1] doesn't refer to the element
immediately before @x[0] is awkward, as is the fact that @x[*-1]
doesn't refer to the element immediately before @x[*+0].  IMHO, it
would be cleaner to have @x[n] count forward and backward from the
front of the array, while @x[*+n] counts forward and backward from
just past the end of the array:

..., -3, -2, -1, 0, 1, 2, ..., *-3, *-2, *-1, *+0, *+1, *+2, ...
^^
 ||
   first last

So perl 5's $x[-1] would always translate to @x[*-1] in perl 6.
Always.  Likewise, @x[+*] would be the same as @x[*+0].  (In fact,
the semantics for @x[*+n] follows directly from the fact that an
array returns the count of its elements in scalar context.)  And
@x[*] would be the same as @x[0..^*] or @x[0..(*-1)].

You would lose one thing: the ability to select an open-ended Range of
elements.  For a five-element list, @x[1..^*] means @x[1, 2, 3,
4], not @x[1, 2, 3, 4, 5, 6, 7, 8, ...].

Technically, one could say @x{+*} to reference the index that
coincides with the number of indices; but it would only be useful in
specific cases, such as referencing the last element of a one-based
contiguous array.

--
Jonathan Dataweaver Lang


Re: [S09] Whatever indices and shaped arrays

2007-03-06 Thread Jonathan Lang

Larry Wall wrote:

I like it.  I'm a bit strapped for time at the moment, but if you send
me a patch for S09 I can probably dig up a program to apply it with.  :)


Could someone advise me on how to create patches?

--
Jonathan Dataweaver Lang


Re: for ... else

2007-03-05 Thread Jonathan Lang

Larry Wall wrote:

On Mon, Mar 05, 2007 at 04:13:16PM +1030, Tom Lanyon wrote:
: Sounds like the following will work, but it doesn't seem 'nice'.
:
: for @invoice
: {
:  .process;
:  1;
: } or fail 'No invoices to process';

Still think if there's no invoices it logically should be tested first.
If you don't want to repeat mentioning the array, how 'bout:

@invoice or fail 'No invoices to process'
== for @() {
.process
}

or equivalently

@invoice or fail 'No invoices to process'
== map {
.process
}

all assuming you don't like my original

for @invoice || fail 'No invoices to process'
{
.process
}


These should work, as long as you don't replace fail 'no invoices to
process' with something that returns a non-empty list.

That said, you could:

 {
   for = || fail 'no input'
   {
 .process
   }
   CATCH {
 do_something_else if 'no input'
   }
 }

...where the 'no input' string is there only so that failures
generated by .process will propagate correctly.

--

This solution isn't generalizable beyond for, though: you wouldn't
be able to use it for while, until, or loop, all of which could
potentially follow the logic of do something special if the loop
fails to run even once.  Hmm...

 while test - $result {
   do_something;
   FIRST { do_something_else unless $result }
 }

...except that I don't think that FIRST would run unless $result is true.

I suppose that you _could_ write:

 if test {
   repeat {
 do_something
   } while test
 } else {
   do_something_else
 }

You'd be having to spell out the test twice, though.

--
Jonathan Dataweaver Lang


Re: for ... else

2007-03-04 Thread Jonathan Lang

herbert breunung wrote:

 Von: Thomas Wittek [EMAIL PROTECTED]
 That's, well, elegant! Yes.
 Because and but it's tricky.
 Nothing where I'd say wow, thats an easy solution to my problem!.
 It's a bit complicated, because you have to understand and combine
 several concepts. That's elegant. But not easy, I think.
 I think it's not simple enough for this simple kind of problem.

exactly, my full support to thomas with this, perl was always about
keep simple things simple too.


Seconded.  I would favor allowing an else block to be attached
following any loop block, with the semantics being that the else block
only gets triggered if the loop block doesn't run at least once.  I'd
do this instead of a block trait (such as FIRST or LAST) because of
the either-or relationship between the loop block and the else block.

--
Jonathan Dataweaver Lang


Re: for ... else

2007-03-04 Thread Jonathan Lang

Jonathan Lang wrote:

Seconded.  I would favor allowing an else block to be attached
following any loop block, with the semantics being that the else block
only gets triggered if the loop block doesn't run at least once.  I'd
do this instead of a block trait (such as FIRST or LAST) because of
the either-or relationship between the loop block and the else block.


The one exception would be the repeat statement, because attaching
an else block to it would be as confusing semantically as attaching
an else block to an unless statement.

--
Jonathan Dataweaver Lang


Re: for ... else

2007-03-04 Thread Jonathan Lang

Daniel Brockman wrote:

What about this?

   given @foo {
 for $_ - $x { ... }
 when .empty { ... }
   }

You can reverse the order if you want:

   given @foo {
 when .empty { ... }
 for $_ - $x { ... }
   }


Actually, you'd be better off using the second order; the when
statement would drop you out of the given block if triggered, and
you'd never get to the loop.  In the first order, you'd be triggering
both the loop and the when every time the given block executes.

--
Jonathan Dataweaver Lang


Re: for ... else

2007-03-04 Thread Jonathan Lang

Rick Delaney wrote:

Smylers wrote:
   for @invoice
   {
 .process;
   } or fail 'No invoices to process';

If that actually works then I'm happy.


It's dependent on .process not returning a false on the final iteration.

--
Jonathan Dataweaver Lang


statement modifiers

2007-03-04 Thread Jonathan Lang

The text of S02, S03, and S04 still contain references to the
now-defunct statement_modifier grammatical category.

Also, what's the reasoning behind specifically disallowing _all_
statement modifiers to do blocks (as opposed to forbidding just
looping statement modifiers)?  Is this legacy from when the
distinction wasn't being made, or is there still a valid reason for
forbidding conditional modifiers?

Finally: when used as a statement modifier, is given considered to
be conditional or looping?  (Gut instinct: conditional.)


Compound grammar

2007-03-04 Thread Jonathan Lang

AFAICT, there's nothing in the documentation to explain how one would
define a statement or operator with syntax along the lines of if ...
else ... or ... ?? ... :: ...  Admittedly, the only cases I know of
where this is still an issue are the two listed above: for statements,
all other perl 5 parallels have been replaced by the use of closure
traits; and the operator listed above is the only more-than-binary
operator that I've ever heard of which uses different delimiters.
That said, for the sake of future customization, it would be nice to
have a way to do these things.  (Or is this what macros are for?)

In the latter case, I find myself thinking about expanding on
infix: to allow for a list of tokens, much like circumfix:
does:

 infix:?? :: ($condition, $true, $false) # $condition ?? $true :: $false 

...and I'm wondering if something like this could be done in the
former case as well:

 statement_control:if else ($condition, true, false?) # if
$condition { ... } else { ... } 

Although this wouldn't cleanly handle an if ... elsif ... elsif ...
else ... statement.

--
Jonathan Dataweaver Lang


Re: statement modifiers

2007-03-04 Thread Jonathan Lang

Larry Wall wrote:

Jonathan Lang wrote:
: Larry Wall wrote:
: : Finally: when used as a statement modifier, is given considered to
: : be conditional or looping?  (Gut instinct: conditional.)
: 
: Why does it have to be one or the other?  It's just a topicalizer.
:
: One implication of replacing statement_modifier with
: statement_mod_cond and statement_mod_loop is that every statement
: modifier has to be defined as one or the other.

Ah, in that sense 'given' is currently considered a loop, and 'when'
is considered a conditional, so it's legal to say

say halt when 42 given $answer;

That follows from the recent decision to allow a condition inside a loop
to make it easy to write list comprehensions.  (The same decision that
turned 'for' into a map clone, by the way, and made 'if' return () when
false, at least in the absence of an 'else'.)


Nice.  Thank you.

--
Jonathan Dataweaver Lang


Re: [S09] Whatever indices and shaped arrays

2007-02-27 Thread Jonathan Lang

David Green wrote:

On 2/24/07, Jonathan Lang wrote:
In effect, using * as an array of indices gives us the ordinals
notation that has been requested on occasion: '*[0]' means 'first
element', '*[1]' means 'second element', '*[-1]' means 'last
element',
'*[0..2]' means 'first three elements', and so on - and this works
regardless of what the actual indices are.

Using * that way works, but it still is awkward, which makes me think
there's something not quite dropping into place yet.  We have the
notion of keyed indexing via [] and counting/ordinal indexing via
[*[]], which is rather a mouthful.  So I end up back at one of
Larry's older ideas, which basically is: [] for counting, {} for keys.


What if you want to mix the two?  I want the third element of row 5.
In my proposal, that would be @array[5, *[2]]; in your proposal,
there does not appear to be a way to do it.

Unless the two approaches aren't mutually exclusive: @array{5,
*[2]}.  That is, allow subscripted Whatevers within curly braces for
to enable the mixing of ordinals and keys.  Since this is an unlikely
situation, the fact that nesting square braces inside curly braces is
a bit uncomfortable isn't a problem: this is a case of making hard
things possible, not making easy things easy.


What about shaped arrays?  A shape means the indices *signify*
something (if they didn't, you wouldn't care, you'd just start at
0!).  So they really are *keys*, and thus should use a hash (which
may not use any hash tables at all, but it's still an associative
array because it associates meaningful keys with elements).  I'm not
put off by calling it a hash -- I trust P6 to recognise when I
declare a hash that is restricted to consecutive int keys, is
ordered, etc. and to optimise accordingly.


The one gotcha that I see here is with the possibility of
multi-dimensional arrays.  In particular, should multi-dimensional
indices be allowed inside square braces?  My gut instinct is yes;
conceptually, the third row of the fourth column is perfectly
reasonable terminology to use.  The thing that would distinguish []
from {} would be a promise to always use zero-based, consecutive
integers as your indices, however many dimensions you specify.  With
that promise, you can always guarantee that the wrap-around semantics
will work inside [], while nobody will expect them to work inside {}.

In short, the distinction being made here isn't unshaped vs.
shaped; it's ordinal indices vs. named indices, or ordinals
vs. keys.

That said, note that - in the current conception, at least - one of
the defining features of a shaped array is that trying to access
anything outside of the shape will cause an exception.  How would
shapes work with the ordinals-and-keys paradigm?

First: Ordinals have some severe restrictions on how they can be
shaped, as specified above.  The only degrees of freedom you have are
how many dimensions are allowed and, for each dimension, how many
ordinals are permitted.  Well, also the value type (although the key
type is fixed as Int where 0..*.  So you could say something like:

 my @array[2, 3, *]

...which would mean that the array must be three-dimensional; that the
first dimension is allowed two ordinals, the second is allowed three,
and the third is allowed any number of them - i.e., 'my @array[^2; ^3;
0..*]' in the current syntax.  Or you could say:

 my @array[2, **, 2]

...meaning that you can have any number of dimensions, but the first
and the last would be constrained to two ordinals each: 'my @array[^2;
**; ^2]'.

Note the use of commas above.  Since each dimension can only take a
single value (a non-negative integer), there's no reason to use a
multidimensional list to define the shape.  Personally, I like this
approach: it strikes me as being refreshingly uncluttered.

Furthermore, you could do away with the notion of shaped vs.
unshaped: just give everything a default shape.  The default shape
for arrays would be '[*]' - that is, one dimension with an
indeterminate number of ordinals.

Meanwhile, shapes for {} would continue to use the current syntax.
'[$x, $y, $z]' would be nearly equivalent to '{0..^$x; 0..^$y;
0..^$z}'.


If there are no meaningful lookup keys, if all I can do to get
through my list is count the items, then an array is called for, and
it can work in the usual way: start at 0, end at -1.  It is useful to
be able to count past the ends of an array, and * can do this by
going beyond the end: *+1, *+2, etc., or before the beginning: *-1,
*-2, etc.  (This neatly preserves the notion of * as all the
elements -- *-1 is the position before everything, and *+1 is the
position after everything else.)


Regardless, I would prefer this notion to the offset from the
endpoint notion currently in use.  Note, however, that [*-1] wouldn't
work in the ordinals paradigm; there simply is nothing before the
first element.  About the only use I could see for it would be to
provide an assignment equivalent of unshift: '@array[*-1] = $x'
could

Re: What criteria mark the closure of perl6 specification

2007-02-25 Thread Jonathan Lang

Smylers wrote:

Richard Hainsworth writes:
 When does the specification of perl6 come to an end?

At a guess: when it's implemented.

Many of the recent changes have been made by Larry in response to his
trying to write the grammar, and encountering problems.


With all due respect:

Once the grammar is written, what's left to do in terms of finalizing
the Perl 6.0 specification?  Surely we don't need to wait for the Perl
6 implementors to finish their work before declaring 6.0 to be fully
specified (and getting on with the business of working on 6.1
features)?  Admittedly, the best way to know if something is
implementable is to implement it; but I doubt that it's the only way.


There are still some 'hey wouldn't it be great if ...' threads on this
list, proposing brand new features, but nowhere near as many as there
used to be.  And at least some of us are trying to discourage such
things, hoping to deflect them away from taking Larry's time away from
getting finished synthesizing what we already have -- especially in the
case of things which could easily be provided by a module.


I submit that you'll have even more luck discouraging such things if
you can give a reasonable and believable timeline as to when the 6.0
spec will be ready and perl 6.1 features can start being considered.

--
Jonathan Dataweaver Lang


Re: [S09] Whatever indices and shaped arrays

2007-02-24 Thread Jonathan Lang

Jonathan Lang  wrote:

Larry Wall wrote:
 : If you want the last index, say '*[-1]' instead of '* - 1'.
 : If you want the first index, say '*[0]' instead of '* + 0'.

 So the generic version of leaving off both ends would be *[1]..*[-2]
 (ignoring that we'd probably write *[0]^..^*[-1] for that instead).

Correct - although that assumes that the indices are consecutive (as
opposed to, say, 1, 2, 4, 8, 16...); this version of * makes no such
assumption.


Another thought: '*[1..-2]' or '*[0^..^-1]' would do the trick here -
except for the fact that the Range 1..-2 doesn't normally make sense.
Suggestion: when dealing with Ranges in unshaped arrays, negative
endpoints are treated like negative indices (i.e., '$_ += [EMAIL PROTECTED]').

In effect, using * as an array of indices gives us the ordinals
notation that has been requested on occasion: '*[0]' means 'first
element', '*[1]' means 'second element', '*[-1]' means 'last element',
'*[0..2]' means 'first three elements', and so on - and this works
regardless of what the actual indices are.


Like I said, I tend to miss intricacies.  For instance, I never
considered what would be involved in applying a subscriptor to a
multidimensional Whatever (e.g., what can you do with '**[...]'?).
Part of that is that I'm not yet comfortable with multidimensional
slices (or arrays, for that matter); when reading about them, I keep
on getting the feeling that there's something going on here that the
big boys know about that I don't - implicit assumptions, et al.


I think I've got a better grip on it now.  Here's how I understand it to work:

A multidimensional array is defined by providing a list of lists, each
giving all of the valid indices along one axis (i.e., in one
dimension).  The overall shape of the array will be rectangular, or a
higher-dimensional analog of rectangular.  There may be gaps in the
indices (in which case the array is a sparse array as well as a
multidimensional array); but if there are, the gaps also conform to
the rectangular structure: it's as if you carved a solid rectangle
into two or more rectangular pieces and pulled them apart a bit.  That
is, @array[-1, +1; -1 +1] is effectively a 2x2 square array with valid
x-indices of -1 and +1 and valid y-indices of -1 and +1.

To access an element in a multidimensional array, use a
semicolon-delimited list of indices in the square braces:
'@cube[1;1;1]' will access the center element of a [^3;^3;^3] shaped
array, while '@array[*;*;1]' will access a 3x3 horizontal slice of it.

When putting together a list literal, things work a bit differently.
Create a one-dimensional literal by means of a comma-delimited list of
values; create a two-dimensional literal by means of a
semicolon-delimited list of comma-delimited lists of values:

1, 2, 3 # one-dimensional list literal with a length of 3
(1, 2, 3; 4, 5, 6) # two-dimensional list literal with a length of 2
and a width of 3.
(1; 2; 3) # two-dimensional list literal with a length of 3 and a width of 1.

I would guess that you would build higher-dimensional literals by
nesting parentheses-enclosed semicolon-delimited lists:

(( 0,  1;  2,  3;  4,  5;  6,  7;  8,  9);
(10, 11; 12, 13; 14, 15; 16, 17; 18, 19);
(20, 21; 22, 23; 24, 25; 26, 27; 28, 29))
# three-dimensional list literal with a length of 3, a width of 5, and
a height of 2.

The outermost set of semicolons delimits the first dimension, and the
commas delimit the last dimension.  That is, semicolon-delimited lists
nest, and comma-delimited lists flatten.

Furthermore, the list literal gets assigned to the array by means of
ordinal coordinates:

 my @cube[-1..+1; -1..+1; -1..+1] =
   ((1, 2, 3; 4, 5, 6; 7, 8, 9);
(10, 11, 12; 13, 14, 15; 16, 17, 18);
(19, 20, 21; 22, 23, 24; 25, 26, 27));

would be equivalent to

 my @cube[1..3; 1..3; 1..3];
 @cube[**[0; **]] = (1, 2, 3; 4, 5, 6; 7, 8, 9);
 @cube[**[0; **]] = (10, 11, 12; 13, 14, 15; 16, 17, 18);
 @cube[**[0; **]] = (19, 20, 21; 22, 23, 24; 25, 26, 27);

or

 my @cube[1..3; 1..3; 1..3];
 @cube[**[0; 0; *]] = 1, 2, 3;
 @cube[**[0; 1; *]] = 4, 5, 6;
 @cube[**[0; 2; *]] = 7, 8, 9;
 @cube[**[1; 0; *]] = 10, 11, 12;
 @cube[**[1; 1; *]] = 13, 14, 15;
 @cube[**[1; 2; *]] = 16, 17, 18;
 @cube[**[2; 0; *]] = 19, 20, 21;
 @cube[**[2; 1; *]] = 22, 23, 24;
 @cube[**[2; 2; *]] = 25, 26, 27;

or

 my @cube[1..3; 1..3; 1..3];
 @cube[**[0; 0; 0]] = 1;
 @cube[**[0; 0; 1]] = 2;
 @cube[**[0; 0; 2]] = 3;
 @cube[**[0; 1; 0]] = 4;
 @cube[**[0; 1; 1]] = 5;
 @cube[**[0; 1; 2]] = 6;
 ...

where

 say @cube[**[1; 1; 1]];

would be equivalent to

 say @cube[0; 0; 0];

Do I have the general idea?

--
Jonathan Dataweaver Lang


[S09] Whatever indices and shaped arrays

2007-02-23 Thread Jonathan Lang

From S09:

When you use * with + and -, it creates a value of Whatever but Num,
which the array subscript interpreter will interpret as the subscript
one off the end of that dimension of the array.

Alternately, *+0 is the first element, and the subscript dwims from
the front or back depending on the sign. That would be more
symmetrical, but makes the idea of * in a subscript a little more
distant from the notion of 'all the keys', which would be a loss, and
potentially makes +* not mean the number of keys.

If '*+0' isn't the first element, then '*+$x' is only meaningful if $x  0.

That said, I think I can do one better:

Ditch all of the above.  Instead, '*' always acts like a list of all
valid indices when used in the context of postcircumfix:[ ].

If you want the last index, say '*[-1]' instead of '* - 1'.
If you want the first index, say '*[0]' instead of '* + 0'.

So the four corners of a two-dimensional array would be:

 @array[ *[0]; *[0] ];  @array[ *[-1]; *[0] ];
 @array[ *[0]; *[-1] ]; @array[ *[-1]; *[-1] ];

The only thing lost here is that '@array[+*]' is unlikely to point
just past the end of a shaped array.  But then, one of the points of
shaped arrays is that if you point at an invalid index, you get a
complaint; so I don't see why one would want to knowingly point to
one.

--

Also, has the syntax for accessing an array's shape been determined
yet?  If not, I'd like to propose the following:

@array.shape returns a list of lists, with the top-level list's
indices corresponding to the dimensions of the shape and each nested
list containing every valid index in that dimension.  In boolean
context, the shape method returns true if the array is shaped and
false if not - though an unshaped array will otherwise pretend to be a
one-dimensional, zero-based, non-sparse, shaped array.

So:

 @array.shape[0][2] # the third valid index of the first dimension of the shape
 @array.shape[-1][0] # the first valid index of the last dimension of the shape
 @array.shape[1] # every valid index of the second dimension of the shape
 @array.shape[1][*] # same as @array.shape[1]

 [EMAIL PROTECTED] # is this a shaped array?

 exists @array.shape[2] # does the array have a third dimension?
 exists @array.shape[3][4] # does the fourth dimension have a fifth element?

 [EMAIL PROTECTED] # how many dimensions does the shape have?
 [EMAIL PROTECTED] # how many indices does the first dimension have?

If we use this notation, then

 @array[ *; * ]

is shorthand for

 @array[ @array.shape[0]; @array.shape[1] ]

--
Jonathan Dataweaver Lang


Re: [S09] Whatever indices and shaped arrays

2007-02-23 Thread Jonathan Lang

Larry Wall wrote:

On Fri, Feb 23, 2007 at 10:49:34AM -0800, Jonathan Lang wrote:
: That said, I think I can do one better:
:
: Ditch all of the above.  Instead, '*' always acts like a list of all
: valid indices when used in the context of postcircumfix:[ ].

Ooh, shiny!  Or at least, shiny on the shiny side...


Thank you...


: If you want the last index, say '*[-1]' instead of '* - 1'.
: If you want the first index, say '*[0]' instead of '* + 0'.

So the generic version of leaving off both ends would be *[1]..*[-2]
(ignoring that we'd probably write *[0]^..^*[-1] for that instead).


Correct - although that assumes that the indices are consecutive (as
opposed to, say, 1, 2, 4, 8, 16...); this version of * makes no such
assumption.

I do find myself wondering what *[-1] would be for an infinite array,
such as @nums[0..*:by(2)].

One possible answer: Inf.

Another possible answer: the shape sets limits on the indices; it does
not set requirements.  For instance:

 my @nums[0..*:by(2)];
 @nums[2 * $_] = $_ for 0..5];
 say @nums[ *[-1] ]; # same as 'say @nums[10];'
 @nums[42] = 21;
 say @nums[ *[-1] ]; # same as 'say @nums[42];'
 say @nums[ *[-2] ]; # same as 'say @nums[40];' - whatever that means.


: Also, has the syntax for accessing an array's shape been determined
: yet?  If not, I'd like to propose the following:
:
: @array.shape returns a list of lists, with the top-level list's
: indices corresponding to the dimensions of the shape and each nested
: list containing every valid index in that dimension.  In boolean
: context, the shape method returns true if the array is shaped and
: false if not - though an unshaped array will otherwise pretend to be a
: one-dimensional, zero-based, non-sparse, shaped array.

That's more or less how I was thinking of it, though I hadn't got as
far as boolean context.


I'm still debating the boolean context myself.  I _think_ it will
work; but I have a tendency to miss intricacies.  You might instead
want to require someone to explicitly check for definedness or
existence instead of merely truth; or you might not.


: If we use this notation, then
:
:  @array[ *; * ]
:
: is shorthand for
:
:  @array[ @array.shape[0]; @array.shape[1] ]

Note also that multidimensional whatever gives us

@array[ ** ]

to mean

@array[ @@( @array.shape[*] ) ]

or some such.


Like I said, I tend to miss intricacies.  For instance, I never
considered what would be involved in applying a subscriptor to a
multidimensional Whatever (e.g., what can you do with '**[...]'?).
Part of that is that I'm not yet comfortable with multidimensional
slices (or arrays, for that matter); when reading about them, I keep
on getting the feeling that there's something going on here that the
big boys know about that I don't - implicit assumptions, et al.


Though ** might want to be even smarter than that if
we want

@array[ 0; **; 42]

to dwim.  That'd have to turn into something like:

@array[ 0; @@( @array.shape[*[1]..*[-2]] ); 42 ]

Also +** might return a shape vector, or maybe +«**.


If by shape vector you mean something that says the array has a
length of 5, a width of 3, and a height of 2, +«** would seem to be
the more appropriate syntax.  Why you'd want that inside an array's
subscriptor is beyond me, for a similar reason to +*.  But that's what
the logic of the syntax gives.

But I _could_ see using '[EMAIL PROTECTED]' to get an array's measurements.

Hmm...

 my @@square = (1, 2; 3, 4);
 say +@@square; # say what?  '2', as in 2 dimensions?  Or '4', as in 4 items?

Answer that, and you'll know what +** would give you.

--

BTW: could the parser handle the following?

 @array[ *[0] * 2; 2 ** **[ [;] 0 x *] ]

--
Jonathan Dataweaver Lang


Y not

2007-02-21 Thread Jonathan Lang

Luke Palmer wrote:

% as the mod operator is a good example of what you describe.
There's no need for mod to be a symbolic operator: when you read 5 % 3
you say 5 mod 3.  Why would we not write 5 mod 3: it is just as
obvious what and how we are doing this operation.  And % is uncommon
enough that no huffman coding principals may apply.  The only thing we
have here is cultural baggage.


I can think of one case where % would be preferable to 'mod': when you
want to ask for a 'remainder' in the form of a non-integer.  That is,
'4.5 % 3' returns 1.5 (and parallels '/'), while '4.5 mod 3' returns 1
(and parallels 'div').  That said, if it's decided that the latter
definition is inappropriate or unnecessary, then I'd be all in favor
of completely dropping '%' in favor of 'mod' for the former
definition.


But I do think that Perl 6 is
gathering some operator bloat, in that we are defining symbols for
things that are not adding to the obviousness of the code.  They may
not be taking away, but all else being equal, we should choose the
option of lower abstraction


Hear, hear.  Huffman coding is all well and good; but not when taken
to the point that it starts interfering with legibility.  That said,
six-character words are the longest that I'd want to see, and I'd much
prefer three- or four-character words if reasonable.

Mind you, there are some cases where I'd like to see the symbol-based
operators supplemented by name-based ones instead of being replaced by
them.  For instance, I could live with a few more word-based
contextualizers: 'scalar' (same as '$:'), 'hash' (same as '%:'), and
'nested' (same as '@@:'); but I wouldn't want to remove '$:', '%:', or
'@@:'.  The only reason I don't also suggest 'sub' to supplement ':'
is the confusion that could arise between contextualization and
declaration.

--
Jonathan Dataweaver Lang


Re: Y not

2007-02-20 Thread Jonathan Lang

Thomas Wittek wrote:

Larry Wall schrieb:
 I think the ¥ and Y operators are going to have to change to something else.

Very probably I missed something as I'm only a distant observer of the
Perl6 development: Why not just call it zip?!
There is a function called zip, wouldn't it be possible to create an
operator with the same name?

zip(@a; @b) - function
@a zip @b - operator

Or would that lead to grammar ambiguities, that are impossible to resolve?


more generally, could we say that any function that has no parameters
other than a list - i.e., :(*@) - automatically gets a list-infix
operator form as well?  e.g.:

 my sub zip([EMAIL PROTECTED]) { ... }

could be called with

 zip (@a; @b; @c)

or

 @a zip @b zip @c

--
Jonathan Dataweaver Lang


Re: Y not

2007-02-20 Thread Jonathan Lang

Damian Conway wrote:

  I'd be more inclined to go
 the other way and say that you can transform any list infix form to
 the corresponding function form:

 @a ZZ @b ZZ @c - zip operator
 ZZ(@a; @b; @c) - zip function

 @a XX @b XX @c - cross operator
 XX(@a; @b; @c) - cross function

 @a X*X @b X*X @c - cross product operator
 X*X(@a; @b; @c) - cross product function

 @a MM @b MM @c - minmax operator
 MM(@a; @b; @c) - minmax function


Can't you already do this, with square braces?

 @a XX @b XX @c
 [XX] (@a; @b; @c)

etc?  Or am I missing something about the reduction metaoperator?


I'm not strongly opposed to this, unless they're the *only* forms of
the functions. If the very much more readable 'zip' and 'minmax' are
to be replaced with 'ZZ' and 'MM', then I think that's a serious step
backwards in usability.


Hear, hear.  I very much prefer 'zip' and 'minmax' to 'ZZ' and 'MM'.

--
Jonathan Dataweaver Lang


Re: Negative fraction subscripts

2007-01-30 Thread Jonathan Lang

Larry Wall wrote:

TSa wrote:
: Luke Palmer wrote:
: When do we do integer/rational math and when do we do floating point math?
:
: Since we have now flooring semantics on modulus and division I wonder
: how the coercion of nums to ints takes place. Does it also use floor?
: E.g. is @array[-0.3] accessing the last element or is it truncating
: to zero and indexing from the front?

Perl 5 truncates, I believe.  One could argue that floor is better behaved,
but the 0/-1 transition in subscripts is totally cork-brained anyway, so
I don't think it really matters if our numbers behave when wrapping around
the end of an array.


Perhaps.  Then again, it isn't the remainder that would define which
element you're looking at in this case; it would be the integer
portion.  And if I understand flooring semantics properly, -0.3 div 1
== -1.  Also, -0.3 mod 1 == 0.7; right?  Or is that the difference
between mod and %: the former returns the remainder as an integer
(e.g., '0'), while % return the remainder as a Num (e.g., '0.7')?
With truncating semantics, -0.3 div 1 == 0, and -0.3 % 1 == -0.3.

I think that TSa has a point here: converting from Num to Int should
always be equivalent to saying 'Num div 1'.  Which means that if you
ever override div to provide different semantics by default (e.g.,
Euclidean), you would also change the semantics of the Num-to-Int
coercion.


Interestingly, negative fractions, if truncated, would give us a way to
talk about the element off the end of the array, presuming that the endness
of the subscript is determined from the sign before it is truncated:

push @array, 42;
@array[-0.1] = 42;  # same thing
@array[-0.0] = 42;  # same thing?


Eh.  A neat little bell-and-whistle, but more confusing than it is useful.


But it probably doesn't matter.  If one really wants infinite modular
arrays, then you probably just say @array[$x % @array] or some such,
which gives you the floor semantics.


True enough.  I'd suggest doing this implicitly (with 'mod' instead of
'%'), ensuring that virtually every index maps to an existing element;
but then you'd lose the ability to append to an array by assigning to
'@[EMAIL PROTECTED]' (not that I'd do this; but I can see why some might
prefer this idiom to being pushy).

It's the sort of thing that I could see using a trait for: 'my @array
but oroborus' would invoke an implicit modulus on the index, while
standard arrays would not.  Likewise, those who don't want the
backward-indexing semantics could remove them by saying something like
'my @array but ray', causing negative indices to throw errors instead.
Ideally, applying both would cause negative indices to choke, but
would wrap too-large positive indices back to the beginning of the
array.

--
Jonathan Dataweaver Lang


  1   2   3   4   >