From: Stevan Little Date: Thu, 17 Aug 2006 15:25:20 +0000 (+0000) Subject: adding in the Y combinator stuff X-Git-Tag: 0_03~6 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=bb5a920e543934195a1c4c236ed63183aaa0615d;p=gitmo%2FMoose-Autobox.git adding in the Y combinator stuff --- diff --git a/Build.PL b/Build.PL index 2b699cb..286ec1f 100644 --- 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 => { diff --git a/MANIFEST b/MANIFEST index 72a60a2..934932a 100644 --- 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 diff --git a/lib/Moose/Autobox.pm b/lib/Moose/Autobox.pm index c952518..775f6a4 100644 --- a/lib/Moose/Autobox.pm +++ b/lib/Moose/Autobox.pm @@ -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) and uses some -shiney new technology (L) 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. It does this using a hierarchy of -roles in a manner similar to what Perl 6 I do. This module, -like L and L, 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 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 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 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 Estevan@iinteractive.comE - -=head1 COPYRIGHT AND LICENSE - -Copyright 2006 by Infinity Interactive, Inc. - -L - -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) and uses some -shiney new technology (L) 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. It does this using a hierarchy of -roles in a manner similar to what Perl 6 I do. This module, -like L and L, 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 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 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 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 Estevan@iinteractive.comE - -=head1 COPYRIGHT AND LICENSE - -Copyright 2006 by Infinity Interactive, Inc. - -L - -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) and uses some -shiney new technology (L) 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. It does this using a hierarchy of -roles in a manner similar to what Perl 6 I do. This module, -like L and L, 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 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 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 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 Estevan@iinteractive.comE - -=head1 COPYRIGHT AND LICENSE - -Copyright 2006 by Infinity Interactive, Inc. - -L - -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) and uses some -shiney new technology (L) 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. It does this using a hierarchy of -roles in a manner similar to what Perl 6 I do. This module, -like L and L, 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 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 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 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 Estevan@iinteractive.comE - -=head1 COPYRIGHT AND LICENSE - -Copyright 2006 by Infinity Interactive, Inc. - -L - -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. - -=cut diff --git a/lib/Moose/Autobox/Code.pm b/lib/Moose/Autobox/Code.pm index 0dabc53..e19ee54 100644 --- a/lib/Moose/Autobox/Code.pm +++ b/lib/Moose/Autobox/Code.pm @@ -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 + +This implements the Y combinator. + +=item B + +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 + +=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 index 0000000..aea470e --- /dev/null +++ b/t/006_y_combinator.t @@ -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'); +