Evaluation of APL direct functions - evaluation

Here is a snippet I was testing recently. It takes two diameters (⍺,⍵) and computes the circumference of a circle:
10{(○1×⍺){⍺ ⍵}○1×⍵}10 ⍝ note the brackets around ⍺
31.4159 31.4159
10{○1×⍺{⍺ ⍵}○1×⍵}10
31.4159 98.696
I would like to understand how evaluation of this expression works - why is the first one evaluating correctly and the second one isn't?
I am using Dyalog APL.

You have nested functions. In both cases, the inner function simply returns its right and left argument. In the first case, the left argument to the inner function is the expression (○ 1×⍺), in the second case the left argument to the inner function is simply ⍺, or the unaltered left argument of the outer function -- then entire result of the inner function is multiplied by ○ and by 1.
Note that the argument to the circle function is everything to its right so the 1 x is totally redundant.
In APL, expressions are evaluated right to left. We can say that function applies to everything to its right unless modified by parens. Therefore we could say that in the first expression ○ takes 1 multiplied by everything to its right which is only ⍺ due to the parentheses. But in the second expression ○ takes 1 multiplied by everything to its right which is the result of the inner function.
Furthermore, note that due to scalar extension, you can compute the two numbers with no braces at all:
○10 10
31.415926535898 31.415926535898
More interesting with a different diameters:
○10 15 20
31.415926535898 47.123889803847 62.831853071796

Related

What is ACTUALLY happening with parenthesis '()' in Clojure?

I'm looking for the technical answer answer here. How is Clojure interpreting these symbols? My current working understanding is that the opening paren '(' is a kind of call that calls the succeeding operator on the operands while the closing paren ')' is a terminate that wraps up the previous evaluation and returns the final value generated (whether function or value).
Any and all details on the truth here would be appreciated. I'm looking to go deep here as well as seeing/knowing every level of abstraction along the way. It bugs me to know that I may have some imaginal thinking going on currently.
(foo x1 x2)
is the syntax for calling a special form or var (function or macro).
So the compiler will analyze the form (foo x1 x2) and will check if foo is a special form (if, try, let*, etc.) and if not, the symbol will be resolved to a var in the context of the current namespace. If that var is macro, then macroexpansion will happen, else the call will be treated as a normal function call.
To prevent treating (foo x1 x2) as a function call you can quote the expression: '(foo x1 x2) and then it will just remain a list of symbols.
More info:
https://clojure.org/reference/special_forms
https://clojure.org/reference/macros
You are trying to do too much at once when you say
'(' is a kind of call that calls the succeeding operator on the operands while the closing paren ')' is a terminate that wraps up the previous evaluation and returns the final value generated
The Clojure evaluation model does not assign semantics to characters directly. Instead, evaluation of a Clojure program goes through two broad phases:
First, read the characters in the source file according to the language's lexical rules, yielding a Clojure data structure
Second, evaluate that data structure, according to the language's evaluation rules, yielding a value
So when we write an expression like (+ (* 4 5) 2), what happens? The reader matches up parentheses to create lists, and yields as its result a list of three elements: the symbol +, another list (containing the symbol * and the numbers 4 and 5), and the number 2.
Next we move to evaluate that expression. Notice, crucially, that at this point there is no trace of parentheses. The textual source of the program is no longer material. We're evaluating a list. Of course, if we printed that list, conventionally we would surround it with parentheses, but that does not concern the evaluator. How do we evaluate this list? Well, the evaluation rule for lists is to, first, evaluate each of the components, and then invoke the first component as a function, passing the remaining components as arguments1. So our list of pending tasks is:
Evaluate +
Evaluate (* 4 5)
Evaluate 2
Invoke the result of (1), passing the results of (2) and (3) as arguments
(1), of course, evaluates to the addition function, (2) evaluates (in a similar manner) to the number 20, and (3) evaluates to the number 2 (since numbers evaluate to themselves). Thus, (4) becomes "Invoke the addition function, passing the numbers 20 and 2 as arguments". Of course, the final result is 22.
1 The rule is actually more complicated than this, because of macros, but for functions this suffices.
The other 2 answers are great. The simple summary is:
foo( x1, x2 ) // Java function call
(foo x1 x2) // Clojure function call
In both cases, the compiler will evaluate any nested function calls in x1 or x2 before calling foo on the resulting values.

Data block Fortran 77 clarification

I am trying to access a data block, the way it is define is as follows
DATA NAME /'X1','X2','X3','X4','X5','X6','X7','X8','X9','10','11',00028650
1'12','13','14','15','16','17','18','19','20','21','22','23','24'/ 00028660
The code is on paper. Note this is an old code, the only thing i am trying to do is understand how the array is being indexed. I am not trying to compile it.
The way it is accessed is as follows
I = 0
Loop
I = I + 1
write (06,77) (NAME(J,I),J=1,4) //this is inside a write statement.
end loop //77 is a format statement.
Not sure how it is being indexed, if you guys can shed some light that would be great.
The syntax (expr, intvar=int1,int2[,int3]) widely refers to an implied DO loop. There are several places where such a thing may occur, and an input/output statement is one such place.
An implied DO loop evaluates the expression expr with the do control integer variable intvar sequentially taking the values initially int1 in steps of int3 until the value int2 is reached/passed. This loop control is exactly as one would find in a do loop statement.
In the case of the question, the expression is name(j,i), the integer variable j is the loop variable, taking values between the bounds 1 and 4. [The step size int3 is not provided so is treated as 1.] The output statement is therefore exactly like
write(6,77) name(1,i), name(2,i), name(3,i), name(4,i)
as we should note that elements of the implied loop are expanded in order. i itself comes from the loop containing this output statement.
name here may refer to a function, but given the presence of a data statement initializing it, it must somehow be declared as a rank-2 (character) array. The initialization is not otherwise important.

dot operator order of evaluation in c++

I am reading "C++ Primer (5th Edition)" and I've run in something I'm not sure I understand correctly.
The example is pretty much similar to one they gave in the book. Imagine we have some function that returns string (or any class that has non-static members):
string some_function(par1, par2) {
string str;
// some code
return str;
}
I know that you can use the return value of any function to access its members, i.e. something like this is valid:
auto size = some_function(arg1, arg2).size(); // or whatever member of class
However, since the dot operator . and function call operator () have left to right grouping and same precedence, the above expression should be something like this:
(some_function(arg1, arg2)).size()
I suppose I am right so far? The thing I don't understand here is order of evaluation. Since order of evaluation is not specified for . operator, it means that either some_function(arg1, arg2) or size() will be evaluated first. But how can it evaluate size() first if it doesn't know on which object is it working on? This implies that order of evaluation should be fixed from left to right, but it is not. How is this possible?
Another example is something like this:
cin.get().get();
Again, it seems like first cin.get() should be evaluated before second get() since it won't know on which object is it working, but this doesn't seem to be necessarily the case.
Operators of the same precedence are evaluated according to their associativity, which you correctly observe is left-to-right for the operator group containing the function call and element selection operators. Therefore, yes, given the expression
x = foo().bar();
The order of operations is
x = (((foo()).bar)());
accounting for relative precedence and associativity of all operators involved. No one writes code in that manner, though.
Likewise, given
cin.get().get()
the order of operations is
(((cin.get)()).get)()
, so yes, the precedence rules result in the cin.get() sub-expression being evaluated first, yielding the object to which the second . (and thence the rest of the expression) is applied.

return list of values between parenthesis (10, 20, 30, 40)?

I am working in C++ (not C++/CLI) in Visual Studio 2012.
I don't understand why this code works, I would have expected it to fail at compilation time, but it doesn't even fail at runtime:
double MyClass::MyMethod() const
{
//some code here
return (10, 20, 30, 40);
}
I produced this code by mistake, wasn't on purpose, I noticed the mistake when I was running my Unit Tests. And I am surprised it works. When I run it, it returns 40, the last number on the list.
Can someone explain me what this syntax means and why it works?
This is using the comma operator which will evaluate each expression from left to right but only return the last. If we look at the draft C++ standard section 5.18 Comma operator it says:
A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded value expression (Clause 5).83 Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression.
the linked article gives the most common use as:
allow multiple assignment statements without using a block statement, primarily in the initialization and the increment expressions of a for loop.
and this previous thread Uses of C comma operator has some really interesting examples of how people use the comma operator if you are really curious.
Enabling warning which is always a good idea may have helped you out here, in gcc using -Wall I see the following warning:
warning: left operand of comma operator has no effect [-Wunused-value]
return (10, 20, 30, 40);
^
and then two more of those.
The comma operator is a 'sequence point' in C++, often used to initialise multiple variables in for loops.
So the code is evaluating a series of integers, one at a time, as single expressions. The last of these is the returned value, and the return statement as a whole is equivalent to simply return (40);
the expression (10, 20, 30, 40) is actually a series of 4 expressions separated by , You can use , to separate multiple expressions and the result is the evaluation of the last one.
You have used the , i.e. comma operator
return () is valid.
and so is return (/*valid evaluation*/)
Comma operator returns the last value i.e 40

Explain the difference:

int i=1,2,3,4; // Compile error
// The value of i is 1
int i = (1,2,3,4,5);
// The value of i is 5
What is the difference between these definitions of i in C and how do they work?
Edit: The first one is a compiler error. How does the second work?
= takes precedence over ,1. So the first statement is a declaration and initialisation of i:
int i = 1;
… followed by lots of comma-separated expressions that do nothing.
The second code, on the other hand, consists of one declaration followed by one initialisation expression (the parentheses take precedence so the respective precedence of , and = are no longer relevant).
Then again, that’s purely academic since the first code isn’t valid, neither in C nor in C++. I don’t know which compiler you’re using that it accepts this code. Mine (rightly) complains
error: expected unqualified-id before numeric constant
1 Precedence rules in C++ apply regardless of how an operator is used. = and , in the code of OP do not refer to operator= or operator,. Nevertheless, they are operators as far as C++ is concerned (§2.13 of the standard), and the precedence of the tokens = and , does not depend on their usage – it so happens that , always has a lower precedence than =, regardless of semantics.
You have run into an interesting edge case of the comma operator (,).
Basically, it takes the result of the previous statement and discards it, replacing it with the next statement.
The problem with the first line of code is operator precedence. Because the = operator has greater precedence than the , operator, you get the result of the first statement in the comma chain (1).
Correction (thanks #jrok!) - the first line of code neither compiles, nor is it using the comma as an operator, but instead as an expression separator, which allows you to define multiple variable names of the same type at a time.
In the second one, all of the first values are discarded and you are given the final result in the chain of items (5).
Not sure about C++, but at least for C the first one is invalid syntax so you can't really talk about a declaration since it doesn't compile. The second one is just the comma operator misused, with the result 5.
So, bluntly, the difference is that the first isn't C while the second is.