June 08, 2013
On 6/7/13 5:41 PM, Mrzlga wrote:
> Andrei, what do you think about the unsigned(x) not showing up on greps
> for 'cast'? No problem? Is the grep irrelevant? Not all casts should be
> marked as a cast?
>
> People told me the grepping was important, so I tried to work their idea
> in.
>
>
> I understand, you can still search for:
> "signed(" // signed or unsigned
> "cast(u" // unsigned
> "cast( ... every type ... )" // trying to find signed conversions
>
>
> But I was trying to make the thing more predictable altogether.

Grepping is useful for identifying dangerous patterns. What a dangerous pattern is varies according to the person, but it's not possible to grep for everything that everyone considers dangerous.

Andrei
June 08, 2013
> How about this: if `Foo` is a template with a single type parameter that returns a type, writing `cast(Foo)bar` will be parsed as `cast(Foo!(typeof(bar))bar`.

My proposal has a bad thing about it:

The 'unsigned' and 'signed' keywords can't be as easily extended the way that an signed(x) template in the library can: A library author could just specialize the signed() template to add support for their own numeric type. To do the same with cast(signed) it needs to invoke some signed operator on the type, or use your solution.

I wanted to deal with the cast(int) x; not showing the intention of "signed". If your cast(SomeTemplate) solution can handle this as well, then it's better.

I don't actually mind writing signed(x), but I want to think of a way to discourage people from writing cast(int) x when they are doing nothing but converting unsigned->signed.
June 08, 2013
"doing nothing but converting unsigned->signed" is a dubious statement.

They are still screwing with the range, they are not just "doing nothing but converting unsigned->signed".
And 'int' says something about the outcome.

So I am really asking for:

cast(signed int) x;   // make them poor programmers write this, lol

That's not what I actually want, but at least it shows: We're making a signed conversion, AND we're screwing with the range to make it into an int.

for further thought.
June 08, 2013
I'm against it since we can do it better in library with same efficiency and better UFCS syntax: see https://github.com/timotheecour/dtools/blob/master/dtools/util/cast_funs.d

to test it, nothing to install, just type: rdmd --main -unittest dtools/all.d

here's the unittest:
----
 version(unittest){
    import std.stdio;
    int foo(int x){
        return x;
    }
}
unittest{
    double c;
//    auto b1=cast(int)c.foo;//means cast(int)(c.foo), so would be CT error
    auto b2=(cast(int)c).foo;//verbose syntax: 2 nested parenthesis
    auto b3=c.Cast!int.foo;//simpler syntax

    int a=1;
    auto b=(a+a).Cast!double;
    static assert(is(typeof(b)==double));
    static assert(is(typeof(a.Cast!Immutable)==immutable(int)));
    static assert(is(typeof(a.Cast!Const)==const(int)));
    static assert(is(typeof(0U.Cast!Signed)==int));
    static assert(is(typeof(a.Cast!Unsigned)==uint));
    static assert(is(typeof(a.Cast!Const)==const(int)));
    static assert(is(typeof((a+a).Cast!Unsigned)==uint));
}
----


On Fri, Jun 7, 2013 at 5:43 PM, Mrzlga <bulletproofchest@gmail.com> wrote:

> "doing nothing but converting unsigned->signed" is a dubious statement.
>
> They are still screwing with the range, they are not just "doing nothing
> but converting unsigned->signed".
> And 'int' says something about the outcome.
>
> So I am really asking for:
>
> cast(signed int) x;   // make them poor programmers write this, lol
>
> That's not what I actually want, but at least it shows: We're making a signed conversion, AND we're screwing with the range to make it into an int.
>
> for further thought.
>


June 08, 2013
On Saturday, 8 June 2013 at 00:43:28 UTC, Mrzlga wrote:
> "doing nothing but converting unsigned->signed" is a dubious statement.
>
> They are still screwing with the range, they are not just "doing nothing but converting unsigned->signed".
> And 'int' says something about the outcome.
>
> So I am really asking for:
>
> cast(signed int) x;   // make them poor programmers write this, lol
>
> That's not what I actually want, but at least it shows: We're making a signed conversion, AND we're screwing with the range to make it into an int.
>
> for further thought.

So, you want a syntactic salt that will force people to write `cast(singed int)` instead of `cast(int)` and `cast(unsigned int)` instead of `cast(uint)`?

What if they are not casting from a number? What if I want the ASCII value of a character - for example, `cast(int)'a'`? Will I have to write `cast(signed int)'a'`, or is this syntactic salt just for casting from numeric types?

I'm against this syntactic salt proposal. Programmers should know that `int` is signed and `uint` is unsigend, and I see little point in forcing them to acknowledge that whenever they do a numeric cast.

Also, casting to unsigned with implicit type is dangerous, since cast(uint)-1 == 4294967295 != 18446744073709551615 == cast(ulong)-1, but casting to signed is less dangerous, since it only affects large numbers. So the syntactic salt is more important for `cast(uint)` than for `cast(int)` - but `unit` already clarifies that the type is unsigned.
June 08, 2013
Timothy,

How do you get everyone to use:
    a.Cast!Signed
    a.Cast!Unsigned
    a.Cast!Const
    a.Cast!Immutable
    a.Cast!Shared

And to stop using:
    cast(const)
    cast(immutable)
    cast(shared)
    cast(inout) ?

And have everyone be consistent about it?

Remove the cast() ones from the language?



And what about variations, 'shared const', 'inout shared', etc?

There are some things that should be available to the language, even when no modules are imported. I think dealing with the basic type system is like that.
June 08, 2013
> So, you want a syntactic salt that will force people to write

No, no, I don't actually want the salt. I hoped I had indicated that in my message.

It was only for your consideration about cast(int), how it would be nice to "indicate everything" if there was no price to it.
June 08, 2013
On Fri, Jun 7, 2013 at 6:53 PM, Mrzlga <bulletproofchest@gmail.com> wrote:

> Timothy,
>
> How do you get everyone to use:
>     a.Cast!Signed
>     a.Cast!Unsigned
>     a.Cast!Const
>     a.Cast!Immutable
>     a.Cast!Shared
>
> And to stop using:
>     cast(const)
>     cast(immutable)
>     cast(shared)
>     cast(inout) ?
>
> And have everyone be consistent about it?
>
> Remove the cast() ones from the language?
>

not suggesting deprecating cast(), just suggesting there's no need to extend the language as it can be done in library code, advantageously. It's trivially extensible as I wrote it. However, any language extension has to be re-implemented by each compiler implementation.


> And what about variations, 'shared const', 'inout shared', etc?
>

it's trivial to add to my code a.Cast!"shared const" or a.Cast!SharedConst, etc, as well as more complex ones.


> There are some things that should be available to the language, even when no modules are imported. I think dealing with the basic type system is like that.
>

Not if the syntax sugar provided by the language is no simple than that provided by library solution. I've argued library solution is more consistent with UFCS (see my code).


June 08, 2013
I don't know the story of how D resolved to not provide 'ulong' and 'unsigned long' as equivalent, but I do understand the motivation to keep things short and standard, with 1-word-per-basic-type.

I should say one thing though,

In C / C++:

unsigned x = f();   // this was traumatic. "unsigned" was an actual type itself, not just a type qualifier.
June 08, 2013
not to mention its much harder to implement in language, whereas its trivial in the library. Also, it makes instrumentation easier, if one wants to add a callback/logging/breakpoint for a particular cast operation. Seems much harder with language solution.

On Fri, Jun 7, 2013 at 6:53 PM, Mrzlga <bulletproofchest@gmail.com> wrote:

> Timothy,
>
> How do you get everyone to use:
>     a.Cast!Signed
>     a.Cast!Unsigned
>     a.Cast!Const
>     a.Cast!Immutable
>     a.Cast!Shared
>
> And to stop using:
>     cast(const)
>     cast(immutable)
>     cast(shared)
>     cast(inout) ?
>
> And have everyone be consistent about it?
>
> Remove the cast() ones from the language?
>

not suggesting deprecating cast(), just suggesting there's no need to extend the language as it can be done in library code, advantageously. It's trivially extensible as I wrote it. However, any language extension has to be re-implemented by each compiler implementation.


> And what about variations, 'shared const', 'inout shared', etc?
>

it's trivial to add to my code a.Cast!"shared const" or a.Cast!SharedConst, etc, as well as more complex ones.


> There are some things that should be available to the language, even when no modules are imported. I think dealing with the basic type system is like that.
>

Not if the syntax sugar provided by the language is no simple than that provided by library solution. I've argued library solution is more consistent with UFCS (see my code).