Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

263
Views
Unexpected behaviours with Raku lambdas that are supposed to be equal (I guess)

I'm learning Raku as a passion project and I wanted to implement a simple fizzbuzz, why is join only retaining buzz if I write lambdas with pointy blocks?

my $iif =-> $x,$y,$z {if $x {$y} else {$z}}
my $modToString =-> $x,$y,$z {$iif($x%%$y,$z,'')}
my $FB =-> $x {join($modToString($x,3,'fizz'),$modToString($x,5,'buzz'))}
my $logic =-> $x {$iif($FB($x),$FB($x),$x)}
say map(-> $x {$logic($x)}, 1..100)

$modToString(1,3,'fizz')
> 
$modToString(3,3,'fizz')
> fizz
$modToString(3,5,'buzz')
> 
$modToString(5,5,'buzz')
> buzz

If I transform the pointy blocks variables into placeholder variables, Rakudo throws an error:

my $iif = {if $^x {$^y} else {$^z}};
my $modToString = {$iif($^x%%$^y,$^z,'')};
my $FB = {join($modToString($^x,3,'fizz'),$modToString($^x,5,'buzz'))}
my $logic = {$iif($FB($^x),$FB($^x),$^x)}
say map(-> $x {$logic($x)}, 1..100)

Too many positionals passed; expected 1 argument but got 3
  in block  at <unknown file> line 1
  in block  at <unknown file> line 1
  in block  at <unknown file> line 1
  in block  at <unknown file> line 1
  in block <unit> at <unknown file> line 1

If I put the brackets around the join arguments it just outputs the numbers:

my $iif =-> $x,$y,$z {if $x {$y} else {$z}}
my $modToString =-> $x,$y,$z {$iif($x%%$y,$z,'')}
my $FB =-> $x {join(<$modToString($x,3,'fizz'),$modToString($x,5,'buzz')>)}
my $logic =-> $x {$iif($FB($x),$FB($x),$x)}
say map(-> $x {$logic($x)}, 1..100)

Why?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Because lots of things in Raku are blocks, even things that don't look like it. In particular, this includes the "argument" to control flow like if.

if 1 { 2 } else { 3 }

We've actually written two blocks here. One is a constant function returning 2 and the other is a constant function returning 3. Now, usually, this is transparent to us and the Raku engine is smart enough to compile those away. But they're still there. In fact, we can make them explicit. The following behaves identically to the above if statement.

if 1 -> { 2 } else -> { 3 }

In your case, however, it ends up mattering. Anonymous arguments (the ones with the ^ twigil) bind to the innermost block. So you've written

{if $^x {$^y} else {$^z}}

and you intended that it be equivalent to

-> $x, $y, $z {if $x {$y} else {$z}}

but what you actually wrote was

-> $x {if $x -> $y {$y} else -> $z {$z}};

So you've really written a function of one argument and passed it three arguments, as the error message states.

As a broad rule, you can generally assume that anytime you see a {, it either begins a hash literal or a block. And the latter always introduces a scope in which local variables and arguments can exist.

In your particular case, you can use the ternary ??!! operator (this is the same thing as ?: in most other languages like C++ or Java)

{$^x ?? $^y !! $^z}

This operator doesn't short-circuit and doesn't introduce blocks, so it'll work fine.

over 4 years ago · Santiago Trujillo Report

0

Migrating OP's solution from the question to an answer.

After Silvio Mayolo's answer I understood the problem and they also pointed out that I wrote a pointless ternary operator!

I also typed join instead of the tilde! I'm happy to say that my fizzbuzz now works:

my $modToString =-> $x,$y,$z {$x%%$y??$z!!''}
my $FB =-> $x {$modToString($x,3,'fizz')~$modToString($x,5,'buzz')}
my $logic =-> $x {$FB($x)??$FB($x)!!$x}
say map(-> $x {$logic($x)}, 1..100)
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!