Is there a way in a where clause in Rust to check if a function passed as a parameter takes specified arguments?
If you're defining a function that takes a function argument, that argument has a very specific type associated with it that dictates the arguments. You cannot call that function with something that doesn't match, it just won't compile.
If you're thinking in terms of dynamic languages where the arguments are somewhat subjective, you're assuming you can make a mistake here and call it incorrectly. You can't. It's strictly disallowed.
I am a novice with PowerShell.
In Msys2 (or Lnux), I have defined a function npp
npp ()
{
${NPP_PATH} "$#"
}
such that if I call from the command prompt npp it launches Notepad++ (as defined in ${NPP_PATH}).
If I call npp "mydir/stage 1/a.txt" it opens that file for editing.
Generally speaking, it allows:
Any number of parameters.
Parameters containing spaces, if suitably escaped.
What would be the equivalent in PowerShell?
I guess in PS I should also go for a function to obtain a similar behavior.
So far, I could receive an undefined number of parameters, and use them in a foreach loop, see code below.
But I could not find the equivalent of the simple "$#" to pass all parameters as they are received.
Moreover, if I use quotes in one of the arguments, they are removed, so it will probably have problems with file paths including blanks.
function multi_params {
param(
[Parameter(
ValueFromRemainingArguments=$true
)][string[]]
$listArgs
)
$count = 0
foreach($listArg in $listArgs) {
'$listArgs[{0}]: {1}' -f $count, $listArg
$count++
}
}
Assuming that NPP_PATH is an environment variable, the equivalent PowerShell function is:
function npp {
& $env:NPP_PATH $args
}
If NPP_PATH is the name of a regular PowerShell variable, use & $NPP_PATH $args.
& is the call operator, which is needed for syntactic reasons whenever you want to invoke a command whose name/path is specified in quotes and/or via a variable.
In simple functions (as opposed to advanced functions) such as the above (use of neither [CmdletBinding()] nor [Parameter()] attributes), you can use the automatic $args variable to pass any arguments through to another command.
If the target command is not an external program, such as here, but a PowerShell command, use the form #args to ensure that all arguments - including those preceded by their parameter names - are properly passed through - see about_Splatting.
Note that the form #args works with external programs too, where it is generally equivalent to $args (the only difference is that only #args recognizes and removes --%, the stop-parsing token)
Note that passing arguments with embedded " chars. and empty arguments to external programs is still broken as of PowerShell v7.0 - see this answer.
Passing arguments through in simple vs. advanced functions (scripts):
In simple functions only, $args contains all arguments that did not bind to declared parameters, if any, on invocation.
If your simple function doesn't declare any parameters, as in the example above, $args contains all arguments passed on invocation.
If your simple function does declare parameters (typically via param(...)), $args contains only those arguments that didn't bind to declared parameters; in short: it collects any arguments your function did not declare parameters for.
Therefore, $args is a simple mechanism for collecting arguments not declared or known in advance, either to be used in the function itself - notably if declaring parameters isn't worth the effort - or to pass those arguments through to another command.
To pass arguments that comprise named arguments (e.g., -Path foo instead of just foo) through to another PowerShell command, splatting is needed, i.e. the form #args.
Note that while $args is technically a regular PowerShell array ([object[]]), it also has built-in magic to support passing named arguments through; a custom array can not be used for this, and the hash-table form of splatting is then required - see about_Splatting
In advanced functions, $args is not available, because advanced functions by definition only accept arguments for which parameters have been declared.
To accept extra, positional-only arguments, you must define a catch-all ValueFromRemainingArguments parameter, as shown in the question, which collects such arguments in an array-like[1] data structure by default.
To also support named pass-through arguments, you have two basic option:
If you know the set of potential pass-through parameters, declare them as part of your own function.
You can then use splatting with the $PSBoundParameters dictionary (hash table) - see below - to pass named arguments through, possibly after removing arguments meant for your function itself from the dictionary.
This technique is used when writing proxy (wrapper) functions for existing commands; the PowerShell SDK makes duplicating the pass-through parameters easier by allowing you to scaffold a proxy function based on an existing command - see this answer.
Otherwise, there is only a suboptimal solution where you emulate PowerShell's own parameter parsing to parse the positional arguments into parameter-name/value pairs - see this answer.
The automatic $PSBoundParameters variable is a dictionary that is available in both simple and advanced functions:
$PSBoundParameters applies only if your function declares parameters, and contains entries only for those among the declared parameters to which arguments were actually bound (passed) on invocation; the dictionary keys are the parameter names, albeit without the initial -.
Note that parameters bound by a default value are not included - see this GitHub issue for a discussion.
Again, note that in advanced functions you can only pass a given argument if a parameter was declared for it, so any argument passed in a given invocation is by definition reflected in $PSBoundParameters.
Because it is a dictionary (hash table), it can be used with hash-table based splatting - #PSBoundParameters - to pass named arguments through to other PowerShell commands and, since it is mutable, you have the option of adding or removing named arguments (such as the ones intended for your function itself).
[1] That type is [System.Collections.Generic.List[object]]; however, you can specify a collection type explicitly, such as [object[]] to get a regular PowerShell array.
I can't find it by searching, what is define* in guile? You can find it for instance in this answer https://stackoverflow.com/a/24101699/387194
You will find it in the documentation here: Creating advanced argument handling procedures.
6.10.4.1 lambda* and define*.
lambda* is like lambda, except with some extensions to allow optional
and keyword arguments.
library syntax: lambda* ([var…]
[#:optional vardef…]
[#:key vardef… [#:allow-other-keys]]
[#:rest var | . var])
body1 body2 …
Optional and keyword arguments can also have default values to take
when not present in a call, by giving a two-element list of variable
name and expression. For example in
(define* (frob foo #:optional (bar 42) #:key (baz 73))
(list foo bar baz))
foo is a fixed argument, bar is an optional argument with default
value 42, and baz is a keyword argument with default value 73. Default
value expressions are not evaluated unless they are needed, and until
the procedure is called.
Normally it’s an error if a call has keywords other than those
specified by #:key, but adding #:allow-other-keys to the definition
(after the keyword argument declarations) will ignore unknown
keywords.
From:
https://www.gnu.org/software/guile/docs/master/guile.html/lambda_002a-and-define_002a.html#lambda_002a-and-define_002a
In the Scheme standard define* is not defined but the naming convention dictates that any symbol that ends in an asterix will provide very similar operation as the symbol without.
In the standard you have let that binds variables and let* which also binds variables but one at a time so that the created variables are available to the next bindings.
There are SRFIs that are a standard way of extending Scheme. Implementations implement many of the SRFIs native and those who don't can in many cases work with just downloading the reference implementation. SRFI-89 implements define* and lambda* and they provide Scheme with optional positional arguments. Looking at Guile's SRFI support SRFI-89 is not listed but the SRFI-89 itself mentions that Guile has them except it uses the notation #:key instead of #!key, thus not portable.
It's common for R5RS implementations to have more global bindings than the standard. If it's not a part of a SRFI you will be locked in by using such extensions.
I see C books that use the same variable names in the function definition, calling function and declaration. Others use the same variable names in the calling function and in the declaration/prototype but a different one in the definition as in:
void blabla(int something); //prototype
blabla(something) // calling function inside main after something has been initialized to int
void blabla(int something_else) //definition
I have two questions:
What convention is best to use in C?;
Does the convention apply regardless whether a value is being passed "by-value" or if it's being passed by a pointer?
Thanks a lot...
The name used for a function parameter in a function declaration is basically just a comment. It doesn't have any meaning and (as you've noticed) doesn't have to match the function definition. That said, it should be a good descriptive name that tells you what the parameter is for. So why not use the same name in the declaration? If you use a different name and one of the names is better (more descriptive), then you should probably use that name in both places.
This question already has answers here:
What's the difference between an argument and a parameter?
(38 answers)
Closed 10 years ago.
I often find myself confused with how the terms 'arguments' and 'parameters' are used. They seem to be used interchangeably in the programming world.
What's the correct convention for their use?
Parameters are the things defined by functions as input, arguments are the things passed as parameters.
void foo(int bar) { ... }
foo(baz);
In this example, bar is a parameter for foo. baz is an argument passed to foo.
A Parameter is a variable in the declaration of a function:
functionName(parameter) {
// do something
}
An Argument is the actual value of this variable that gets passed to the function:
functionName(argument);
For user1515422, a very concrete example showing the difference between parameters and arguments:
Consider this function:
int divide(int numerator, int denominator) {
return numerator/denominator;
}
It has two parameters: numerator and denominator, set when it's defined. Once defined, the parameters of a function are fixed and won't change.
Now consider an invocation of that function:
int result = divide(8, 4);
In this case, 8 and 4 are the arguments passed to the function. The numerator parameter is set to the value of the argument 8, and denominator is set to 4. Then the function is evaluated with the parameters set to the value of the arguments. You can think of the process as equivalent to:
int divide() {
int numerator = 8;
int denominator = 4;
return numerator/denominator;
}
The difference between a parameter and an argument is akin to the difference between a variable and its value. If I write int x = 5;, the variable is x and the value is 5. Confusion can arise because it's natural to say things like "x is five," as shorthand for "The variable x has the value 5," but hopefully the distinction is clear.
Does that clarify things?
Arguments are what you have when you're invoking a subroutine. Parameters are what you are accessing inside the subroutine.
argle(foo, bar);
foo and bar are arguments.
public static void main(final String[] args) {
args.length;
}
args is a parameter.
There is nice section in parameter Wikipedia article about this subject.
In short -- parameter is the formal name defined by function and argument is actual value (like 5) or thing (like variable) passed into function.
Although Wikipedia is hardly an authoritative source, it does a decent job of explaining the terms.
I guess you could say that parameters are to arguments what classes are to instances of objects...
When you define a function like:
MyFunction(param1,param2) {
print parameter1, parameter
}
You set the parameters when you define the function.
When you call the function like this:
MyFunction('argument1', 'argument2');
You set the values of the parameters to the arguments you passed. The arguments are what you put in the question when you call it. Hope that helped.
Simply there is no major differences. If we go deeply inside this we can identify the diff.Mainly we know that Argument/Parameter/signature all are same.
Basically Parameter defines the type of Data we are passing.Where as the Argument defines the actual data/variable we are passing.
Parameter Example :-
int add(int a,int b){ //Here a and be both can treated as Parameter
return a+b;
}
Argument Example :-
int return_result=add(3,4); // Here 3 and 4 both can treated as Argument
or
int x=3,y=4;
int return_result=add(x,y);// Here x and y both can treated as Argument
In most cases, a procedure needs some information about the circumstances in which it has been called. A procedure that performs repeated or shared tasks uses different information for each call. This information consists of variables, constants, and expressions that you pass to the procedure when you call it.
To communicate this information to the procedure, the procedure defines a parameter, and the calling code passes an argument to that parameter. You can think of the parameter as a parking place and the argument as an automobile. Just as different automobiles can park in the parking place at different times, the calling code can pass a different argument to the same parameter each time it calls the procedure.
Parameters
A parameter represents a value that the procedure expects you to pass when you call it. The procedure's declaration defines its parameters.
When you define a Function or Sub procedure, you specify a parameter list in parentheses immediately following the procedure name. For each parameter, you specify a name, a data type, and a passing mechanism (ByVal or ByRef). You can also indicate that a parameter is optional, meaning the calling code does not have to pass a value for it.
The name of each parameter serves as a local variable within the procedure. You use the parameter name the same way you use any other variable.
Arguments
An argument represents the value you pass to a procedure parameter when you call the procedure. The calling code supplies the arguments when it calls the procedure.
When you call a Function or Sub procedure, you include an argument list in parentheses immediately following the procedure name. Each argument corresponds to the parameter in the same position in the list.
In contrast to parameter definition, arguments do not have names. Each argument is an expression, which can contain zero or more variables, constants, and literals. The data type of the evaluated expression should normally match the data type defined for the corresponding parameter, and in any case it must be convertible to the parameter type.
In fact both parameter and argument are different types of parameters. Those are
1)Formal Parameters - variables appear in function/subroutine definitions
for eg. (in Java)
public void foo(Integer integer, String... s2)
Here both integer and s2 are formal parameters or loosely speaking parameters.
2)Actual parameters or arguments - variables appear in subroutines while calling the
already defined subroutine
for eg. (in Java)
suppose If the function "foo" resides in object "testObject" ,
testObject.foo(new Integer(1), "test")
So variables in the function definition are called formal parameters or simply parameters and variables while calling methods are called as actual parameters or arguments. I hope it helps.
Think of it like basic algebra. X is the parameter that you have to fill in, and the number you place inside of it is the argument. So if you have an equation like X+2, X is your parameter, and any numbers you change for X become known as the arguments. So if using that equation you supplement 1 for x, you get 1+2. That means that 1 is an argument, supplied to the parameter of X.
Equally, if you have a function like dosomething("This"), it's definition would be dosomething(string parametername), but "This" would be the actual argument that is being supplied to the parameter, here named parametername.
In the simplest way to look at it, the parameter is the thing that the argument fills in, and the argument can be any number of things allowed by that parameter.
So it's a many-to-one relationship between Parameters and arguments, as you can have one parameter that can have many valid arguments, like our X+1 equation above. X can be any number known, and they are all valid.
A variable is a storage location and an associated symbolic name (an identifier) which contains data, a value.
A parameter is a variable passed to a function.
An argument is data (a value) passed to a function.
$variable = 'data/value';
function first($variable){ ... }
function second('data/value'){ ... }
function third(16){ ... }
In function first we are passing a parameter.
In function second and third we are passing arguments.