Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'master' of https://github.com/perl6/doc
  • Loading branch information
dha committed Oct 8, 2015
2 parents 8b9f93c + 894232a commit 55755e0
Show file tree
Hide file tree
Showing 269 changed files with 1,924 additions and 390 deletions.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Expand Up @@ -19,9 +19,9 @@ in the [#perl6 IRC channel](http://perl6.org/community/irc).

## Documenting types

The POD documentation of types is located in the `lib/Type` directory and
The POD documentation of types is located in the `doc/Type` directory and
subdirectories of this repository. For example the POD of `X::Bind::Slice`
lives in `lib/Type/X/Bind/Slice.pod`.
lives in `doc/Type/X/Bind/Slice.pod`.

To start contributing fork and checkout the repository, find the document
you want to improve, commit your changes, and create a pull request. Should
Expand All @@ -33,7 +33,7 @@ with the helper tool `util/new-type.p6`. Say you want to create `MyFunnyRole`:

$ perl6 util/new-type.p6 MyFunnyRole

Fill the documentation file `lib/Type/MyFunnyRole.pod` like this:
Fill the documentation file `doc/Type/MyFunnyRole.pod` like this:

=TITLE role MyFunnyRole

Expand Down
4 changes: 4 additions & 0 deletions Makefile
Expand Up @@ -19,3 +19,7 @@ help:
@echo " html: generate the HTML documentation"
@echo " html-nohighlight: generate HTML documentation without syntax highlighting"
@echo " test: run the test suite"

run:
@echo "Starting local server…"
perl app.pl daemon
1 change: 1 addition & 0 deletions WANTED
Expand Up @@ -25,6 +25,7 @@ API docs:
Functions:
* srand()
* use [probably really important...]
* on (S17)

Miscellaneous:
* Add TODO comments to undocumented items ("=comment TODO") (Have started - dha)
12 changes: 6 additions & 6 deletions bin/p6doc
Expand Up @@ -27,17 +27,17 @@ sub tempfile() {
}

sub search-paths() {
(findbin() X~ <../doc/perl6/lib/ ../lib/> X~ '',<Type/ Language/ Routine/>),
@*INC.map({CompUnitRepo.new($_)})».IO».Str.map({ /\/$/ ?? $_ !! $_ ~ '/' });
((findbin() X~ <../doc/perl6/lib/ ../lib/> X~ <Type/ Language/ Routine/>).list,
@*INC.map({CompUnitRepo.new($_)})».IO».Str.map({ /\/$/ ?? $_ !! $_ ~ '/' }).list).flat.list;
}

sub module-names(Str $modulename) {
$modulename.split('::').join('/')
X~ '.pm', '.pm6', '.pod';
[$modulename.split('::').join('/')
X~ <.pm .pm6 .pod>].list;
}

sub locate-module(Str $modulename) {
my $m = (search-paths() X~ module-names($modulename)).first: *.IO.f;
my $m = (search-paths() X~ module-names($modulename).list).first: *.IO.f;
unless $m.defined {
my $message = join "\n",
"Cannot locate $modulename in any of the following paths:",
Expand Down Expand Up @@ -120,7 +120,7 @@ sub disambiguate-f-search( $docee, %data ) {
my $ndocee = $pref ~ " " ~ $docee;

if %data{$ndocee} {
my @types = %data{$ndocee}.values>>.grep({ $^v ~~ /^ 'Type' / and not $^v ~~ / 'Cool' $ / });
my @types = %data{$ndocee}.values>>.Str.grep({ $^v ~~ /^ 'Type' / and not $^v ~~ / 'Cool' $ / });
%found{$ndocee}.push: @types X~ "." ~ $docee;
}
}
Expand Down
2 changes: 1 addition & 1 deletion bin/p6doc-index
Expand Up @@ -32,7 +32,7 @@ multi sub MAIN('build') {
next unless $lib_path.e;

$lib_path = $lib_path.Str;
my @files := find(:dir($lib_path),:type('file'));
my @files = find(:dir($lib_path),:type('file')).map({.IO});

for @files -> $f {
my $file = $f.path;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
166 changes: 46 additions & 120 deletions lib/Language/containers.pod → doc/Language/containers.pod
Expand Up @@ -80,6 +80,19 @@ is equivalent to
method attr() is rw { $!attr }
}
Scalar containers are transparent to type checks and most kinds of read-only
accesses. A C<.VAR> makes them visible:
my $x = 42;
say $x.^name; # Int
say $x.VAR.^name; # Scalar
And C<is rw> on a parameter requires the presence of a writable Scalar
container:
sub f($x is rw) { say $x };
f 42; # Parameter '$x' expected a writable container, but got Int value
=head2 Binding
Next to assignment, Perl 6 also supports I<binding> with the C<:=> operator.
Expand Down Expand Up @@ -116,7 +129,7 @@ There are a number of positional container types with slightly different
semantics in Perl 6. The most basic one is L<List|/type/List>
It is created by the comma operator.
say (1, 2, 3).WHAT; # (List)
say (1, 2, 3).^name; # List
A list is immutable, which means you cannot change the number of elements
in a list. But if one of the elements happens to be a scalar container,
Expand Down Expand Up @@ -154,11 +167,12 @@ the same thing: discard the old value(s), and enter some new value(s).
Nevertheless, it's easy to observe how different they are:
my $x = 42; say $x.WHAT; # (Int)
my @a = 42; say @a.WHAT; # (Array)
my $x = 42; say $x.^name; # Int
my @a = 42; say @a.^name; # Array
This is because the C<Scalar> container type hides itself well, but C<Array>
makes no such effort.
makes no such effort. Also assignment to an array variable is coercive, so
you can assign a non-array value to an array variable.
To place a non-C<Array> into an array variable, binding works:
Expand All @@ -182,7 +196,8 @@ at run time).
The answer is that binding to array elements is recognized at the syntax
level and instead of emitting code for a normal binding operation, a special
method on the array is called that knows how to do the binding itself.
method (called C<BIND-KEY>) is called on the array. This method handles binding
to array elements.
Note that, while supported, one should generally avoid directly binding
uncontainerized things into array elements. Doing so may produce
Expand All @@ -200,135 +215,46 @@ a thing happening accidentally.
=head2 Flattening, items and containers
The C<%> and C<@> sigils in Perl 6 generally indicate flattening. Hence
flattening list context iterates over them as if there were no container
boundary:
my @a = 1, 2, 3;
my @b = @a, 4, 5;
say @b.elems; # 5
say @b.join: '|'; # 1|2|3|4|5
Here C<@a> is flattened out in the second line.
The C<%> and C<@> sigils in Perl 6 generally indicate multiple values
to an iteration construct, whereas the C<$> sigil indicates only one value.
Item containers prevent flattening, thus allowing the programmer to write
nested data structures.
my @a = 1, 2 3;
for @a { }; # 3 iterations
my $a = (1, 2, 3);
for $a { }; # 1 iteration
The following examples all do the same and do not flatten:
Contrary to earlier versions of Perl 6, and to Perl 5, C<@>-sigiled variables
do not flatten in list context:
my @a = 1, 2, 3;
my @b = @a.item, 4, 5;
@b = $(@a), 4, 5;
@b = $@a, 4, 5;
@b = [1, 2, 3], 4, 5;
my $item = @a;
@b = $item, 4, 5;
say @b.perl; # Array.new([1, 2, 3], 4, 5);
C<[...]> creates an itemized array, and C<Array.new(...)> a non-itemized
array.
There is a slight exception though: if you call a method on an itemized
container, it will generally behave as if it weren't itemized. So C<[1, 2,
3].join(',')> produces C<"1,2,3"> as a result, as one might hope.
This also means that calling the C<.list> method flattens out an itemized
container:
my $item = [1, 2, 3];
my @b = $item.list, 4, 5; # 5 elems
@b = @($item), 4, 5; # a shortcut
@b = @$item, 4, 5; # another shortcut
Other methods on lists also return flat lists, so for example
my $item = [1, 2, 3];
my @b = $item.sort, 4, 5; # 5 elems
sorts the elements of C<$item> and then returns a list that is flattened out
in the array assignment.
Note that C<.list> de-itemizes only the invocant; it does not recursively
flatten the whole data structure. For example in
my @a = [1, [2, 3, 4]].list;
say @a.elems; # 2
the C<.list> only de-itemizes the outer brackets, the inner ones create an
array that is stored in the second element of the Array and is not touched
by C<.list>.
=head3 Non-flattening contexts
In the examples above, it was always assignment to an array variable that
flattened out non-itemized arrays. However, sometimes you want to preserve
the structure.
The most common case (and one of the reasons for the whole flattening vs.
non-flattening distinction to exist) is to have some list-like operator that
could conceivably return either a flat list, or a list of lists. Consider
the zip operator C<Z>, which takes an element from each list like a zipper:
my @left = <a b c>;
my @right = 1, 2, 3;
my @flat = @left Z @right;
my @tree = (@left Z @right).tree;
The expression C<@left Z @right> returns C<(('a', 1), ('b', 2), ('c', 3))>.
In a flattening context like array assignment, that flattens out into a list
of 6 elements, C<('a', 1, 'b', 2, 'c', 3)>. But if you want to preserve the
structure, you can append C<.tree>, and it returns the array
['a', 1], ['b', 2], ['c', 3]
On the other hand, assigning (or binding) to a scalar preserves the
structure without itemizing any inner arrays or lists:
my $x = (<a b c> Z <D E F>);
say $x.perl; # (("a", "D"), ("b", "E"), ("c", "F")).list.item
Again C<.tree> can turn the inner parcels into "hard", itemized arrays:
say $x.tree.perl; # (["a", "D"], ["b", "E"], ["c", "F"]).list
my @b = @a, 4, 5;
say @b.elems; # 3
What happens when you call C<$x.list>?
There are operations that flatten out sublists that are not inside a scalar
container: slurpy parameters (C<*@a>) and explicit calls to C<flat>:
say $x.list.perl; # (("a", "D"), ("b", "E"), ("c", "F")).list
It just returned the same object without the outer C<.item> container, but
didn't look inside the list. If that's what you want, there is another
utility method called C<flat>:
my @a = 1, 2, 3;
say (flat @a, 4, 5).elems; # 5
say $x.flat.perl # ("a", "D", "b", "E", "c", "F").list
sub f(*@x) { @x.elems };
say f @a, 4, 5; # 5
To reiterate the previous point: C<.list> only removes the itemization (or
scalar container) of the invocant, whereas C<.flat> walks the elements of
the invocant and removes their itemization (note that both methods don't
modify the invocant object; they just return a modified copy).
As hinted above, scalar containers prevent that flattening:
=head3 What flattens, what doesn't?
sub f(*@x) { @x.elems };
say f $@a, 4, 5; # 3
In general, operations that have to iterate the list usually flatten the
list. Other operations don't. Here is a list of a few operations that
flatten:
The C<@> character can also be used as a prefix to remove a scalar container:
=item .map, .grep, .first
=item Iteration with "for"
=item .join
=item assignment to an array variable
=item assignment to a hash variable
my $x = (1, 2, 3);
.say for @$x; # 3 iterations
And a few that don't flatten:
Methods generally don't care whether their invocant is in a scalar, so
=item Indexing with [$idx]
=item .elems
=item .tree
my $x = (1, 2, 3);
$x.map(*.say); # 3 iterations
The first two cannot flatten, otherwise it would be very hard to get access
to the structure that's actually stored in the list and the whole
point of C<.tree> is not to flatten.
maps over a list of three elements, not of one.
=end pod
File renamed without changes.
File renamed without changes.
18 changes: 11 additions & 7 deletions lib/Language/functions.pod → doc/Language/functions.pod
Expand Up @@ -166,30 +166,34 @@ many modules, will follow. These produce a consistent look and feel.
Perhaps the most important of these is the way slurpy list arguments are
handled. Most of the time, functions will not automatically flatten
slurpy lists. The rare exceptions are those functions that don't have a
reasonable behavior on lists of lists, for example, L<chrs|routine/chrs>.
reasonable behavior on lists of lists, for example, L<chrs|routine/chrs>,
or where there is a conflict with an established idiom, like L<pop|routine/pop>
being the inverse of C<push|routine/push>.
If you wish to match this look and feel, any Iterable argument must
be broken out element-by-element using a **@ slurpy, with two nuances:
=item An Iterable inside a L<Scalar container|containers#Scalar_containers|> does not count.
=item Lists created with a L<C<,>|routine/,> at the top level only count as one Iterable.
This can be achieved by defining two multi candidates:
This can be achieved by using a slurpy with a C<+> or C<+@> instead of C<**>:
sub grab (+@a) { "grab $_".say for @a }
...which is shorthand for something very close to:
multi sub grab (**@a) { "grab $_".say for @a }
multi sub grab (\a) {
a ~~ Iterable and a.VAR !~~ Scalar ?? nextwith(|a) !! nextwith(a,)
}
This results in the following behavior, which is known as the "single
argument rule" or "the rule of comma" and is important to understand
when invoking slurpy functions:
argument rule" and is important to understand when invoking slurpy functions:
grab(1,2); # grab 1 grab 2
grab((1,2)); # grab 1 grab 2
grab($(1,2)); # grab 1 2
grab((1,2),3); # grab 1 2 grab 3
grab((1,2),); # grab 1 2
This also makes user-requested flattenning feel consistent whether there is
one sublist, or many:
Expand Down Expand Up @@ -348,7 +352,7 @@ sub circumfix:<START END>(*@elems) {
}
say START 'a', 'b', 'c' END; # start a b c end
=end code;
=end code
Postcircumfixes also receive the term after which they are parsed as
an argument:
Expand Down Expand Up @@ -392,7 +396,7 @@ use C<is equiv(&other-operator)> instead.
=head2 Associativity
When the same operator appears several times in a row, there are multiple
possible interpretation. For example
possible interpretations. For example
1 + 2 + 3
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion lib/Language/grammars.pod → doc/Language/grammars.pod
Expand Up @@ -118,7 +118,7 @@ as an argument.
To make it clear that the argument is a match object, the example uses C<$/>
as a parameter name to the action method, though that's just a handy
convention, nothing intrinsic. C<$match> would have worked too. (Though using
C<$/> does give the advantage of providing C<< $<capture> >>> as a shortcut
C<$/> does give the advantage of providing C<< $<capture> >> as a shortcut
for C<< $/<capture> >>).
A slightly more involved example follows:
Expand Down
File renamed without changes.

0 comments on commit 55755e0

Please sign in to comment.