@@ -750,6 +750,119 @@ the JVM. It is an abbreviation of C<Rakuda-do>, which, when translated
750
750
from Japanese, means "The Way of the Camel". Also, in Japanese, "Rakudo"
751
751
means "Paradise."
752
752
753
+ = head1 Reify
754
+ X < |Reify >
755
+
756
+ In English language, L < reify means|http://www.dictionary.com/browse/reify > to
757
+ "to convert into or regard as a concrete thing." Its meaning in Perl 6 is very
758
+ similar, in that conceptual things, like "elements of an infinite list" get
759
+ I < reified > when you try to operate on some of them:
760
+
761
+ # A list containing innfinite number of unreified Fibonacci numbers:
762
+ my @fibonacci = 1, 1, * + * … ∞;
763
+
764
+ # We reify 10 of them, looking up the first 10 of them with array index:
765
+ say @fibonacci[^10]; # OUTPUT: «(1 1 2 3 5 8 13 21 34 55)»
766
+
767
+ # We reify 5 more: 10 we already reified on previous line, and we need to
768
+ # reify 5 more to get the 15th element at index 14. Even though we need only
769
+ # the 15th element, the original Seq still has to reify all previous elements:
770
+ say @fibonacci[14]; # OUTPUT: «987»
771
+
772
+ Above we were reifying a L < Seq > we created with the
773
+ L < sequence operator|/language/operators#index-entry-%E2%80%A6_operators > , but
774
+ other things use the concept as well. For example, an unreified L < Range > is just
775
+ the two end points. In some languages, calculating the sum of a huge range is a
776
+ lengthy and memory-consuming process, but Perl 6 calculates it instantly:
777
+
778
+ say sum 1 ..9_999_999_999_999; # OUTPUT: «49999999999995000000000000»
779
+
780
+ Why? Because the sum can be calculated I < without > reifying the Range; that is
781
+ without figuring out all the elements it contains. This is why this feature
782
+ exists. You can even make your own things you can reify-on-demand, using
783
+ L « C < gather > and C < take > |/syntax/gather%20take» :
784
+
785
+ my $seq = gather {
786
+ say "About to make 1st element"; take 1;
787
+ say "About to make 2nd element"; take 2;
788
+ }
789
+ say "Let's reify an element!";
790
+ say $seq[0];
791
+ say "Let's reify more!";
792
+ say $seq[1];
793
+ say "Both are reified now!";
794
+ say $seq[^2];
795
+
796
+ # OUTPUT:
797
+ # Let's reify an element!
798
+ # About to make 1st element
799
+ # 1
800
+ # Let's reify more!
801
+ # About to make 2nd element
802
+ # 2
803
+ # Both are reified now!
804
+ # (1 2)
805
+
806
+ Following the output above, you can see the print statements I < inside > the
807
+ C < gather > got printed only when we reified the individual elements while looking
808
+ up an element. Also note, the elements got reified just once. When we printed
809
+ the same elements again on the last line of the example, the messages inside
810
+ C < gather > we no longer printed. This is because the construct used
811
+ already-reified elements from the L < Seq > 's cache.
812
+
813
+ Note that above we assigned the C < gather > to a L < Scalar > container (the C < $ >
814
+ sigil), not the L < Positional > one (the C < @ > sigil). The reason is that the
815
+ C < @ > -sigiled variables are I < mostly lazy > . What this means is their
816
+ I < reify the stuff assigned to them > right away I < most of the time > . The only
817
+ time they don't do it is when the items are known to be
818
+ L « C < is-lazy > |/routine/is-lazy» , like our sequence generated with infinity as the
819
+ end point. We we to assign the C < gather > to a C < @ > -variable, the C < say > statements
820
+ inside of it would've been printed right away.
821
+
822
+ Another way to fully-riefy a list, is by calling L « C < .elems > |/routine/elems» on
823
+ it. This is the reason why checking whether a list contains any items is best
824
+ done by using C < .Bool > method (or just using C < if @array { … } > ), since you don't
825
+ need to reify I < all > the elements to find out if there are C < any > of them.
826
+
827
+ There are times where you I < do > want to fully-reify a list before doing something.
828
+ For example, the L « C < IO::Handle.lines > |/type/IO::Handle#method_lines» returns
829
+ a L < Seq > . The following code contains a bug; keeping reification in mind, try to
830
+ spot it:
831
+
832
+ = for code :skip-test
833
+ my $fh = "/tmp/bar".IO.open;
834
+ my $lines = $fh.lines;
835
+ close $fh;
836
+ say $lines[0];
837
+
838
+ We open a L < file handle|/type/IO::Handle > , then assign return of
839
+ L « C < .lines > |/type/IO::Handle#method_lines» to a L < Scalar > variable, so the
840
+ returned L < Seq > does not get reified right away. We then
841
+ L « C < close > |/routine/close» the file handle, and try to print an element from
842
+ C < $lines > .
843
+
844
+ The bug in the code is by the time we reify the C < $lines > L < Seq > on the last
845
+ line, we've I < already closed > the file handle. When the C < Seq's > iterator tries
846
+ to generate the item we've requested, it results in the error about attempting
847
+ to read from a closed handle. So, to fix the bug we can either assign to
848
+ a C < @ > -sigiled variable or call L « C < .elems > |/routine/elems» on C < $lines > before
849
+ closing the handle:
850
+
851
+ = for code :skip-test
852
+ my $fh = "/tmp/bar".IO.open;
853
+ my @lines = $fh.lines;
854
+ close $fh;
855
+ say @lines[0]; # no problem!
856
+
857
+ Also good:
858
+
859
+ = for code :skip-test
860
+ my $fh = "/tmp/bar".IO.open;
861
+ my $lines = $fh.lines;
862
+ say "Read $lines.elems() lines"; #reifying before closing handle
863
+ close $fh;
864
+ say $lines[0]; # no problem!
865
+
753
866
= head1 Repository
754
867
X < |Repository >
755
868
0 commit comments