Skip to content

Comments

Convert range constraints to Conjunctive Normal Form#5461

Closed
andralex wants to merge 1 commit intodlang:masterfrom
andralex:cnf
Closed

Convert range constraints to Conjunctive Normal Form#5461
andralex wants to merge 1 commit intodlang:masterfrom
andralex:cnf

Conversation

@andralex
Copy link
Member

Convert the currently opaque and unstructured constraints for ranges to simple CNF formulae. This makes the constraints simpler and clearer. But the largest opportunity is having the compiler recognize these formulae and print the failing clause. There are plans to include a mechanism for user-defined messages, too.

@andralex
Copy link
Member Author

For some reason I can't squash the commits together with git rebase -i HEAD~4. Help please?

@wilzbach
Copy link
Contributor

For some reason I can't squash the commits together with git rebase -i HEAD~4. Help please?

Should I squash everything into one or only the last four?

@andralex
Copy link
Member Author

Should I squash everything into one or only the last four?

https://www.youtube.com/watch?v=KBKXu3Kg4yg

@dnadlinger
Copy link
Contributor

dnadlinger commented Jun 11, 2017

Somehow, you ended up with a series of merges:

*   d3f75790a - (HEAD -> cnf, dlang/pull/5461, andralex/cnf) Convert range constraints to Conjunctive Normal Form (20 minutes ago)<Andrei Alexandrescu>
|\
| *   3b658fe94 - WIP (10 hours ago)<Andrei Alexandrescu>
| |\
* | \   4a0b99ace - WIP (10 hours ago)<Andrei Alexandrescu>
|\ \ \
| |/ /
|/| /
| |/
| * 6a7da721a - Add and use more introspection amenities (26 hours ago)<Andrei Alexandrescu>
| * 13528b3a5 - --amend (31 hours ago)<Andrei Alexandrescu>
| * d2ad7f503 - WIP (35 hours ago)<Andrei Alexandrescu>
* | 72c57039a - --amend (31 hours ago)<Andrei Alexandrescu>
* | ee3b8a51c - WIP (31 hours ago)<Andrei Alexandrescu>

I just did git merge master; git reset master; git commit -a --author=Andrei, recreating the commit from scratch while keeping the working tree intact.

@dnadlinger
Copy link
Contributor

(EEEEVERYTHING is squashed!)

@dnadlinger
Copy link
Contributor

Leaving any implementation details aside, this looks to be a good change. The opaque test blocks have alway irked me, precisely because they make better error messages impossible. (It sounds like you have a concrete compiler patch in the works?)

enum bool isInputRange(R) =
is(typeof((ref R r) => r))
&& is(ReturnType!((R r) => r.empty) == bool)
&& is(typeof(lvalueOf!R.front))
Copy link
Contributor

Choose a reason for hiding this comment

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

Didn't the original code also require the front to be copyable?

Copy link
Member Author

Choose a reason for hiding this comment

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

is(typeof((ref R r) => r)) requires the range to be copyable.

Copy link
Contributor

@dnadlinger dnadlinger Jun 11, 2017

Choose a reason for hiding this comment

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

I was referring to front (i.e. the element type, not the range itself).

}));
}
enum bool isInputRange(R) =
is(typeof((ref R r) => r))
Copy link
Contributor

@dnadlinger dnadlinger Jun 11, 2017

Choose a reason for hiding this comment

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

Doesn't this check for copyability, whereas the original checked for non-@disabled init?

Copy link
Member Author

Choose a reason for hiding this comment

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

hmmmm... you may be on to something. How would init be disabled?

@dnadlinger
Copy link
Contributor

@andralex
Copy link
Member Author

@klickverbot changed the input range constraint to the original

@WalterBright
Copy link
Member

This is a huge improvement in style, debuggability, and comprehensibility.

@andralex
Copy link
Member Author

andralex commented Jun 11, 2017

How do I repro the dscanner error locally? Thanks.

@wilzbach
Copy link
Contributor

wilzbach commented Jun 11, 2017

How do I repro the dscanner error locally? Thanks.

It's libdparse, which is failing - not Dscanner ;-)

  1. Build Phobos from your current branch
  2. Git clone libdparse (it's now part of dlang-community)
  3. Run the failing test from Jenkins

In this case libdparse has a custom test suite:

cd test
DMD=~/dlang/dmd/generated/linux/release/64/dmd  ../test/run_tests.sh

But usually running the tests with DUB is more convenient (works here as well):

dub test --compiler=$HOME/dlang/dmd/generated/linux/release/64/dmd

@andralex andralex force-pushed the cnf branch 2 times, most recently from 6fd9846 to 4a7bc13 Compare June 11, 2017 01:54
@andralex
Copy link
Member Author

For an odd reason libdparse doesn't like is(typeof(lvalueOf!R.popFront)) but loves is(typeof((R r) => r.popFront)). I'm unclear on what's going on. I will note I've encountered a few oddities e.g. isBidirectionalRange must decide whether r.popBack is callable, which does a UFCS lookup which in turn us liable to evaluate isBidirectionalRange again.

@andralex
Copy link
Member Author

So... vibed seems to have trouble with this. I tried:

dub fetch vibe
dub fetch vibed
dub fetch vibe.d

(search the net...)
dub fetch vibe-d

Fetching vibe-d 0.7.31...
Placing vibe-d 0.7.31 to /Users/andrei/.dub/packages/...
Getting a release version failed: Missing package description for package at /Users/andrei/.dub/packages/vibe-d-0.7.31
Retry with ~master...
Fetching vibe-d ~master...
Placing vibe-d ~master to /Users/andrei/.dub/packages/...
Error executing command fetch: Missing package description for package at /Users/andrei/.dub/packages/vibe-d-master

Tried the same command again, got:

Fetching vibe-d 0.7.31...
Placing vibe-d 0.7.31 to /Users/andrei/.dub/packages/...
Getting a release version failed: vibe-d (0.7.31) needs to be removed from '/Users/andrei/.dub/packages/vibe-d-0.7.31' prior placement.
Retry with ~master...
Fetching vibe-d ~master...
Placing vibe-d ~master to /Users/andrei/.dub/packages/...
Error executing command fetch: vibe-d (~master) needs to be removed from '/Users/andrei/.dub/packages/vibe-d-master' prior placement.

And again after rm -rf /Users/andrei/.dub/packages/vibe-d-master:

Fetching vibe-d 0.7.31...
Placing vibe-d 0.7.31 to /Users/andrei/.dub/packages/...
Getting a release version failed: vibe-d (0.7.31) needs to be removed from '/Users/andrei/.dub/packages/vibe-d-0.7.31' prior placement.
Retry with ~master...
Fetching vibe-d ~master...
Placing vibe-d ~master to /Users/andrei/.dub/packages/...
Error executing command fetch: Missing package description for package at /Users/andrei/.dub/packages/vibe-d-master

@CyberShadow
Copy link
Member

vibed seems to have trouble with this

I think that's just yet another dub bug. Try nuking ~/.dub I guess.

@wilzbach
Copy link
Contributor

I think that's just yet another dub bug. Try nuking ~/.dub I guess.

Yes, dub is kinda buggy :S
Vibe.d shouldn't compile anyways due to the std.experimental.allocator regressions ;-)

@andralex
Copy link
Member Author

FWIW deleted ~/.dub, same problem

@wilzbach
Copy link
Contributor

FWIW deleted ~/.dub, same problem

Weird - btw if you were looking at the ICE on Jenkins in vibe.d, Walter already has you covered: dlang/dmd#6875

There's still a regression manifesting from #5427 though ...

}
enum bool isInputRange(R) =
is(typeof((R r) => R.init))
&& is(ReturnType!((R r) => r.empty) == bool)
Copy link
Contributor

@tgehr tgehr Jun 11, 2017

Choose a reason for hiding this comment

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

This constraint is stronger than before. (The old constraint checked for cast(bool)r.empty being valid.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct. I'd like to keep it that way.

enum bool isInputRange(R) =
is(typeof((R r) => R.init))
&& is(ReturnType!((R r) => r.empty) == bool)
&& is(typeof((R r) => r.front))
Copy link
Contributor

Choose a reason for hiding this comment

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

This constraint is weaker than before. (front can now return 'void').

Copy link
Member Author

Choose a reason for hiding this comment

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

Will fix, thanks.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

}));
}
enum bool isInputRange(R) =
is(typeof((R r) => R.init))
Copy link
Contributor

Choose a reason for hiding this comment

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

The delegate seems redundant.

Copy link
Member Author

Choose a reason for hiding this comment

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

The previous constraint verified that this works: R r = R.init;. That passes even for ranges with both this() and this(this) disabled, so you're right about that.

The only types rejected by this would be those that play shenanigans with init, i.e. have it return a different type etc. We don't want to support such styles. I'll remove the line.

Copy link
Member Author

Choose a reason for hiding this comment

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

@tgehr std.algoritm.mutation, std.algoritm.iteration, and std.algoritm.searching don't pass unittests without this line. I'll leave it here for this PR and will investigate separately.

Copy link
Contributor

@tgehr tgehr Jun 11, 2017

Choose a reason for hiding this comment

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

My suggestion was not to delete the line entirely; I don't see why it should be typeof((R r) => R.init) (with unused parameter r) instead of something like is(typeof(R.init) == R).

Copy link
Member Author

Choose a reason for hiding this comment

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

@tgehr cool, that works. Updated.

Copy link
Member

Choose a reason for hiding this comment

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

The only types rejected by this would be those that play shenanigans with init, i.e. have it return a different type etc. We don't want to support such styles. I'll remove the line.

I thought that we were going to make it illegal to redefine init (certainly, changes were made to TypeInfo so that we could move towards doing that). Until we do, we do need to be a bit careful, but allowing it to be redefined just seems like a disaster waiting to happen - especially when you consider code like this.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that property should become reserved at some point.

@property bool empty();
void front();
}
//static assert(!isInputRange!VoidFront);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why commented out?

Copy link
Member Author

Choose a reason for hiding this comment

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

sry, fixed

@jmdavis
Copy link
Member

jmdavis commented Jul 13, 2017

If, in the future, we decide that all random access ranges with length should define $ (which I think they should), then adding hasOpDollar could be useful.

Well, if we would ever get some form of https://issues.dlang.org/show_bug.cgi?id=7177 implemented, then requiring that $ work when the range is random access would be reasonable...

@andralex andralex force-pushed the cnf branch 7 times, most recently from 3f2e3c7 to 0c2d36a Compare July 13, 2017 16:30
@andralex
Copy link
Member Author

OK, so I did a bit of git cleanup and now everything is nicely in one commit. Ready to merge?

@JackStouffer
Copy link
Contributor

@andralex Looks like the reuse of the git hash is confusing circle and the doc builder.

Can you change the commit message and then force push?

@andralex
Copy link
Member Author

@JackStouffer much obliged

@JackStouffer
Copy link
Contributor

Uhh ... it didn't work.

Let's try this trick then

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @andralex!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

@JackStouffer
Copy link
Contributor

Well, that did get circle to start, but it looks like the problem with the git history is worse than I thought.

Any ideas @wilzbach @CyberShadow?

@CyberShadow
Copy link
Member

Closing an reopening a PR has zero effect on the documentation tester. I'm not sure what went wrong yet (I added more logging yesterday) but to force a retest you can either rebase/amend (to change the tip commit SHA1) or wait until something else is merged, so that it's tested with a new merge target.

@wilzbach
Copy link
Contributor

Well, that did get circle to start, but it looks like the problem with the git history is worse than I thought.
Any ideas @wilzbach @CyberShadow?

It seems to be a recent problem that I have seen on a few other PRs lately - not so sure on what's going on ...
@CyberShadow do your logs provide any insight?

@CyberShadow
Copy link
Member

I just answered that in another PR not 5 minutes ago.

@wilzbach
Copy link
Contributor

I just answered that in another PR not 5 minutes ago.

Didn't see that until now. Sorry

@andralex
Copy link
Member Author

OK what would be a reasonable course of action here?

wilzbach pushed a commit to andralex/phobos that referenced this pull request Jul 15, 2017
@wilzbach
Copy link
Contributor

OK what would be a reasonable course of action here?

Tried the typical "kick the CI with a rebase" trick, but without success. I will close this PR and maybe we just had terrible luck here due to so many people using the contributor push feature?

image

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.