Iterative golfing
Lured by the Weekly, I went on twitter and lost an hour because lizmat could not resist.
sub sc($str) {
$str.words.map({
.comb(2).map({
.chars == 1 ?? .lc !! .lc.flip.tc.flip
} ).join
}).join(" ")
}
say sc "sarcasmcase FOR YOU";
# sArCaSmCaSe fOr yOu
That’s nice and short but in my eyes, showing off on twitter should involve more Raku features. My first shot as follows.
sub sc($_) {
.words».&{
my @c = &uc, &lc;
.comb».map({ @c = @c[1..*,0].flat; @c[0]($_); }).join
}.flat;
}
I’m trying to use a functional approach by building a list of functions and then rotating that list while I apply the first element in that list. Thus, &lc
and &uc
are called alternating. That works but looks a bit line noisy.
sub sc($_) {
my \c = (|(&lc, &uc) xx *).cache;
.words».&{ (.comb Z c.clone).map( -> ($c, &c) { c($c) }).join }.flat;
}
By building an infinite list of functions, I don’t need to mutate that list. Just using Z
will create the right amount of iterators in the background to alternate &lc
and &uc
. I’m still not happy with the map
-part.
sub sc($_) {
.words».&{ (.comb »,» (&lc, &uc)).flat.map({ &^b($^a) }).join }.flat
}
That’s much shorter and I don’t need to build the infinite list of functions by hand any more. Of cause, that list still exists. It is just hidden within the hyper operator. I’m still not happy with the .map
. I’m building a pair of a value and a function-object. If I could .assume
, I would not need the .map
at all.
multi sub infix:<⊙>(&c, +@a) {
&c.assuming(|@a)
}
sub sc($_) {
.words».&{ ((&lc, &uc) «⊙« .comb)».().join }
}
By turning .assuming
into an infix, I can use it straight in the hyper-operator. The resulting list of .assume
d function can then be called via ».
.
Infix operators allow us to play functional tricks with very few keystrokes. We already got ∘ to combine functions. It may make sense to include ⊙ into CORE too. I’m not sure about its Texas-variant thought. Any suggestions?
I came up with the regex-style `{.lc.&{S:g{\S<(.}=$/.uc}}` or `{S:g{\S<(.}=$/.uc}o&lc`, though I wanted to do `S:g{\S<(.}.=&uc`, but unfortunately you can't use `.=` in that fashion for substitutions. Come join us on code.golf if you feel like doing some more golfing!