The other day I was trying to find a way to find all possible combination of
2-4 particular letters of the alphabet (A, C, G, N, T), with repetition. The objective was
to try to build an associative array of letter combinations and the corresponding
ordered string. (See
Sorting characters within a string).
Generating all combinations would usually takes a cartesian cross-product to be
efficient (see
japhy's
post
about that).
I came up with a simple but (very) inefficient method of doing the same thing:
my @strings = (grep /[acgmt]{2}/, ('aa' .. 'tt'),
grep /[acgmt]{3}/, ('aaa' .. 'ttt'),
grep /[acgmt]{4}/, ('aaaa' .. 'tttt'));
This yields exactly what I want, but to the price of a high cost in memory and processing.
The problem is with the
.. operator. The number of elements generated before the
grep by the
.. operator is 361,173. After the
grep you are left
with only 774 "useful" strings. And if you wanted to get all strings up to 5 letters you
would then have to deal with nearly 10,000,000 elements. And things only get worse.
I then began to wonder about the availability of a lazy form of evaluation for expression.
For the uninitiated, lazy evaluation of an expression is delaying evaluation until the
last moment, at which point you may realize that you only need to compute a part of the expression.
The aim here would be to avoid storing the intermediary result of the
.. operator in memory
by applying the
grep directly, as a filter function.
Well, programmers of Perl, rejoice. It seems Perl6 might have a
lazy operator (see
rfc123) that will allow to do exactly this.
With the
lazy operator, we could rewrite the previous piece of code like this:
my @strings = (grep /[acgmt]{2}/, lazy ('aa' .. 'tt'),
grep /[acgmt]{3}/, lazy ('aaa' .. 'ttt'),
grep /[acgmt]{4}/, lazy ('aaaa' .. 'tttt'));
This would causes a lazy list to be passed to the filter function
grep, saving
us from allocating the entire letter combinations array in memory. While this might not be the greatest
example ever, I think it's simple enough to illustrate the possibilities.
Lazy evaluation is (to the best of my knowledge) mostly available in functionnal
programming language. It is a powerful concept that can only reinforce the variety
of Perl idioms you can use to easily solve complex problems.
So everything is good, Perl6 will allow us to be lazy and use
lazy. I can't wait to
see the
impatience and
hubris functions ;-)
Guillaume
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.