Skip to content

Make parseUUID pure#1708

Merged
MartinNowak merged 2 commits intodlang:masterfrom
monarchdodra:UUIDPure
Dec 16, 2013
Merged

Make parseUUID pure#1708
MartinNowak merged 2 commits intodlang:masterfrom
monarchdodra:UUIDPure

Conversation

@monarchdodra
Copy link
Collaborator

http://dlang.org/phobos/std_uuid.html#parseUUID :

BUGS:
Could be pure, but this depends on parse!(string, 16).

I was reading this, and I remembered that recently, parse!(string, 16) was made pure (and safe), so I changed the code accordingly. It now only relies on inference (and a @trusted exception builder).

Tagging @jpf91 .

@jpf91
Copy link
Contributor

jpf91 commented Nov 20, 2013

LGTM.
I guess this constructor:
http://dlang.org/phobos/std_uuid.html#UUID%28string%29
should now work with pure as well?

@monarchdodra
Copy link
Collaborator Author

I guess this constructor: should now work with pure as well?

I missed that. I only did that one function, but I should really check the entire module. I'll do it ASAP (a day or two).

@monarchdodra
Copy link
Collaborator Author

Alright, I ended giving the entire module a minor facelift:

  • Removed dependency on std.algorithm (I think a we can also remove a lot more).
  • Removed not-needed anymore "parameterless templates" for template/non-template overloads (eg this()(int a)).
  • Changed parameter passing to use "in". This allows initializing an UUid from an immutable dynamic array.
  • Used "documented unittests".

This is supposed to be "trivial" changes only, so if you see anything you don't agree with, I'll just straight up remove it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I removed this comment, since "complexity" makes no sense in the context of a UUID, which has constant length.

Copy link
Contributor

Choose a reason for hiding this comment

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

You're of course right. I have to admit back then I didn't really understand the complexity concept. Probably shows that I don't have a formal background in computer science ;-)

Copy link
Member

Choose a reason for hiding this comment

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

Technically, it is linear complexity. It's just that n is always a fixed value, so there isn't much point to the comment.

@jpf91
Copy link
Contributor

jpf91 commented Nov 23, 2013

Those changes look good to me except for the change removing @trusted. See inline comment for details.

BTW: Thanks for doing this, this would probably have been my job otherwise ;-)

@monarchdodra
Copy link
Collaborator Author

Alright, randomUUID is now trusted again.

@monarchdodra
Copy link
Collaborator Author

Alright, randomUUID is now trusted again.

Just be clear, it basically means I left that part "as-is" (which may or may not be correct, but that is outside of the bounds of this PR now). Are there any other changes anybody sees as problematic?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure that it's worth rejecting this over, but I honestly think that we should never use in. The fact that it mixes in scope - which is unimplemented in the vast majority of cases - is just plain dangerous. We run a serious risk of code breakage if/when scope is properly, fully implemented if in is ever used where scope wouldn't work. And honestly, if it were up to me, in would be removed from the language. Combining two attributes in one like that just invites misuse, particularly when so many people seem to like to use it as the opposite of out without taking into account what it actually means.

Copy link
Contributor

Choose a reason for hiding this comment

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

Any breakage caused by scope being implemented/fleshed out will have found (potentially very serious) bugs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, in this case, I chose in specifically because it meant both const and scope. scope don't make much difference here, since it's a value type anyways, but in the later sig, you have in T[] uuid: that's a reference type, so scope would make more sense here. Also, when passed by ref, the reference never escapes scope. So I believe "in" is correct.

That said, I noticed you can't use scope (or const scope) and ref together, yet you can pass by in ref. since in is supposed to be const scope, so I'm a bit confused.

Please advise what you think is actually correct here.

Copy link
Member

Choose a reason for hiding this comment

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

Part of the problem here is that what scope means is not well-defined. All the spec says on the matter is "references in the parameter cannot be escaped (e.g. assigned to a global variable)". I don't believe that it even talks about scope affecting closures. You get the basic idea of what scope is supposed to do but not the specifics. And based on what TDPL lists in its index, as far as I can tell, it doesn't discuss it either.

The only thing that I am aware of that is fully agreed upon that scope is supposed to do (and the only thing that is even partially implemented for it) is to make it so that a closure is not allocated when a delegate function parameter is marked with it. And I don't believe that even that is fully implemented.

There are plenty of folks who assume that scope should impact ref or arrays or your ability to take the address of a parameter or something that it points to, etc. But AFAIK, there is no official word or decision on any of that. And given Walter's aversion to flow analysis, I don't know how we could ever implement scope properly even for delegates, let alone anything else. As far as I can tell, fully implementing scope (especially if it involved all types rather than just delegates) either requires fairly advanced flow analysis or makes it so that you can do almost nothing with the parameter, because the compiler can't guarantee that you're not doing something which makes it or anything it refers to escape the current scope.

So, honestly, I'm inclined to argue that the only place that scope should be used at this point is delegate parameters, and that in should be used absolutely nowhere. We don't even know for sure what they're supposed to do, and if/when they're finally implemented, there's a high chance that we'll have used them incorrectly, so using them just increases the odds of breaking code later.

Copy link
Contributor

Choose a reason for hiding this comment

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

That said, I noticed you can't use scope (or const scope) and ref together, yet you can pass by in ref. since in is supposed to be const scope, so I'm a bit confused.

I think that's just part of the quirkiness of the implementation. i.e. it's a bug. I think there are also other parameter storage class combinations which should work but are rejected by the compiler as an invalid combination.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't believe that it even talks about scope affecting closures.

It doesn't need to because it's purely an optimization.

We don't even know for sure what they're supposed to do, and if/when they're finally implemented, there's a high chance that we'll have used them incorrectly, so using them just increases the odds of breaking code later.

It says right there in the spec what it's supposed to do. When we see scope used in pull requests, we should verify that it's used correctly (that it doesn't escape the parameter, to the strictest degree, i.e. including indirections). Then if it breaks code when implemented, then that code was broken anyway, because we knew we intended the parameter to not be escaped.

The only good argument against using scope is if we suppose that it might get removed, but even then it's a trivial search & replace to fix broken code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So, should I just mark these as const? It's the "least involved change"...

@MartinNowak
Copy link
Member

What's the state of this?

@monarchdodra
Copy link
Collaborator Author

What's the state of this?

AFAICT, it's waiting for a merge.

@MartinNowak
Copy link
Member

LGTM

MartinNowak added a commit that referenced this pull request Dec 16, 2013
@MartinNowak MartinNowak merged commit 22a2098 into dlang:master Dec 16, 2013
@monarchdodra
Copy link
Collaborator Author

Thanks

@MartinNowak
Copy link
Member

General remark, I'm somewhat biased regarding the use of templated functions to trigger attribute inference.
At least on the API layer attributes should be explicit.
The problem that we require too much annotations for internal functions should be handled by making the compiler smarter.

@monarchdodra
Copy link
Collaborator Author

General remark, I'm somewhat biased regarding the use of templated functions to trigger attribute inference.
At least on the API layer attributes should be explicit.
The problem that we require too much annotations for internal functions should be handled by making the compiler smarter.

I'd agree, but in this case, it does allow correct inference, whereas it used to be un-conditionally marked as trusted, which, IMO, is even worst. I had to chose the least of two evils on that one.

@monarchdodra monarchdodra deleted the UUIDPure branch December 19, 2013 18:40
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like this introduced a @safe-ty violation: https://issues.dlang.org/show_bug.cgi?id=14135

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed, but the code does contain a trusted "binary trusted copy". Gonna see if I can't fix this.

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.

7 participants