On 02/04/2012 06:55 PM, Artur Skawina wrote:
On 02/04/12 02:03, Timon Gehr wrote:
On 02/03/2012 11:08 AM, Artur Skawina wrote:
On 02/03/12 00:20, Jonathan M Davis wrote:
in is pointless on value types. All it does is make the function parameter
const, which really doesn't do much for you, and in some instances, is really
annoying. Personally, I see no point in using in unless the parameter is a
reference type, and even then, it's often a bad idea with reference types,
because in is really const scope, and the scope is problematic if you want to
return anything from that variable. It's particularly problematic with arrays,
since it's frequently desirable to return slices of them, and scope (and
therefore in) would prevent that. It's useful in some instances (particularly
with delegates), but I'd use in _very_ sparingly. It's almost always more
trouble than it's worth IMHO.

BTW, scope should have been the default for *all* reference type function
arguments, with an explicit modifier, say "esc", required to let the thing
escape. It's an all-or-nothing thing, just like immutable strings - not using
it everywhere is painful, but once you switch everything over you get the
benefits.

I totally agree. Most function arguments are not escaped. However, it is nice 
that the shortest storage class, 'in', implies scope.

There are currently two problems with using "in": a) the one mentioned, where
using in/scope means you can't (or shouldn't be able to) pass the thing to 
another
function w/o scope marked args, and b) "in" implies "const", which is a problem
because you may want to reassign the argument - a perfectly safe thing to do.
With "const" itself you can use parentheses to limit its scope to not include
the reference itself; the problematic case is the builtin "string" alias, ie
"int f(in string s);" would have to allow reassigning 's' inside the function.


Semi-related quiz:

    immutable(char)[] a = "a";
    const    (char)[] b = "b";

    auto aa = a ~ a;
    auto bb = b ~ b;
    auto ab = a ~ b;

    writeln("aa: ", typeid(aa), "  bb: ", typeid(bb), "  ab: ", typeid(ab));

And the question is: How many people, who have not already been bitten by this,
will give the correct answer to: "What will this program print?"?


I think this is covered in this issue:

http://d.puremagic.com/issues/show_bug.cgi?id=7311

But feel free to open a more specific enhancement/bug report.


There should have been another class, in addition to immutable/const, say 
"uniq".
For cases where an expression results in new unique objects. This class 
implicitly
converts to any of const/immutable and mutates to the new type. IOW

    string a = "a";
    char[] b = "b";

    auto c = a ~ b;  // typeid(c) == (uniq(char)[])

    string d = c; // Fine, "c" is unique and can be safely treated as a string.
                  // But, from now on, "c" is (immutable(char)[]) so:
    char[] e = c; // Fails.

    // And the other way:

    auto f = a ~ b;
    char[] g = f; // OK
    string h = f  // Fails, as f is now a (char[])

No need for unsafe-looking casts, just so that the compiler accepts perfectly 
safe
code, like: "string c = ab;", which would currently fail if used in the above 
quiz,
and has to be written as "string c = cast(string)ab;". [1]

artur

[1] Using a helper template is not different from adding a comment, it only 
serves
to document /why/ the programmer had to something, which is only a workaround 
for
a language/compiler limitation. "Compiler" because at least the simple cases 
could
be silently fixed in a backward compatible way (by not disallowing safe 
conversions).
"Language" because "uniq" would also be useful when the programmer knows it 
applies,
but the compiler can't figure it out by itself.

I am certain we'll get something like this eventually, once the compiler bug count has shrunk sufficiently. It is a natural thing to add.

Reply via email to