Home > Uncategorized > You can call me Whatever you like

## You can call me Whatever you like

The docs spend many words to explain in great detail what a `Whatever` is and how to use it from the caller perspective. There are quite a few ways to support `Whatever` as a callee as I shall explain.

`Whatever` can be used to express “all of the things”. In that case we ask for the type object that is `Whatever`.

``````sub gimmi(Whatever) {};
gimmi(*);
``````

Any expression that contains a `Whatever` * will be turned into a thunk. The latter happens to be a block without a local scope (kind of, it can be turned into a block when captured). We can ask specifically for a `WhateverCode` to accept `Whatever`-expressions.

``````sub compute-all-the-things(WhateverCode \$c) { \$c(42) }
say compute-all-the-things(*-1);
say (try say compute-all-the-things({\$_ - 1})) // 'failed';
# OUTPUT: «41␤failed␤»
``````

We could also ask for a `Block` or a `Method` as both come preloaded with one parameter. If we need a `WhateverCode` with more then one argument we have to be precise because the compiler can’t match a Callable sub-signature with a WhateverCode.

``````sub picky(WhateverCode \$c where .arity == 2 || fail("two stars in that expession please") ) {
\$c.(1, 2)
}
say picky(*-*);
# OUTPUT: «-1␤»
say (try picky(*-1)) // \$!;
# OUTPUT: «two stars in that expession please␤  in sub picky at …»
``````

The same works with a `Callable` constraint, leaving the programmer more freedom what to supply.

``````sub picky(&c where .arity == 2) { c(1, 2) }
``````

There are quite a few things a `WhateverCode` can’t do.

``````sub faily(WhateverCode \$c) { \$c.(1) }
say (try faily( return * )) // \$!.^name;
# OUTPUT: «X::ControlFlow::Return␤»
``````

The compiler can take advantage of that and provide compile time errors or get things done a little bit qicker. So trading the flexibility of `Callable` for a stricter `WhateverCode` constraint may make sense.