Discussion Thread: DIP 1030--Named Arguments--Final Review

Steven Schveighoffer schveiguy at gmail.com
Wed May 13 12:15:38 UTC 2020


On 5/13/20 4:17 AM, Jacob Carlborg wrote:
> On 2020-05-12 08:22, Jonathan Marler wrote:

>> A sleep function that takes milliseconds on the other hand could be 
>> helpful:
>>
>> sleep(100);
>> sleep(msecs:100); // helpful
> 
> I disagree. It's much better what we already have. The `sleep` method on 
> `Thread` takes a duration, instead of a specific time unit. The duration 
> is also encoded in its own type:
> 
> Thread.getThis.sleep(100.msecs);
> Thread.getThis.sleep(1.seconds); // this works too

I love the Duration factory functions, one of the best parts of D.

Just wanted to point out here that sleep is a static function, so you 
only need to do Thread.sleep(1.seconds).

I also wanted to say that the example has to do with existing code, not 
specifically the way to sleep in D. The example is *if you have* a sleep 
function that takes milliseconds, as could be in a library other than 
druntime (like say an event library that needs to listen for other 
events for other fibers).

While it might be nice to adjust such a function to take a Duration, 
that would be a breaking change, and simply changing the name to reflect 
better the parameter would be a non-breaking first step.

>> Given that, here are a list of conventions:
>>
>> 2. Common generic parameter names
>>
>> p (generic pointer argument, prefer this over ptr or pointer)
>> s (generic string argument, prefer this over str or string)
>> i (generic integer argument)
> 
> I disagree. I think there are very few cases of APIs where a function 
> expects a truly generic value. It's better to try to encode the purpose 
> or how a value is used in the parameter name. Naming something based on 
> what it is rarely useful, we have a much better system for that, which 
> is the type system :). For example:
> 
> void foo(int* p);
> void foo(int* pointer);
> void foo(int* ptr);
> 
> The signature already contains the information that the parameter is a 
> pointer, no need to encode that in the name, be it `pointer`, `ptr` or 
> `p`.

I agree, but also there's a lack of convincing examples here. I would 
say for pointers or references where data is to be read, `src` is a good 
name, and `dest` is a good name for a pointer to data to be written.

e.g.:

copyTo(T)(ref T src, ref T dest);

Other than that, I can't really imagine that there's any hard rule that 
we need to adhere to -- pointers are passed for various reasons, you 
should identify the purpose with the name.

> There are cases where a function accepts a truly generic value, 
> like a function that can convert any value to a string:
> 
> string toString(T)(T value);
> toString(value: 3);
> 
> But in this case named arguments don't help much and I think it falls 
> under the first category (your example with `floor`). Better to call it 
> like:
> 
> toString(3);
> 3.toString();

Agree.

> Also, we should avoiding having short, abbreviated symbol names (any 
> kind of symbol names, not just parameter names). Although it's worse to 
> have abbreviated names which are part of the API or show up in generated 
> documentation. There are always exceptions, like when abbreviated name 
> is more known and common than the actual full name. Examples are: HTTP, 
> FTP and so on.

HTTP and FTP are acronyms, which in my opinion ARE the full names.

Abbreviations are fine when the abbreviation is unambiguous, like src 
and dest.

One thing that should be added: for overloaded functions, names of 
similar parameters should be the same.

Though I suppose one could select a specific overload for literals using 
naming? Is that something that should be promoted?

e.g.:

double atan(double doubleVal);
real atan(real realVal);

-Steve


More information about the Digitalmars-d mailing list