adding in the Y combinator stuff
Stevan Little [Thu, 17 Aug 2006 15:25:20 +0000 (15:25 +0000)]
Build.PL
MANIFEST
lib/Moose/Autobox.pm
lib/Moose/Autobox/Code.pm
t/006_y_combinator.t [new file with mode: 0644]

index 2b699cb..286ec1f 100644 (file)
--- a/Build.PL
+++ b/Build.PL
@@ -7,7 +7,7 @@ my $build = Module::Build->new(
     license => 'perl',
     requires => {
         'autobox'         => '1.03',
-        'Moose'           => '0.09_02',
+        'Moose'           => '0.11',
         'Perl6::Junction' => '1.10',
     },
     optional => {
index 72a60a2..934932a 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -26,5 +26,6 @@ t/002_role_hierarchy.t
 t/003_p6_example.t
 t/004_list_compressions.t
 t/005_string.t
+t/006_y_combinator.t
 t/pod.t
 t/pod_coverage.t
index c952518..775f6a4 100644 (file)
@@ -166,639 +166,3 @@ This library is free software; you can redistribute it and/or modify
 it under the same terms as Perl itself.
 
 =cut
-
-package Moose::Autobox;
-
-use strict;
-use warnings;
-
-use Carp        qw(confess);
-use Scalar::Util ();
-
-our $VERSION = '0.02';
-                        
-package Moose::Autobox::SCALAR;
-# NOTE:
-# this doesnt make sense, but 
-# I need to prevent Moose from 
-# assiging to @ISA
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Scalar';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::ARRAY;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Array';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::HASH;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Hash';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::CODE;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Code';  
-
-*does = \&Moose::Object::does;            
-                 
-1;
-
-__END__
-
-=pod
-
-=head1 NAME 
-
-Moose::Autobox - Autoboxed for her pleasure
-
-=head1 SYNOPOSIS
-
-  use Moose::Autobox;
-  use autobox;
-  
-  print 'Print squares from 1 to 10 : ';
-  print [ 1 .. 10 ]->map(sub { $_ * $_ })->join(', ');
-
-=head1 CAVEAT
-
-First, a warning.
-
-This module is very very very very very very very experimental. It 
-makes use of a very experimental module (L<autobox>) and uses some 
-shiney new technology (L<Moose::Role>) to accomplish it's goals.
-
-Use this at your own risk. If it breaks the lamp in the living room
-and your mother yells at you, don't come complaining to me.
-
-Also, as this is so experimental, it's API should not be considered 
-to be stable. It could very well change in radical ways.
-
-=head1 DESCRIPTION
-
-Moose::Autobox provides an implementation of SCALAR, ARRAY, HASH
-& CODE for use with L<autobox>. It does this using a hierarchy of 
-roles in a manner similar to what Perl 6 I<might> do. This module, 
-like L<Class::MOP> and L<Moose>, was inspired by my work on the 
-Perl 6 Object Space, and the 'core types' implemented there.
-
-=head2 A quick word about autobox
-
-The L<autobox> module provides the ability for calling 'methods' 
-on normal Perl values like Scalars, Arrays, Hashes and Code 
-references. This gives the illusion that Perl's types are first-class 
-objects. However, this is only an illusion, albeit a very nice one.
-I created this module because L<autobox> itself does not actually 
-provide an implementation for the Perl types but instead only provides 
-the 'hooks' for others to add implementation too.
-
-=head2 Is this for real? or just play?
-
-My intent is to try and make this module as production worthy as 
-possible. This may or may not be possible, depending on how well 
-L<autobox> works out. At this point, I have high hopes for things
-but only time (and more tests and code) will tell.
-
-=head1 ROLES
-
-This is a rough diagram of the roles involved to get our 4 
-autoboxed types (SCALAR, ARRAY, HASH & CODE). 
-                                                          
-  +------------------------+-------------------------------+
-  |  Identity              |  Behavioral                   |
-  +------------------------+-------------------------------+
-  |  Item                  |                               |
-  |      Undef             |                               |
-  |      Defined           |                               |
-  |          Scalar*     <-|- String, Number <--+          |
-  |          Ref           |                    |-- Value  |
-  |              Array*  <-|- List <------------+          |
-  |              Hash*     |                               |
-  |              Code*     |                               |
-  |                        |                               |
-  +------------------------+-------------------------------+
-                                                          
-  * indicates actual autoboxed types
-
-=head1 TODO
-
-=over 4
-
-=item More docs
-
-=item More tests
-
-=back
-  
-=head1 NOTES  
-  
-  - String, Number & List are currently the only 'Value's.
-  
-  - Indexed is pretty much an interface, we probably will 
-    need more of these (see Smalltalk Collection Trait 
-    Refactoring)
-  
-=head1 BUGS
-
-All complex software has bugs lurking in it, and this module is no 
-exception. If you find a bug please either email me, or add the bug
-to cpan-RT.
-
-=head1 AUTHOR
-
-Stevan Little E<lt>stevan@iinteractive.comE<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2006 by Infinity Interactive, Inc.
-
-L<http://www.iinteractive.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-package Moose::Autobox;
-
-use strict;
-use warnings;
-
-use Carp        qw(confess);
-use Scalar::Util ();
-
-our $VERSION = '0.02';
-                        
-package Moose::Autobox::SCALAR;
-# NOTE:
-# this doesnt make sense, but 
-# I need to prevent Moose from 
-# assiging to @ISA
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Scalar';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::ARRAY;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Array';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::HASH;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Hash';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::CODE;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Code';  
-
-*does = \&Moose::Object::does;            
-                 
-1;
-
-__END__
-
-=pod
-
-=head1 NAME 
-
-Moose::Autobox - Autoboxed for her pleasure
-
-=head1 SYNOPOSIS
-
-  use Moose::Autobox;
-  use autobox;
-  
-  print 'Print squares from 1 to 10 : ';
-  print [ 1 .. 10 ]->map(sub { $_ * $_ })->join(', ');
-
-=head1 CAVEAT
-
-First, a warning.
-
-This module is very very very very very very very experimental. It 
-makes use of a very experimental module (L<autobox>) and uses some 
-shiney new technology (L<Moose::Role>) to accomplish it's goals.
-
-Use this at your own risk. If it breaks the lamp in the living room
-and your mother yells at you, don't come complaining to me.
-
-Also, as this is so experimental, it's API should not be considered 
-to be stable. It could very well change in radical ways.
-
-=head1 DESCRIPTION
-
-Moose::Autobox provides an implementation of SCALAR, ARRAY, HASH
-& CODE for use with L<autobox>. It does this using a hierarchy of 
-roles in a manner similar to what Perl 6 I<might> do. This module, 
-like L<Class::MOP> and L<Moose>, was inspired by my work on the 
-Perl 6 Object Space, and the 'core types' implemented there.
-
-=head2 A quick word about autobox
-
-The L<autobox> module provides the ability for calling 'methods' 
-on normal Perl values like Scalars, Arrays, Hashes and Code 
-references. This gives the illusion that Perl's types are first-class 
-objects. However, this is only an illusion, albeit a very nice one.
-I created this module because L<autobox> itself does not actually 
-provide an implementation for the Perl types but instead only provides 
-the 'hooks' for others to add implementation too.
-
-=head2 Is this for real? or just play?
-
-My intent is to try and make this module as production worthy as 
-possible. This may or may not be possible, depending on how well 
-L<autobox> works out. At this point, I have high hopes for things
-but only time (and more tests and code) will tell.
-
-=head1 ROLES
-
-This is a rough diagram of the roles involved to get our 4 
-autoboxed types (SCALAR, ARRAY, HASH & CODE). 
-                                                          
-  +------------------------+-------------------------------+
-  |  Identity              |  Behavioral                   |
-  +------------------------+-------------------------------+
-  |  Item                  |                               |
-  |      Undef             |                               |
-  |      Defined           |                               |
-  |          Scalar*     <-|- String, Number <--+          |
-  |          Ref           |                    |-- Value  |
-  |              Array*  <-|- List <------------+          |
-  |              Hash*     |                               |
-  |              Code*     |                               |
-  |                        |                               |
-  +------------------------+-------------------------------+
-                                                          
-  * indicates actual autoboxed types
-
-=head1 TODO
-
-=over 4
-
-=item More docs
-
-=item More tests
-
-=back
-  
-=head1 NOTES  
-  
-  - String, Number & List are currently the only 'Value's.
-  
-  - Indexed is pretty much an interface, we probably will 
-    need more of these (see Smalltalk Collection Trait 
-    Refactoring)
-  
-=head1 BUGS
-
-All complex software has bugs lurking in it, and this module is no 
-exception. If you find a bug please either email me, or add the bug
-to cpan-RT.
-
-=head1 AUTHOR
-
-Stevan Little E<lt>stevan@iinteractive.comE<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2006 by Infinity Interactive, Inc.
-
-L<http://www.iinteractive.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-package Moose::Autobox;
-
-use strict;
-use warnings;
-
-use Carp        qw(confess);
-use Scalar::Util ();
-
-our $VERSION = '0.02';
-                        
-package Moose::Autobox::SCALAR;
-# NOTE:
-# this doesnt make sense, but 
-# I need to prevent Moose from 
-# assiging to @ISA
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Scalar';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::ARRAY;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Array';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::HASH;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Hash';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::CODE;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Code';  
-
-*does = \&Moose::Object::does;            
-                 
-1;
-
-__END__
-
-=pod
-
-=head1 NAME 
-
-Moose::Autobox - Autoboxed for her pleasure
-
-=head1 SYNOPOSIS
-
-  use Moose::Autobox;
-  use autobox;
-  
-  print 'Print squares from 1 to 10 : ';
-  print [ 1 .. 10 ]->map(sub { $_ * $_ })->join(', ');
-
-=head1 CAVEAT
-
-First, a warning.
-
-This module is very very very very very very very experimental. It 
-makes use of a very experimental module (L<autobox>) and uses some 
-shiney new technology (L<Moose::Role>) to accomplish it's goals.
-
-Use this at your own risk. If it breaks the lamp in the living room
-and your mother yells at you, don't come complaining to me.
-
-Also, as this is so experimental, it's API should not be considered 
-to be stable. It could very well change in radical ways.
-
-=head1 DESCRIPTION
-
-Moose::Autobox provides an implementation of SCALAR, ARRAY, HASH
-& CODE for use with L<autobox>. It does this using a hierarchy of 
-roles in a manner similar to what Perl 6 I<might> do. This module, 
-like L<Class::MOP> and L<Moose>, was inspired by my work on the 
-Perl 6 Object Space, and the 'core types' implemented there.
-
-=head2 A quick word about autobox
-
-The L<autobox> module provides the ability for calling 'methods' 
-on normal Perl values like Scalars, Arrays, Hashes and Code 
-references. This gives the illusion that Perl's types are first-class 
-objects. However, this is only an illusion, albeit a very nice one.
-I created this module because L<autobox> itself does not actually 
-provide an implementation for the Perl types but instead only provides 
-the 'hooks' for others to add implementation too.
-
-=head2 Is this for real? or just play?
-
-My intent is to try and make this module as production worthy as 
-possible. This may or may not be possible, depending on how well 
-L<autobox> works out. At this point, I have high hopes for things
-but only time (and more tests and code) will tell.
-
-=head1 ROLES
-
-This is a rough diagram of the roles involved to get our 4 
-autoboxed types (SCALAR, ARRAY, HASH & CODE). 
-                                                          
-  +------------------------+-------------------------------+
-  |  Identity              |  Behavioral                   |
-  +------------------------+-------------------------------+
-  |  Item                  |                               |
-  |      Undef             |                               |
-  |      Defined           |                               |
-  |          Scalar*     <-|- String, Number <--+          |
-  |          Ref           |                    |-- Value  |
-  |              Array*  <-|- List <------------+          |
-  |              Hash*     |                               |
-  |              Code*     |                               |
-  |                        |                               |
-  +------------------------+-------------------------------+
-                                                          
-  * indicates actual autoboxed types
-
-=head1 TODO
-
-=over 4
-
-=item More docs
-
-=item More tests
-
-=back
-  
-=head1 NOTES  
-  
-  - String, Number & List are currently the only 'Value's.
-  
-  - Indexed is pretty much an interface, we probably will 
-    need more of these (see Smalltalk Collection Trait 
-    Refactoring)
-  
-=head1 BUGS
-
-All complex software has bugs lurking in it, and this module is no 
-exception. If you find a bug please either email me, or add the bug
-to cpan-RT.
-
-=head1 AUTHOR
-
-Stevan Little E<lt>stevan@iinteractive.comE<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2006 by Infinity Interactive, Inc.
-
-L<http://www.iinteractive.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-package Moose::Autobox;
-
-use strict;
-use warnings;
-
-use Carp        qw(confess);
-use Scalar::Util ();
-
-our $VERSION = '0.02';
-                        
-package Moose::Autobox::SCALAR;
-# NOTE:
-# this doesnt make sense, but 
-# I need to prevent Moose from 
-# assiging to @ISA
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Scalar';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::ARRAY;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Array';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::HASH;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Hash';
-
-*does = \&Moose::Object::does;
-
-package Moose::Autobox::CODE;
-use base 'UNIVERSAL';
-use Moose;
-with 'Moose::Autobox::Code';  
-
-*does = \&Moose::Object::does;            
-                 
-1;
-
-__END__
-
-=pod
-
-=head1 NAME 
-
-Moose::Autobox - Autoboxed for her pleasure
-
-=head1 SYNOPOSIS
-
-  use Moose::Autobox;
-  use autobox;
-  
-  print 'Print squares from 1 to 10 : ';
-  print [ 1 .. 10 ]->map(sub { $_ * $_ })->join(', ');
-
-=head1 CAVEAT
-
-First, a warning.
-
-This module is very very very very very very very experimental. It 
-makes use of a very experimental module (L<autobox>) and uses some 
-shiney new technology (L<Moose::Role>) to accomplish it's goals.
-
-Use this at your own risk. If it breaks the lamp in the living room
-and your mother yells at you, don't come complaining to me.
-
-Also, as this is so experimental, it's API should not be considered 
-to be stable. It could very well change in radical ways.
-
-=head1 DESCRIPTION
-
-Moose::Autobox provides an implementation of SCALAR, ARRAY, HASH
-& CODE for use with L<autobox>. It does this using a hierarchy of 
-roles in a manner similar to what Perl 6 I<might> do. This module, 
-like L<Class::MOP> and L<Moose>, was inspired by my work on the 
-Perl 6 Object Space, and the 'core types' implemented there.
-
-=head2 A quick word about autobox
-
-The L<autobox> module provides the ability for calling 'methods' 
-on normal Perl values like Scalars, Arrays, Hashes and Code 
-references. This gives the illusion that Perl's types are first-class 
-objects. However, this is only an illusion, albeit a very nice one.
-I created this module because L<autobox> itself does not actually 
-provide an implementation for the Perl types but instead only provides 
-the 'hooks' for others to add implementation too.
-
-=head2 Is this for real? or just play?
-
-My intent is to try and make this module as production worthy as 
-possible. This may or may not be possible, depending on how well 
-L<autobox> works out. At this point, I have high hopes for things
-but only time (and more tests and code) will tell.
-
-=head1 ROLES
-
-This is a rough diagram of the roles involved to get our 4 
-autoboxed types (SCALAR, ARRAY, HASH & CODE). 
-                                                          
-  +------------------------+-------------------------------+
-  |  Identity              |  Behavioral                   |
-  +------------------------+-------------------------------+
-  |  Item                  |                               |
-  |      Undef             |                               |
-  |      Defined           |                               |
-  |          Scalar*     <-|- String, Number <--+          |
-  |          Ref           |                    |-- Value  |
-  |              Array*  <-|- List <------------+          |
-  |              Hash*     |                               |
-  |              Code*     |                               |
-  |                        |                               |
-  +------------------------+-------------------------------+
-                                                          
-  * indicates actual autoboxed types
-
-=head1 TODO
-
-=over 4
-
-=item More docs
-
-=item More tests
-
-=back
-  
-=head1 NOTES  
-  
-  - String, Number & List are currently the only 'Value's.
-  
-  - Indexed is pretty much an interface, we probably will 
-    need more of these (see Smalltalk Collection Trait 
-    Refactoring)
-  
-=head1 BUGS
-
-All complex software has bugs lurking in it, and this module is no 
-exception. If you find a bug please either email me, or add the bug
-to cpan-RT.
-
-=head1 AUTHOR
-
-Stevan Little E<lt>stevan@iinteractive.comE<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2006 by Infinity Interactive, Inc.
-
-L<http://www.iinteractive.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
index 0dabc53..e19ee54 100644 (file)
@@ -32,6 +32,16 @@ sub conjoin {
        return sub { $f->(@_) && $f2->(@_) }    
 }
 
+sub u {
+    my $f = shift;
+    sub { $f->($f, @_) };
+}
+
+sub y {
+    my $f = shift;
+    (sub { my $h = shift; sub { $f->(($h->u())->())->(@_) } }->u())->();
+}
+
 #sub dump {
     #my ($self) = @_;
     #require Data::Dump::Streamer;
@@ -51,12 +61,25 @@ Moose::Autobox::Code - the Code role
 =head1 SYNOPOSIS
 
   use Moose::Autobox;
-  use autobox;
   
   my $adder = sub { $_[0] + $_[1] };
   my $add_2 = $adder->curry(2);
   
   $add_2->(2); # returns 4
+  
+  # create a recursive subroutine 
+  # using the Y combinator
+  *factorial = sub {
+      my $f = shift;
+      sub {
+          my $n = shift;
+          return 1 if $n < 2;
+          return $n * $f->($n - 1);
+      }
+  }->y;
+  
+  factorial(10) # returns 3628800
+  
 
 =head1 DESCRIPTION
 
@@ -79,6 +102,14 @@ This is a role to describe operations on the Code type.
 This will take a list of C<@subs> and compose them all into a single 
 subroutine where the output of one sub will be the input of another. 
 
+=item B<y>
+
+This implements the Y combinator.
+
+=item B<u>
+
+This implements the U combinator.
+
 =back
 
 =over 4
@@ -87,6 +118,14 @@ subroutine where the output of one sub will be the input of another.
 
 =back
 
+=head1 SEE ALSO
+
+=over 4
+
+=item L<http://en.wikipedia.org/wiki/Fixed_point_combinator>
+
+=back
+
 =head1 BUGS
 
 All complex software has bugs lurking in it, and this module is no 
diff --git a/t/006_y_combinator.t b/t/006_y_combinator.t
new file mode 100644 (file)
index 0000000..aea470e
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 3;
+use Test::Exception;
+
+BEGIN {
+    use_ok('Moose::Autobox');
+}
+
+use Moose::Autobox;
+
+# we need a control in the experiment
+sub fact {
+    my $n = shift;
+    return 1 if $n < 2;
+    return $n * fact($n - 1);
+}
+
+*fact2 = sub {
+    my $f = shift;
+    sub {
+        my $n = shift;
+        return 1 if $n < 2;
+        return $n * $f->($n - 1);
+    }
+}->y;
+
+*fact3 = sub {
+    my $f = shift;
+    sub {
+        my $n = shift;
+        return 1 if $n < 2;
+        return $n * ($f->($f))->($n - 1);
+    }
+}->u;
+
+is(fact(10), fact2(10), '... our factorials match');
+is(fact(10), fact3()->(10), '... our factorials match');
+