I have a function, which depends on calling context and i wanted to use this function as as argument to other function. Surprisingly i discovered that this second
function is called in list context now. I tried force scalar context with +()
but it does not work as i expected. So only way was to call it implicitly with scalar
.
use 5.010;
say first( 1, second( 'y' ) );
say first( 1, +( second( 'y' ) ) );
say first( 1, scalar second( 'y' ) );
sub first {
my $x = shift;
my $y = shift;
return "$x + $y";
}
sub second {
my $y = shift;
if ( wantarray ) {
qw/ array array /;
} else {
'scalar';
}
}
__END__
1 + array
1 + array
1 + scalar
Arguments to function are treated as list, but does it mean that every argument in that list implies list context too? If yes, then why?
And, using scalar
works, but which other ways i have to call this function in scalar context (without intermediate variable)?
In mathematics, an argument of a function is a value provided to obtain the function's result. It is also called an independent variable. , is called a unary function. A function of two or more variables is considered to have a domain consisting of ordered pairs or tuples of argument values.
Note the difference between parameters and arguments: Function parameters are the names listed in the function's definition. Function arguments are the real values passed to the function. Parameters are initialized to the values of the arguments supplied.
Argument Vs. Parameter : Explore the Major Difference between Argument and Parameter. The values that are declared within a function when the function is called are known as an argument. Whereas, the variables that are defined when the function is declared are known as a parameter.
The terms parameter and argument can be used for the same thing: information that are passed into a function. From a function's perspective: A parameter is the variable listed inside the parentheses in the function definition. An argument is the value that are sent to the function when it is called.
Why function arguments induce list context?
Subroutines accept a variable number of scalars as arguments. What other choice is there?
Arguments to function are treated as list, but does it mean that every argument in that list implies list context too? If yes, then why?
Yes. Because you want to be able to build lists from the contents of hashes and arrays. There's a million reason why that's useful.
%h = (%h, ...); # Add to a hash
f( $x, @opts ); # Composing argument lists
etc
using
scalar
works, but which other ways i have to call this function in scalar context (without intermediate variable)?
Kinda.
say first( 1, "".second( 'y' ) ); # Side-effect: stringification
say first( 1, 0+.second( 'y' ) ); # Side-effect: numificatiion
say first( 1, !!second( 'y' ) ); # Side-effect: conversion to boolean
Subrountine prototypes can also enforce scalar context, but they're generally seen as bad for that very reason.
It makes sense that function arguments are evaluated in list context:
In Perl, all subroutines map lists to lists.
If a sub takes a list, it makes sense to evaluate all arguments in list context, which makes functions composable. Consider map
:
map { ... } 1, 2, 3; # makes sense
map { ... } foo(); # can we "return 1, 2, 3" for the same effect?
Should the foo()
be called in scalar context, this would be equivalent to return 3
when we intended to return the list 1, 2, 3
. Using list context enables us to compose list transformations without to many explicit loops. The Schwartzian Transform is a prime example of this:
my @sorted =
map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map { [make_key($_), $_] }
@input;
There are two ways to evaluate an argument in list context:
Use an expression that forces scalar context, like scalar
or scalar operations.
Use prototypes like ($)
. This destroys composability of functions, requires your subroutine to be predeclared, can have confusing semantics, and is action at a distance. Prototypes should therefore be avoided.
Your +(...)
did not force scalar context because unary plus does not impose context. It is commonly used to disambiguate parens (e.g. used for precedence) from a function application, e.g. map +($_ => 2*$_), 1, 2, 3
.
The unary plus is distinct from the binary plus, an arithmetic operator which imposes scalar context on its operands and coerces them to numbers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With