On 2015-04-27, Anton Treuenfels <
teamt...@yahoo.com> wrote:
>
> "Aharon Robbins" <
arn...@skeeve.com> wrote in message
> news:mhgmel$4u4$1...@dont-email.me...
>>
>> The documentation says:
>>
>> The syntax is similar to that of a regular function call: an
>> identifier immediately followed by an opening parenthesis, any
>> arguments, and then a closing parenthesis, with the addition of
>> a leading @samp{@@} character:
>>
>> That's pretty clear. numndx[i] is an expression, not a single identifier.
>
> Indeed it is, as is any scalar variable when I assign a string to it. But
> what the documentation implies is that the same character string is being
> used with two different meanings in the same function. Ie.,
>
> {
> i = "myfunction" # here 'i' is a variable name
> @i() # here 'i' is not a variable name
> }
So Gawk is a "Lisp-2", effectively, and @ is something like its funcall
operator.
The dual-namespace Lisp-2 approach has advantages.
One is that you can name local variables without worrying that they shadow
functions that you might use in the same scope.
The second advantage, related to the first, is that you can have a simple
non-hygienic macros system in which macro expansion assume that standard
functions are not shadowed by anything, and only take care of using
"gensyms" in the variable namespace.
In a Lisp-2 like Common Lisp, if we write a macro which uses standard library
functions in its macro expansion, like list, cons and whatever, the only way
there will be a hygiene problem is if the code uses these as the names of local
functions:
(flet ((list () )) ;; local function named list
(some-macro ...)) ;; oops, macro expansion uses list function!
(let ((list '(a b c))) ;; local variable named list
(some-macro ...)) ;; macro expansion uses list; no problem!
In Lisp-1 dialects, hygienic macros are needed to avoid problems like a
variable called list or cons capturing a function. And of course you cannot use
any function name as a variable, if there is a use of that function in the
variable's scope. So for instance Scheme code is littered with "lst"
instead of "list" as a variable name.
> I'm not used to such equivocation. I had imagined that once a variable,
> always a variable, which is why I was dismayed to find
>
> {
> a[i] = "myfunction"
> @a[i]()
> }
>
> does not work.
You're probably also used to a single namespace for functions and variables in
most of the languages you use.
> Which is puzzling to me. Being naive, I had imagined that indirect function
> calls were implemented simply by retrieving the name from the - well, it's
"indirect function call" is a machine-language concept. A call is direct
if the machine language instruction contains the destination address.
A call is indirect if the machine language instruction calculates the
address using run-time data. (With various in-between possibilities, like
an offset from the instruction, plus run-time data: relative jump,
jump indexed through a table, etc.)
Even the fairly low-level language C doesn't have "indirect call" as a concept:
at least not one that is distinguished in the syntax.
f(x, y) is an indirect call if f is a pointer, otherwise a direct call.
This terminology is not used in ISO C, to my recollection.
The abstract semantics of f(x, y) is that even if f is the name of a function,
it first produces a pointer, and then the arguments are applied to the
function pointer to produce a call.
In any case, no special indirection operator is needed to call the pointer.
(In some very old C sources, you sometimes see pointer calls written
like (*f)(x, y). It might have been needed.)
It's ironic if a high level data munging language (loosely based on C) makes
you use some "splat" to indirect on a function, when the underlying C doesn't
itself have that inconvenience. *facepalm*.