Jump to page: 1 2
Thread overview
small idea
Jan 09, 2013
eles
Jan 09, 2013
SH
Jan 09, 2013
bearophile
Jan 09, 2013
Tim Krimm
Jan 09, 2013
bearophile
Jan 09, 2013
eles
Jan 09, 2013
eles
Jan 09, 2013
eles
Jan 09, 2013
eles
Jan 09, 2013
David Piepgrass
Jan 09, 2013
F i L
Jan 09, 2013
monarch_dodra
Jan 09, 2013
David Nadlinger
Jan 09, 2013
eles
Jan 09, 2013
Ali Çehreli
Jan 09, 2013
Nick Sabalausky
Jan 09, 2013
H. S. Teoh
January 09, 2013
Disclaimer: I do not ask for anything, it is just an idea, do not blame me (too much).

One thing that I really like about a function is to know quite clearly which of its parameters are for input, which for output and, yes, which one are for carrying (input/output parameters).

In D, this is signalled by the in/out/inout keywords. However, these are only visible at the moment of function declaration, not calling.

In C, you usually can distinguish since parameters intended to be modified are passed through address (pointers), and you see that at use time:

void make_a_equal_to_b(&a,b);

In D, it would be:

void make_a_equal_to_b(a,b);

Yes, the name of the function can convey the intention. But, in C, the calling, too. It is a kind of a double check.

Now, what about accepting a quick and optional (to not break existing code) annotation at the time of the call:

void make_a_equal_to_b(??a,!!b); //I give you "b", give me "a"

so that in, out and inout could be replaced by !!, ?? and !?

Alternatives could be: >>, <<, >< but that's more complex.

Non-concordance between !!/!?/?? use and in/out/inout declaration could be sanctioned with a warning or an error, or explicitely ignored through a compiler flag.
January 09, 2013
This is actually one of the things I miss. In C# you have to
specify what direction the variables are traveling in the calling
function.

int a,b=2;

a_eq_b(a,b); // works..
a_eq_b(out a,b); // this would be nice
a_times2(ref a); // same here

void a_eq_b(out int a, int b)
{
   a = b;
}
void a_times2(ref int a)
{
   a *= 2;
}
January 09, 2013
eles:

> void make_a_equal_to_b(??a,!!b); //I give you "b", give me "a"

A saner syntax is just to use the same in/out/inout keywords at the call point, This is essentially what C# does (with one exception for COM):

make_a_equal_to_b(ref a, in b)

This feature was discussed several times in past for D. The advantage is more readability for the code and less surprises. The disadvantages are more typing, some code breakage of D2 code (because even if at the beginning it's a warning, and later a deprecation, you will eventually need to enforce it with an error).

One more small D-specific problem is what to do if the first argument is a ref and you want to use UCFS.

In the end it's one of those features that are borderline, they have both advantages and disadvantages. I generally like languages that are clear and avoid surprises.

Bye,
bearophile
January 09, 2013
On Wednesday, 9 January 2013 at 15:10:47 UTC, bearophile wrote:
> eles:
>

>
> make_a_equal_to_b(ref a, in b)
>
> This feature was discussed several times in past for D. The advantage is more readability for the code and less surprises. The disadvantages are more typing, some code breakage of D2 code (because even if at the beginning it's a warning, and later a deprecation, you will eventually need to enforce it with an error).
>

Why make it a requirement or give a warning.
Just allow the programmer to do it in version 2.x or 3.x.
If it catches on, then start with a warning in version 4.x or whatever.

Note: I would not add this feature if it creates a lot of work for the compiler writers.
January 09, 2013
Tim Krimm:

> Why make it a requirement or give a warning.

If it's not enforced I think it becomes a not useful enough feature.


> Note: I would not add this feature if it creates a lot of work for the compiler writers.

I don't think this is a significant problem.

Bye,
bearophile
January 09, 2013
Yes this has been requested a few times.

I just want to point out that while I like the idea (seeing how well it works in C#), I also think it should be optionally how it is now. There are times when you want to pass and object as ref for optimization only, and aren't actually modifying the value (like Matrix Multiplication for example). In these cases, the way D works right now is nice, because it hides that detail from the end user.

Still, I think 'ref'/'out' should be require at call-site by default, to avoid any gotchas.

I also don't see any problem with UFCS really. I mean, using that syntax is pseudo-OOP and implies the first parameter might be modified in the function.

January 09, 2013
On Wednesday, 9 January 2013 at 14:28:32 UTC, eles wrote:
> In D, this is signalled by the in/out/inout keywords.

Just FYI: This may not be accurate.

For starters, inout has *nothing* to do with in or out. It is used as a wild qualifier: http://dlang.org/function.html#Inout_Functions

"in" means not only that you will read the variable, but that it will be both const and scope. const is *very* restrictive in D.

"out" parameters are first init initialized. This means that if you want to pass a parameter, that the function is supposed to modify, but not necessarily read (such as an appender), then "out" won't work (it will clobber your out parameter first).

So the "general" case where you pass something by value, but mutate it (for example, passing range), then neither "in" nor "out" will work (nor "inout").

January 09, 2013
On Wednesday, 9 January 2013 at 14:28:32 UTC, eles wrote:
> In D, this is signalled by the in/out/inout keywords.

This should be »in/out/ref«, inout only had that meaning in D1.

David
January 09, 2013
On Wednesday, 9 January 2013 at 15:10:47 UTC, bearophile wrote:
> eles:
>
>> void make_a_equal_to_b(??a,!!b); //I give you "b", give me "a"
>
> A saner syntax is just to use the same in/out/inout keywords

True. I was worried that it would be too long to type it. However, if those are made optional, maybe is not a so bad choice, as typing them is not required.

More, they are typed only if the programmer feels the need, somehow like a self-documentation. One that can be checked by the compiler, though.
January 09, 2013
On Wednesday, 9 January 2013 at 15:36:21 UTC, Tim Krimm wrote:
> On Wednesday, 9 January 2013 at 15:10:47 UTC, bearophile wrote:
>> eles:
>>
>
>>
>> make_a_equal_to_b(ref a, in b)
>>
>> This feature was discussed several times in past for D. The advantage is more readability for the code and less surprises. The disadvantages are more typing, some code breakage of D2 code (because even if at the beginning it's a warning, and later a deprecation, you will eventually need to enforce it with an error).
>>
>
> Why make it a requirement or give a warning.

My feeling about such feature is that it is an annotation (read: "intention"), rather than a warning (read: potential misuse) and error (read: "obvious misuse").

I would go for having annotations somewhere on the scale error/warning/annotation/correct in between the warning and correct. That is, a stand-alone language/compile feature and even flag.

« First   ‹ Prev
1 2