Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

264
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda