Passing $ as a function argument

Neia Neutuladh neia at ikeran.org
Thu Oct 11 01:55:50 UTC 2018


On 10/10/2018 05:01 PM, James Japherson wrote:
> All I'm proposing is to to allow one to escape that syntax to function 
> calls.
> 
> foo(int index)
> {
>     return arr[index];
> }
> 
> and D can support
> 
> foo($-1);
> 
> which simply gets translated in to
> 
> arr[arr.length - 1]

I think you might have a misunderstanding about how $ works.

$ is a variable of type size_t. It's an integer. It is syntactic sugar. 
You can't pass $ as a special value; it's expanded to refer to a 
specific array at compile time, and it's an alias to the .length 
property of that array. In order to pass it to a function, you need an 
array as context.

Right now, the compiler looks at the enclosing index expression and uses 
it to determine the value to pass.

You want it to look into the function you're calling to determine the 
value to pass.

It's obvious what you want it to do in this particular case -- the 
compiler should track where that function parameter is used, find the 
relevant array, and use it to get the length to pass. How about:

   module a;
   extern(C) int foo(int index)
   {
     return someGlobalArray[index];
   }

   module b;
   extern(C) int foo(int index);
   void main() { foo($); }

The compiler doesn't have access to the function body to determine what 
array you're talking about.

Or:

   int foo(int index)
   {
     if (someCondition)
       return someGlobalArray[index];
     else
       return someOtherArray[index];
   }
   foo($);

There are two arrays you could be talking about, potentially of 
different lengths, and the compiler can't tell which you're going to access.

Or:

   int foo(int index)
   {
     int something = index;
     return someGlobalArray[something];
   }

The compiler can't just track how the `index` variable is used; it has 
to track how every variable is used and where it can get its value. This 
gets complicated fast.

Or:

   int foo(int index)
   {
     return std.process.environment["PATH"].split(":")[index];
   }

The compiler has to execute the bulk of this function at runtime in 
order to figure out what value to pass to it.

Your proposal only works in the most trivial cases. Because of that, if 
we made that change, you'd try using it at call sites, then the function 
definition would change slightly and your code would break.

It's generally not good for a programming language to have brittle 
features like that.


More information about the Digitalmars-d mailing list