Re: S26 - The Next Generation

2009-08-24 Thread Jon Lang
Smylers wrote:
 Jon Lang writes:
 FWIW, the current proposal for aliasing blocks of ambient text is
 functional; it just feels a bit kludgey,

 Why?  To me it seems the opposite: what could be more natural for
 delimiting a block of code than braces?

Because sometimes you'll want to capture only part of a block of code,
or a little bit more than a block of code.  In short, what you want
for documentation purposes won't always align with the conceptual
structure of the ambient code.  I don't like the idea of being
required to break the code up into blocks whose only purpose is
documentation: if you're breaking the ambient code up into chunks for
documentation purposes, it should _look_ like the code is being broken
up into chunks for documentation purposes.  Using Pod tricks for
denoting the start and end of aliased ambient text does that; using a
Perl block doesn't.

 and I'm a bit bothered by the fact that you can't alias any ambient
 text other than a code block.

 Can't is a bit strong: it's more that if you want to quote an
 arbitrary portion of code then you need to add some braces around it.
 But those braces are unlikely to harm the program.

 The exception is if you want to quote an 'unbalanced' portion of code,
 for example the start of a loop but not the entire loop.  Do you
 consider that to be likely?

Actually, yes; I do.

 how about saying that an ambient code alias is normally
 terminated by the next blank line or Pod directive (as per =for)

 Braces are more robust than blank lines; if aliasing a brace-delimited
 block I may unthinkingly edit it to have a blank line in the middle of
 it, on the basis that the blank line isn't significant to perl.

And =begin blocks are more robust than =for blocks in the same way.
Perl may not care about blank lines; but Pod does.  And the author of
a file with both Perl and Pod in it is being remiss in his duties if
he doesn't consider both paradigms.  Incidently, note that declarator
blocks already behave this way in Pod: the presence or absence of a
blank line determines the code to which it gets attached.

 (Whereas if I edit the braces then I've changed the program as well as
 its docs.)

Right.  If the braces weren't part of the ambient code, and were there
merely to delineate the aliased text, I'd have less of a problem with
them.  In fact, my main problem with them at that point would be how
much they look like a code block without being one, and the confusion
that's sure to arise.

  Let's see what others think.

 OK.

 I like the braces.  I suggest initially only providing for braces, but
 with the possibility of later adding options to indicate other
 termination points if in practice there turn out to be many situations
 where the braces don't work well.

I like the idea of using the braces if they're there, and using
something else if they're not.  Again, my concern is is being forced
to alias an entire code block, never anything more or less; I'm not
opposed to being _able_ to alias an entire code block, and I'm
especially not opposed to being able to do so in a simple and
intuitive manner.

But let me propose something for the absence of braces case:
introduce a new kind of delimiter into Perl - something that works
like an embedded comment, except that it doesn't actually comment
anything out.  In the absence of a curly brace at the start of the
next line of code, a code alias will bind to the first document tag
that it finds, that isn't already claimed by another =alias directive.
 For example:

=alias loop
#:[[
=alias loop-head
loop #:[($i = 1; $i  $j; $i *= 2)]
=alias loop-body
{
DoSomething($i);
}
]]

In this example, I'm using #:[...] as a stand-in for the
documentation tag syntax.  As such,

loop is aliased to:

loop ($i = 1; $i  $j; $i *= 2)
{
DoSomething($i);
}

loop-head is aliased to:

($i = 1; $i  $j; $i *= 2)

And loop-body is aliased to:

{
DoSomething($i);
}

I'm not fond of the document tag syntax used in the above example;
it looks a little bit too much like a comment.  But whatever does get
used, it should be brief and distinct.

And since we're talking about connecting code and documentation, it's
possible that we might want to have this kind of alias be a special
case of the declaration block rather than a stand-alone directive,
using similar rules to determine what to alias (but focused on code
blocks and doc tags rather than declarators).

I've got to run right now; but I've more thoughts that just got
triggered by this.  I'll get back to you as soon as I can.

-- 
Jonathan Dataweaver Lang


Re: $*CWD and chdir()

2009-08-21 Thread Jon Lang
Martin D Kealey wrote:
 I wonder if this is becoming the new Perl mantra use lexically scoped
 pragmata.

Larry said it much more succinctly: all's fair if you predeclare.

-- 
Jonathan Dataweaver Lang


Re: [perl #64566] @a[1..*] adds trailing undef value

2009-08-19 Thread Jon Lang
On Wed, Aug 19, 2009 at 5:37 AM, Jan Ingvoldstadfrett...@gmail.com wrote:
 On Wed, Aug 19, 2009 at 1:54 PM, Moritz Lenz via RT 
 perl6-bugs-follo...@perl.org wrote:


 Since the discussion came up on #perl6 if this is really the expected
 behaviour, S09 says:

 As the end-point of a range, a lone whatever means to the maximum
 specified index (if fixed indices were defined):

    say @calendar[5..*];          # Same as:  say @calendar[5..11]
    say @calendar{Jun..*};        # Same as:  say @calendar{Jun..Dec}

 or to the largest allocated index (if there are no fixed indices):

    say @data[1..*];              # Same as:  say @results[1..5]


 It doesn't mention how the postcifcumfix:[ ] is supposed to introspect
 those to find out if the WhateverCode object constructed by 1..* needs
 to receive self.elems or self.elems-1 as an argument.

 Which is why I CC: p6l to get some ideas or clarification, and if we
 want to maintain this DWIMmy but not very consistent behaviour.

Given that it's relatively easy to say 1..^*, I wouldn't mind
standardizing this so that '*' always refers to the element just past
the last one, at least when dealing with the standard index.  That
said, when dealing with a custom index, there generally isn't an
easily identified one element past the end position that can be
referenced; so I'd be inclined to standardize everything there such
that '*' always refers to the last element.  And if we're going to do
that, why not do the same for standard indexing? e.g., '*' is always
the last element; '*-1' is always one in from the last element; etc.

 I like it the way S09 says it.

 But there is a problem with sparse arrays, isn't there?

There shouldn't be, because there shouldn't be sparse arrays - at
least, not in standard indexing.  One of the reasons for the
introduction of custom indices was the idea that sparseness would
take place in them, so that the standard index could be relied upon yo
provide ordinal access to the elements: @a[0] should _always_ be the
first element; @a[1] should always be the second element, and so on.
And you should always be able to reach the next item by adding one to
the current item's index.  That is, the standard index will always be
'0..^$number-of-items'.

If we're not going to follow this rule, then I see no reason why we
shouldn't just have the custom indexing mechanism _replace_ standard
indexing, rather than exist side by side with it.  If the standard
index can't be depended on for standardized behavior, it's useless.

That said, a case could be made that the custom indexing model is too
strict as written: it forces you to pre-establish a one-to-one
relationship between the standard and custom indices, which largely
negates its usefulness in implementing the concept of sparse arrays.
I recommend loosening up the restrictions on custom indexing and
putting a note in the spec to clarify the intended purpose and
features of the standard index.

 S32/Containers (S32-array) says this about elems:

  our Int method elems (@array: ) is export

 Returns the length of the array counted in elements. (Sparse array types
 should return the actual number of elements, not the distance between the
 maximum and minimum elements.)

This is exactly what the division between standard and custom indexing
was supposed to avoid.  When using standard indexing, the distance
between the minimum (i.e., [0]) and maximum (i.e., [*-1]) elements
should always be the actual number of elements; so no such special
note should be needed.

-- 
Jonathan Dataweaver Lang


Re: S26 - The Next Generation

2009-08-19 Thread Jon Lang
Damian Conway wrote:
 When using the code block alias, are the outermost curly braces
 considered to be part of the ambient code?

 Yes. All ambient code is actual code.

OK.  Let me propose an alternative (which I expect will be immediately
shot down):

Allow '=begin alias', '=end alias', and '=for alias' as special cases:
the Perl parser makes an exception for them and doesn't treat them as
the start or end of POD Blocks, merely as single-line directives; but
the Pod parser treats them as normal Pod Blocks, with the contents
being attached to the alias.  Net result: said contents count both as
ambient code and as aliased text.  Benefits: you can alias any ambient
code that you want, as long as it consists of one or more full lines;
and your method for delimiting the alias is one that Pod writers will
be quite use to.  Drawback: the Perl parser will need to look forward
a bit further before deciding how much ambient commentary there is.

-- 
Jonathan Dataweaver Lang


Re: S26 - The Next Generation

2009-08-19 Thread Jon Lang
FWIW, the current proposal for aliasing blocks of ambient text is
functional; it just feels a bit kludgey, and I'm a bit bothered by the
fact that you can't alias any ambient text other than a code block.

On Wed, Aug 19, 2009 at 11:29 AM, Damian Conwaydam...@conway.org wrote:
 Jonathan Dataweaver Lang proposed:

 OK.  Let me propose an alternative (which I expect will be immediately
 shot down):

 BANG!

 ;-)

D'oh!

 Allow '=begin alias', '=end alias', and '=for alias' as special cases:
 the Perl parser makes an exception for them and doesn't treat them as
 the start or end of POD Blocks, merely as single-line directives; but
 the Pod parser treats them as normal Pod Blocks, with the contents
 being attached to the alias.

 Well, clearly I'm not going to be in favour of introducing exceptions to
 the general syntax.

 However, I had originally thought that we should have =alias and
 =dealias directives to delimit code extractions. In the end I liked the
 use of the code's own delimiters better, but I guess if people preferred
 to have two directives as delimiters, we could consider that instead.

What I liked the most about my proposal was that it allowed for a
blank line termination form as well as an explicit directive
termination form.  On review, '=for alias' would have been redundant
with '=alias' (although I don't think that redundancy hurts).  And
again, the Pod coder would be able to think in the same terms that he
does for ordinary blocks.

But assuming for the moment that the pseudo-block idea is off the
table, how about saying that an ambient code alias is normally
terminated by the next blank line or Pod directive (as per =for)
unless you give it a :begin adverb, in which case it terminates with
an appropriately nested =alias name :end directive:

=alias outer :begin
while (...) {
   =alias inner
   blah blah blah

}
=alias outer :end

Unless there's some reason why adverbs don't work for =alias
directives, that's fully consistent with normal syntax.  OTOH, that's
exactly what the problem would be, isn't it?  '=alias outer :begin'
would be parsed as an inline alias, where outer is equated with
:begin.  So how about borrowing from your earlier example of
numbered items, and identifying explicitly terminated blocks with a +
or - immediately following the '=alias':

=alias+ outer
while (...) {
   =alias inner
   blah blah blah

}
=alias- outer

I'm also considering a more radical possibility whereas the ambient
code has a means of tagging portions of itself for Pod inclusion.
I'll think it through some more and then offer a proposal.

Still, I think that treating =alias as a block when it has only one
argument, and as a directive when it has none or two, would be more
user-friendly (though admittedly more hostile to the guy coding the
Pod Parser) than any of these alternatives.

 Let's see what others think.

OK.

-- 
Jonathan Dataweaver Lang


Re: [perl #64566] @a[1..*] adds trailing undef value

2009-08-19 Thread Jon Lang
David Green wrote:
 Jon Lang wrote:
 Given that it's relatively easy to say 1..^*, I wouldn't mind
 standardizing this so that '*' always refers to the element just past
 the last one, at least when dealing with the standard index.

 I like the DWIMmery, but the more I think about it, for such a little
 difference, it seems more worthwhile to be consistent than to be DWIMy.  So,
 yes, either * always means last+1, and use 1..^*, or make * mean the last
 index, and use [*+1] to append.

...and if addressed properly, it can be DWIMmy too.  In many ways,
saying that * is just off the end of the index range is
counterintuitive; it's more reasonable to people who haven't been
trained to think in terms of Perl 5's negative indices to think of 0
as being the first element and * as being the last element.  And
again, there are fewer problems with custom indexing if you go this
route.

 But there is a problem with sparse arrays, isn't there?

 Sparseness is an implementation detail.  Arrays all look the same to the
 user; sparseness just means perl is smart enough to do
 @foo[1]=$bar without trying to suck up a zillobyte of RAM.

To the extent that that is true, @foo.elems should equal 10001.

-- 
Jonathan Dataweaver Lang


Re: directories of interest, a multiplicity alternative to CWD

2009-08-19 Thread Jon Lang
'home' should be spelled '~'.

-- 
Jonathan Dataweaver Lang


Re: $*CWD and chdir()

2009-08-18 Thread Jon Lang
On Tue, Aug 18, 2009 at 7:03 PM, Mark J. Reedmarkjr...@gmail.com wrote:
 The OS-level chdir() and getcwd() are not thread-safe. The usual
 advice is to ignore them completely in multithreaded programs, in
 favor of absolute paths (or relative paths from a fixed location,
 never calling chdir()).  This is part of the a reason that Apache2
 recommends fastcgi for non-prefork MPMs (since the CGI spec requires
 cgi scripts to start with getcwd() set to the directory containing
 them).

I like Timothy's suggestion: do not associate $*CWD with chdir at all,
but tie $*CWD in with every standard routine that makes use of the
current working directory concept.  Keep chdir around, but add a
note saying that its use should be avoided in favor of assigning to
$*CWD.  Ditto with getcwd and reading the value of $*CWD.

The only thing that gets clobbered by this is the inability to use
relative paths when changing the current working directory.
Personally, I have no problem with the idea that $*CWD is a magical
Path that resolves itself into an absolute Path when you assign a
relative Path to it (that is, $*CWD = ($path.relative ?? $*CWD ~ $path
:: $path).resolvepath, or something to that effect) - and thus is
always an absolute Path; but I can understand that others have a
problem with this.  On a similar note, I wouldn't mind a bit of magic
that has $*CWD test for the existence of the new value before actually
making the change, and throwing an exception if the target is not a
directory; that way, you're guaranteed that $*CWD is always a valid
Path.  With this magic in place, I would never be tempted to use chdir
or getcwd.  Alternatively, $*CWD should be readonly and have a chdir
method that implements the above behavior, emulating the features of
the OS's chdir in a thread-safe manner.

Or just warn people _not_ to alter $*CWD directly, and change chdir
and getcwd so that they alter and read $*CWD appropriately by default,
and only perform their OS equivalents if you explicitly ask them to.

-- 
Jonathan Dataweaver Lang


Re: Filename literals

2009-08-17 Thread Jon Lang
Timothy S. Nelson wrote:
 David Green wrote:
 Jon Lang wrote:
 If so, could you give some examples of how such a distinction could be
 beneficial, or of how the lack of such a distinction is problematic?

        Well, my main thought in this context is that the stuff that can be
 done to the inside of a file can also be done to other streams -- TCP
 sockets for example (I know, there are differences, but the two are a lot
 the same), whereas metadata makes less sense in the context of TCP sockets;
 I guess this was one of the thoughts that led me to want separate things
 here.

Ah.  I can see that.

 Well, I definitely think there needs to be a class that combines the
 inside and the outside, or the data and the metadata.  Certainly the
 separate parts will exist separately for purposes of implementation, but
 there needs to be a user-friendlier view wrapped around that.  Or maybe
 there are (sort of) three levels, low, medium, and high; that is, the basic
 implementation level (=P6 direct access to OS- and FS- system calls); the
 combined level, where an IO or File object encompasses IO::FSnode and
 IO::FSdata, etc.; and a gloss-over-the-details level with lots of sugar on
 top (at the expense of losing control over some details).

        Hmm.  With the quoting idea, I don't see the need for a both type
 of object.  I mean, I'd see the code happening something like this:

 if (path{/path/to/file}.e) {
       �...@lines = slurp(path{/path/to/file});
 }

        Or...

 if (path{/path/to/file}.e) {
        $handle = open(path{/path/to/file});
 }



        (I'm using one of David's suggested syntaxes above, but I'm not
 closely attached to it).

For the record, the above syntax was my suggestion.

        I guess what I'm saying here is that I think we can do the things
 without people having to worry about the objects being separate unless they
 care.  So, separate objects, but hide it as much as possible.  Is that
 something you're fine with?

It looks good to me.

 In fact, having q, Q, or qq involved at all strikes me as wrong,
 since those three are specifically for generating strings.

 Pathnames still are strings, so that's fine.  In fact, there are different

        Hmm.  I'm not so sure; maybe I'm just being picky, but I want to
 clarify things in case it's important (in other words, I'm thinking out loud
 here to see if it helps).

        First, Q and friends don't generate strings, they generate
 string-like objects, which could be Str, or Match, or whatever.  Think of
 quoting constructs as a way of temporarily switching to a different
 sublanguage (cf. regex), and you'll have the idea that I have in mind.

        As for pathnames being strings, you may be right FSVO string.  But
 I'd say that, while they may be strings, they're not Str, but they do Str,
 as in

 role    IO::FSNode does Str {...}

        (FSNode may not be the right name here, but is used for illustrative
 purposes).

I'd go one step further.  Consider the Windows path 'C:\Program
Files\'.  Is the string what's really important, or is it the
directory to which the string refers?  I ask because, for legacy
reasons, the following points to the same directory: 'C:\PROGRA~1\'.
Then there's the matter of absolute and relative paths: if the current
working directory is 'C:\Program Files\', then the path 'thisfile'
actually refers to 'C:\Program Files\thisfile'.  And because of parent
directory and self-reference links, things like '/bin/../etc/.' is
just an overcomplicated way of pointing to '/etc'.  I'd like Perl 6's
treatment of filenames to be smart enough that smart-matching any of
these pairs of alternative spellings would result in a successful
match.  So while I'll agree that filenames are string-like, I really
don't want them to _be_ strings.

 things going on here; one is to have a way of conveniently quoting strings
 that contain a lot of backslashes.  Just as Perl lets you pick different
 quotation marks, to make it easier to quote strings that have a lot of  or
 ' characters, so it should have a way to make it easy to quote strings with
 a lot of backslashes.  (The most obvious example being Windows paths; but
 there are other possibilities, such as needing to eval some code that
 already has a lot of backslashes in it.)

 Now, you can already turn backwhacking on or off via Q's :backslash
 adverb; Q:qq includes :b (and Q:q recognises a few limited escape sequences
 like \\). So you could say Q[C:\some\path], and you could add scalar
 interpolation to say Q:s[C:\some\path\$filename].  But there's no way to
 have all of: literal backslashes + interpolation + escaped sigils.

 Perhaps instead of a simple :b toggle, we could have an :escapeStr
 adverb that defaults to :escape\? Then you could have
 Q:scalar:escape(^)[C:\path\with\literal^$\$filename].

        Maybe a global variable?  It's an interesting idea, and I'll see how
 others feel :).

I'm leery of global variables, per se; but I _do_ like the idea

Re: Filename literals

2009-08-17 Thread Jon Lang
Troels Liebe Bentsen wrote:
 Hey,

 Just joined the list, and I too have been thinking about a good path literal
 for Perl 6. Nice to see so many other people are thinking the same :).

Welcome to the list!

 Not knowing where to start in this long thread, I will instead try to show how
 I would like a path literal to work.

A well-considered proposal, and one with which I mostly agree.  Some thoughts:

 The default p{} should only allow / as separator and should not allow
 characters that won't work on modern Windows and Unix like \ / ? % * : |   
 ,
 etc. The reason for this is that portable Path's should be the default and if
 you really need platform specific behavior it should be shown in the code.

I note that you explicitly included * and ? in the list of forbidden
characters; I take it, then, that you're not in favor of Path as a
glob-based pattern-matching utility?  E.g.:

my Path $path;
...
unless $path ~~ pastro* { say the file doesn't begin with 'astro'. }

Admittedly, this particular example _could_ be accomplished through
the use of a regex; but there _are_ cases where the use of wildcard
characters would be easier than the series of equivalent tests that
Perl would otherwise have to perform in order to achieve the same
result.  Hmm... maybe we need something analogous to q vs. qq; that
is:

pastro* #`{ syntax error: '*' is not a valid filename character. }
ppastro* #`{ returns an object that is used for Path
pattern-matching; perhaps Pathglob or somesuch? }

 We should allow windows style paths so converting and maintaining code on this
 platform is not a pain.
:
 For Unix specific behavior we should have a p:unix{} literal, here the only
 limit are what is defined by locale.
:
 And for people where this is a problem p:bin{} can be used as no checking is
 done here.
:
 Old style Mac paths could also be supported where the : is used as separator.
:
 Or old dos paths where 8 char limits and all the old dos stuff apply.

Hear, hear.  Note that these are all mutually exclusive, which
suggests that the proper format ought to be something like:

 my Path $path = p:formatwin{C:\Program Files}

However, I have no problem with the idea that :win is short for
:formatwin; the feature here is brevity.

 Urls could also be support with:

 my Path $path = p:url{file:///home/test.file}

I would be very careful here, in that I wouldn't want to open the can
of worms inherent in non-file protocols (e.g., ftp, http, gopher,
mail), or even in file protocols with hosts other than localhost.

 ** Path Object like File::Spec, etc. just nicer **
:
 ** Comparing Paths should do the right thing **

Agreed on all counts.

 ** Utility functions **

 Path in itself knows nothing about the filesystem and files but might have a
 peek in $*CWD to do some path logic. Except for that a number of File related
 functions might be available to make it easy to open and slurp a file a Path
 points to.

 my File $file = p{/etc/passwd}.open;
 if($file.type ~~ 'text/plain') {
  say looks like a password file;
 }

 my @passwd = p{/etc/passwd}.lines;


 if(p{/etc/passwd}.exists) {
  say passwd file exists;
 }

As soon as you allow methods such as .exists, it undermines your claim
that Path knows nothing about the filesystem or files.  IMHO, you
should still include such methods.

-- 
Jonathan Dataweaver Lang


Re: S26 - The Next Generation

2009-08-17 Thread Jon Lang
On Sun, Aug 16, 2009 at 1:26 PM, Damian Conwaydam...@conway.org wrote:
   * This means Pod can be indented; the = is no longer tied to the
     first column. The indentation preceding the opening = (using the
     ($?TABSTOP // 8) rule, as for heredocs) now specifies the zeroth
     column of the Pod block.

Will ther be any ambiguity between Pod and wraparound operators that
begin with =?  e.g.,

my Dog $spot
  = new Dog; # Pod, or Perl assignment?

if really_long_expression
   == value { ... } # Pod, or equality operator?

   * In addition to delimited, paragraphed, and abbreviated Pod blocks,
     documentation can now be specified in a fourth form:

       my $declared_thing;   #= Pod here until end of line

       sub declared_thing () {   #=[ Pod here
                                     until matching
                                     closing bracket
                                   ]
            ...
       }

Note the recent revisions to how Perl comments work - in particular,
an embedded comment is now spelled #`[ ... ].  Should embedded
attached Pod be spelled as #=`[ ... ]?  My preference would be to
simply say that if the very first character within a comment is an =,
then it becomes a Pod attachment.  That is, we're not dealing with a
variation of the Pod Comment syntax (i.e., s/#/#=/); rather, we're
dealing with a special use of a normal comment.  Thus, an embedded Pod
attachment would be written as #`[=...].  The main benefit of this
would be that if any further refinements occur to Perl's comment
syntax, Pod will adapt to those changes seamlessly[1].  As well, this
would help with any effort that might be made to integrate the use of
Pod into other languages: e.g., Javascript-with-Pod would handle a Pod
attachment as /*=...*/ or //=... (for embedded and end-of-line
comments, respectively).

-- 
Jonathan Dataweaver Lang

[1] Not to derail the conversation, but I would consider this to be
another argument in favor of the proposed '(#...)' syntax for embedded
comments: with this syntax, an embedded Pod attachment would be
spelled '(#=...)'.  Much more aesthetically pleasing.


Re: S26 - The Next Generation

2009-08-17 Thread Jon Lang
Could we also get =numbered and =term directives that are
equivalent to =item :numbered and =item :term, respectively, for
use with abbreviated blocks? E.g.:

=numbered First Item
=numbered Second Item
=numbered Third Item

=term First Name
Definition
=term Second Name
Definition

Within tables, you should probably replace whitespace with multiple
whitespace as a column delimiter; otherwise, the space between two
words in an identifier would trigger a new column:

column 1   column 2
^^ ^   ^^ ^

(Each group of ^'s would be a separate column.)

When using the code block alias, are the outermost curly braces
considered to be part of the ambient code?

Why is =END a block, and not a directive?

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-17 Thread Jon Lang
On Tue, Aug 11, 2009 at 12:42 PM, Jon Langdatawea...@gmail.com wrote:
 jerry gay wrote:
 for the latest spec changes regarding this item, see
 http://perlcabal.org/svn/pugs/revision/?rev=27959.

 is everyone equally miserable now? ;)

 Already seen it.  My latest points still stand, though: #`(...) is
 still vulnerable to ambiguity relative to #..., whereas `#(...),
 `#...#`, or (#...) don't share the same vulnerability.

With the latest S26 proposal (and its new declarator blocks) in mind,
I think that I would be happiest if embedded comments used the (#...)
syntax.  Reason: you still get the flexibility of choosing your own
delimiters (unlike `#...#`), and you don't have to worry about where
the = goes (unlike #`(...): is it #=`(...), #=(...), or #`(=...)?
Likewise for `#(...)).

-- 
Jonathan Dataweaver Lang


Re: Filename literals

2009-08-15 Thread Jon Lang
On Sat, Aug 15, 2009 at 7:17 AM, Timothy S. Nelsonwayl...@wayland.id.au wrote:
 On Sat, 15 Aug 2009, Austin Hastings wrote:

 This whole thread seems oriented around two points:

 1. Strings should not carry the burden of umpty-ump filesystem checking
 methods.

 2. It should be possible to specify a filesystem entity using something
 nearly indistinguishable from standard string syntax.

 I agree with the first, but the relentless pursuit of the second seems to
 have gone beyond the point of useful speculation.

 What's wrong with

  File('C:\Windows')

 or Path() or Dir() or SpecialDevice()?

 Not to get all Cozens-y or anything, but chasing after ways to jam some
 cute string-like overloading into the syntax so that we can pull out the
 other overloading (which at least had the virtue of simplicity) seems
 pointless.

 The File::* functionality is probably going to be one of the very early p6
 modules, and it is probably going to be in core. If that's true, why not
 allocate some really short names, ideally with 0 colons in them, and use
 them to spell out what's being done?

        S32/IO already specifies all these things as living in the IO
 namespace.  That could be changed, of course.

 Neither q:io:qq:{.} nor qq:io{.} really stand out at excellent ways to say

        q:io{.} would be the normal case, unless you want variable
 interpolation or the like.  And it would be possible to come up with shorter
 versions (someone suggested qf).

 this is a path, or directory, or file, or whatever. If it's
 plug-in-able, I'd take qq:file{.} or qq:dir{.} or qq:path{.}, but I'd rather
 see C  File q{.} .

        I'm not particularly attached to :io if we can think of something
 better.  These things often have a short name and a long name.  I'm against
 file because the IO::File object models what is inside the file (ie.
 open/read/write/close/etc), whereas the
 IO::FSNode/IO::FileNode/IO::DirectoryNode/IO::LinkNode objects model stuff
 on the outside of the file.  It's things of this second type that I'm
 recommending that we return here.  We could change the names of the objects
 of course, but I'm keen on keeping the class that does stuff to the inside
 of the file separate from the class that does stuff to the outside of the
 file. Path might be a good alternative in my mind.

IOW, your outside the file stuff is whatever can be done without
having to open the file, and your inside the file is whatever only
makes sense once the file has been opened.  Correct?  If so, could you
give some examples of how such a distinction could be beneficial, or
of how the lack of such a distinction is problematic?

        Anyway, back to the :io name.  An alternative might be to have the
 short name be :p and the long name be :path.  That would mean that we could
 do:

 q:p{.}

Isn't there something in the spec that indicates that qq is merely
shorthand for q:qq?  That is, it's possible to bundle a bunch of quote
adverbs together under a special quote name.  If so, you might say
that q:path and q:p are longhand for path:

path{.} # same as q:p{.}

And yes, 'path' is longer that 'q:p' - but only by one character; and
it's considerably more legible.  As well, this is more in keeping with
what's really going on here: path{.} would be no more a string than
m{.} or rx{.} are.  In fact, having q, Q, or qq involved at all
strikes me as wrong, since those three are specifically for generating
strings.

Also note the following:

   string # same as qq[string]
   'string' # same as q[string]
   /pattern/ # same as m[pattern]?

The ultimate in path literals would be to establish a similar
default delimiter.  For example, what if the backtick were pressed
into service for this purpose?  (No, I'm not actually suggesting this;
at the very least, there would be p5 false-compatibility issues
involved.  This is strictly illustrative.)

   `path` # same as path[path]
   `path`.e # does that filename exist?  Returns boolean.
   `path`.size # how big is the file?  Returns number.
   `path`.open # Returns new file handle.

        That's a fair bit shorter than Path(q{.}).  Hmm.  Let's compare some
 code samples:

 if (q:p'/path/to/file' ~~ :r) {
        say Readable\n;
 }
 if (Path('/path/to/file') ~~ :r) {
        say Readable\n;
 }

if (path'/path/to/file'.r) {
   say Readable;
}
if (`/path/to/file`.r) {
   say Readable;
}

 $fobj = new IO::File(FSNode = q:p'/path/to/file');
 $fobj = new IO::File(FSNode = Path('/path/to/file'));

$fobj = path[/path/to/file].open;
$fobj = `/path/to/file`.open;

        I used single quotes for the Path() things because I think that's
 what people would probably do.

        Now, say we want to use backslashes.

 if (Q :p {C:\Windows\file} ~~ :r) {
        say Readable\n;
 }
 if (Path(Q {C:\Windows\file}) ~~ :r) {
        say Readable\n;
 }

if (path:win[C:\Windows\file].r) {
   say Readable;
}

        Anyway, we have possibilities.  Further thoughts anyone?

As illustrated above, I think 

Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-11 Thread Jon Lang
Ben Morrow wrote:
 However, I would much rather see a general syntax like

    (# ... )
    {# ... }
    [# ... ]

 with no whitespace allowed between the opening bracket and the #: this
 doesn't seem to conflict with anything. Allowing # ...  in rules would
 also be nice.

That's rather elegant.  It's no longer than the current embedded
comment syntax, and avoids the start-of-line issue.  The only
complication arises when you prepend the brackets with a quote or
pseudo-quote character:

   say q(# is this a string or a comment?); # DWIM - string.

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-11 Thread Jon Lang
smuj wrote:
 Jon Lang wrote:
 smuj wrote:
 Jon Lang wrote:
 Here's a radical notion: use something other than '#' to initiate an
 inline comment.

 [snippage]

 Or maybe just don't allow embedded comments unless they are actually
 embedded, i.e. if a line starts with a # (ignoring leading whitespace)
 then it's _always_ a line-end comment, no matter what follows the #, e.g.

 That has the advantage of preserving a three-character embedded
 comment.  It has the disadvantage that you get differing behavior
 depending on where the comment is on the line.  As I see it, the whole
 point of this exercise is to get rid of the gotchas, and not just to
 shift them around - thus my ':#' proposal.

 I think whatever the solution is, it must begin with a # -- anything else
 will likely create even more gotchas.

When inline comments begin with a '#', the main gotcha arises when you
go to comment out a series of lines by prepending a # to each, and one
of those lines begins with the proper series of characters to create
an inline comment instead.  If you add the condition that a line
beginning with a '#' is automatically a full-line comment (or, as
currently specced, simply complains about the ambiguity), you replace
this gotcha with one where someone types in what he intends to be an
inline comment, but forgets to indent it.  Adding a secondary
character after the '#' reduces the likelihood of this happening, but
doesn't eliminate it.

When inline comments begin with something other than '#', none of the
above gotchas exist.  Instead, the main gotcha occurs when you go to
create an end-of-line comment at the end of a line that ends with
whatever the first character of an inline comment is.  A programmer
who forgets to put whitespace between that character and the '#' will
get an inline comment instead.  IMHO, this is no different than any
other case where the programmer mistakenly allows two different tokens
to run together.  As well, when programmers add comments to the ends
of a series of lines, they generally lead off with whitespace intended
to align said comments with each other; so existing habits would not
cause difficulties as they currently do for commenting out lines.

 Also, we have to realize that no
 matter what sequence we choose for embedded comments, there will _always_ be
 a chance of a gotcha, so all we can do is minimize the likelihood, as well
 as making the gotcha easy to spot, whilst not making embedded comments too
 difficult to use for those who like them.

My argument is that starting an inline comment with something other
than a '#' minimizes the likelihood of gotchas, makes gotchas easy to
spot, and doesn't make embedded comments too difficult to use for
those who like them.  Is there anything that my argument missed?

 My current personal favourite would be to keep things as they are with
 regards to bracketing, but to introduce a + between the # and the brackets.

This reduces the likelihood of ambiguity cropping up between an
embedded comment and an end-of-line comment; but it doesn't eliminate
the possibility.  Reversing the order to '+#' _would_ eliminate any
possibility of ambiguity at the start of a line; and the only thing
you'd have to watch out for would be someone deciding to start an
end-of-line comment immediately after a '+', with no intervening
whitespace.  As well, '+#' is just as easy to type as '#+'.  Heck,
while I like the bracketing idea, you could even say that any comment
that begins with '+#' followed immediately by a non-bracketing
character is an inline comment that will be terminated by the first
'#+' sequence it finds:

  #end-of-line comment
  #(end-of-line) comment
  #+end-of-line comment
  #+(end-of-line) comment
  +# embedded comment #+
  +#(embedded comment)

I'm not picky as to the choice of the additional character; but if
you're going to add it in, add it in where it will cause the least
amount of trouble: just before the '#'.

 I'd also change the terminology from embedded comments to extended
 comments.

toMAYto, toMAHto.

--
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-11 Thread Jon Lang
Ben Morrow wrote:
 This appears to be leading to a :comment modifier on quotables, with
 some suitable shortcut. Perhaps 'q#'? Or are we not allowed mixed alpha
 and symbols?

It's probably a bad practice, if possible.

 (I really want to suggest £, just to teach USAnians '#' isn't called
 'pound'... :) )

In all seriousness, there's another use to which I'd like to put '£'.

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-11 Thread Jon Lang
jerry gay wrote:
 for the latest spec changes regarding this item, see
 http://perlcabal.org/svn/pugs/revision/?rev=27959.

 is everyone equally miserable now? ;)

Already seen it.  My latest points still stand, though: #`(...) is
still vulnerable to ambiguity relative to #..., whereas `#(...),
`#...#`, or (#...) don't share the same vulnerability.

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-10 Thread Jon Lang
On Mon, Aug 10, 2009 at 12:25 PM, Patrick R. Michaudpmich...@pobox.com wrote:
 I'd be fine with the ##(embedded comment solution) approach (doubling
 the #'s), but it's much less visually appealing to me.  I think I'd
 prefer to see a doubling of the bracketing chars instead of doubling
 the #'s -- the # is visually a heavy glyph and I'd prefer
 something a bit lighter.

    #((embedded comment))
    #{{embedded comment}}

I could definitely go with this.  The only question lies in how often
you're likely to find a doubled open-bracket at the start of a line.

However, let me toss out some other possibilities for consideration:

If you want lightweight, another possibility would be to insist that
an inline comment must be preceded by horizontal whitespace; so #{
comment } would be an end-of-line comment, whereas  #{ comment }
would be an inline comment.  This is in keeping with the current
spec's use of whitespace to distinguish between a start-of-line
comment and an inline comment.  Then again, perhaps that's a bit _too_
lightweight.  And it adds to another problem that I have with Perl 6,
namely the variety of mandatory/forbidden whitespace rules.  They are,
IMHO, a necessary evil, and should be kept to a minimum.  Plus, when I
typed the latter one out in this message, the composition window
wrapped the line between the start of the quote and the #.  One of the
lesser purposes of an inline comment is when you're passing code
through channels that might insert word-wraps into the code: an
end-of-line comment has the possibility of breaking, whereas the
inline comment handles it without complaint.

Another possibility: instead of ## for an inline comment, how about
some other two-character pair that starts with a '#', where the second
character is a non-bracketing character that's unlikely to be found at
the start of a line?  E.g., '#:' - the colon is visible, lightweight,
and is almost always tacked onto the end of something else.  In this
approach, the minimum number of characters needed for an inline
comment will be four: the '#:' pair, an open-bracket, and a
close-bracket.  (Compare to '#{{ ... }}', which requires a minimum of
five characters.)  It also avoids the question of how much repetition
of the '#' is permitted.  So:

  #line comment
  #:line comment
  #(line comment)
  #:(inline comment)

OTOH, :( ... ) is the Perl syntax for a signature; and it wouldn't be
unreasonable to find a signature at the beginning of a line.  Far less
common than the current situation of finding an open-bracket there;
but perhaps too common to ignore.  I'd recommend '#='; but if that
isn't already being used by pod, it should be reserved for use by pod
(and it's visually heavy).

What other symbols are reasonably easy to type, are visually
lightweight, and are unlikely to be found at the start of a line and
immediately followed by an open bracket?  Hmm... how about '#.'?

  #line comment
  #.line comment
  #(line comment)
  #.(inline comment)

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-10 Thread Jon Lang
On Mon, Aug 10, 2009 at 2:16 PM, Mark J. Reedmarkjr...@gmail.com wrote:
 I still like the double-bracket idea. I don't much mind the extra
 character; 5 characters total still beats the 7 of HTML/XML.

Agreed.  As I said, the biggest potential stumbling block for this
would be the existence of a double-bracket that sees frequent use at
the start of a line.  Query: does '' count as a double bracket, or
as a single bracket (since it's equivalent to '«')?  If the former,
then there's a respectable chance of seeing a line that begins with
'' which would comment out as an inline comment rather than an
end-of-line comment.  If the latter, lines beginning with '' would
still comment out as end-of-line comments.  Off the top of my head, I
can't think of any other bracketing characters that are commonly
doubled up.

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-10 Thread Jon Lang
On Mon, Aug 10, 2009 at 3:36 PM, Darren Duncandar...@darrenduncan.net wrote:
 Personally, I think that comments should have trailing # as well as leading
 ones, so they are more like strings in that the same character is used to
 mark both ends.

You mean like the following?

q[quoted text]
qq(interpolated quote)
spattern = string
rx(pattern)

The leading # in an inline comment is akin to the q|qq|s|tr etc. of
the various pseudo-quote structures: it identifies to what purpose the
brackets are being used.  A trailing # would be superfluous.

 Note that my proposal is orthogonal to other issues like double-leading # or
 whatever bracketing chars are used.

 Also note that if the # are treated more like delimiters, then potentially
 we could also have \# to escape literal #, same as we have \' or \ etc.

Ugh. One of the reasons for the likes of q ... , etc. is to provide
an alternative to having to escape the delimiter by allowing you to
select a delimiter that won't clash.   By making '#' a delimiter, you
remove that ability.

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-10 Thread Jon Lang
smuj wrote:
 smuj wrote:
 Jon Lang wrote:
 ... the biggest potential stumbling block for this
 would be the existence of a double-bracket that sees frequent use at
 the start of a line.  Query: does '' count as a double bracket, or
 as a single bracket (since it's equivalent to '«')?  If the former,
 then there's a respectable chance of seeing a line that begins with
 '' which would comment out as an inline comment rather than an
 end-of-line comment.  If the latter, lines beginning with '' would
 still comment out as end-of-line comments.  Off the top of my head, I
 can't think of any other bracketing characters that are commonly
 doubled up.

 [S02] {Note however that bare circumfix or postcircumfix ... is not a
 user-selected bracket, but the ASCII variant of the «...» interpolating word
 list. Only # and the q-style quoters (including m, s, tr, and rx) enable
 subsequent user-selected brackets.}

 Just to clarify on that quote from S02, what I was trying to say (if I
 understand the synopsis correctly) is that  counts as either single or
 double depending on context. If you stick a # on the front, then  will
 count as a double bracket.

Thanks for the clarification.  Either we change this so that ''
counts as a single bracket for inline comment purposes, or we live
with the risk of start-of-line inline comments '# ... ' when
prepending #'s to comment out sections of code.

Or we leave it as is.  Is it really _that_ big of a problem to retrain
yourself to type #  instead of # when commenting out lines?

Here's a radical notion: use something other than '#' to initiate an
inline comment.  I suggested before the possibility of '#:' as the
inline comment identifier; what if we reverse this, and require ':#'
instead?  This would completely remove the risk of a start-of-line
comment being confused with an inline comment.  It would be visially
lightweight.  It would be short (four characters minimum).  It
wouldn't require you to double up on anything.  And the only danger
would be if you try to insert a comment immediately after a colon,
with no intervening whitespace - which strikes me as an _extremely_
bad practice which should be discouraged regardless.  So:

   # line comment
   #(line comment)
   :# syntax error (missing brackets)
   :#(inline comment)

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-10 Thread Jon Lang
Darren Duncan wrote:
 Still, I like the idea of #...# also being supported from the point of
 symmetry with '...' and ... also being supported, not that this is
 necessary.

This is mutually exclusive with the practice of commenting out a bunch
of lines by prepending them with '#'.

-- 
Jonathan Dataweaver Lang


Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-10 Thread Jon Lang
smuj wrote:
 Jon Lang wrote:
 Here's a radical notion: use something other than '#' to initiate an
 inline comment.

 [snippage]

 Or maybe just don't allow embedded comments unless they are actually
 embedded, i.e. if a line starts with a # (ignoring leading whitespace)
 then it's _always_ a line-end comment, no matter what follows the #, e.g.

That has the advantage of preserving a three-character embedded
comment.  It has the disadvantage that you get differing behavior
depending on where the comment is on the line.  As I see it, the whole
point of this exercise is to get rid of the gotchas, and not just to
shift them around - thus my ':#' proposal.

OTOH, you just (inadvertently?) pointed out that ':#...' is very
much like adverbial syntax; this could be quite useful if we ever find
a need for the parser to associate comments directly with code, in
that anything that can take an adverb could theoretically have a
comment associated with it.  But that's a can of worms that doesn't
need to be opened yet, if ever.

 We could always have a Q form in place of #'s to achieve the above effect
 from S02, more like a funny heredoc, e.g.

 Q :#                     # embedded
 sub foo                     # comment
 {                           # extends
  ...                        # to
 }                           # (wait for it)
                         # here!

 Maybe call it a theredoc! :-)

We can already do this using POD sections:

   =begin comment
   sub foo
   {
   ...
   }
   =end comment

I don't see much need for a #-based multi-line comment beyond this.
But it _would_ be nice to be able to indent POD Sections in the same
way that you can indent heredocs.  Especially if the former is
intended to be the standard means of commenting out blocks of lines.

OTOH, let's say for the moment that we choose to extend the analogy
between embedded comments and quotes: one could, in theory, do a
Heredoc-style comment:

   :#  END
   line 1
   line 2
   line 3
   END

where ':#' is the comment-equivalent of 'q', whatever that turns out
to be. (I'm not sold on ':#'; but I _would_ like to see a two-symbol
token that begins with a non-'#' and ends with a '#', for conciseness
and clarity.)

Technically, this would also allow for the likes of ':#comment'.
But I agree with the gentleman from the original discussion years ago
that we should probably forbid non-bracketing characters when
delimiting embedded comments.

-- 
Jonathan Dataweaver Lang


Re: confusing list assignment tests

2009-07-28 Thread Jon Lang
Larry Wall wrote:
 Moritz Lenz wrote:
 : Either it's parsed as '@a[0] = (W, W)' (list assignment), then @a should
 : get both elements, and so should @z.

 Not according to S03, at least by one reading. �...@a[0] as a scalar
 container only wants one item, so it only takes the first item off
 the list, and the list assignment produces a warning on the second
 because it's discarded.  Since an assignment returns its left side,
 only one element is available to @z from @a[0].

So, do we still have p5's 'want_array' (or whatever it was called)?
That is, the predicate that tells the you whether the function is
being called in item or list context?  I know that the generalized
'want' function proved to be unworkable; but I'd expect p6 to at least
be able to do everything that p5 can do; and that includes functions
that are aware of whether they're being used as singular or plural.

-- 
Jonathan Dataweaver Lang


Re: confusing list assignment tests

2009-07-28 Thread Jon Lang
Damian Conway wrote:
 Mark J. Reed wrote:
 My understanding is that the P6 way to do that is to return a Capture
 containing the desired return values (which can lazily do things only
 when accessed) in the appropriate slots.

 Return a Capture or a more heavily overloaded object, depending on how
 fine a degree of context discrimination you need.

 Further to that idea, I'm actually planning to attempt to port
 Contextual::Return to Perl 6 in the next few weeks.

Right.  I don't think that a Capture has sufficiently fine context
discrimination to handle even those cases that Perl 5 was able to
handle.  For instance, consider a function that's intended to return a
list of items in list context, or a count of the items in item
context: since imposing item context on a Capture object extracts the
first positional parameter, a Capture object wouldn't be able to be
loaded properly to do this.  So something along the lines of
Contextual::Return is probably a good idea.

Hmm... it might be nice to be able to use something akin to a given
... when construct:

sub foo() {
return context {
when Item { 5 }
when List { a, b, c, d, e }
}
}

The idea here is that the 'context' keyword means that the block is to
be called as soon as the desired context is known, with said context
being passed to the block as its topic ('$_').

-- 
Jonathan Dataweaver Lang


Re: r27635 - docs/Perl6/Spec

2009-07-20 Thread Jon Lang
On Mon, Jul 20, 2009 at 6:03 PM, pugs-comm...@feather.perl6.nl wrote:
 Author: lwall
 Date: 2009-07-21 03:03:38 +0200 (Tue, 21 Jul 2009)
 New Revision: 27635

 Modified:
   docs/Perl6/Spec/S03-operators.pod
 Log:
 [S03] rename 'nonchaining infix' to 'structural infix'


 Modified: docs/Perl6/Spec/S03-operators.pod
 ===
 --- docs/Perl6/Spec/S03-operators.pod   2009-07-20 23:56:21 UTC (rev 27634)
 +++ docs/Perl6/Spec/S03-operators.pod   2009-07-21 01:03:38 UTC (rev 27635)
 @@ -42,7 +42,7 @@
     X  Junctive and       also
     X  Junctive or       | ^
     L  Named unary       sleep abs sin temp let
 -    N  Nonchaining infix but does = leg cmp .. ..^ ^.. ^..^
 +    N  Structural infix  but does = leg cmp .. ..^ ^.. ^..^
     C  Chaining infix    != ==  =  = eq ne lt le gt ge ~~ === eqv !eqv
     X  Tight and         
     X  Tight or          || ^^ // min max

Hmm... maybe Chaining infix should become Comparison?

-- 
Jonathan Dataweaver Lang


Re: r27635 - docs/Perl6/Spec

2009-07-20 Thread Jon Lang
On Mon, Jul 20, 2009 at 7:15 PM, Darren Duncandar...@darrenduncan.net wrote:
 Jon Lang wrote:

 On Mon, Jul 20, 2009 at 6:03 PM, pugs-comm...@feather.perl6.nl wrote:

 Modified: docs/Perl6/Spec/S03-operators.pod
 ===
 --- docs/Perl6/Spec/S03-operators.pod   2009-07-20 23:56:21 UTC (rev
 27634)
 +++ docs/Perl6/Spec/S03-operators.pod   2009-07-21 01:03:38 UTC (rev
 27635)
 @@ -42,7 +42,7 @@
    X  Junctive and       also
    X  Junctive or       | ^
    L  Named unary       sleep abs sin temp let
 -    N  Nonchaining infix but does = leg cmp .. ..^ ^.. ^..^
 +    N  Structural infix  but does = leg cmp .. ..^ ^.. ^..^
    C  Chaining infix    != ==  =  = eq ne lt le gt ge ~~ === eqv !eqv
    X  Tight and         
    X  Tight or          || ^^ // min max

 Hmm... maybe Chaining infix should become Comparison?

 I second that notion,

 ... assuming that the category would not later be expanded with other
 operators that don't fit the Comparison description.

Tight or includes min and max; I see nothing wrong with the
Comparison precedence level eventually picking up a handful of
operators that aren't comparators, as long as so many of them are.
And especially if the question being asked when creating a new
operator is should this have the same precedence as the comparison
operators?

A stronger argument against it would be to find comparison operators
that exist at other precedence levels.  I don't think that there are
any.  (Well, besides =, leg, and cmp.)

Indeed, I'll be surprised if there are any other precedence levels
that are chaining - which is another key point: what kind of operator
would be chaining, but _not_ some sort of comparison?

 And please don't even consider instead using the term Relational in
 reference to these operators, that some people do.  The Comparison term is
 more descriptive, and it doesn't conflict with other meanings of
 relational that relational databases deal with.

Seconded. :)

-- 
Jonathan Dataweaver Lang


Re: YAPC::EU and Perl 6 Roles

2009-07-15 Thread Jon Lang
Raphael Descamps wrote:
 Am Freitag, den 10.07.2009, 17:06 -0700 schrieb Jon Lang:
 How about this: in role composition, mandate causes methods to take
 precedence over other methods with which they would normally conflict,
 and to conflict with methods that would normally take precedence over
 them.

 I really dislike this because it is contrary to the original idea of the
 stateless traits as defined in the original paper from Nathanael
 Schärli.

Agreed.  OTOH, Roles are already contrary in this respect, because
they can provide attributes as well as methods.  Note also that this
was my first proposal; I have since abandoned it in favor of (I hope)
a more intuitive approach.

 The main reason why traits have been introduced was to solve the
 problems inherent to mixins. In mixins the main problem is that the
 class using the mixin is not able to control the composition (which is
 simply done sequencially) and that lend to fragile hierarchies.

 The brilliant idea with traits is that it bring back the control to
 the class consuming the trait and conflicts have to be solved
 explicitly. The traits paper propose 3 different operators to solve such
 conflicts: overriding, excluding or aliasing.

 I definitively think that perl 6 roles should also have an excluding
 operator because I think that *every* composition conflicts arising
 should be solvable by the class comsuming the role.

 What you propose here is a step behind: you reintroduce the problem
 existing with mixins by bringing back precedence rules in the way
 composition is made.

Well, yes and no.  The class still has the final say on how a given
method is to be implemented; the only thing being debated here is
whether or not the class should have to explicitly pull rank to
redefine a method being provided by a role, or if it does so silently.
 The latter approach is how things currently stand, and is being
criticized as a source of bugs as authors of classes inadvertently
override method definitions that they didn't intend to override.

 So far, I have only seen reference to the original paper decribing the
 stateless traits. As roles are an implementation of stateful traits,
 maybe we should start to point to the paper formalising it:
 http://scg.unibe.ch/archive/papers/Berg07eStatefulTraits.pdf

Thanks for the link.

-- 
Jonathan Dataweaver Lang


Re: YAPC::EU and Perl 6 Roles

2009-07-15 Thread Jon Lang
TSa wrote:
 HaloO,

 Jon Lang wrote:

 Well, yes and no.  The class still has the final say on how a given
 method is to be implemented; the only thing being debated here is
 whether or not the class should have to explicitly pull rank to
 redefine a method being provided by a role, or if it does so silently.
  The latter approach is how things currently stand, and is being
 criticized as a source of bugs as authors of classes inadvertently
 override method definitions that they didn't intend to override.

 I think the distinction can be made implicitly. Methods in a role
 with no implementation are silently overridden. Ones with an
 implementation produce a warning if the composing class overrides
 it without some extra syntax. This bites only the case where the
 role provides a default implementation intended for overriding.

Perhaps.  FWIW, applying the supersede keyword to the class method
would work as the extra syntax to which you refer.  Your last
sentence is pointing to the distinction that I was trying to make with
the mandate/suggest pairing.

For clarity, let me propose the following terminology: an interface
is a role with methods that suggest their implementations by default;
a mixin is a role with methods that mandate their implementations by
default.  I could see adopting one of these terms as a variation on
role and treating role itself as the other one; if we do this,
which would be preferable: interfaces and roles, or roles and mixins?
That is: when you think role, do you think of the interface
semantics or the mixin semantics most readily?

-- 
Jonathan Dataweaver Lang


Re: RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)

2009-07-12 Thread Jon Lang
Daniel Ruoso wrote:
 Jon Lang wrote:
 The key to understanding roles is to note that roles don't implement
 methods; classes implement methods.

 Er, while I see your point, Roles are not just interfaces... they are OO
 components that can be plugged into other classes. They often are used
 for type identity exactly because of that attribute, since you won't be
 enforcing any hierarchy.

Right.  But as they were originally conceived, they were interfaces
that could also handle code reuse, rather than units of code reuse
that could also be used as interfaces.  From this perspective, it
makes perfect sense that a role's methods can be overridden as easily
as they are.

But you make a good point: there are some (a few? most?) programmers
who are going to want to use roles primarily for code reuse, and who
will want it to be a little more difficult to override the code
provided by a role (e.g., requiring the use of supersede and perhaps
augment in order to replace the definition with a new one).  First and
foremost, this distinction between suggested ans mandatory
implementation is what I was trying to make a little more explicit in
my proposal: a suggested method can be overridden by the class with no
extra effort; a mandatory method requires that the class be explicit
about the override.

The next question is which of these approaches Perl 6 should use with
roles.  Currently, it's using suggested implementations; what I'm
hearing you say is that you'd rather have mandatory implementations.
IMHO, there's a time ans place for both; so I was trying to come up
with a compromise of sorts: a way of letting the programmer select the
approach that most suits his needs.

 Roles define which methods must be implemented, and suggest ways that
 they might be implemented; classes decide which implementation to use.
 Anything that breaks this paradigm is a Bad Thing.

 That's not the common conception in Roles usage, specially in Moose. As
 I said, Roles are not just interfaces, they are OO reuseable components.

FWIW, I never said that they're just interfaces.  Also, I question
whether that is or is not the common conception of role usage.  I
readily admit that it isn't so in the programming circles that you
travel in; but are you typical of the perl community in this regard?
This is not a rhetorical question; the way that we end up addressing
this issue hinges on this question: should roles provide suggested
implementations by default, or should they provide mandatory
implementations by default?  Even if Perl is rich enough to provide
for both, the decision of which way to go when no explicit decision
has been made is an important one.

 The spec itself says:

        Classes are primarily for instance management, not code reuse.
        Consider using Croles when you simply want to factor out
        common code.

Right: roles are preferable to classes when it comes to code reuse.
That doesn't necessarily mean that roles are _primarily_ intended for
code reuse.  They _might_ be; but if so, it's because they've grown
beyond their original concept.

 The key issue here is Perl 6 wasn't yet used to the extent that
 Moose::Roles are, and Moose people have identified that the use of Roles
 as reusable components raised the issue when the class inadvertedly
 overrides one of the methods that are implemented by one of the composed
 roles.

You know what?  Until Moose was mentioned in this conversation, I had
never heard of it.

 I did think that this should be the expected behavior, but when the
 people that is heavily using it says it took me a lot of time to
 debug, it indicates that there's something wrong with the behavior.

 So now I changed my mind, inheritance is about overriding behavior, so
 when you implement a method in the subclass it is a natural thinking
 that this should override the superclass, but when you think about it
 really carefully this logic doesn't really map well to Roles
 (considering roles as OO reuseable components).

That may indeed be the case.  It's entirely possible that we may want
to change things so that roles define mandated methods, and possibly
introduce interfaces as a variation of roles that define suggested
methods.  But we may instead want to keep roles as they are, and
define some other variation that works just like a role except that it
mandates its methods.

And its also possible that I'm fundamentally wrong about this, and
that we _don't_ need both approaches available for roles.

 That being said, I'd think the following as an interesting solution:

  role R1 {
   method foo() {...} # degenerates to interface
  }
  role R2 does R1 {
   method bar() {
     # some implementation
   }
   method baz() {
     # some implementation
   }
  }

  class Bla does R2 {
   method foo {
     # implementing here is natural, since the role only
     # declared a stub, it's even a warning not to implement it
   }
   supersede method bar  {
     # explicitly tells that I want to ignore

Re: Reusing code: Everything but the kitchen sink

2009-07-10 Thread Jon Lang
The key to understanding roles is to note that roles don't implement
methods; classes implement methods.  Roles define which methods must
be implemented, and suggest ways that they might be implemented;
classes decide which implementation to use.  Anything that breaks this
paradigm is a Bad Thing.

Where things get slightly fuzzy is that there is one case where a
class is implicitly assumed to accept an implementation suggested by a
role - namely, if that implementation is the only one available.
Otherwise, the role is required to explicitly define a given method's
implementation.

David Green wrote:
 Jonathan Worthington wrote:
 The spec is right in that you need to write a method in the class that
 decides what to do. This will look something like:

  method fuse() { self.Bomb::fuse() }

 That makes sense for using the combined role on its own, but can we still
 handle separate roles that get mixed together?  That is, after defining that
 method so I can call $joke.fuse(), can I still call $joke.Bomb::fuse and
 $joke.Spouse::fuse as well?

This is one of the distinctions between role composition and class
inheritance.  With class inheritance, the full tree of inherited
classes is publicly accessible; with role composition, the methods of
the combined role are the only ones that are made available to the
class.  In effect, a combined role acts as a middle manager that looks
over the available implementations and picks one, provides its own
alternative, or defers the decision to its boss (i.e., the class or
role into which it is composed).  Either way, once the class has
chosen an implementation, that is the implementation that will be
used.

As I understand it, the reason for this has more to do with attributes
than with methods: with role composition, you want to be able to cut
away any attributes that have become extraneous to the
implementations defined in the class.  E.g.:

role R {
has $foo;
}

class C does R {
method foo() is rw { doIO() }
}

The idea here is that C has chosen to implement foo by querying an
outside source (such as a database) whenever a read request is made of
it, and by sending information to an outside source whenever a write
request is made.  It never refers to the internal state that R
defined.  As such, there's no reason for C to set aside memory to
track an internal state.  You can't do this if someone is allowed to
explicitly call R::foo from any object of class C, overriding C's
choice as to how foo should be implemented.

 I'm thinking that it's useful to be able to refer to the fully-qualified
 names for anything composed into a role or class; often there will be no
 ambiguity, so the full name won't be necessary.  If the names aren't unique,
 then you can specify them fully, and perhaps add an unqualified fuse()
 that does one or the other (or both? or neither??) for convenience.  That
 shouldn't be necessary, I think -- it just means you would have to spell out
 exactly which method you wanted.

This is class inheritance think.  In role composition think, you
should never have to worry about how the composed roles might have
done things once composition is complete; you only concern yourself
with how the class does things.

 In the case Ovid also mentioned where two roles have a method of the same
 name because both methods really are doing the same thing, there ought to be
 a way to indicate that (though if they both come with implementations, you'd
 still have to pick one or write your own).

 Of course, in a perfect world, the common method would come from its own
 role: if Foo.fuse and Bar.fuse really mean Foo.Bomb::fuse and
 Bar.Bomb::fuse, then doing Foo and Bar together should automatically give
 you a single .fuse method (again, at least as far as the interface is
 concerned).

You have a point: it would be nice if you didn't have to engage in
unnecessary conflict resolution.  Of course, this may actually be the
case already; it all depends on how the compiler decides when to
complain about conflicting methods.

role R { method foo() { say foo }
role R1 does R { method bar() { say bar }
role R2 does R { method baz() { say baz }
class C does R1 does R1 { }

The question is whether or not Rakudo is smart enough to realize that
R1::foo is the same as R2::foo, or if it complains that R1 and R2 are
both trying to supply implementations for foo.  The former is the
desired behavior.

 I guess being able to create a role by dropping some bits from an existing
 role would be useful sometimes, but it seems to lose one of the most useful
 benefits of roles: as Jon Lang pointed out, R1 :withoutfoo bar would
 effectively be a new role, one that doesn't do R1.  But you want something
 to do a role in the first place so that it will work anywhere else there is
 code looking for that role.

Obviously, someone who explicitly drops methods from a role isn't
concerned with the new role being usable wherever the original role
could

Re: Reusing code: Everything but the kitchen sink

2009-07-10 Thread Jon Lang
The key to understanding roles is to note that roles don't implement
methods; classes implement methods.  Roles define which methods must
be implemented, and suggest ways that they might be implemented;
classes decide which implementation to use.  Anything that breaks this
paradigm is a Bad Thing.

Where things get slightly fuzzy is that there is one case where a
class is implicitly assumed to accept an implementation suggested by a
role - namely, if that implementation is the only one available.
Otherwise, the role is required to explicitly define a given method's
implementation.

David Green wrote:
 Jonathan Worthington wrote:
 The spec is right in that you need to write a method in the class that
 decides what to do. This will look something like:

  method fuse() { self.Bomb::fuse() }

 That makes sense for using the combined role on its own, but can we still
 handle separate roles that get mixed together?  That is, after defining that
 method so I can call $joke.fuse(), can I still call $joke.Bomb::fuse and
 $joke.Spouse::fuse as well?

This is one of the distinctions between role composition and class
inheritance.  With class inheritance, the full tree of inherited
classes is publicly accessible; with role composition, the methods of
the combined role are the only ones that are made available to the
class.  In effect, a combined role acts as a middle manager that looks
over the available implementations and picks one, provides its own
alternative, or defers the decision to its boss (i.e., the class or
role into which it is composed).  Either way, once the class has
chosen an implementation, that is the implementation that will be
used.

As I understand it, the reason for this has more to do with attributes
than with methods: with role composition, you want to be able to cut
away any attributes that have become extraneous to the
implementations defined in the class.  E.g.:

role R {
has $foo;
}

class C does R {
method foo() is rw { doIO() }
}

The idea here is that C has chosen to implement foo by querying an
outside source (such as a database) whenever a read request is made of
it, and by sending information to an outside source whenever a write
request is made.  It never refers to the internal state that R
defined.  As such, there's no reason for C to set aside memory to
track an internal state.  You can't do this if someone is allowed to
explicitly call R::foo from any object of class C, overriding C's
choice as to how foo should be implemented.

 I'm thinking that it's useful to be able to refer to the fully-qualified
 names for anything composed into a role or class; often there will be no
 ambiguity, so the full name won't be necessary.  If the names aren't unique,
 then you can specify them fully, and perhaps add an unqualified fuse()
 that does one or the other (or both? or neither??) for convenience.  That
 shouldn't be necessary, I think -- it just means you would have to spell out
 exactly which method you wanted.

This is class inheritance think.  In role composition think, you
should never have to worry about how the composed roles might have
done things once composition is complete; you only concern yourself
with how the class does things.

 In the case Ovid also mentioned where two roles have a method of the same
 name because both methods really are doing the same thing, there ought to be
 a way to indicate that (though if they both come with implementations, you'd
 still have to pick one or write your own).

 Of course, in a perfect world, the common method would come from its own
 role: if Foo.fuse and Bar.fuse really mean Foo.Bomb::fuse and
 Bar.Bomb::fuse, then doing Foo and Bar together should automatically give
 you a single .fuse method (again, at least as far as the interface is
 concerned).

You have a point: it would be nice if you didn't have to engage in
unnecessary conflict resolution.  Of course, this may actually be the
case already; it all depends on how the compiler decides when to
complain about conflicting methods.

role R { method foo() { say foo }
role R1 does R { method bar() { say bar }
role R2 does R { method baz() { say baz }
class C does R1 does R1 { }

The question is whether or not Rakudo is smart enough to realize that
R1::foo is the same as R2::foo, or if it complains that R1 and R2 are
both trying to supply implementations for foo.  The former is the
desired behavior.

 I guess being able to create a role by dropping some bits from an existing
 role would be useful sometimes, but it seems to lose one of the most useful
 benefits of roles: as Jon Lang pointed out, R1 :withoutfoo bar would
 effectively be a new role, one that doesn't do R1.  But you want something
 to do a role in the first place so that it will work anywhere else there is
 code looking for that role.

Obviously, someone who explicitly drops methods from a role isn't
concerned with the new role being usable wherever the original role
could

Re: YAPC::EU and Perl 6 Roles

2009-07-10 Thread Jon Lang
Larry Wall wrote:
 Dave Whipp wrote:
 Ovid wrote:

 I'd like to see something like this (or whatever the equivalent Perl 6 
 syntax would be):

   class PracticalJoke does Bomb does SomeThingElse {
     method fuse() but overrides { ... }
   }

 The overrides tells Perl 6 that we're overriding the fuse() method
  from either Bomb or SomeThingElse (or both).  Otherwise, a warning
  or exception would be useful to prevent me from accidentally overriding
  needed behavior.

 This would also be useful to catch the case where you mistype the
 override method, and so have to go debug why you're still using the
 base-class (or role) version of the method.

 Note we already have syntax that can be applied here:

    supersede method fuse {...}
    augment method fuse {...}

 It only remains to spec what those mean... :)

supersede already has a meaning with respect to classes; and what
I'm thinking of would apply to classes as well as roles; so I'm going
to suggest another keyword.

How about this: in role composition, mandate causes methods to take
precedence over other methods with which they would normally conflict,
and to conflict with methods that would normally take precedence over
them.  So:

role R1 { mandate method foo { ... } }
role R2 { method foo { ... } }
class C does R1 does R2 { ... }

Normally, the compiler would complain of a conflict between R1 and R2;
but because R1::foo is mandated, it wins out.

role R { mandate method foo { ... } }
class C does R { method foo { ... } }

Normally, C::foo would take precedence over R::foo; but because R::foo
is mandated, the compiler complains of a conflict between C and R.

When two methods have the mandate keyword, they are compared to each
other as if neither had the keyword.

role R { mandate method foo { ... } }
class C does R { mandate method foo { ... } }

Since both R::foo and C::foo are mandated, C::foo supersedes R::foo.

Applying the mandate keyword to a role is shorthand for applying it
to all of its methods.

mandate role R {
method foo { ... }
method bar { ... }
method baz { ... }
}

is the same as:

role R {
mandate method foo { ... }
mandate method bar { ... }
mandate method baz { ... }
}

This behavior can be overridden by the suggest keyword:

mandate role R {
suggest method foo { ... }
method bar { ... }
method baz { ... }
}

is the same as:

role R {
method foo { ... }
mandate method bar { ... }
mandate method baz { ... }
}

That is, every method is either mandated or suggested, and suggested
by default.  Mandating a role changes the default for its methods, or
you could explicitly suggest the role.  The latter possibility would
allow for a pragma that changes the role's default importance from
suggested to mandated.

Ovid's distinction between interface and unit of behavior could be
managed by this distinction: suggest role R is primarily intended as
an interface, with behavior being a suggestion only and implicitly
overriden by the class; mandate role R is primarily intended as a
unit of behavior, and overriding its behavior requires that you
explicitly supersede it.  In Ovid's programs, he might start by saying
use mandate, so that roles operate as units of behavior by default,
and can be declared as interfaces by saying suggest role instead of
role.  Or maybe the pragma declares interface as a synonym for
suggest role.  (I'd be more comfortable with this if I could think
of a comparable synonym for mandate role; at that point, you could
do away with the pragma - use role, suggest role, or interface
to mean interface, and use mandate role or ??? to mean unit of
behavior.)

At this point, you can strengthen the importance of a method (raising
it from a suggestion to a mandate); but you cannot weaken it.  Thus,
interfaces can be composed into units of behavior; but not vice versa:
attempting to do so would result in a unit of behavior.  I think that
the converse _should_ be possible; but I'm not quite sure how it might
be done.

-- 
Jonathan Dataweaver Lang


Re: Huffman's Log: svndate r27485

2009-07-10 Thread Jon Lang
On Fri, Jul 10, 2009 at 2:22 PM, Austin
Hastingsaustin_hasti...@yahoo.com wrote:
 Mark J. Reed wrote:

 I'm all for not having any variety of log() in the default namespace.
 Regardless, mathematical functions should follow mathematical norms.
 Changing Perl tradition is one thing, but we have centuries, sometimes
 millennia, of tradition to deal with in the mathematical realm.  It
 should not be violated lightly.



 That's okay. Preserve their thousands of years of historical legacy. Just
 preserve it in a separate container.

 #! /usr/bin/perl6

 say(log(1000, 10));   # Error - no such function log

 use Math::Simple;

 say(log(1000, 10)); # 2.999...

Ugh; no thanks.

However, it occurs to me that when you log messages, you should
specify where you're logging them as well as what they are.  log(Str)
might lead to ambiguous results; but IO.log(Str) should be pretty
clear.

But maybe I'm not understanding what people are wanting out of message
logging.

-- 
Jonathan Dataweaver Lang


Re: YAPC::EU and Perl 6 Roles

2009-07-10 Thread Jon Lang
Jon Lang wrote:
 supersede already has a meaning with respect to classes; and what
 I'm thinking of would apply to classes as well as roles; so I'm going
 to suggest another keyword.

 How about this: in role composition, mandate causes methods to take
 precedence over other methods with which they would normally conflict,
 and to conflict with methods that would normally take precedence over
 them.

Or, perhaps more simply, say that if you mandate a method in a role,
you must supersede it in whatever you are composing it into in order
to override the definition.  So:

role R { mandate method foo { ... } }
class C does R { supersede method foo { ... } }

I'd still recommend the suggest/mandate pairing, and their application
directly to methods or indirectly via the role; the only change is
that mandate be redefined as Thou Shalt Not Override This/These
Methods... and supersede becomes ...Unless You Really Mean It.
Conflicts still occur as normal when composing multiple roles; the
only catch is that you _have to_ resolve them using a supersede method
if any of the conflicting methods are mandated.

Or maybe not.  Perhaps a conflict between composed roles cancels out
the conflicting method implementations whether or not any of them are
mandates, leaving the class free to define its own version.  That is,
the only time you must supersede a method is when you're trying to
override a single mandate method.

I'd still like to get a synonym for mandate role, though - a word
that captures the meaning of unit of behavior.

-- 
Jonathan Dataweaver Lang


Re: YAPC::EU and Perl 6 Roles

2009-07-08 Thread Jon Lang
Jonathan Worthingtonjonat...@jnthn.net wrote:
 Ovid wrote:
 Though I have issues with Jonathan's approach (I don't like classes
 silently discarding role methods as this has caused us many bugs at the
 BBC), it's much cleaner that what I see here.

 s/Jonathan's approach/Perl 6's approach/ # at least, so far as I understand
 Perl 6

No; I think he meant Jonathan's approach, as in the suggestion that
I made earlier about disambiguating by exclusion.

It occurs to me that but might be a way to approach this, since the
linguistic purpose of that operator is to generate a class or role
that is a slight departure from an existing role:

   A but without(foo)

might generate an anonymous role that's exactly like A except that it
doesn't have the foo method; you could then say something like:

  role A { method foo() { }; method bar() { }; method baz() { } }
  role B { method foo() { }; method bar() { }; method baz () { } }
  class C does A but without(foo, bar) does B but without(baz) { }

I agree that there are dangers involved in excluding methods from a
role; thus my use of fairly lengthy phrases in order to accomplish it
- a sort of handle with care warning.

Alternatively, I could see a version of this exclusionary policy being
done through method delegation, by means of the whatever splat -
something like:

  class C {
  has A $a handles * - (foo, bar);
  has B $b handles * - baz;
  }

-- 
Jonathan Dataweaver Lang


Reusing code: Everything but the kitchen sink

2009-07-08 Thread Jon Lang
Jonathan Worthington wrote in YAPC::EU and Perl 6 Roles:
 More fitting to me would be an adverb to the does trait modifier...

 class C does R1 :withoutfoo bar does R2 :withoutbaz { ... }

 The thing is that in this case, does the class actually do R1 and R2? If you
 are going to derive an anonymous role with the methods missing, then answer
 is no. That is, C ~~ R1 would be false.  So I think it'd need to act as a
 modifier to the action of composition, rather than a modification to the
 thing that we're composing.

Moving the adverb from the role to the trait modifier would still
violate the notion that C ~~ R1; so it doesn't actually gain us
anything.  Instead, consider the following possibility: R1
:withoutfoo bar is a separate but related role from R1.  The
implicit relationship between them is that R1 ~~ R1 :withoutfoo bar.
 So C ~~ R1 would be false; but C ~~ R1 :withoutfoo bar would be
true.

 I wonder if we'd want to mandate that a method of the name must come from
 _somewhere_ otherwise it's an error. At least then you get a promise that a
 method of that name exists...which is about all that it does this role
 tells you as an interface contract anyway.

Right.  Another way to handle this without establishing reverse-does
relationships that I describe above would be to say that the adverb
doesn't actually remove the method in question; it just suppresses its
implementation.  That is, given:

role R1 {
method foo() { say foo }
}

class C does :blockingfoo R1 { ... }

this would compose R1 into C, but would discard the implementation of
R1::foo while doing so.

In the spirit of TIMTOWTDI, both approaches could be available:

R1 :withoutfoo acts as an anonymous role that R1 implicitly does,
and which is set up almost exactly like R1 except that it doesn't have
method foo.  This could have other uses besides role composition, such
as expanding a web of roles from the specific to the general.

C does :blockingfoo R1 composes R1 into C, but discards foo's
implementation while doing so.

 Alternatively, I could see a version of this exclusionary policy being
 done through method delegation, by means of the whatever splat -
 something like:

  class C {
      has A $a handles * - (foo, bar);
      has B $b handles * - baz;
  }

 The RHS of the handles is something we smart-match the method name against
 (unless it's one of the special syntactic cases). And thus if you care about
 performance you probably don't want to be falling back to handles to do your
 role composition, since it's kind of the last resort after we've walked
 the MRO and found nothing.

You're right, but for a different reason.  Perl 6 has three techniques
for code reuse, which I refer to as the be, do, have triad:

Class inheritance (to be): 'is C;'
Role composition (to do): 'does R;'
Attribute delegation (to have): 'has A $a handles foo;'

Just on a conceptual level, you don't want to fall back on attribute
delegation in order to emulate role composition.  Still, there are
uses for delegating to all or most of an attribute's methods.

 Anyway, you'd put something on the RHS maybe
 like:

 has A $a handles none(foo bar)

 But I'm not sure that will fall through to B for anything that A doesn't
 define other than those two. You'd perhaps just get a dispatch error if you
 said A handles everything but those and it didn't. So it'd probably look
 more like...

 has A $.a handles all(any(A.^methods.name), none(foo bar));

 Which you almost certainly don't want to be writing. ;-)

Right; which is why I was looking for a more abbreviated form.  If we
go with the idea that we're using a Set on the RHS, then '*' could be
shorthand for 'Set($a.^methods)', and 'Set::infix:-' could be the
Set Difference operator, with the item, list, or set on the RHS being
excluded from the LHS.  So:

$a handles * - foo bar

would be short for something like:

$a handles Set($a.^methods) - Set(foo, bar)

This use of the Whatever splat is similar to its use in a list index,
where '*' behaves as if it were the list's element count.

--

Looking this over, I note that the only code reuse mechanism for which
we haven't looked at the everything except... concept is class
inheritance.  OTOH, I think that the blocking tool that works for role
composition could be adapted for use with class inheritence as well:

Class C is :blockingfoo bar C1 is :blockingbaz C2 { ... }

That is, if you were to search the class heierarchy for foo, it would
skip the C1 branch in its search.  This would have to be treated with
care, because it would mean that C doesn't inherit everything from C1.
 This _would_ break the anything you can do I can do, too nature of
class inheritence; but I'm not sure how big of a crime that is.  Perl
generally discourages the use of class hierarchies, and it certainly
isn't the preferred means of type-checking.  And maybe you could get
around this by having the isa predicate return a more involved
response than 

Re: YAPC::EU and Perl 6 Roles

2009-07-07 Thread Jon Lang
On Tue, Jul 7, 2009 at 2:48 AM,
Ovidpubliustemp-perl6langua...@yahoo.com wrote:

 Giving a talk about roles at YAPC::EU in Lisbon and I'm a bit stuck on how to 
 translate a Perl 5 example into Perl 6.  Basically, Imagine a PracticalJoke 
 class which has fuse() and explode methods().  It needs the timed fuse() from 
 a Bomb role and a non-lethal explode() from a Spouse role, though each role 
 provides both methods.  In Moose, it's easy:

  package PracticalJoke;
  use Moose;
  with 'Bomb'   = { excludes = 'explode' };
       'Spouse' = { excludes = 'fuse' };

 Try as I might, I can't figure out how to translate that into Perl 6.  I have 
 the following:

  role Bomb {
    method fuse ()    { say '3 .. 2 .. 1 ..' }
    method explode () { say 'Rock falls. Everybody dies!' }
  }

  role Spouse {
    method fuse ()    { sleep rand(20); say Now! }
    method explode () { say 'You worthless piece of junk! Why I should ...' }
  }

  class PracticalJoke does Bomb does Spouse {
  }

 Nothing I see in S14 (http://perlcabal.org/syn/S14.html) seems to cover this 
 case. I can't declare them as multis as they have the same signature.  
 There's a note that one can simply to write a class method that overrides 
 the conflicting role methods, perhaps figuring out which role method to 
 call, but I don't understand how a particular role's methods would be called 
 here.


I believe that the official word is to say:

  class PracticalJoke does Bomb does Spouse {
method fuse () { Bomb::fuse }
method explode () { Spouse::explode }
  }

Personally, I agree that some sort of ability to exclude individual
methods from Roles, such as what Moose does, would be beneficial; but
this is an old argument that has been hashed out many times before.

-- 
Jonathan Dataweaver Lang


Re: Signature for the series operator

2009-06-26 Thread Jon Lang
On Thu, Jun 25, 2009 at 1:20 PM, Moritz Lenzmor...@faui2k3.org wrote:
 Hi,

 I had the pleasure to implement the series operator (infix:...) in
 Rakudo(*), and came across the difficulty to come up with a signature
 for it. These are the use cases I want to cover:

 1, 2 ... { $^a + $^b }
 1 ... { $_ + 1 }

 The first one can clearly be written as

 sub infix:...(@values, Code $geneator)

 but the second will fail to bind to that signature, because the 1 isn't
 a list. I'd like to write

 sub infix:...(*...@values, Code $generator)

 instead, but I think that required positional parameters are forbidden
 after slurpy arrays. Do I have to install another multi that accepts a
 single scalar? Or is there a neat trick to cover both use cases with a
 single signature?

I'm surprised that '1, 2 ... { $^a + $^b }' binds properly.  I suppose
that it's because of the relative precedences of '...' vs ','.  ','
gets evaluate first, combining 1 and 2 into a two-element list; then
that list gets fed into the left side of '...'.  If that's not the
case, then I don't see why '...' isn't just grabbing the '2', and then
failing to bind it because '2' isn't a list.

Perhaps non-associating infix operators should be an exception to the
usual rules concerning signatures, seeing as how you are guaranteed to
have exactly two positional parameters.  In particular, I'm thinking
that a non-associating infix operator might be permitted to have a
slurpy array as either _or both_ of its positional parameters, on the
theory that Perl 6 should strive to allow as much flexibility as
possible within the constraints of ambiguity.  (Currently, I believe,
it's sheer nonsense to have a slurpy array in either position.)

Or perhaps not; this may open a can of worms that we don't want to
mess with.  I can think of two complications off the top of my head:
pipes and reducing operators.  If you allow a slurpy list on either
side of an infix operator, how does that interact with piping
operators?  If you allow one on both sides, how do you determine which
one you're piping to?  If you reduce the operator so that it operates
according to function syntax (i.e., name first; then parameters) and
the first parameter is a slurpy list, how will you know when the first
parameter ends and the second begins?  Do you use an all but the
last rule?  etc.

-- 
Jonathan Dataweaver Lang


Re: XOR does not work that way.

2009-06-24 Thread Jon Lang
On Wed, Jun 24, 2009 at 10:35 AM, John Macdonaldj...@perlwolf.com wrote:
 On Tue, Jun 23, 2009 at 07:51:45AM +1000, Damian Conway wrote:
 Perl 6's approach to xor is consistent with the linguistic sense of
 'xor' (You may have a soup (x)or a salad (x)or a cocktail), [ ... ]

 That choice tends to mean exactly one, rather than the first one
 the waiter hears.  (A good waiter will explain the choice limitation
 at the time the order is made rather than having to deal with it
 being escalated to a complaint when the missing item is demanded.)

 Which means that short-circuiting is not right here - it must
 go through the entire list to determine whether there are zero
 true selections, find the first of exactly one true selections,
 or die if there are more than one true selections.

Which, I believe, is exactly how XOR short-circuiting currently works:
it short-circuits to false if both sides are true; otherwise, it
returns true or false as usual for XOR and continues on down the
chain.

-- 
Jonathan Dataweaver Lang


Re: XOR does not work that way.

2009-06-22 Thread Jon Lang
On Mon, Jun 22, 2009 at 4:12 PM, Minimiscienceminimiscie...@gmail.com wrote:
 On Jun 22, 2009, at 5:51 PM, Damian Conway wrote:

 Perl 6's approach to xor is consistent with the linguistic sense of
 'xor' (You may have a soup (x)or a salad (x)or a cocktail), and also
 with the IEEE 91 standard for logic gates.

 I don't think natural language -- especially the abomination that is English
 -- is the best guide for understanding logical operations (why, yes, I *do*
 speak Lojban; how did you know?).  As for consistency, Perl 6's bitwise
 exclusive-or operators follow the mathematical meaning of XOR, so using the
 exactly one true value definition for ^^ and xor would make Perl 6
 inconsistent with itself.

You're aware that Perl was designed by a linguist, with an eye toward
incorporating natural language concepts, right?

As for the bitwise xor: I consider the inconsistency between it and
the logical xor to be a feature, not a bug.  Mind you, it's a feature
that needs to be made apparent; but it's a feature nonetheless.
Specifically, it gives you a simple way of choosing which semantics
you wish to use: '^' gives you the natural language semantics, while
'?^' gives you the mathematical semantics.  This gives the programmer
an easy way of choosing which semantics he wants to use.

 I was going to say more in support of adding a separate operator for
 exactly one true value, but Darren Duncan beat me to it.

Well, we already have one to mean exactly one true value.

-- 
Jonathan Dataweaver Lang


Re: XOR does not work that way.

2009-06-22 Thread Jon Lang
Take a look at the page to which Damian provided a link.  You'll find
that XOR does indeed correspond to the definition being used by Perl
6, as well as the natural language meaning.  What other languages call
XOR is actually an odd parity check.

As I suggested above, I think that Perl 6 already addresses both of
these: use '^' or 'xor' (or 'one()') if you want XOR semantics; use
'?^' if you want odd parity semantics.

 I suggest that to aid learnability, Perl 6 has the same semantics for 'xor'
 as other languages with that operator, unless there is a good explicit
 reason to do differently; that is, don't do differently just for the heck of
 it.

We never do things differently for the heck of it.

-- 
Jonathan Dataweaver Lang


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-13 Thread Jon Lang
On Fri, Jun 12, 2009 at 11:23 PM, Matthew
Waltonmatt...@matthew-walton.co.uk wrote:
 Although some things may be able to be implemented far more
 efficiently if they know that they're being called with infix:.= and
 not with infix:..

Last I checked, Perl 6 had some types that are mutating and others
that aren't (e.g., List and Array, I think).  An additional benefit of
setting up the primitive methods as non-mutating is that you
increase the amount of functionality shared by the two: if all
mutating methods are syntactic sugar for non-mutating counterparts,
then non-mutating types will be able to do everything that their
mutating brethren can do (except mutate, of course).  E.g., a List can
push, unshift, splice, etc; an Array can append, perpend, impend, etc.

And if you want to do purely functional programming, you can do so by
restricting yourself to the use of non-mutating types and staying away
from those methods that have side effects (which should [i]also[/i] be
easily identifiable).  Indeed, this same notion of ensuring that pure
functional versions of mutating methods exist should also apply to
methods with side effects: as much as possible, if a method is
designed to perform a calculation and to produce a side effect, there
should also be an equivalent method that merely performs the
calculation.  Even better would be to segregate the methods that
produce side effects from the methods that perform calculations.

Am I making sense?

-- 
Jonathan Dataweaver Lang


Re: Array rotate

2009-06-12 Thread Jon Lang
On Fri, Jun 12, 2009 at 10:02 AM, yarynot@gmail.com wrote:
 I am tickled pink to see an Array rotate method in the settings spec
 S032, as I was thinking of writing up a little discussion on the very
 topic.

 Has there been discussion on using array rotate on multi-dimensional
 arrays? Being able to pass in a vector as the amount to rotate would
 be useful.

With a multi-dimensional array, a number of transforms can be considered:

* you can rearrange the elements along a given dimension (e.g., rotate
and reverse).
* you can rearrange the dimensions themselves (e.g., transpose).

-- 
Jonathan Dataweaver Lang


Re: Multi-d array transforms (was Re: Array rotate)

2009-06-12 Thread Jon Lang
On Fri, Jun 12, 2009 at 10:58 AM, yarynot@gmail.com wrote:
 * you can rearrange the dimensions themselves (e.g., transpose).

 Reflecting on 2 or more axes creates a transposition.

No, it doesn't:

@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

Reflecting on two axes would result in:

@a = (9, 8, 7; 6, 5, 4; 3, 2, 1);

Transposing the axes would result in:

@a = (1, 4, 7; 2, 5, 8; 3, 6, 9);

-- 
Jonathan Dataweaver Lang


Re: Array Dimensionality (Was: Re: Multi-d array transforms (was Re: Array rotate))

2009-06-12 Thread Jon Lang
On Fri, Jun 12, 2009 at 11:51 AM, Daniel Ruosodan...@ruoso.com wrote:
 Ok, There's one thing that is not clear in the thread, which is when an
 array is multidimensional or not...

 For instance:

 �...@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

 Will produce a flatten array, because list assignment causes flattening,
 so the dimensionality was lost.

Right.  I should have said:

@@a = (1, 2, 3; 4, 5, 6; 7, 8, 9);

-- 
Jonathan Dataweaver Lang


Re: Assigning duplicate values to several hash keys using junctions?

2009-06-08 Thread Jon Lang
2009/6/8 Ville Koskinen vrk...@iki.fi:
 Hello all,

 I was curious if this is possible in Perl 6:

 %hash{ 'foo'  'bar' } = 'some value';
 # %hash{'foo'} eq 'some value' and %hash{'bar'} eq 'some value'

By autothreading, this would be equivalent to:

(%hash{'foo'}  %hash{'bar'}) = 'some value';

which in turn is the same as:

   (%hash{'foo'} = 'some value')  (%hash{'bar'} = 'some value');

So yes, this is possible.

-- 
Jonathan Dataweaver Lang


Re: Implicit threading vs Imperative barriers

2009-06-04 Thread Jon Lang
On Thu, Jun 4, 2009 at 9:57 AM, TSa thomas.sandl...@vts-systems.de wrote:
 HaloO,

 Daniel Ruoso wrote:

 So the questions are:

  * Are there any imperative barriers in Perl 6?

 I would think that at least every method call is a barrier.
 An object's lifetime is a sequence of states and methods are either
 returning information about the state or calculate a new state. The
 latter cannot be concurrent. Furthermore it is usually a bad idea
 to have an object in several concurrent computations such that
 streams of mutating method calls interleave. So objects destined
 for parallel computing need some explicit locking mechanism.

Perhaps it isn't the method call that's the barrier, but rather the
mutating function.  If you do nothing but call a series of
non-mutating methods, I don't see how it matters how quickly any given
one of them gets evaluated, or even in what order they're evaluated,
as long as the information is ready by the time you need it.  But as
soon as you call a mutating method, you'd better get all of those
pending non-mutating calls taken care of before you proceed with the
mutating call.  Rule of thumb: if you want to be lazy, look but don't
touch.

-- 
Jonathan Dataweaver Lang


Re: Module naming conventions

2009-06-01 Thread Jon Lang
On Mon, Jun 1, 2009 at 5:44 PM, Daniel Carrera
daniel.carr...@theingots.org wrote:
 I think we might need to come up with some sort of standard naming
 convention to distinguish dependencies. Something that the *user* can
 recognize quickly when he browses CPAN.

Why do we need the dependencies to be part of the name?  Perl 6
provides a rugged versioning system for its modules; we should use it.

-- 
Jonathan Dataweaver Lang


Re: Amazing Perl 6

2009-05-29 Thread Jon Lang
On Fri, May 29, 2009 at 6:52 AM, John Macdonald j...@perlwolf.com wrote:
 Yep, I've done that.

 But comparing the difference in effort between:

 - press a key
 - Google for a web page that has the right character set, cut, refocus, paste

 means that I don't bother for the one or two weird characters
 every few months that is my current Unicode usage.  If I were
 working with Unicode frequently, it would be worth setting up
 links and mechanisms, or learning the keyboard compose sequences
 for frequently used characters.  I'm sure that there are many
 people in a similar situation.

Agreed.  Given the frequency with which « and » come up in Perl 6, I'd
love to be able to have a simple keyboard shortcut that produces these
two characters.  Unfortunately, I am often stuck using a Windows
system when coding; and the easiest method that I have available to me
there (that I know of) is to pull up Character Map.

-- 
Jonathan Dataweaver Lang


renaming or adding some operators

2009-05-29 Thread Jon Lang
On Fri, May 29, 2009 at 6:53 PM, Darren Duncan dar...@darrenduncan.net wrote:
 I had some thoughts lately about the Perl 6 operators, and wanted to bounce
 some ideas.

 

 Firstly, regarding the string replication ops as documented in Synopsis 3,
 'x' and 'xx', I'm wondering whether it might be better to have something
 that incorporates a '~', since that operation is about catenation.

 Would perhaps '~*' work better than 'x' to signify better what the operation
 is doing; the '~' in this case means catenation and the '*' is meant to
 invoke 'multiply', not 'whatever'.  So '~*' means catenate a multiple of
 times.

 This would then free up 'x' to be used for something else, if anything.

 As for a substitution for 'xx', I'm less sure about that.

 Thoughts?

I wouldn't mind 'x' becoming '~x' and 'xx' becoming 'x'; it strikes me
as a lot more intuitive - and I've wanted to see this done for a while
now.  I suppose that you might also introduce a '?x' and/or a '+x' to
complete the set, though for the life of me I can't think of how
they'd work or what they'd be good for.

 Secondly, regarding the Bool type, I think it would be useful for Perl 6 to
 define the full complement of dyadic logical operators, of which I count a
 few that you don't appear to already have.  Probably the best place is in
 Synopsis 32.

 Note that all the dyadic ops I am discussing are meant to be read as infix
 ops only.

 These are the boolean/logical ops you already have:

 Niladic ops aka value literals / constants:
 * Bool::False
 * Bool::True

 Monadic:
 * not aka !, but ¬ alias could be added

 Dyadic:
 * and aka , but ∧ alias could be added
 * or aka ||, but ∨ alias could be added
 * xor aka ^^ aka !===, but ⊻, ↮ aliases could be added
 * ===, but xnor, ↔ aliases could be added

 Now I'm not sure whether or not [also, andthen, orelse] have the desired
 semantics of any others or not, or whether [if, unless] could be used as a
 value-resulting infix operator or not.

also andthen orelse carry subtly varied semantics involving
short-circuiting behavior: andthen and orelse are like  and ||
except that they work off of success/failure instead of true/false;
also is an ordered, short-circuiting version of  (and thus
all).  For some time now, I've wanted an analog for '|' and 'any' -
but the only name I can think of for it would be 'else', which has
some obvious clarity issues.

 But here are a few more dyadic:
 * nand aka ⊼ aka ↑
 * nor aka ⊽ aka ↓
 * implies aka imp aka →
 * nimp aka ↛
 * if aka ←
 * nif aka ↚

 For that matter, as you know, every single boolean/logical operator could
 also have a bitwise analogue, if people were so inclined.

Side note: one thing that I recently learned concerning implication
operators is that the direction of the implication doesn't necessarily
follow the direction of the arrow.  In particular, A if B is A←B,
and A only if B is A→B: in both of the original statements, the
implication flows right to left.

Most of these suggestions could be implemented in a Unicode
Operators module; I see little need to put them into the default
setting.  I'm leery of introducing new unicade operators that don't
have ASCII aliases, as you might be inclined to do with set operators.

--
Jonathan Dataweaver Lang


Re: renaming or adding some operators

2009-05-29 Thread Jon Lang
Darren Duncan wrote:
 Side note: one thing that I recently learned concerning implication
 operators is that the direction of the implication doesn't necessarily
 follow the direction of the arrow.  In particular, A if B is A←B,
 and A only if B is A→B: in both of the original statements, the
 implication flows right to left.

 I thought that the direction did matter, and that's why there are distinct
 versions in each direction.  It's like how  and  are the same thing but
 with the direction reversed, or subset/superset or contains/contained-by.

 If you read A → B as A implies B then that's the same as if A then B,
 then the cause-effect reads left to right, which does follow the direction
 of the arrow, like Perl's if cond() then action().

The point is that it's equally valid to read A → B as A only if B,
with the cause-effect going from B to A.  You have the same truth
table for both A only if B and if A then B, so they use the same
logical operator; but the cause/effect flow is reversed between them.

-- 
Jonathan Dataweaver Lang


Re: Amazing Perl 6

2009-05-28 Thread Jon Lang
On Thu, May 28, 2009 at 1:37 AM, Daniel Carrera
daniel.carr...@theingots.org wrote:
 Hi Damian,

 This is a really good list. Mind if I copy it / modify it and post it
 somewhere like my blog? One question:

    * Compactness of expression + semi-infinite data structures:

       �...@fib = 1,1...[+]        # The entire Fibonacci sequence

 Very impressive. That's even shorter than Haskell. What's [+] ? How does
 this work? In Haskell:

Start with the addition operator, '1 + 1'.  Apply the reducing
metaoperator to it so that it works syntactically like a function:
'[+] 1, 1'.  Instead of calling it, pass a code reference to it:
'[+]'.  The lazy list then uses that function to extend the list as
needed.

What I'm wondering is how the list knows to feed two items into '[+]'.
 While 'infix:+' must accept exactly two arguments, '[+]' can accept
an arbitrarily long (or short) list of arguments.

-- 
Jonathan Dataweaver Lang


Re: Continuations

2009-05-27 Thread Jon Lang
Andrew Whitworth wrote:
 The issue mentioned in the Synopses is that junctions autothread, and
 autothreading in a conditional could potentially create multiple
 threads of execution, all of which are taking different execution
 paths. At some point, to bring it all back together again, the various
 threads could use a continuation to return back to a single execution
 flow.

Hmm.  If that's the case, let me suggest that such an approach would
be counterintuitive, and not worth considering.  When I say if any of
these books are out of date, review your records for inconsistencies;
otherwise, make the books available for use, I don't expect to end up
doing both tasks.  In a similar manner, I would expect junctions not
to autothread over conditionals, but to trigger at most one execution
path (continuation?).  The real issue that needs to be resolved, I
believe, is illustrated in the following statement:

if any of these books are out of date, review them.  The question,
as I understand it, is what is meant by 'them'?  Is it these
books, or is it the ones that are out of date?  In perl 6 terms:

   $x = any(@books);
   if $x.out-of-date { $x.review }

Is this equivalent to:

   if any(@books).out-of-date { any(@books).review }

or:

   if any(@books).out-of-date { any(@books.grep {.out-of-date} ).review }

I don't mean to reopen the debate; though if we can get some
resolution on this, I won't mind.  But I _would_ at least like to see
the summary of the issue stated a bit more clearly.

-- 
Jonathan Dataweaver Lang


Re: Unexpected behaviour with @foo.elems

2009-05-27 Thread Jon Lang
On Wed, May 27, 2009 at 7:05 AM, John Macdonald j...@perlwolf.com wrote:
 On Tue, May 26, 2009 at 04:38:21PM -0700, yary wrote:
 perl4-perl5.8 or so had a variable that let you change the starting
 index for arrays, so you could actually make the above work. But then
 everyone who'd re-arranged their brains to start counting at 0, and
 written code that has a starting index of 0, would have problems.

 That was $[ and it goes back to perl 1 or so.  I recall
 experimenting with it a couple of times.  Using it, though,
 means that you have to use $[ as the lower range limit for
 *every* array everywhere.

Is it still a global in Perl 6?  I've noticed a trend toward using
less expansive scopes, so that setting $[ to 1 might mean that arrays
that are defined in the current scope are 1-based instead of 0-based,
whereas arrays defined in other scopes (such as inside a function
imported from a module) might continue to be 0-based.

 That gets stale very quickly, and I then decided that I would
 just never change the setting of $[ and would remove such a
 change from any code that I called.

...which is probably the cleanest way to handle it.  It's for a
similar reason that postcircumfix:[ ] always uses $[-based
consecutive integers for indexing: you always have a consistent way of
referring to, e.g., the first element (@x[0]) or the last element
(@x[*-1]), without having to worry about which indexing scheme any
particular array might be using.

That's also the reason for custom indexing: if you _want_ to use
1-based indexing for a given array, you can always define a custom
index and then refer to the first element by saying @x{1}'.

-- 
Jonathan Dataweaver Lang


Re: Unexpected behaviour with @foo.elems

2009-05-27 Thread Jon Lang
Jonathan Scott Duff wrote:
 Or perhaps

    for 0...@foo.end - $k { ... }

 @foo.keys may not be what the user wanted if @foo is a sparse array.

IIRC, you have to explicitly ask for the custom index in order to get
sparse array keys.  By design, the normal index is never sparse;
only the custom index.

That said, a case could be made that the custom index rules as
currently presented are too restrictive to implement sparse arrays.
In particular, the fact that you must map the custom index to the
standard index when the array is first created, and that you are not
permitted to adjust things later on, kills much of the power inherent
in sparse arrays.

To implement a sparse array, I'd recommend using hashes.  In
particular, allow hashes that have sortable keys to be able to access
them by number as well as by name - E.g.:

my %x = { 'b' = 2, 'c' = 3 }
say %x[0]; # same as say %xb
%xa = 1;
say %x[0]; #same as say %xa

-- 
Jonathan Dataweaver Lang


Continuations

2009-05-26 Thread Jon Lang
From S09, under Junctions:

The exact semantics of autothreading with respect to control
structures are subject to change over time; it is therefore erroneous
to pass junctions to any control construct that is not implemented via
as a normal single or multi dispatch. In particular, threading
junctions through conditionals correctly could involve continuations,
which are almost but not quite mandated in Perl 6.0.0.

What is a continuation?

-- 
Jonathan Dataweaver Lang


Re: Meditations on a Loop

2009-05-22 Thread Jon Lang
On Thu, May 21, 2009 at 11:25 PM, John M. Dlugosz
2nb81l...@sneakemail.com wrote:
 Larry Wall larry-at-wall.org |Perl 6| wrote:

 And since the when modifier counts as a conditional, you can rewrite

    grep Dog, @mammals

 as

    $_ when Dog for @mammals;

 So perhaps will see a lot of subtypes used this way:
    subset Odd if Int where { $_ % 2 };
   �...@evens = ($_ * 2 when Odd for 0..*);




   @primes = do $_ if prime($_) for 1..100;

 becomes

   @primes = $_ when prime($_) for 1..100;

 ?

 Not sure that is any better.

subset Prime of Int where { prime($_) }
@primes = do $_ when Prime for 1..100;

But yes, something does get lost when you have to explicitly pass $_
into a function; its topical nature gets degraded.  Back when .prime
was shorthand for prime $_, this wasn't a big deal; now, with the
fact that you'd somehow have to add a prime method to Int before you
could reliably say .prime, it's a bit more of a problem.

-- 
Jonathan Dataweaver Lang


Re: Meditations on a Loop

2009-05-22 Thread Jon Lang
On Fri, May 22, 2009 at 5:34 AM, Timothy S. Nelson
wayl...@wayland.id.au wrote:
 On Fri, 22 May 2009, Jonathan Worthington wrote:

 Daniel Ruoso wrote:

 Em Sex, 2009-05-22 às 01:25 -0500, John M. Dlugosz escreveu:

   �...@primes = do $_ if prime($_) for 1..100;
 becomes
   �...@primes = $_ when prime($_) for 1..100;



 you gained one stroke, it's certainly better... I think it's time to
 play golf with Perl 6 already ;)

 jokes aside, $_ when prime($_) looks more natural than do $_ if
 prime($_)


 Yes and:

 @primes = 1..100.grep: { prime($^n) };

 Is actually vaguely, like, readable AND two characters shorter than the
 best you've managed so far.

        Oh, if we're looking for readability, I'd look for:

 1..100.grep: { prime($^n) } == @primes;

        It's longer, though :).

These are only readable if you know geek-speak (i.e., what does
'grep' mean?).  The alternatives being proposed are using words like
do, if, when, and for.  I think that it's rather impressive
that they're coming within a handful of characters of a grep-based
version.

-- 
Jonathan Dataweaver Lang


Re: r26700 - docs/Perl6/Spec

2009-05-06 Thread Jon Lang
 @@ -1836,6 +1836,12 @@
  prototype objects, in which case stringification is not likely to
  produce something of interest to non-gurus.)

 +The C.^parents method by default returns a flattened list of all
 +parents sorted in MRO (dispatch) order. Other options are:
 +
 +    :local              just returns the immediate parents
 +    :hierarchical       the inheritance heirarchy as nested arrays

Bad Huffman coding, IMHO.  Could we s/hierarchical/tree/?

-- 
Jonathan Dataweaver Lang


Re: Docstrings in Perl 6

2009-05-04 Thread Jon Lang
This message deals strictly with the syntax of '#='-based POD; the
semantics is a separate issue.

--

I'd like '#=' to follow similar rules to what '#' follows, with the
caveat that a line beginning with '#' counts as a single-line comment
no matter what the second character is.  Specifically, having the
second character be an = does not transform a full-line comment into a
single line of documentation.  This preserves the ability to comment
out a series of lines by prepending a '#' to each of them without
having to worry about whether or not any given line will start doing
strange things.  This means that '#=' can never appear at the start of
the line if you want it to denote documentation; but anywhere else is
fine.  This should be a simple enough rule for a POD parser to handle
with minimal trouble.

There are additional complications that arise with '#=', such as:

   say '#=';

In order to keep a POD parser from having to parse the code as well,
we'd want to say that the #= sequence initiates a POD block that
extends to the end of the line.  IOW, the POD parser would end up
with:

CODE:
say '
POD:
';

But if that's the case, how would you ever actually print the
character sequence '#='?  Conversely, if you say that the fact that
it's within a string literal means that it counts as string characters
rather than the start of some POD, the POD parser will need to know
how to identify string literals - which, as Perl illustrates, may not
be a simple task.

A possible middle ground might be to say that '#=' starts some POD,
but (e.g.) '\#=' doesn't: where a POD extractor would remove '#=' and
the following POD from the resulting code, it would replace '\#=' with
'#='.  So to actually display the '#=' character sequence, you'd say:

   say '\#=';

With this in play, you can place '#='-based POD literally anywhere
except at the beginning of a line.

--

With this in mind, I'd propose two forms of '#=', based on what comes
after the '='.  If it is followed by one or more '['s, you have
bracketed POD which is terminated by an equal number of ']'s;
otherwise, you have POD which is terminated at the end of the current
line.  Note that I specifically said '[' rather than 'a bracketing
character'; this is for the same reason that 'Ccode' is POD markup,
but 'C{code}' isn't.  As well, I chose '[' instead of '' to minimize
the need to double or triple up on the encapsulating brackets whenever
inline POD markup is involved.  Compare:

   #=This text has Iitalics!
   #=[This text has Iitalics!]

   #=C$x5
   #=[C$x5]

Conversely:

   #=$x[5] = 7
   #=[[$x[5] = 7]]

...which isn't too bad IMHO (and is pretty close to a worst-case scenario).

Finally, I'd want bracketed POD to follow indentation rules similar to
what Hinrik suggested above: if the '#=' is preceded by nothing but
whitespace and every line within the bracketed POD starts with at
least as much whitespace, trim the shortest whitespace off of every
line within the POD.

--

Again, note that the above addresses only the syntax of '#='-based
POD, and not the semantics.

--
Jonathan Dataweaver Lang


Re: junctions and conditionals

2009-04-02 Thread Jon Lang
Martin Kealey wrote:
 On Tue, 31 Mar 2009, Jon Lang wrote:
 Another issue: what happens if conditional code mutates a junction
 that it filtered?  For example:

     $x = any (-5 .. 5);
     if $x  0 { $x++ };

 At this point, which of the following does $x equal?

     any(-4 .. 6) # the original junction gets mutated
     any(-5 .. 0, 2 .. 6) # the filtered part of the original junction
 gets mutated; the rest is untouched
     any(2 .. 6) # the filtered part of the original junction gets
 mutated; the rest is lost

 I choose #3.

 Reality can only take one path through a conditional; which one depends
 on the one/any/all/none binding of the junction.

 Once you've passed the conditional, you have:

        one - single matching value (no longer a junction)
        any - filtered list
        all - original junction
        none - empty (*1)

I'm a bit worried about 'none', for reasons that I'll get to in a moment.

 The threading is an implementation detail; the important thing is a
 junction is collection of values and a smart way of rewriting
 expressions that contain them, with special treatment for comparison
 operators (or indeed anything that forces Boolean content):

        $x CMP all($y,$z)       $x CMP $y  $x CMP $z
        $x CMP one($y,$z)       $x CMP $y ^^ $x CMP $z  (*2)
        $x CMP none($y,$z)      all($x !CMP $y, $x !CMP $z)
        $x CMP any($y,$z)       $x !CMP none($y, $x)

        $x OP all($y,$z)        all( $x OP $y, $x OP $z)
        $x OP any($y,$z)        any( $x OP $y, $x OP $z)
        $x OP one($y,$z)        one( $x OP $y, $x OP $z)
        $x OP none($y,$z)       none($x OP $y, $x OP $z)

 -Martin

 (*1: An argument could be made that none should leave the junction alone,
 the same as all.)

 (*2: I would like to suggest that the semantics of one be changed to mean
 pick one (randomly) rather than exactly one. In this respect it
 would be the same as any except it wouldn't have the overhead of
 filtering *every* match, just at least one.)

A few thoughts here.  First: should autothreading be lazy or eager?
As things stand, it seems to be eager: the moment you pass a junction
into a routine that doesn't ask for a junction in its signature, you
autothread that routine.  This has the nice benefit of being easy to
implement (autothread if the parameter doesn't specify 'junction';
don't autothread if it does); but as has been mentioned before, making
life easy on the implementor isn't a primary design goal for Perl.  I
submit that autothreading should be lazy.

As I see it, there are currently three things that can be done with a junction:

  1. Nothing.  Using the junction as threads paradigm, you bundle
the threads together and route them through a given part of the
program as a single rope.

  2. Autothreading.  You feed each thread through individually, and
rebundle the results on the other side.

  3. Sieving.  You feed only some of the threads through a decision
point into its guarded region, and rebundle at the end of the guarded
region.

Option 3 raises some additional questions.  What do you rebundle at
the end of the guarded region?  Just the threads that were passed
through it, or all of the original threads?  And what happens if the
program flow gets rerouted inside the guarded region such that it
never comes out the other side?

If I say:

$x = any(-5 .. 5)
if $x  0 { $x++ }
if $x ~~ (-1 .. 1) { $x *= 2 }

What is $x just before and just after '$x++'?  What is $x just before
and just after 'if $x  0 { $x++ }'?  Ditto with '$x *= 2' and 'if $x
 0 { $x *= 2 }'?

If I say:

$x = any(-5 .. 5)
if $x  0 { return }
if $x ~~ (-1 .. 1) { doit($x) }

What junction should doit be receiving?

Second:

sub sayit (Str $s) { say $s }
sayit 'S' | 5;

What should happen?  Should the junction be autothreaded, and then one
of the threads fail due to a type mismatch?  Or does parameter-passing
count as a kind of decision-point, such that you only get the sayit
'S' thread?

And what happens with the following?

sayit none('S');

-- 
Jonathan Dataweaver Lang


Re: S08 Draft questions (Captures and Signatures)

2009-04-01 Thread Jon Lang
Jonathan Worthington wrote:
 Jon Lang wrote:

 Invocants:

 * Does anyone object to roles having an invocant, and that invocant
 referring to the class that is doing the role?



 Yes; on further reflection, the ability to type that invocant raises all
 kinds of possible WTFs without a good enough use case. So I'd really rather
 we don't go down this road.

How does this situation differ from the ability to type a method's
invocant?  I'm thinking that an argument might be made that you don't
get to specify any invocant's type: a method's invocant would always
be typed as the class to which it belongs (with the value set as the
object calling it), while a role's invocant would always be typed as a
type reference (i.e., the :: sigil), with the value being the class
composing it.  Would any significant functionality be lost in such a
move?

 Longnames:

 * Are placeholder parameters ever considered to be part of a
 function's longname?  (I'm expecting that they aren't: if you want a
 longname, you ought to specify it in a formal signature.)



 Placeholder parameters result in a signature being generated based upon
 them, as far as I can tell (and so far as we've implemented in Rakudo). So
 yes, they would all count in the long name - or at least, the positional
 ones. Also note that if you do have placeholder parameters it's illegal to
 write a signature on the block too.

True: forbidding placeholder parameters from counting as part of the
longname would effectively forbid functions that use placeholder
parameters from _having_ a longname; and if you've explicitly asked
for one (via the multi keyword), you should get one.

 Placeholder parameters:

 * does the use of placeholder parameters interfere with the use of the
 slurpy parameters normally provided by the default signature (i.e.,
 *...@_ and *%_)?  I'm guessing not.


 We only generate *...@_ and *%_ for subs when there is no signature; the
 presence of placeholder parameters generates a signature, so you'd not get
 them. Exception: methods, where by S12 we always add a *%_ unless the method
 defines its own slurpy named parameter.

Is this the desired behavior, or merely the current behavior?  I can
see a case for wanting the placeholder parameters to be pushed onto
front of the default signature instead of replacing it.

-- 
Jonathan Dataweaver Lang


Re: simultaneous conditions in junctions

2009-04-01 Thread Jon Lang
On Wed, Apr 1, 2009 at 12:58 AM, Richard Hainsworth
rich...@rusrating.ru wrote:
 Thinking about Jon Lang's -1|+1 example in another way, I wondered about
 simultaneous conditions.

 Consider

 $x = any (1,2,5,6)

 How do we compose a conditional that asks if any of this set of eigenstates
 are simultaneously both  2 and  5?
 Clearly the desired answer for $x is False, but

 my $x = any(1,2,5,6); say ?( 2  $x  5); # true

 Is there some combination of any/all that will achieve this?

As Carl indicated, there are other ways to do this.  For instance, s/
2  $x  5 / $x ~~ 2 ^..^ 5 /.  But as I indicated in a recent email,
part of my concern is that those two expressions _ought to be_
equivalent: changing the junction, or making do without one as Carl
proposes, doesn't fix this lack of equivalence.

As for Carl's proposed alternative: no, it isn't _much_ longer (but it
_is_ longer), and _perhaps_ it's _slightly_ more understandable - or
perhaps not.  Other than making the implementors' lives harder, what's
wrong with trying to find a way to get Jonathan's example to work the
way people expect it to?

I don't understand this aversion to everything remotely hinting of
eigenstates/eigenthreads/threshing/whatever.

-- 
Jonathan Dataweaver Lang


Re: S08 Draft questions (Captures and Signatures)

2009-04-01 Thread Jon Lang
On Wed, Apr 1, 2009 at 5:07 AM, Daniel Ruoso dan...@ruoso.com wrote:
 Em Ter, 2009-03-31 às 22:54 -0700, Jon Lang escreveu:
 Yes, I know that there is no S08.  I'm working on writing one, and I'd
 like some feedback to help me do so.

 ++

 My draft is going to be about Signatures and Captures.  Thus, my questions:
 Invocants:

 The concept of invocant only exists in terms of syntax now. In runtime
 the invocant is simply the first positional argument. This simplifies
 things a lot.

I think you're confusing signatures with captures here.  Captures and
the arguments that they, well, capture, don't care about the invocant;
but signatures and the parameters that they define still do.

 * Likewise, if I interpolate a signature with an invocant into another
 signature (somewhere other than at the start), is this an error, or
 will the invocant be silently converted into an ordinary positional
 parameter?

 What does interpolate a signature mean?

...my bad.  For some reason, I made the opposite mistake: I thought
that it was possible to assemble a signature out of other signatures.

 * Why are we using ;; to denote the end of a multi function's
 longname?

 Because a capture may have more than one dimension, which would be
 delimited by ;.

Note that I didn't propose ; as the longname terminator.

 * Can any required parameter be part of the longname, or are only
 positional parameters allowed?  (I'm expecting the latter; but I'd
 like confirmation.)

 I suspect you meant named parameter in place of required parameter.

I meant both, actually: can required named parameters be part of the longname?

 For Perl 6.0.0, it is accepted that named parameters don't take part in
 multi dispatch.

OK.

 * does the use of placeholder parameters interfere with the use of the
 slurpy parameters normally provided by the default signature (i.e.,
 *...@_ and *%_)?  I'm guessing not.

 Yes, it does. The default signature is the *default*. Having placeholder
 parameters imply defining a signature, one could argue that *...@_ and *%_
 are still part of that generated signature, but @_ certainly won't
 contain the values that were in the placeholder parameters.

...nor would I expect it to.  I'm just wondering if (@_, %_) _are_
still part of a placeholder-generated signature.  In short, is there a
way to access a slurpy array or hash in a block that uses placeholder
parameters?

-- 
Jonathan Dataweaver Lang


junctions and conditionals

2009-03-31 Thread Jon Lang
In Junction Algebra, Martin Kealey wrote:
 On Mon, 30 Mar 2009, Mark J. Reed wrote:
         ( $a = any(-1,+1) = $b ) == ( $a = any(-1,+1)  any(-1,+1) = 
  $b )

 Clearly, the RHS is true for $a == $b == 0, but I'm not sure the LHS
 shouldn't also be.  Isn't it just syntactic sugar for the RHS?

 I suspect not. Rather I think that

        $a = any(-1,+1) = $b

 corresponds to

        $tmp = any(-1,+1);
        $a = $tmp = $b

 and thence to

        $tmp = any(-1,+1);
        $a = $tmp  $tmp = $b

 The more I think about this, the more I come to the conclusion that a
 junction should appear to have a uniform (single) value in each
 eigenthread.

Ugh.  Let me float another problem, and a possible solution to both,
that doesn't require persistent threading environments:

$x = -1 | +1;
if $x  0 { say $x }

As I understand junctions right now, the result of this code is identical to:

   say -1 | +1;

In both cases, the problem arises when you apply a predicate to a
junction, and then use the junction within code that only gets
executed according to the truth of the predicate.

The possible solution to both of these: junctions collapse when they
hit conditional statements - but only within the conditioned scope.
So: within the code block for the if $x  0 statement above, $x only
equals +1, since -1 didn't pass the test.  Thus, say $x is the same
as say 1.  In the case of the range test, the code on the RHS of the
 only executes if the code on the LHS evaluated to true; therefore,
when evaluating the RHS, $tmp doesn't include any of the
possibilities that would have failed on the LHS.  That means that:

0 = -1 | +1 = 0

...becomes:

0 = -1 | +1  +1 = 0

...which, obviously, is false.

Extending this further:

$x = +1 | -1;
if $x  0 { say $x is positive. }
else { say $x is negative. }

I suspect that both codeblocks would be executed; but within the first
block, $x == +1, and within the second codeblock, $x == -1.

$x = +1 | -1;
say $x  0 ?? $x + 2 :: $x * 2;

In this case, $x is +1 when evaluating $x + 2, and it is -1 when
evaluating $x * 2.  After this expression is fully evaluated, they
get recombined into a single junction: +3 | -2.

This last one might be easier to manage simply by having $x autothread
through the ?? :: operator, since you need to be able to reassemble
a junction on the other end.

-- 
Jonathan Dataweaver Lang


Re: junctions and conditionals

2009-03-31 Thread Jon Lang
I've been having some second thoughts concerning this.  Here's where I
stand on it now:

In Perl 6, you have the following decision points, where code may or
may not be executed depending on a condition:
if/unless/while/until/loop/when statements; if/unless/while/until
statement modifiers; short-circuit operators; the trinary conditional
operator.  When you apply a junction to a decision point, only one of
the possible paths will be taken; and the any/all/one/none nature of
the junction will determine which one.  (Without this, there would be
no reason to have a distinction between any/all/one/none.)  However, I
stand by my proposal that after passing one of these decision points,
and until you get back to code that would have been reached regardless
of the decision point, every junction that was involved in the
decision point should be limited such that it acts as if only those
possibilities within it that would have passed the decision point
exist.

With unless, while, until, and loop, the associated block is
the conditional block where the junction gets filtered.  With if,
the main block likewise filters the junctions; but the else block
also provides junction filtering, but in a way that's complementary to
what the main block does.

With short-circuit operators, the RHS counts as a block that
provides junction filtering based on what it would take for the LHS to
avoid tripping the short-circuit behavior.  Similarly, ?? :: treats
the expression following the ?? as a junction-filtering block and
the expression following the :: as a complementary junction-filtering
block, in direct analogy to if/else, above.

Finally, there's the when statement: as with if, etc., the block
that follows the when statement filters junctions according to the
match criterion.  However, when is a bit more complicated in terms
of getting it to DWIM w.r.t. junctions.  Because of the way that
when works conceptually, I'd recommend that for the rest of the
block containing the when statement, it should provide the same sort
of complementary filtering that an else block does for an if
statement.  That is:

given $x {
when $a { ... }
when $b { ... }
when *
}

...should not be thought of as being equivalent to:

given $x {
if $_ ~~ $a { ...; break }
if $_ ~~ $b { ...; break }
if $_ ~~ * {...; break }
}

...but rather:

given $x {
if $_ ~~ $a { ... }
else {
if $_ ~~ $b { ... }
else {
if $_ ~~ * { ... }
}
}
}

--

Another issue: what happens if conditional code mutates a junction
that it filtered?  For example:

$x = any (-5 .. 5);
if $x  0 { $x++ };

At this point, which of the following does $x equal?

any(-4 .. 6) # the original junction gets mutated
any(-5 .. 0, 2 .. 6) # the filtered part of the original junction
gets mutated; the rest is untouched
any(2 .. 6) # the filtered part of the original junction gets
mutated; the rest is lost

--
Jonathan Dataweaver Lang

-- 
Jonathan Dataweaver Lang


S08 Draft questions (Captures and Signatures)

2009-03-31 Thread Jon Lang
Yes, I know that there is no S08.  I'm working on writing one, and I'd
like some feedback to help me do so.

My draft is going to be about Signatures and Captures.  Thus, my questions:

Invocants:

* Is it illegal to specify an invocant in a sub, or is it merely
nonsensical?  That is, should the compiler complain, or should it
silently treat the invocant as the first positional parameter?  (The
latter has the advantage that you don't have to worry about what the
signature is being used for; it has the disadvantage of being, well,
nonsensical: invocants are meaningless without the context of a method
- and /maybe/ a role - to provide them meaning.)

* Likewise, if I interpolate a signature with an invocant into another
signature (somewhere other than at the start), is this an error, or
will the invocant be silently converted into an ordinary positional
parameter?

* What types are you allowed to assign to an invocant?

* Does anyone object to roles having an invocant, and that invocant
referring to the class that is doing the role?

Longnames:

* Why are we using ;; to denote the end of a multi function's
longname?  I'm thinking that doubling up on the normal delimiter may
make more sense - which would normally mean ,,, but would mean ;;
if you're using a multidimensional argument list and the longname ends
where a semicolon would normally go.

* Can any required parameter be part of the longname, or are only
positional parameters allowed?  (I'm expecting the latter; but I'd
like confirmation.)

* Are placeholder parameters ever considered to be part of a
function's longname?  (I'm expecting that they aren't: if you want a
longname, you ought to specify it in a formal signature.)

Starting and Ending delimiters:

* Why are pointy blocks forbidden from enclosing their signatures in
parentheses, or from using the :( ... ) notation?  Is this a
holdover from the early days, when parentheses denoted a list?  Or is
there still a good reason not to allow such notation?

* Why do parameterized roles use [ ... ] for their signatures
instead of :( ... ) or ( ... )?

Named parameters:

* Must required named parameters be defined before optional named
parameters are, or are we allowed to interleave the two?

Placeholder parameters:

* does the use of placeholder parameters interfere with the use of the
slurpy parameters normally provided by the default signature (i.e.,
*...@_ and *%_)?  I'm guessing not.

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-30 Thread Jon Lang
On Sun, Mar 29, 2009 at 10:57 PM, Mark Lentczner ma...@glyphic.com wrote:
 What I see here is that there is a tendency to want to think about, and
 operate on, the eigenstates as a Set, but this seems to destroy the single
 value impersonation of the Junction.

In my case, this tendency comes more from a desire to be able to
reverse the creation of a junction: you create a (singular) junction
from a (plural) list ('1|3|5' === 'any 1, 3, 5'); so I naturally want
to be able to (more or less) reverse this process and create a
(plural) Set from a (singular) junction.

 Further, if one ever calls .!eigenstates() on a Junction, then you have
 really bollox'd your code up, as then this code fails if the value you
 thought was a Junction happens to be, actually, just a single value!
  (Unless .!eigenstates() is defined on Object, and returns a Set of self...)

Which is why I'd _want_ eigenstates to be callable on an Object as
described - and, in general, _any other_ function that operates
directly on junctions should be able to accept Objects as well,
treating the Object as a one-eigenstate junction.

Otherwise, the moment you write a function that passes a junction as a
parameter, your code will break if you ever try to pass an Object in
instead.  And the only other ways to avoid that would be: 1. to
provide a means of testing whether or not something is a junction, or
2. to forbid anyone from ever using junction in a signature.

 I think what is needed is a single value threshing function, which can be
 applied to, well, single values.  Such a function would take a value and a
 predicate, and if the predicate applied to the value is true, returns the
 value, else it returns... nothing. If such a function were applied to a
 Junction, then the result would be a Junction of just those those
 eigenstates that passed this function.  The nothings would not end up
 contributing to the Junction.

...that could work.  The only catch is that if you ever want to get a
list of the cases that passed so that you can operate on them
individually, you'd still need a means of extracting the eigenstates
from the junction.

 Now, I'm not sure I know how to return nothing in Perl6, but I'll guess
 that undef can serve the purpose, since I can't think of a useful use of
 undef as part of a Junction.

As Daniel indicated, returning an empty list should work.

-- 
Jonathan Dataweaver Lang


Re: Junction Algebra

2009-03-30 Thread Jon Lang
Here's another useful one:

any($x) eqv all($x) eqv one($x) eqv $x

but:

none($x) !eqv $x

That is, applying any, all, or one to a one-item list produces the
equivalent to a single item.  For an empty list: any() eqv all() eqv
().  But what about one() and none()?

-- 
Jonathan Dataweaver Lang


Re: On Sets (Was: Re: On Junctions)

2009-03-29 Thread Jon Lang
On Sun, Mar 29, 2009 at 1:18 PM, John Macdonald j...@perlwolf.com wrote:
 On Sat, Mar 28, 2009 at 10:39:01AM -0300, Daniel Ruoso wrote:
 That happens because $pa and $pb are a singular value, and that's how
 junctions work... The blackjack program is an example for sets, not
 junctions.

 Now, what are junctions good for? They're good for situation where it's
 collapsed nearby, which means, it is used in boolean context soon
 enough. Or where you know it's not going to cause the confusion as in
 the above code snippet.

 Unfortunately, it is extremely common to follow up a boolean is this
 true with either if so, how and/or if not, why not.  A boolean test
 is almost always the first step toward dealing with the consequences,
 and that almost always requires knowing not only what the result of the
 boolean test were, but which factors caused it to have that result.

True point.  Along these lines, I'd like to see at least one
threshing function that separates a junction's eigenstates that
passed a boolean test from those that didn't.  I can see several
possible semantics for such:

  1. It returns a list of the eigenstates that passed the test.

  2. It returns a junction composed of only those parts of the
junction which passed the test.

  3. It returns a two-item list: the wheat and the chaff.  The form
that the items take would conform to one of the first two options.

The G[op] proposal could be thought of as one approach to the first
option.  Note also that this option can be turned into a generic list
all of the eigenstates function by choosing a test that every
possible eigenstate is guaranteed to pass; as such, it would be a very
small step from this sort of threshing function to a public
.eigenstates method - e.g., $j.eigenstates :where { ... } (to add
optional threshing capabilities to a list of eigenstates function)
or * G~~ $j (to use a thresher to retrieve all of the eigenstates).

The infix:where (junction, Code -- junction) proposal that I made
earlier is an example of the second option.  This option has the
advantage that it preserves as much of the junction's internal
structure (e.g., composite junctions) as possible, in case said
structure may prove useful later on.  (I'm a big fan of not throwing
anything away until you're sure that you don't need it anymore.)  The
downside is that if you want a list of the eigenstates that passed the
test, this is only an intermediate step to getting it: you still have
to figure out how to extract a list of eigenstates from the threshed
junction.

The third option has the benefit of letting you handle if so  if
not without having to thresh twice, once for the wheat and again for
the chaff.  OTOH, it's bound to be more complicated to work with, and
is overkill if you only care about one of the outcomes.  I have no
syntax proposals at this time.

Note further that these aren't necessarily mutually exclusive options:
TIMTOWTDI.  I prefer the ones that use some form of where; but
that's just because those approaches feel intuitive to me.

 The canonical example of quantum computing is using it to factor huge
 numbers to break an encryption system.  There you divide the huge number
 by the superposition of all of the possible factors, and then take the
 eigenstate of the factors that divide evenly to eliminate all of the
 huge pile of potential factors that did not divide evenly.  Without
 being able to take the eigenstate, the boolean answer yes, any(1..n-1)
 divides n is of very little value.

Right.  Something like:

any(2 ..^ $n).eigenstates :where($n mod $_ == 0)

or:

( any(2 ..^ $n) where { $n mod $_ == 0 } ).eigenstates

...might be ways to get a list of the factors of $n.  (I'm not sure
how this would be done with junctions and the proposed grep
metaoperator - although I _can_ see how to do it with _just_ the
metaoperator, or with just a grep method.  But that's list
manipulation, not junctive processing.)  Of course, evaluating this
code could be a massive headache without a quantum processor.

I'm sure that one _could_ come up with a Set-based approach to doing
this; it might even be fairly easy to do.  But again, TIMTOWTDI.  Perl
has never been about trying to come up with an ideal approach and
then forcing everyone to use it - that would be LISP, among others.
Telling people that they must use Sets instead of junctions in cases
such as this runs counter to the spirit of Perl.

-- 
Jonathan Dataweaver Lang


Re: [perl #62528] Match.keys method returns nothing.

2009-03-29 Thread Jon Lang
Moritz Lenz wrote:
 Since afaict this is not specced, I'll hand that over to p6l.

 Eric Hodges (via RT) wrote:
 use v6;

 rule test {test};

 test ~~ /test/;
 say '$/.keys = ', $/.keys.perl;
 say '%($/).keys = ', %($/).keys.perl;

 # outputs
 # $/.keys = []
 # %($/).keys = [test]


 Same could be said for .values and .kv

 It would be very DWIM for it to act like a hash in these cases by default.

 Actually I think it would DWIM more in the general case if Match.keys
 (and .kv, .pairs, .values etc) would give a list of the array and hash
 part, so $/.keys would be  @($/).keys, %($/).keys.
 Your suggestion would be just a degenerate case of that.

 Any thoughts on that?

Take it one step more general: IIRC, Match returns a Capture of the
matches found.  What happens if you apply .keys, .values, etc.
directly to a Capture object?  I'm thinking that it should return a
multidimensional array: e.g., (@$capture; %$capture).«keys.

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-28 Thread Jon Lang
Daniel Ruoso wrote:
 But the semantics of sets are still somewhat blurry... there are some
 possibilities:

  1) Sets are in the same level as junctions, but have no collapsing and
     allow you to get its values. The problem is if it autothreads on
     method calls or not... It also makes $a  $b confuse...

  2) Set ~~ Any, and all the inteligence is made implementing multis,
     it has the disadvantage that new operators will need to have
     explicit implementations in order to get Set DWIMmery...

 I have been unsure about that, but lately I'm mostly thinking option 2
 is the sanest, which means we only get as much DWIMmery as explicitly
 implemented (which may or may not be a good idea).

My understanding is that Set operates on the same level as Hash and
List - indeed, a Set could be thought of as a Hash that only cares
about the keys but not the values, and has a few additional methods
(i.e., the set operations).

That is, a junction is an item with an indeterminate value; but a Set
is a collection of values in the same way that a hash is.  And the
proper sigil for a Set is %, not $.

-- 
Jonathan Dataweaver Lang


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Jon Lang
On Sat, Mar 28, 2009 at 6:39 AM, Daniel Ruoso dan...@ruoso.com wrote:
 Em Sáb, 2009-03-28 às 13:36 +0300, Richard Hainsworth escreveu:
 Daniel Ruoso wrote:
  The thing is that junctions are so cool that people like to use it for
  more things than it's really usefull (overseeing that junctions are too
  much powerfull for that uses, meaning it will lead to unexpected
  behaviors at some point).
 What are the general boundaries for junctions?

 Junctions are superposition of values with a given collapsing type.

 The most important aspect of junctions is that they are a singular
 value, which means that they are transparent to the code using it. You
 always use it as a singular value, and that's what keep its semantics
 sane.

Closely related to this is that junctions autothread.  If you type in
foo($a | $b), it will be processed exactly as if you had typed
foo($a) | foo($b) - that is, it will call foo twice, once for $a and
once for $b, and it won't care which order it uses.  And this is true
whether or not you know that a junction is involved.  Given 'foo($j)',
foo will be called once if $j isn't a junction, and will be called
multiple times if $j is a junction.

If you were dealing with a Set instead, you'd need to make use of
'map' and/or hyperoperators to achieve a similar result.

-- 
Jonathan Dataweaver Lang


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Jon Lang
Thomas Sandlaß wrote:
 Set operations are with parens.

Which Synopsis is this in?

-- 
Jonathan Dataweaver Lang


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Jon Lang
Henry Baragar wrote:
 The blackjack program is an excellent example for junctions (and not so good
 for sets, IMHO).  The problem in the example above is that the calculation
 of the value of a hand was not completed.  The complete calculation is as
 follows:

   my $pa = ([+] @a).eigenstates.grep{$_ 21}.max

Per the recent change to the synopses, eigenstates is now a private
method, rendering the above code invalid.

-- 
Jonathan Dataweaver Lang


Re: deciphering infix:cmp

2009-03-27 Thread Jon Lang
In the case of strings and numbers, I'd recommend using leg instead of
cmp - that is, coerce both items to strings, then compare the strings.
 But as far as cmp goes, 3 cmp '3' should fail because a number
isn't a string.

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-27 Thread Jon Lang
On Fri, Mar 27, 2009 at 10:39 AM, Dave Whipp d...@dave.whipp.name wrote:
 Richard Hainsworth wrote:

 The following arose out of a discussion on #perl6. Junctions are new and
 different from anything I have encountered, but I cant get rid of the
 feeling that there needs to be some more flexibility in their use to make
 them a common programming tool.

 I strongly agree with you, but Larry has repeatedly said that he wants to
 view Junctions as lexical sugar rather than as a powerful programming tool.
 So I'm thinking that we'll need to experiment with modules before anything
 gets admitted to the core language.

Maybe you could have something like a filter function that takes a
junction and a test condition and returns a junction of those
eigenstates from the original one that passed the test.  You could
then handle the Blackjack problem by saying something to the effect
of:

   $p = [+] @p;
   $d = [+] @d;
if $p = 21 { # Could the total be 21 or less?
$p where= { $_ = 21 } #[ infix:where filters the junction
according to the given criteria. ]
if $p  $d { say you won! }
} else { say you went over. }

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-27 Thread Jon Lang
Dave Whipp wrote:
 [I’d been planning to put this suggestion on hold until the spec is
 sufficiently complete for me to attempt to implement it as a module. But
 people are discussing this again, so maybe it's not just me. I apologize if
 I appear to be beating a dead horse...]

 Jon Lang wrote:

 Maybe you could have something like a filter function

 yes, but

 that takes a
 junction and a test condition and returns a junction of those
 eigenstates from the original one that passed the test.

 But why is this a useful thing to do? I think that you're proposing, for
 compound junctions:

 ok any( 1|2, 12, 5|15, 515 ) where { $_  10 }
   === any( 1|2, 12, 5|15 )

...not really, no.  The way I was looking at it, the above expression
is ultimately a junction of the values 1, 2, 5, and 15; no matter how
compounded the junction is, these would be its eigenstates.  Since 15
would fail the test, anything having to do with it would be filtered
out.  Exactly how that would work with a compound junction, I'm not
sure; as I said, I was thinking of the eigenstates as ordinary items,
not nested junctions.  But yes, I _was_ suggesting something that
transforms one junction into another.

That said, I'm also leery of compound junctions.  Please tell me the
difference between:

any( 1|2 )

...and:

any( 1, 2 )

If there is no difference, then:

 any( 1|2, 12, 5|15, 515 ) eqv any( 1, 2, 12, 5, 15, 515 )

For that matter, I'm not seeing a difference between:

any( 12 ) # any of all of (1, 2)

...and:

any( 1, 2 ) # any of (1, 2)

If I'm not mistaken on these matters, that means that:

any( 1|2, 12, 5|15, 515 ) eqv any(1, 2, 5, 15)

And I expect that similar rules hold for other compound junctions.  In
short, I won't be surprised if all compound junctions can flatten into
equivalent simple junctions.

 To me, it still feels like you're thinking of a junction as a set of values,
 and inventing an operator specifically for the purpose of messing with those
 values. I do not see values of a junction as a meaningful user-level
 concept.

I'm pretty sure that Larry agrees with you here, seeing as how his
latest revision concerning junctions makes direct access to a
junction's eigenstates very difficult to arrange.

 I prefer to turn the problem around, and suggest a different
 operator, motivated by a different issue, and then apply that operator to
 junctions.

 Consider this statement:

    say (0..Inf).grep: { $_  10 };

 I would expect it to take infinite time to complete (or else fail quickly).
 It would be wrong to expect perl to figure out the correct answer
 analytically, because that is impossible in the general case of an arbitrary
 code block. So I instead propose an operator-based grep:

    say 0..inf G[] 10;
     [0..9]

 This “grep metaoperator” can be expected to analytically determine the
 result (of grepping an infinite list) in finite time.

 It might also be used
 to avoid curlies for simple greps:

    say @lines G~~ /foo/;

 The operator exists to filter infinite lists in finite time. But it also
 solves the junction problem:

    say (-Inf .. Inf) G== 3|4;
     [3,4]

And how would it handle a compound junction (assuming they exist)?  That is:

say (-Inf .. Inf) G== any(1|2, 12, 5|15, 515);
 ???

    $score = [+] 1|11, 1|11, 1+11, 1+11, 4;

I assume you meant:

$score = [+] 1|11, 1|11, 4;

    say max( 1..21 G== $score ) // bust;
     18

...and the answer to that would be 16, right?

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-27 Thread Jon Lang
Damian Conway wrote:
 Jon Lang wrote:

 For that matter, I'm not seeing a difference between:

    any( 12 ) # any of all of (1, 2)

 ...and:

    any( 1, 2 ) # any of (1, 2)

 Those two are very different.

     any(1,2) == 2  is true

     any(12) == 2  is false


 Nested heterogeneous junctions are extremely useful. For example, the
 common factors of two numbers ($x and $y) are the eigenstates of:

    all( any( factors($x) ), any( factors($y) ) )

I stand corrected.  That said: with the eigenstates method now
private, it is now quite difficult to get a list of the eigenstates of
the above expression.

-- 
Jonathan Dataweaver Lang


Re: Logo considerations

2009-03-24 Thread Jon Lang
2009/3/24 Larry Wall la...@wall.org:
 http://www.wall.org/~larry/camelia.pdf

Cute.  I do like the hyper-operated smiley-face.

What I'd really like to see, though, is a logo that speaks to Perl's
linguistic roots.  That, more than anything else I can think of, is
_the_ defining feature of Perl.

-- 
Jonathan Dataweaver Lang


Re: routine arrow syntax and return/of types

2009-03-22 Thread Jon Lang
Darren Duncan wrote:
 Jon Lang wrote:
 Spitballing here: you drew an analogy to the feed operators.  I wonder
 if that analogy could be taken further: use -- and -- outside of
 signatures as feed operators - but instead of feeding arrays back and
 forth, have them feed capture objects and engage in some implicit
 currying.  That is:

    foo -- $capture
    $capture -- foo

 would both be equivalent to:

    foo :assuming(|$capture)

 ...or something to that effect.  So instead of composing a series of
 functions by nesting them in each others' argument lists, you could do
 so by chaining them together using -- or --.

 That could be interesting.  But do you have an example use case or example
 code illustrating its use?

Perhaps something like:

my $name = jonathan;
$name -- capitalize -- say;

Or:

$y = acos 'degrees' -- sin 'radians' -- $x;

-- 
Jonathan Dataweaver Lang


Re: routine arrow syntax and return/of types

2009-03-19 Thread Jon Lang
Darren Duncan wrote:
 Maybe the problem is a technicality with the parser because ...

 I'm guessing that the problem is that until you see the -- then what you've
 read so far on its left is ambiguous as to whether it is a result type or a
 parameter.  I can understand that but I don't know if its a big problem.

 AFAIK the token -- isn't used anywhere yet in Perl 6 and so its presence
 inside a parameterized list would be unambiguous once you've read up to it.

And AFAIK the token -- is used in exactly one place in perl 6: within
signature syntax, to mark the transition from the parameter signature
to the return type signature.  As with Darren, I don't see why this
would be a big problem.  The biggest stumbling block that I can think
of is that a return type cannot have an invocant, whereas the
parameter signature might be able to have one.  May I inquire as to
the nature of the complications that I'm missing, for my own
edification?  (If you can't afford the time, I'll understand.)

 Anyway, while I would appreciate if -- worked, if it doesn't then I can
 live with one of the existing alternatives ('of' being my current
 preference).  This is a nice to have but not something I would push as
 hard yet as some other issues.

Yeah; definitely not an urgent request.  I wonder how hard it would be
to write a module that hacks the parser to enable this feature...

Spitballing here: you drew an analogy to the feed operators.  I wonder
if that analogy could be taken further: use -- and -- outside of
signatures as feed operators - but instead of feeding arrays back and
forth, have them feed capture objects and engage in some implicit
currying.  That is:

foo -- $capture
$capture -- foo

would both be equivalent to:

foo :assuming(|$capture)

...or something to that effect.  So instead of composing a series of
functions by nesting them in each others' argument lists, you could do
so by chaining them together using -- or --.

But, like Darren's request, this definitely isn't something that I'd
insist on for 6.0.0.

-- 
Jonathan Dataweaver Lang


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

2009-03-18 Thread Jon Lang
 +    method !eigenstates (Junction $j: -- List)

Shouldn't that be lowercase-j junction?

-- 
Jonathan Dataweaver Lang


Re: a junction or not

2009-03-17 Thread Jon Lang
Larry Wall wrote:
 I think I've mentioned before that .perl autothreads.  It's the final
 (low-level) stringification of a junction that slaps the appropriate
 quantifier around that, I suspect.

Please bear with me; I'm starting to get a little lost: are you
telling me that $j.perl does what I'd expect of an indeterminate item,
and that the trick is in getting a perlization of the Junction itself?
 If so, cool.

 So maybe $j.Str returns the
 eigenstring, while prefix:~ autothreads.  Or maybe there's a method
 named .eigenstring or some such for use by print and say and anyone
 else who absolutely must end up with something printable.

Or maybe there's a method that returns a frozen reference that
masquerades as the Junction, but doesn't trigger autothreading.  Or
would that be opening up an infinitely regressing can of worms?  I
don't know; I've got this gut feeling that something's off here, but I
can't quite put my finger on what it is.

Although, maybe I can.  As written (I believe), .perl generates a
String representation of whatever code is needed to build the object
that called it.  However, there may come a point somewhere down the
road where you'll want .perl to instead return a parse-tree of that
code, with the ability to stringify appropriately.  If you've written
a separate .eigenstring function to perform the same purpose with
Junctions, or you've set it up so that prefix:~ autothreads while
Junction.Str returns the eigenstring, that will potentially be two
functions that will need to be rewritten.

More generally, a programmer who writes a function that operates on an
Object (and thus autothreads when given a Junction) will be forced to
decide between writing a second Junction-aware version if he wants to
treat the Junction as a Junction instead of autothreaded Objects, or
not bothering and thus not allowing the function to manipulate a
Junction directly.  In short, you have to reinvent the wheel every
time the to Junction or not to Junction question arises.  Providing
a means to momentarily disable a Junction's autothreading properties
would, in one fell swoop, solve every instance of this problem.  At
least, I think it would.  If it wouldn't, it would at least solve a
large swath of them.

-- 
Jonathan Dataweaver Lang


Re: a junction or not

2009-03-17 Thread Jon Lang
Darren Duncan wrote:

 Jon Lang wrote:

 Darren Duncan wrote:
 I would assume that invoking .perl on a Junction would result in Perl
 code
 consisting of the appropriate any/all/etc expression. -- Darren Duncan

 Tough to parse, though; and feels like a kludge.  I expect better of Perl
 6.

 What do you mean by tough to parse and feels like a kludge?

If I'm understanding Larry correctly, then given:

my $choice = any(1..10);

$choice.perl will return the same thing that the following would:

any($choice.eigenstates.«perl)

That is, it would return a Junction of Str, not a Str.  So the
question is how to get something that returns an expression to the
effect of:

'any(' ~ $choice.eigenstates.«perl.join(',') ~ ')'

Or, if I'm reading Larry incorrectly and $choice.perl provides the
latter, how do you get the former (without knowing ahead of time that
$choice is an any-junction)?

--

The other question is: given $choice as defined above, how do I find
out which type of junction it is?  Do I somehow call something that
would produce the latter string, and then extract the first word from
it?  Or is there a more direct way to find out which kind of Junction
you're dealing with?

-- 
Jonathan Dataweaver Lang


Re: a junction or not

2009-03-16 Thread Jon Lang
Larry Wall wrote:
 Sigh.  The current design of Junctions is quite extensible *because*
 it is based on a real type.  You can easily write operators that
 work only on Junctions, just as you can easily write operators that
 are transparent to Junctions or autothread on Junctions by declaring
 their arguments to take Object or Any, respectively.

Right; that was the solution to which I was referring.

 That being said, the reason Junctions are there in Perl 6 is primarily
 *linguistic* rather than mathematical; Perl 6 has a Set type because
 we've had this argument already.  Anyone who extends Junctions to
 try to do some kind of set theory is on the road to Perdition, or at
 least the road to Brain Pretzels Without End, amen.

Agreed.  My own concern has nothing to do with set theory; it's in
making sure that there's an easy way to distinguish between method
calls that are supposed to be fielded by the Junction itself (e.g.,
give me perl for the Junction) and method calls that are supposed to
be fielded by the Junction's eigenstates (e.g., give me a Junction of
perls for the eigenstates of this Junction) - bearing in mind that
the Junction _does_ try to stay out of the way and pretend to be (a
superposition of) its individual eigenstates as much as possible.

_That's_ why I suggested pushing its methods into HOW: not to make it
not a type, but rather to ensure that its method calls will never
clobber (or be clobbered by) the method calls of its eigenstates.
This allows the programmer to continue to think of 1 | 2 as an
item, although I'm not sure which one most of the time, and only as
a Junction when it is convenient to do so (i.e., by making his
intent explicit).

The business of referring to it as a meta-type was perhaps an
unfortunate digression from my main point; but I mentioned it to
justify why I would feel comfortable with allowing Junction to put
things in HOW: not only the practical reason that you wouldn't need to
present _another_ HOW-like collection of methods to keep the
Junction's stuff out of the way, but also because Junction _is_ a
strange creature in that it's a collection of items that can usually
be treated as a single (indeterminate) item - and this would highlight
this fact to the programmer, perhaps making the task of understanding
the Junction easier by providing an analogy to another language
feature that has similar properties (i.e., meta-operators).

Admittedly though, this latter reason takes a back seat to the
practicalities.  Bottom line, the goal is to keep Junction's methods
from conflicting with its members' methods.

-- 
Jonathan Dataweaver Lang


Re: Roles driven by events

2009-03-16 Thread Jon Lang
Ovid wrote:
 Requiring methods and requiring methods to be called are different things.  
 It might be a nice feature to have roles which tie into events.  If a 
 particular condition doesn't hold true by, say, INIT time, the role fails.

 How would I implement something like that in Perl 6?  Or am I just looking at 
 this wrong?

AFAICT, event-driven programming hasn't been incorporated into Perl 6
yet.  S17 has mention of an event loop, and S12 speculates on a WHEN
introspective method that would have something to do with events.

-- 
Jonathan Dataweaver Lang


Signature notes and questions

2009-03-16 Thread Jon Lang
OK: as I see it, this is how signatures work:

There are three broad use-cases for signatures: function parameters
(S06), role parameters (S14), and variable declarators (S03).
Question: Do binding operators (S03) count as a fourth use?

There are two broad styles of signatures: those that want an invocant,
and those that don't.  The former includes methods, submethods, and
roles; the latter includes subroutines, regexes, tokens, rules,
macros, and variable declarators.  Signatures that want an invocant
will implicitly add one if none is explicitly specified; signatures
that don't want one will complain if you specify one.

Signature literal syntax: usually, this involves enclosing the
signature between ':(' and ')'.  In variable and function declarators,
you may omit the leading colon; in a pointy-block signature, you must
omit both the colon and the parentheses.  In a role declarator, you
must use square braces instead.  (Questions: why is the pointy-block
exclusion of the enclosing delimiters mandatory?  Why do role
declarators use different enclosing delimiters?)

Variable declarators have no use for longname parameters.  Function
and role declarators do.  (Question: are optional and/or slurpy
parameters excluded from the longname?)

Can attributive parameters be used in methods, or are they exclusive
to submethods?

---

Questions and issues pertaining to absent signatures:

All functions have a default signature of :(*%_, *...@_).  Note that
methods and submethods will implicitly prepend :($?CLASS $self:) to
this.  All roles are parameterized, and have a default signature of
:(Any $?CLASS:).  Variable declarators have no default signatures.
(Question: is it still appropriate to use the '$?' twigil?)

Placeholder variables can be used within bare blocks (but not pointy
blocks) and methods that lack signatures.  Can they be used in any
other function declarators?  If not, why not?  If so, are they
considered to be part of the longname of a named function?
(Doubtful.)  They can't be used in variable declarators for several
reasons, not the least of which is that a variable declarator will
always have an explicit signature.  But can they be used in roles?

Can you have a placeholder variable for a type parameter?

-- 
Jonathan Dataweaver Lang


Re: a junction or not

2009-03-16 Thread Jon Lang
Larry Wall wrote:
 This is basically a non-problem.  Junctions have one public method,
 .eigenstates, which is vanishingly unlikely to be used by accident by
 any mere mortal any time in the next 100 years, give or take a year.
 If someone does happen to be programming quantum mechanics in Perl 6,
 they're probably smart enough to work around the presence of a
 reserved--well, it's not even a reserved word-- a reserved method name.

Actually, the problem isn't with '.eigenstates'; the problem is with
'.perl'.  If I'm viewing a Junction of items as a single indeterminate
item, I'd expect $J.perl to return a Junction of the items' perl by
default.  Admittedly though, even that isn't much of an issue, seeing
as how you _can_ get that result by saying something to the effect of
Junction of $J.eigenstates.«perl - the only tricky part being how to
decide which kind of junction to use (e.g., any, all, one, none) when
putting the perl-ized eigenstates back together.  (And how _would_ you
do that?)  This would represent another corner-case where the
programmer would be tripped up by a simplistic understanding of what a
Junction is; but being a corner-case, that's probably acceptable.

-- 
Jonathan Dataweaver Lang


Re: a junction or not

2009-03-16 Thread Jon Lang
Darren Duncan wrote:
 Jon Lang wrote:
 Larry Wall wrote:
 This is basically a non-problem.  Junctions have one public method,
 .eigenstates, which is vanishingly unlikely to be used by accident by
 any mere mortal any time in the next 100 years, give or take a year.
 If someone does happen to be programming quantum mechanics in Perl 6,
 they're probably smart enough to work around the presence of a
 reserved--well, it's not even a reserved word-- a reserved method name.

 Actually, the problem isn't with '.eigenstates'; the problem is with
 '.perl'.  If I'm viewing a Junction of items as a single indeterminate
 item, I'd expect $J.perl to return a Junction of the items' perl by
 default.  Admittedly though, even that isn't much of an issue, seeing
 as how you _can_ get that result by saying something to the effect of
 Junction of $J.eigenstates.«perl - the only tricky part being how to
 decide which kind of junction to use (e.g., any, all, one, none) when
 putting the perl-ized eigenstates back together.  (And how _would_ you
 do that?)  This would represent another corner-case where the
 programmer would be tripped up by a simplistic understanding of what a
 Junction is; but being a corner-case, that's probably acceptable.

 I would assume that invoking .perl on a Junction would result in Perl code
 consisting of the appropriate any/all/etc expression. -- Darren Duncan

Tough to parse, though; and feels like a kludge.  I expect better of Perl 6.

-- 
Jonathan Dataweaver Lang


Re: a junction or not

2009-03-15 Thread Jon Lang
This isn't the first (or second, or third, or fourth...) time that
I've seen complications arise with regard to junctions.  Every time,
the confusion arises when some variation of the question is it a
junction? is raised.  Ultimately, this is because Perl is trying it's
darnedest to treat Junctions as their members; this is something that
it doesn't try anywhere else, leading to a counterintuitive approach.
The other big example of this phenomenon that I've seen has to do with
passing parameters into a routine: Should the code auto-parallelize,
executing the code separately for each value in the junction, or
should it execute only once, passing the parallelization buck on to
whatever routines it happens to call?  That is, should parallelization
be eager or lazy?  (I'm pretty sure that this was resolved, although
I'm not recalling how.)

The problem that Richard just identified is that Junctions don't fully
manage to hide themselves when it comes to their method calls.  Let's
say that I'm writing a role that deals with quantum mechanics  (say,
Quantum), and for whatever reason I decide that I need an eigenstate
method.  Now we've got a problem: if I ever find myself dealing with a
Junction that has at least one Quantum among its eigenstates, what
happens when I call the .eigenstates method?  I'm betting that I'll
get Junction.eigenstates, rather than a Junction of
Quantum.eigenstates.  In fact, I see no easy way to get the latter.

I'm thinking that maybe Junction shouldn't be a type.  Instead, it
should be a meta-type, in (very rough) analogy to the concept of the
meta-operator.  In particular, Junction bears a certain resemblance to
the hyper-operator.  Thus far, it's the only meta-type; and, like
meta-operators, additional meta-types should be added sparingly.

As I see it, the difference between a type and a meta-type is that all
of the meta-type's methods are accessed via HOW.  You wouldn't say
$x.eigenstates to access a Junction's eigenstates; you'd say
$x.^eigenstates for that.  (Further speculation: maybe there's a
meta-type that defines the default HOW methods.)

That still doesn't solve the problem that Richard first raised,
though.  To do that, I'm thinking that his original suggestion should
also be implemented: in the same way that an item can be treated as a
one-item list for the purposes of list context (and vice versa), a
non-Junction should be able to be treated as a Junction with a single
eigenstate (i.e., a Singleton) for the purposes of junctive semantics.
 That is, $x.^eigenstates === ($x) if $x is not a junction.  Not only
does this reduce the need to test for junctions, but it also makes
that test fairly straightforward: count the eigenstates.  If you only
have one, it isn't a junction.  (Further speculation: perhaps
undefined values have _no_ eigenstates...)

-- 
Jonathan Lang


Re: r25807 - docs/Perl6/Spec

2009-03-14 Thread Jon Lang
On Sat, Mar 14, 2009 at 7:29 AM, Larry Wall la...@wall.org wrote:
 : So if I were to say:
 :
 :     rand $n:
 :
 : is the compiler smart enough to notice that trailing colon and
 : recognize this as an indirect method call rather than two adjacent
 : terms?

 No, currently under STD you get:

    Obsolete use of rand(N); in Perl 6 please use N.rand or (1..N).pick 
 instead at (eval) line 1:

 : Or would I have to say:
 :
 :     rand($n:)
 :
 : to get the indirect method call?

 That would work, but then why not:

    rand*$n
    $n*rand
    $n.rand
    (1..$n).pick

 In fact, given that you usually want to integerize anyway, I could
 almost argue myself out of supporting the $n.rand form as well...

It's largely a matter of principle: if I can say $x.foo, I expect to
be able to say foo $x: as well.  Every time you introduce an exception
to the rule, you're throwing something in that has the potential to
cause confusion; so you should do so with some caution.  I think that
best uses should include something to the effect of avoid using the
same identifier for both a term and a routine.  IMHO, rand should
either be a term or a method; but not both.

There are also some linguistic reasons for this best uses proposal:
people tend to think of terms as nouns and routines as verbs.  And
gerunds are more akin to foo than to term:foo.

Left-field idea here: there was recently some discussion on this list
about the possibility of continuous ranges, which would be in contrast
to how 1..$n is a discrete list of options.  If you were to do this,
then you could use .pick on a continuous range to generate a random
number anywhere within its bounds.  So:

(1 to 5).pick

(where infix:to creates a continuous range, inclusive of both
boundaries) would in theory be as likely to return 2.5 or pi as 3.
IMHO, this does a better job of handling what most people want rand to
do when they start thinking in terms of assigning parameters to it.
And with that in place, rand could become a term that's short for
something like:

pick (0 to^ 1):

-- 
Jonathan Dataweaver Lang


Re: r25807 - docs/Perl6/Spec

2009-03-12 Thread Jon Lang
 +To declare an item that is parsed as a simple term, you must use the
 +form C term:foo , or some other form of constant declaration such
 +as an enum declaration.  Such a term never looks for its arguments,
 +is never considered a list prefix operator, and may not work with
 +subsequent parentheses because it will be parsed as a function call
 +instead of the intended term.  (The function in question may or
 +may not exist.)  For example, Crand is a simple term in Perl 6
 +and does not allow parens, because there is no Crand() function
 +(though there's a C$n.rand method).

So if I were to say:

rand $n:

is the compiler smart enough to notice that trailing colon and
recognize this as an indirect method call rather than two adjacent
terms?  Or would I have to say:

rand($n:)

to get the indirect method call?

-- 
Jonathan Dataweaver Lang


Re: new Capture behavior (Was: Re: r25685 - docs/Perl6/Spec)

2009-03-05 Thread Jon Lang
Daniel Ruoso wrote:
 Daniel Ruoso escreveu:
 What really got me confused is that I don't see what problem this change
 solves, since it doesn't seem that a signature that expects an invocant
 (i.e.: cares about invocant) will accept a call without an invocant, so
 method foo($b,$c) is export still need to have a transformed signature
 in the sub version of foo.

 Thinking again,

 Unless that actually means that we're really removing all the runtime
 semantics around the invocant... and methods implicitly do my $self =
 shift all the time...

 That'd be sad... we loose invocant semantics... SMOP will require a
 HUGE refactoring... :(

Remember that Captures are also being used as Perl 6's answer to
references.  When used in that way, problems arise when you treat a
single item as being fundamentally different from a one-item list.

-- 
Jonathan Dataweaver Lang


Re: new Capture behavior (Was: Re: r25685 - docs/Perl6/Spec)

2009-03-05 Thread Jon Lang
Darren Duncan wrote:
 Here's a question:

 Say I had an N-adic routine where in OO terms the invocant is one of the N
 terms, and which of those is the invocant doesn't matter, and what we really
 want to have is the invocant automatically being a member of the input list.

How about allowing submethods to be declared outside of classes and
roles as well as inside them?  When declared inside a class or role,
it is declared in has scope, and works as described; when declared
elsewhere, it is declared in my scope, and works just like a sub,
except that you're forced to specify an invocant in the signature(s).
You could then use the same sort of tricks that subs can use to
specify alternate signatures, including the one that lets the
positional arguments be filled out in any order.

-- 
Jonathan Dataweaver Lang


Re: new Capture behavior (Was: Re: r25685 - docs/Perl6/Spec)

2009-03-05 Thread Jon Lang
OK; let me get a quick clarification here.  How does:

say Hello, World!;

differ from:

Hello, World!.say;

or:

say $*OUT: Hello, World!;

in terms of dispatching?  And more generally, would there be a
reasonable way to write a single routine (i.e., implementation) that
could be invoked by a programmer's choice of these calling
conventions, without redirects (i.e., code blocks devoted to the sole
task of calling another code block)?

Could you use binding?

my sub say (String *$first, String *...@rest, OStream :$out = $*OUT,
OStream :$err = $*ERR)
{ ... }

role String {
has say:(String $first: String *...@rest, OStream :$out = $*OUT,
OStream :$err = $*ERR)
:= OUTER::say;
}

That (or something like it) might be doable.  But in the spirit of
TIMTOWTDI, I'd like to explore another possibility: what difficulties
would arise from allowing subs to have signatures with invocants,
which in turn allow the sub to be called using method-call syntax
(though possibly not method dispatch semantics)?  In effect, allow
some syntactic sugar that allows properly-sigged subs outside of a
role to masquerade as methods of that role.

-- 
Jonathan Dataweaver Lang


Re: Range and continuous intervals

2009-03-01 Thread Jon Lang
Thomas Sandlaß wrote:
 The benefit of a dedicated Interval type comes from supporting set
 operations (), (|) etc. which are still unmentioned in S03.

Have set operations been implemented in either Rakudo or Pugs?

 BTW,
 what does (1..^5).max return? I think it should be 4 because this
 is the last value in the Range. Only in 4.7 ~~ 1..^5 does the five
 matter. How does ~~ retrieve that information? For open intervals
 the .min and .max methods should return the bound outside. Or better,
 we should introduce infimum and supremum as .inf and .sup respectively.

No offense, but I've noticed a tendency on your part to suggest highly
technical names for things.  Infimum and supremum may be
technically accurate; but I wouldn't know, since I don't know for
certain what they mean.  Min and max may be misleading in terms of
the specifics; but they get the general point across.

 I'm thinking of a Range-alike that one could use with Rat|Num or Instant
 etc, and not just Int etc.  There would be operators to test membership of
 a value in the interval, and set-like operators to compare or combine
 intervals, such as is_inside, is_subset, is_overlap, union, intersection,
 etc.  Such an interval would be what you use for inexact matching and would
 be the result of a ± infix operator or % postfix operator.  Also, as Range
 has a .. constructor, this other type should have something.

 Since the Interval type shall be an addition to the Set subsystem I
 propose the (..) Interval creation operator together with the open
 versions. Admittedly that leaves (^..^) at a lengthy six chars. But
 Jon's proposal of setting the by to zero isn't any shorter. Note that
 the open versions are more important for Interval than they are for Range
 because for Range you can always write it without ^ at the ends.

In defense of my proposal, note that it _can be_ shorter if you say
that :by defaults to zero when the endpoints are of continuous types
such as Num, Instance, or Rat.  That said, I admit that my proposal is
something of a kludge - albeit te type of kludge that Perl tends to
embrace (where reasonable, make a best guess as to the programmer's
intentions; but provide a means gor him to be more explicit if your
guess is wrong).

-- 
Jonathan Dataweaver Lang


Re: Range and continuous intervals

2009-02-28 Thread Jon Lang
Darren Duncan wrote:
 In reply to Jon Lang,

 What I'm proposing here in the general case, is a generic collection type,
 Interval say, that can represent a discontinuous interval of an ordered
 type.  A simple way of defining such a type is that it is a Set of Pair of
 Ordered, where each Pair defines a continuous interval in terms of 2
 ordered end-points, and the whole set is discontinuous (or replace Pair with
 2-element Seq).

Note that you lose the distinction between inclusive and exclusive
endpoints if you do this.  That is one benefit that Range has over
Pair: Range _does_ keep track of whether its endpoints are inclusive
or exclusive.  The main problem with Range is that it is (usually?)
enumerable - which is generally considered to be a feature, but which
gets in the way in the case of using it to represent a continuous
interval.  Thus my suggestion of somehow doing away with the
enumerability if the step size is zero.  As such, I'd be inclined to
define Interval as a Range-like role that isn't enumerable,
representing a continuous span between its lower and upper boundaries.
 A disjoint interval would be a role that usually delegates to an
internal Set of Interval of Type, except when it needs to do otherwise
in order to resemble a Set of Type.

-- 
Jonathan Dataweaver Lang


<    1   2   3   4   >