Function binding and function call evaluation - sml

I have a little trouble understanding the evaluation of function bindings and function calls in SML.
A simple example of a function binding and a function call:
val w = 12;
fun pow(x:int,n:int) =
if n = 0
then 1
else x * pow(x,n-1)
pow((1+1),3);
A little theory:
Formal parameter — the identifier used in a method to stand for the value that is passed into the method by a caller.
In the above function binding, the formal arguments are x and n.
Actual parameter — the actual value that is passed into the method by a caller.
In the function call below, the actual arguments are (1+1) and 3.
My two questions:
1.) When we type-check function bindings, we store, in the static environment, the types of earlier declarations, types of function arguments and the functions type, so it looks something like this:
[w=int, x=int, n=int, pow=int*int->int]
Now to the evaluation. It says here (on slide 6) that the variable "pow" is added to the dynamic environment. I'm a little confused about this. Shouldn't it store the whole function binding, so the dynamic environment would look something like this?
[pow = whole function body]
2.)When we call the function above we pass the actual parameters (1+1) and 3 to the pow function. I've read that after these expressions are evaluated ( 1+1 = 2 and 3 = 3) the values are assigned
to the formal parameters. What type of parameters is then actually used for the evaluation of a function call, if the values are assigned to the formal parameters? By definition, the formal parameters shouldn't have much to do with this.
Thank you in advance for your help.
EDIT: found the page, which says, that the evaluated actual parameters are assigned to the formal parameters in the method's definition.

Adding "pow" to the environment is the same thing as binding its name to its value, i.e. the function itself.
It doesn't make much sense to reason about SML's evaluation model based on some document about Java, but in this case you might say that during evaluation of a function body, the names of the formal parameters are bound to the values of the actual parameters in the environment.

Related

How are quantities referenced in Fortran?

I was told a long time ago that in FORTRAN, everything is passed by value. Therefore I would need to do this (provided mySubroutine is suitably defined elsewhere):
double precision :: myArray(2)
myArray(1:2) = (/ 2.3d0, 1.5d0 /)
CALL mySubroutine(myArray)
However, I also found that the program compiles and runs as expected if I do this
CALL mySubroutine((/ 2.3d0, 1.5d0 /))
without needing to define an intermediary array myArray. I thought that I was passing myArray into mySubroutine by reference. What is going on under the hood in the second version? Is the compiler unpacking the subroutine call, declaring a temporary variable only to pass it by reference?
To a large extent, trying to classify Fortran procedure calling with pass-by-reference and pass-by-value is not too helpful. You can find more detail on that in response to questions like this one and this one.
In short, generally procedure references are such that changes to a variable in a procedure are reflected in the variable where the procedure was referenced. In some cases a compiler may choose to do copy-in/copy-out, and in others it effectively must. Equally, the value attribute of a dummy argument specifies that an anonymous copy be made.
Where this question adds something a little different is in the use of an expression such as in
call mySubroutine([2.3d0, 1.5d0]) ! Using F2003 array constructor syntax
Is the compiler creating a temporary variable?
Admittedly, this is perhaps just a looseness in terminology but it's worth saying that there is certainly no variable involved. [2.3d0, 1.5d0] is an expression, not a variable. Crucially this means that it cannot be modified (appear in a variable definition context) in the procedure. Restrictions that apply in the case using an expression rather than a (temporary) variable include:
the dummy argument associated with an expression may not have the intent(inout) or the intent(out) attribute;
if the dummy argument hasn't an intent attribute then that argument may not be modified if the associated actual argument is an expression.
Now, if the dummy argument has the value attribute the effect of the procedure is the same whichever way it is referenced.
To conclude, the program may work just as well with an expression instead of an intermediate variable. If it doesn't that's because of violation of some aspect of Fortran. How it works is a problem for the compiler not the programmer.

Initializing parameter of a class method with value during declaration C++

I am working on another persons C++ code and don't understand why they did something.
They have a notification class that has a public method called check which takes in the time as a parameter
void check(unsigned long time = 1);
Every time the method is called in the code a current time is passed to it.
notification1.check(currentTime);
My question is why did they give the parameter a value when they defined the method? Why not just say,
void check(unsigned long time);
That's because if no argument if provided in function call, default argument value will be used for time which is 1 in this case. This is called Default Argument
If you call check function and provide no argument, default value of 1 will be assigned to time by the compiler. If you pass an argument while calling check function, that passed value will override the default value of time.
When a function has a default argument passed in to it, you are not required to pass an argument while calling that function and you can specify as many default arguments as you want.
Do you have access to the implementation of check function?
since there is default argument specified in function declaration, you can call it without arguments as well. (ex: notification1.check() ) you should explore what is the behaviour of the check(...) function in each of following scenarios
Function call WITH an argument? (i.e. notification1.check(currentTime))?
Function call WITHOUT argument? (i.e. notification1.check())?
As a best practice of coding, these behaviours has to be documented with the member function declaration. if it is not the case, you'll have to explore the implementation.
It's a default argument. http://en.cppreference.com/w/cpp/language/default_arguments explains all you ever wanted to know about this C++ feature.
My question is why did they give the parameter a value when they defined the method?
If the default argument is not used anywhere, i.e. if the function is always called with a non-default argument, then chances are it was a wrong design decision. Perhaps they thought the default argument was useful when they originally designed the code, but it now turned out that there is no useful default value. Or perhaps they think that the default argument may still be useful in the future.
As a matter of fact, 1 is a questionable value for an unsigned long time parameter, which looks a lot like a value representing milliseconds since January 1st 1970. Why not 0?

passing variable without a name to function

I saw a function written in the following manner:
retVal PreProcessor::TxSlotCB(void *a_pClass, PRE_PARAMS &/*commonParam*/)
{
some code
}
struct PRE_PARAMS
{
uint32_t param1;
uint32_t param2;
};
what is happening in the second parameter? how can it be empty? and is there any way to access to it?
In C++, a formal parameter can be given but anonymous. This means that the actual argument should be given but is not used in the called function.
So it should be given in calling context, it is transmitted, but the called function cannot and does not use it. And the compiler won't give any warnings.
You cannot access it in the body of the function. If you need to access it, change the declaration of the formal parameter to give it some name.
This means that parameter of type PRE_PARAM is not used by this function currently.
So, what happens is when you design a function you decide on the parameters this function would take to fulfill it's purpose.
But later you find that this parameter is not of much significance to this function. However, removing this parameter from function declaration is a tedious job as you have to check for all calls to this function and make sure they confirm to that change.
So, a better way is to not provide the name for argument in function's definition making that parameter redundant.

Why can't I use constexpr with lambda function?

I need an explanation for this. How does lambda differ from others function to it don't be allowed? Is this a nonsense to be not part of C++ standard? for example, I wanted to write a "nested" function in C++ but like it isn't possible to do directly I do use lambda instead of. This function does a very small job: take a single int parameter and multiply with some values and returns. This values are locals to where lambda function is defined and all them are constexpr and know at run-time for this reason I do want to let the compiler put a const value instead of call the function. It's very often used function (that's why I write this as function) and I don't want this beging computed at run-time.
It is because the standard list lambda as non constant expression : "5.19 Constant expressions" … "is a core constant expression unless it involves one of the following as a potentially evaluated subexpression" … "— a lambda-expression (5.1.2);"
That is enough for any compiler to reject constexpr function with a lambda involved.

How do to pass variable number of arguments to a function in c++ with no named parameters

I need to write a function which takes a variable number of arguements, its essentially a wrapper around a snprintf like function. I understand how to do this in general as shown in Passing variable number of arguments around.
How ever it appears that, atleast in C, we are required to pass one named parameter to the function before the variable arguments start( Why is void f(...) not allowed in C? ).
However the answers to the same questions say this is easily possible in C++. I was wondering how to achieve this, especially since the method for handling vararg functions seems to be the same as C(va_start, etc). Or are they referring to variadic templates?
So basically is it possible to write a variadic function with no named arguements, as shown below, and if so, how?
void f(...){
...
}
p.s. I would like to do this with c++03 if possible.
While C++ language allows writing functions whose parameter list consist only of ..., the language provides no means for accessing the arguments in functions declared with (...) parameter list.
Basically such functions in C++ exist for their behavior in overload resolution (... parameters match any parameter type). The body of such function will not have access to the arguments. If you see no uses for such functions, just don't use them.
Such functions are often used in non-executed context in some well-known template meta-programming techniques, in which case they don't even have to be defined - a mere declaration is sufficient.