Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ read first.
| **silent** | `abs(x) = c` for a negative `c` | a set of non-solutions | the empty set |
| loud | implicit `List<Entity>` to `Entity` | made a `FiniteSet`, and made three `params` overloads uncallable | removed |
| loud | implicit `Entity[]` to `Entity` | made a `FiniteSet`, discarding order and repeats | removed |
| loud | implicit `(Entity, Entity)` to `Entity` | made a **closed** interval, though `(a, b)` reads as the open one | removed |
| **silent** | a `MathS.Settings` scope across an `await`, or inside a task | lost, or somebody else's | follows the call |
| **silent** | a `RewriteRecording` across an `await`, or work started under it | lost, or somebody else's | follows the call |

Expand Down Expand Up @@ -164,6 +165,32 @@ Entity set = new Entity[] { 1, 2, 3 }.ToSet();

Only one place in the whole repository relied on it, which was the test pinning it.

**And the conversion from a pair, which had the same fault from the other side.** A
two-element tuple became an `Interval`, and since a tuple says nothing about whether its
endpoints are included, the conversion had to supply that:

```csharp
Entity e = ((Entity)1, (Entity)5);
// was: [1; 5] — both endpoints included, and 1 is a member
```

Where the array conversion dropped information that was there, this one produced
information that was not — and chose the reading opposite to the notation, since `(1, 5)`
is the open interval in ordinary mathematical writing and `[1, 5]` the closed one. A caller
writing what looks like an open interval got a closed one, silently.

```csharp
Entity e = MathS.Interval(1, 5); // closed, said out loud
Entity e = MathS.Interval(1, false, 5, false); // open
Entity e = new Interval(1, true, 5, true);
```

Nothing in the library, the tests, the F# wrapper or the utilities used it.

The pairs elsewhere in the API are unaffected, because none of them has to guess: an
integration `Range`, the arguments of `Substitute`, the cases of `MathS.Piecewise` and
`ToProvided` are all ordered pairs whose two halves have distinct, stated roles.

### A settings scope belongs to the call, not to the thread

`MathS.Settings` values were held in `[ThreadStatic]` fields — fourteen of them. A scope
Expand Down
1 change: 0 additions & 1 deletion Sources/AngouriMath/Core/Entity/Omni/Entity.Set.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public bool Contains(Entity entity)

#pragma warning disable CS1591
public static implicit operator Entity(Domain domain) => Set.SpecialSet.Create(domain);
public static implicit operator Entity((Entity left, Entity right) interval) => new Interval(interval.left, true, interval.right, true);
#pragma warning restore CS1591

}
Expand Down
21 changes: 21 additions & 0 deletions Sources/Tests/UnitTests/Common/ImplicitOperators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,26 @@ public sealed class ImplicitOperators
[Fact] public void FromEInteger() => Test(EInteger.FromString("32324"), "32324");
[Fact] public void FromERational() => Test(ERational.Create(EInteger.FromString("32324"), EInteger.FromString("243244")), ((Entity)"32324/243244").InnerSimplified);
[Fact] public void FromEDecimal() => Test(EDecimal.FromString("3.4"), "3.4");

/// <summary>
/// The conversions that used to exist from a collection and from a pair are gone,
/// because each had to supply something its input did not carry — an array has an
/// order and repeats where a set has neither, and a pair says nothing about whether
/// its endpoints are included. An interval is asked for by name instead, which also
/// makes the choice visible rather than assumed.
/// </summary>
/// <remarks>
/// This test compiling is the part that matters: bring either conversion back and the
/// assertions below start passing for the wrong reason, but the ones in
/// <c>ListArgumentOverloadTest</c> stop building.
/// </remarks>
[Fact]
public void AnIntervalIsAskedForByName()
{
Test(MathS.Interval(1, 5), new Entity.Set.Interval(1, true, 5, true));
Assert.NotEqual(
(Entity)MathS.Interval(1, true, 5, true),
(Entity)MathS.Interval(1, false, 5, false));
}
}
}
1 change: 0 additions & 1 deletion Sources/Tests/UnitTests/Common/PublicApi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2144,7 +2144,6 @@ AngouriMath.Entity.op_Implicit(System.String) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.UInt16) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.UInt32) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.UInt64) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.ValueTuple<AngouriMath.Entity,AngouriMath.Entity>) : AngouriMath.Entity
AngouriMath.Entity.op_Inequality(AngouriMath.Entity, AngouriMath.Entity) : System.Boolean
AngouriMath.Entity.op_LessThan(AngouriMath.Entity, AngouriMath.Entity) : AngouriMath.Entity
AngouriMath.Entity.op_LessThanOrEqual(AngouriMath.Entity, AngouriMath.Entity) : AngouriMath.Entity
Expand Down
Loading