Don't ask to ask, just ask | |
PerlMonks |
Simulating Perl6 Meta/Hyper operators with pure Functional Programmingby LanX (Saint) |
on Oct 01, 2013 at 16:30 UTC ( [id://1056507]=perlquestion: print w/replies, xml ) | Need Help?? |
LanX has asked for the wisdom of the Perl Monks concerning the following question:
Hi
IntroductionI'm doing a case study to simulate Perl6 -Meta-Operators in Perl5 and I'm stuck with a special when restricting myself to pure FP. See for instance the Cross operator X
can be simulated with
Where X is a function with signature (&;$) which accepts an iterator as second argument and returns an iterator. So in LIST context it produces the whole array in scalar context it just returns a lazy iterator. (i.e. allowing infinite lists) This functions (and similar others) can be nested and produce nice syntactic sugar, for instance the above has the following precedence X {"a","b"} ( X {1..2} ( X {"x","y"} ) ) Here my purely functional implementation so far. (Please note that this is a case study for the API and not optimized for speed. A well designed and tested set of such operators could be optimized and/or reimplemented in XS later, w/o messing with the P5's parser while being as closs as possible to P6 semantics.)
ExtensionPerl6 also allows to use sub-operators which are applied to each combination, like:
this could be simulated by passing a string or a anonymous sub in the last parameter slot.
An operator symbol like '+' would just be looked up and produce something like 'sub {$a+$b}' to be applied.
ProblemOnly the rightmost X has the information about the operation and there is only one slot free to pass an iterator. Is it possible to write the intermediate (and final) iterators in a purely functional way that the operation (here plus) is incapsulated within the logic of the passed iterators? Of course there are ways to cheat with OOP by blessing/tying the iterator-ref and returning the operation with something like $op = $iter->get_op() Another (ugly) way is to check the passed parameters within the iterator $op = $iter->("get_op") One functional solution could be that all nested iterators just call the next one and append the values so far, and the lowest nested iterator encapsulates the operation and adds over all values reduce {$a+$b} @_ and returns the result thru all levels. This approach is less optimal, since it inhibits any benefit from memoization, cause sum($a,$b,$c) = sum($a, sum($b,$c)), so many intermediate results from subtrees could be cached. Memoization would result in an extreme performance boost. I hope my intention is clear now, I don't know there is a solution but it helped talking about it. =) So there are work arounds but I wonder if a purely functional approach with just one passed function is possible...
Cheers Rolf ( addicted to the Perl Programming Language)
updatePS: If you are wondering about the title ... I was in a hurry and my brain entered a German word so s/mit/with/. :)
Back to
Seekers of Perl Wisdom
|
|