Skip to content

Implement issue# 10314 (add std.traits.signed). #1341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 4, 2013
Merged

Conversation

jmdavis
Copy link
Member

@jmdavis jmdavis commented Jun 9, 2013

This adds std.traits.signed, since for some reason, we have
std.traits.unsigned but do not have std.traits.signed.

else
{
static assert(T.min != 0, "Bug in either signed or isIntegral");
return cast(Unqual!T) x;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is dead code. It should be removed.

edit:

Nevermind, I read wrong.

@JakobOvrum
Copy link
Member

The documentation does not indicate that it removes const, immutable or shared, which it does.

Integral types are value types with no indirection, so it's not a huge issue, but considering that signed and unsigned exist primarily for generic code to begin with, I can imagine these functions being less than ideal in many situations where type inference or typeof is involved. Would it be a lot of work to make them preserve the type qualifier?

@yebblies
Copy link
Member

yebblies commented Jun 9, 2013

UnsignedTypeOf?

@JakobOvrum
Copy link
Member

I see that we have std.traits.Unsigned and std.traits.Signed which preserve the type qualifier. Maybe we should reuse these for the implementation of unsigned and signed?

@jmdavis
Copy link
Member Author

jmdavis commented Jun 9, 2013

On the whole, I wouldn't expect it to be a big deal to make signed and unsigned return the same level of immutability as was passed in, but with unsigned, it does technically risk breaking existing code that was using auto to hold the return value. I'm not sure that the risk is enough to not make the change, but it is something to consider.

@JakobOvrum
Copy link
Member

Yeah, I understand the concern. Further, signed should behave like unsigned in this manner, so either we change unsigned as well, or implement signed with unsigned's behaviour (which this pull request currently does).

I'd argue that unsigned's current behaviour is a bug and that code that relies on it is most likely wrong already. It is not mentioned in the documentation that type qualifiers are erased. It's also inconsistent with how the similarly named Unsigned and Signed templates work, as they preserve the type qualifier.

It would be most intuitive if:

Returns the corresponding unsigned value for x

Meant immutable(int) becomes immutable(uint) and not uint.

In this interpretation, the behaviour is simply changed to match both the documentation and similar interfaces in the module.

@andralex
Copy link
Member

andralex commented Jun 9, 2013

I think we're stuck with making it remove qualifiers. @jmdavis could you please add that info to the docs with this diff?

One question that comes to mind is moving signed and unsigned to std.conv. We could put std.traits.unsigned on the deprecation path, or leave it as an undocumented alias.

@monarchdodra
Copy link
Collaborator

If we actually go through the trouble of moving them, then it would be better to also take the opportunity to give them the "correct" semantic. Simply going through the effort of moving them, yet doing only half the job seems (sorry) stupid to me.

My stance would be that the current implementation is just bugged, and should simply be fixed with no questions asked.

If we move it, then I think it should be put on a deprecation path. Having undocumented aliases in phobos doesn't help anyone. Either we move it for reals, or we don't do anything.

@andralex
Copy link
Member

andralex commented Jun 9, 2013

If we actually go through the trouble of moving them, then it would be better to also take the opportunity to give them the "correct" semantic. Simply going through the effort of moving them, yet doing only half the job seems (sorry) stupid to me.

s/stupid/odd/

There is reason, unexpectedly :o). It's one thing to have an alias to the same name in a different module; defining distinct unsigned variants, subtly different, in different modules - that's potentially more confusing.

My stance would be that the current implementation is just bugged, and should simply be fixed with no questions asked.

I don't think it's bugged. It has a spec and it implements it. People can easily add qualifiers on the receiver side. Is a qualifier-preserving definition better? Most likely. Is this a disaster? I don't think so.

If we move it, then I think it should be put on a deprecation path. Having undocumented aliases in phobos doesn't help anyone. Either we move it for reals, or we don't do anything.

OK.

@monarchdodra
Copy link
Collaborator

I don't think it's bugged. It has a spec and it implements it.

Maybe not bugged, but what it definitely has is lack of spec. I guess the implementation was free to be implemented around the hole, but at the same time, the user shouldn't rely on something not specified in the spec.

People can easily add qualifiers on the receiver side.

I think that does make a good point actually. Combining both Signed and signed should give the user the power to to anything he/she wants pretty conveniently.

auto s = signed(u); //not qualified
Signed!U s = signed(u); //same qualification
immutbale s = signed(u); //totally qualified

So with proper documentation and rationale, I think keeping it as is should work OK.

@jmdavis
Copy link
Member Author

jmdavis commented Jun 10, 2013

Okay. I updated the documentation and included an example of how to use Signed or Unsigned to retain the same level of constness.

*/
auto signed(T)(T x) if (isIntegral!T)
{
static if (is(Unqual!T == ubyte )) return cast(byte ) x;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this whole static if/else chain be replaced by return cast(SignedTypeOf!T)x;?

@jmdavis
Copy link
Member Author

jmdavis commented Jun 10, 2013

I just updated it so that it takes advantage of Signed and Unsigned.

@monarchdodra
Copy link
Collaborator

So... No use beating around the bush here I say? We either keep signed/unsigned here, and pull this, or we decide to move it to std.conv.

The fact that nobody even noticed that signed was missing would be a good indication that moving them would not be very problematic. On the other hand, given that signed does not exist yet, it would be a shame to include it here, just to deprecate it later.

Let's decide which we do... I'm in favor of putting these in std.conv.

@andralex
Copy link
Member

I'd say move them and leave undocumented aliases in std.traits.

@jmdavis
Copy link
Member Author

jmdavis commented Jun 19, 2013

Okay. I moved signed and unsigned to std.conv and put an undocumented, deprecated alias for unsigned in std.traits.

(e.g from $(D int) to $(D long)).

Note that the result is always mutable even if the original type was const
or immutable. In order to retain the constness, use $(LREF Unsigned).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XREF now though. I think this is the correct syntax?
$(XREF traits,Unsigned)
ditto in signed

This moves std.traits.unsigned to std.conv and adds std.conv.signed,
since for some reason, we have std.traits.unsigned but do not have
std.traits.signed.
@jmdavis
Copy link
Member Author

jmdavis commented Jun 19, 2013

Okay, I fixed the docs.

@jmdavis
Copy link
Member Author

jmdavis commented Jun 23, 2013

Anything left on this?

@monarchdodra
Copy link
Collaborator

Anything left on this?

I have nothing to add.

LGTM.

@jmdavis
Copy link
Member Author

jmdavis commented Jul 4, 2013

Ping?

@9rnsr
Copy link
Contributor

9rnsr commented Jul 4, 2013

LGTM.

9rnsr added a commit that referenced this pull request Jul 4, 2013
Implement issue# 10314 (add std.traits.signed).
@9rnsr 9rnsr merged commit 1b230c3 into dlang:master Jul 4, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants