Skip to content
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

Raise if either argument to poly compare is a mixed block #2504

Closed

Conversation

ncik-roberts
Copy link
Contributor

@ncik-roberts ncik-roberts commented Apr 29, 2024

This PR makes a small preparation step toward supporting declarations like type t = A | B of float# | C of float#. That step is: make polymorphic comparison raise if either argument is a mixed block, instead of short-circuiting if the tag (or Long_val bit) doesn't match.

Previously, compare A (C #4.0) and compare (B #4.0) (C #4.0) would both return a negative value, whereas compare (B x) (B y) would raise for any x/y. Now, all of these things raise.

My reasoning for this change is that it makes it much more predictable that comparisons involving mixed blocks will raise. Otherwise your unit test might not exercise the combination of arguments that cause a raise, and you'll be rueful when you deploy your code to production.

You might wonder about abstract blocks, comparisons involving which only raise if both values are abstract blocks. What's different about abstract blocks vs. mixed blocks? Well, it's going to be extremely common for a type to allow both mixed blocks and normal blocks (see example above), whereas this is somewhat less common for abstract blocks.

Note for reviewer: The implementation differs slightly between runtime 4 and runtime 5. That's because, in runtime 4, checks as to whether something is a mixed block must be guarded by Is_in_value_area. It's nice to avoid duplicating those guards (for runtime efficiency). This amounts to a slightly different placement of those checks in runtime 4, so that they always are preceded by the appropriate Is_in_value_area.

@stedolan
Copy link
Contributor

stedolan commented May 6, 2024

I'm not yet convinced by this change. The compiler "knows" that immediates compare equal only to immediates, and so given type t = A | B of float# it will optimise A = x to a physical equality. Are you proposing to disable this optimisation? (If not, program behaviour will change with inlining).

Both before and after this change, compare will short-circuit and return normally as soon as it determines that values are different. For instance, compare (0, B #1) (1, B #2) returns normally without ever inspecting the B values, since it's already enough to have looked at the first element of each tuple. The change here is to no longer inspect the tags before inspecting the values, but I'm not convinced that really makes a big difference. (In particular, it doesn't seem worth losing the x = [] optimisation)

ncik-roberts added a commit that referenced this pull request May 6, 2024
ncik-roberts added a commit that referenced this pull request May 6, 2024
* tmp

* Update comment and factor out element_repr

* Implement core of variant code

* Some progress

* Get more things working

* Fix some bugs

* Remove lies about tags being 0

* Improve and fix bugs in error messages

* Update existing tests

* Add constructor args to generated tests

* make fmt

* Restore bytecode test to same size

* Fix extensible variant bug

* Add extensible variant typing tests

* Commit half-failing test

* chamelon

* Fix layout bug and add more tests

* Move a giant chunk of code closer to where it was at the base of this diff

* Fix test generation to do all-float constructors

* Fix whitespace in tests + build

* Fix upstream build, I hope

* Get rid of layout_field

* [make fmt] and remove some straggling layout_fields

* Remove debug code

* improve garbled comment

* Add some more tests

* Refactor inlined record error message to fix infelicity

* Fix rec check

* rename 'mixed record' to 'mixed product' and fix toplevel printing

* Add test for recursive mixed blocks

* comment misleading support

* Review: update comment to note dummy value

* minor cleanups from review

* note infelicity in comment

* Update tests due to shelving of #2504
lukemaurer pushed a commit that referenced this pull request Oct 23, 2024
* tmp

* Update comment and factor out element_repr

* Implement core of variant code

* Some progress

* Get more things working

* Fix some bugs

* Remove lies about tags being 0

* Improve and fix bugs in error messages

* Update existing tests

* Add constructor args to generated tests

* make fmt

* Restore bytecode test to same size

* Fix extensible variant bug

* Add extensible variant typing tests

* Commit half-failing test

* chamelon

* Fix layout bug and add more tests

* Move a giant chunk of code closer to where it was at the base of this diff

* Fix test generation to do all-float constructors

* Fix whitespace in tests + build

* Fix upstream build, I hope

* Get rid of layout_field

* [make fmt] and remove some straggling layout_fields

* Remove debug code

* improve garbled comment

* Add some more tests

* Refactor inlined record error message to fix infelicity

* Fix rec check

* rename 'mixed record' to 'mixed product' and fix toplevel printing

* Add test for recursive mixed blocks

* comment misleading support

* Review: update comment to note dummy value

* minor cleanups from review

* note infelicity in comment

* Update tests due to shelving of #2504
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants