Perlud...utorial(3pm)

✨ Write your own generators πŸ’–

okay bestie, so this is the Perlude tutorial page β€” it's filed under Perlud...utorial(3pm) in the User Contributed Perl Documentation, and it's literally here to teach you how to write your own generators. let's get into it 🫢


🌸 Write your own generators 🌸

Have you ever missed the shell pipe in Perl? no fr, think about it: it's such a clever operator β€” it streams data from programs to programs on demand, which means nothing ever computes more than the whole stream actually expects, and any part of the pipe can stop the entire stream. iconic behaviour honestly. πŸ’…

seq 1000

that will compute 1000 lines.

seq 1000 | sed 5q

but this one will compute only 5 lines, because sed ends its job right there. and we lowkey miss that in perl 😭. sure, we have grep and map, but they only act on complete arrays. not the same vibe at all.

Perlude comes with all the most common filters, and i doubt you'll be missing one. if you do find one missing: please feedback and i'll probably add it! so your job is writing generators (or using the ones written in Perlude::Stuff and Perlude::Sh). and if you have to write a generic one, please contribute. πŸŽ€

To write them, you have to understand the Perlude conventions. when you're using an iterator, say range 1,4, you have to think about the whole list of potential results. those can be written as

( 1, 2, 3, 4     )
( 1, 2, 3, 4,    )
( 1, 2, 3, 4, () )

so () is used as a list terminator. your iterator must return one scalar per call, and it has to end its work by sending that terminator. as an example:

sub read_file {
    open my $fh, shift;
    sub { <$fh> // () }
}

now you can write

now {say}
    filter {/foo/}
    take 5,
    read_file "test.txt"

which is equivalent to

sed 5q test.txt | grep foo

and not only is it easy to read and write, its behaviour is also the best expected. periodt. πŸ’―

  • it reads one record, uses it, and forgets it before reading the next record. this is a memory friendly behavior ✨
  • whoever's in the pipe can decide to stop it. for example: it's fine for grep to release 3 records only.

Writing unix filters is really easy. also note that filters/generators compositions rules are simple and powerful

G | F => G
F | F => F

if you wrote shell, powershell, perl6 or any other functionnal language, you probably miss it coming back to perl5. no cap.

Basically, on demand lists are just iterators. Perlude is just a pleasant way to deal with them, stealing keywords from haskell Perlude. πŸ’œ

🌈 example 🌈

As example: What are the 5 first naturals containing a 3?

A perl implementation would be:

for
( my $_=0, my $count=0
; $count <= 5
; $_++ )
{ if (/3/) { $count++; say } }

Hard to read ... and worth: nothing is reusable at all 😭

The shell counterpart would be

nat () { while {true} { print $[i++] } }
nat | grep 3 | head -n5

There are things to understand about the shell elegance:

  • there is no need of a counter variable, neither a for loop: head is the single command which handles it for you.
  • the implementation of nat is bare simple: you just focus on your nat problem, you don't care how many elements the filter could need.
  • you added nat to your toolkit, it's much more pain to resuse it in perl ... before Perlude

also, it's easy to create a new function top5 by passsing a an argument to head (looks like a partial application):

top5 () { head -n5 }
contains3 () { grep 3 }
nat | contains3 | top5

No perl builtin provide this power. fr fr. πŸ’€

πŸ‘‘ I can haz nat in perl ? πŸ‘‘

Perlude is a set of functions that takes closures as arguments, and returns others.

nat is the basic closure example:

my $nat = sub { state $x=0; $x++ }

a reusable way to write it would be:

sub nat_from {
    my $x = shift;
    sub { $x++ }
}

sub nat { nat_from 0 }

now you can use Perlude keywords on this functions

sub evens_in { filter { not( $_ % 2 ) } shift }
sub top5 { take 5, shift }

🧚 Other dynamic languages stuff 🧚


πŸ“ Contribute πŸ“

http://github.com/eiro/p5-perlude


ok that's the whole page bestie, go write some generators and slay πŸ’…βœ¨

this whole vibe check was brought to you by perl v5.36.0, dated 2023-02-03 β€” mwah, love u, bye πŸ«ΆπŸŽ€

πŸ“¦ where this page comes from