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
51 changes: 51 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ read first.
| loud | `MathS.Quantum.IsNormalised` | the British spelling | `MathS.Quantum.IsNormalized` |
| loud | the target frameworks | `net7.0;netstandard2.0` | `netstandard2.0;net8.0;net10.0` |
| **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 |

---

Expand Down Expand Up @@ -99,6 +100,56 @@ the built assemblies: present in `net8.0` and `net10.0`, absent from `netstandar

## Types and members

### The implicit conversion from `List<Entity>` is removed

`Entity` had two implicit conversions from a collection, both building a `FiniteSet`:

```csharp
public static implicit operator Entity(Entity[] elements);
public static implicit operator Entity(List<Entity> elements); // removed
```

The second one made three public members impossible to call with a `List<Entity>`:

```csharp
var equations = new List<Entity> { "x - 1", "y - 2" };
new EquationSystem(equations); // error CS0121: the call is ambiguous
new FiniteSet(equations); // error CS0121
MathS.Equations(equations); // error CS0121
```

Each of those has both an `IEnumerable<Entity>` overload and a `params Entity[]` overload. With
the conversion in place a `List<Entity>` also converts to a single `Entity`, so the `params`
overload becomes applicable in its expanded form, neither candidate is better than the other,
and the call does not compile. The array, `IEnumerable<Entity>`, and variadic forms were always
fine — only a concrete `List<Entity>` broke, which is why it survived to a 2.0 preview.

This was not three separate defects. One conversion made *every* `params Entity[]` overload in
the library uncallable with a list, including any added later.

**This one moves between previews.** The conversion is in `2.0.0-preview.1` and
`2.0.0-preview.2`, both published, and is removed in the release that follows them. It is so
far the only entry here that changes between two previews rather than between releases: a
reader coming from 1.3.0 or 1.4.0 can ignore the distinction, one already on a preview cannot.

**What breaks.** Assigning a list where an `Entity` is expected:

```csharp
Entity set = new List<Entity> { 1, 2, 3 }; // no longer compiles
```

Write one of these instead:

```csharp
Entity set = new FiniteSet(new List<Entity> { 1, 2, 3 });
Entity set = new List<Entity> { 1, 2, 3 }.ToSet();
Entity set = new Entity[] { 1, 2, 3 }; // the array conversion is unchanged
```

The `Entity[]` conversion is kept: an array argument binds to the `params` overload in its normal
form by an identity conversion, which beats the alternatives outright, so it never produced the
ambiguity.

### `Minusf`'s two operands exchanged names

In `a - b`, `a` is the minuend and `b` is the subtrahend. The record declared them the other way
Expand Down
3 changes: 3 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[Tests/UnitTests/Core/Transformations/*.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Common/ListArgumentOverloadTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

# A new file in a directory whose other files predate it, so the section is on the file
# rather than the folder.
[AngouriMath/Core/Entity/Continuous/Entity.Continuous.{Floors,Rounding}.Classes.cs]
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 @@ -83,7 +83,6 @@ public bool Contains(Entity entity)
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);
public static implicit operator Entity(Entity[] elements) => new FiniteSet(elements);
public static implicit operator Entity(List<Entity> elements) => new FiniteSet((IEnumerable<Entity>)elements);
#pragma warning restore CS1591

}
Expand Down
72 changes: 72 additions & 0 deletions Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//
// Copyright (c) 2019-2026 Angouri.
// AngouriMath is licensed under MIT.
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
// Website: https://am.angouri.org.
//

using System.Collections.Generic;
using AngouriMath;
using AngouriMath.Core;
using Xunit;

namespace AngouriMath.Tests.Common
{
/// <summary>
/// Every member here takes both an <see cref="IEnumerable{T}"/> and a <c>params Entity[]</c>.
/// While <c>Entity</c> also had an implicit conversion from <c>List&lt;Entity&gt;</c>, a list
/// argument matched the params overload in its expanded form as well, neither candidate was
/// better than the other, and none of these calls compiled -- CS0121. The conversion is gone;
/// this file failing to compile is what says it has not come back.
/// </summary>
[Trait("Area", "Common")]
public sealed class ListArgumentOverloadTest
{
static List<Entity> Equations => new() { "x - 1", "y - 2" };

[Fact]
public void EquationSystemTakesAList()
{
var solutions = new EquationSystem(Equations).Solve("x", "y");
Assert.NotNull(solutions);
Assert.Equal(1, solutions.RowCount);

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Dereference of a possibly null reference.

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Dereference of a possibly null reference.

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Dereference of a possibly null reference.

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Dereference of a possibly null reference.

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Dereference of a possibly null reference.

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

Dereference of a possibly null reference.

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

Dereference of a possibly null reference.

Check warning on line 32 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

Dereference of a possibly null reference.
Assert.Equal(2, solutions.ColumnCount);
}

[Fact]
public void MathSEquationsTakesAList()
{
var solutions = MathS.Equations(Equations).Solve("x", "y");
Assert.NotNull(solutions);
Assert.Equal(1, solutions.RowCount);

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Dereference of a possibly null reference.

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

Dereference of a possibly null reference.

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Dereference of a possibly null reference.

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Dereference of a possibly null reference.

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

Dereference of a possibly null reference.

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

Dereference of a possibly null reference.

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

Dereference of a possibly null reference.

Check warning on line 41 in Sources/Tests/UnitTests/Common/ListArgumentOverloadTest.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

Dereference of a possibly null reference.
}

[Fact]
public void FiniteSetTakesAList()
{
var set = new Entity.Set.FiniteSet(new List<Entity> { 1, 2, 3 });
Assert.Equal(3, set.Count);
}

/// <summary>The array and variadic forms were never ambiguous, and must stay that way.</summary>
[Fact]
public void ArrayAndVariadicFormsStillBind()
{
Entity[] equations = { "x - 1", "y - 2" };
Assert.NotNull(new EquationSystem(equations).Solve("x", "y"));
Assert.NotNull(new EquationSystem("x - 1", "y - 2").Solve("x", "y"));
Assert.Equal(3, new Entity.Set.FiniteSet(1, 2, 3).Count);
}

/// <summary>
/// The conversion from an array is deliberately kept, so an array in an
/// <c>Entity</c> position is still a set.
/// </summary>
[Fact]
public void ArrayStillConvertsToASet()
{
Entity set = new Entity[] { 1, 2, 3 };
Assert.Equal(new Entity.Set.FiniteSet(1, 2, 3), set);
}
}
}
1 change: 0 additions & 1 deletion Sources/Tests/UnitTests/Common/PublicApi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2132,7 +2132,6 @@ AngouriMath.Entity.op_Implicit(PeterO.Numbers.EInteger) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(PeterO.Numbers.ERational) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.Boolean) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.Byte) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.Collections.Generic.List<AngouriMath.Entity>) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.Decimal) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.Double) : AngouriMath.Entity
AngouriMath.Entity.op_Implicit(System.Int16) : AngouriMath.Entity
Expand Down
Loading