Skip to content

Commit 5170b29

Browse files
authored
Release v1.8.0 (#140)
* Add expression calculator with state sample. * Rev to v1.8.0 * Add v1.8.0 features to readme.
1 parent a221f7f commit 5170b29

File tree

5 files changed

+109
-29
lines changed

5 files changed

+109
-29
lines changed

Dunet.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PokemonClient", "samples\Po
2121
EndProject
2222
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExpressionCalculator", "samples\ExpressionCalculator\ExpressionCalculator.csproj", "{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}"
2323
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionCalculatorWithState", "samples\ExpressionCalculatorWithState\ExpressionCalculatorWithState.csproj", "{943A33D0-FAC8-44B2-9D20-205CA415F940}"
25+
EndProject
2426
Global
2527
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2628
Debug|Any CPU = Debug|Any CPU
@@ -59,6 +61,10 @@ Global
5961
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
6062
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
6163
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}.Release|Any CPU.Build.0 = Release|Any CPU
64+
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65+
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Debug|Any CPU.Build.0 = Debug|Any CPU
66+
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Release|Any CPU.Build.0 = Release|Any CPU
6268
EndGlobalSection
6369
GlobalSection(SolutionProperties) = preSolution
6470
HideSolutionNode = FALSE
@@ -69,6 +75,7 @@ Global
6975
{2D2D1B9E-BF43-496F-9EA1-410B40B0566B} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
7076
{ED68670F-60E0-410F-8427-C83D39A886F8} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
7177
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
78+
{943A33D0-FAC8-44B2-9D20-205CA415F940} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
7279
EndGlobalSection
7380
GlobalSection(ExtensibilityGlobals) = postSolution
7481
SolutionGuid = {587D0652-52E0-4A29-84A8-DE4C64FE1F02}

Readme.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,6 @@ public partial record HttpResponse
255255
{
256256
public partial record Success;
257257
public partial record Error(string Message);
258-
259258
// 1. All variants shall have a status code.
260259
public required int StatusCode { get; init; }
261260
}
@@ -294,6 +293,48 @@ public static async Task<HttpResponse> CreateUserAsync(
294293
}
295294
```
296295

296+
## Stateful Matching
297+
298+
To reduce memory allocations, use the `Match` overload that accepts a generic state parameter as its first argument. This allows your match parameter lambdas to be `static` but still flow state through:
299+
300+
```cs
301+
using Dunet;
302+
using static Expression;
303+
304+
var environment = new Dictionary<string, int>()
305+
{
306+
["a"] = 1,
307+
["b"] = 2,
308+
["c"] = 3,
309+
};
310+
311+
var expression = new Add(new Variable("a"), new Multiply(new Number(2), new Variable("b")));
312+
var result = Evaluate(environment, expression);
313+
314+
Console.WriteLine(result); // "5"
315+
316+
static int Evaluate(Dictionary<string, int> env, Expression exp) =>
317+
exp.Match(
318+
// 1. Pass your state "container" as the first parameter.
319+
state: env,
320+
// 2. Use static lambdas for each variant's match method.
321+
static (_, number) => number.Value,
322+
// 3. Reference the state as the first argument of each lambda.
323+
static (state, add) => Evaluate(state, add.Left) + Evaluate(state, add.Right),
324+
static (state, mul) => Evaluate(state, mul.Left) * Evaluate(state, mul.Right),
325+
static (state, var) => state[var.Value]
326+
);
327+
328+
[Union]
329+
public partial record Expression
330+
{
331+
public partial record Number(int Value);
332+
public partial record Add(Expression Left, Expression Right);
333+
public partial record Multiply(Expression Left, Expression Right);
334+
public partial record Variable(string Value);
335+
}
336+
```
337+
297338
## Nest Unions
298339

299340
To declare a union nested within a class or record, the class or record must be `partial`. For example:
@@ -328,3 +369,4 @@ var variant1 = new Parent1.Parent2.Nested.Variant1();
328369
- [Option Monad](./samples/OptionMonad/Program.cs)
329370
- [Web Client](./samples/PokemonClient/PokeClient.cs)
330371
- [Recursive Expressions](./samples/ExpressionCalculator/Program.cs)
372+
- [Recursive Expressions with Stateful Matching](./samples/ExpressionCalculatorWithState/Program.cs)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net7.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Dunet" Version="1.7.2-pre1">
12+
<PrivateAssets>all</PrivateAssets>
13+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
14+
</PackageReference>
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using Dunet;
2+
using static Expression;
3+
4+
var environment = new Dictionary<string, int>()
5+
{
6+
["a"] = 1,
7+
["b"] = 2,
8+
["c"] = 3,
9+
};
10+
11+
var expression = new Add(new Variable("a"), new Multiply(new Number(2), new Variable("b")));
12+
var result = Evaluate(environment, expression);
13+
14+
Console.WriteLine(result); // "5"
15+
16+
static int Evaluate(Dictionary<string, int> env, Expression exp) =>
17+
exp.Match(
18+
// 1. Pass your state "container" as the first parameter.
19+
state: env,
20+
// 2. Use static lambdas for each variant's match method.
21+
static (_, number) => number.Value,
22+
// 3. Reference the state as the first argument of each lambda.
23+
static (state, add) => Evaluate(state, add.Left) + Evaluate(state, add.Right),
24+
static (state, mul) => Evaluate(state, mul.Left) * Evaluate(state, mul.Right),
25+
static (state, var) => state[var.Value]
26+
);
27+
28+
[Union]
29+
public partial record Expression
30+
{
31+
public partial record Number(int Value);
32+
33+
public partial record Add(Expression Left, Expression Right);
34+
35+
public partial record Multiply(Expression Left, Expression Right);
36+
37+
public partial record Variable(string Value);
38+
}

src/Dunet.csproj

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,14 @@
1414
<PackageReadmeFile>Readme.md</PackageReadmeFile>
1515
<RepositoryUrl>https://github.com/domn1995/dunet</RepositoryUrl>
1616
<PackageTags>source; generator; discriminated; union; functional; tagged;</PackageTags>
17-
<AssemblyVersion>1.7.2</AssemblyVersion>
18-
<FileVersion>1.7.2</FileVersion>
17+
<AssemblyVersion>1.8.0</AssemblyVersion>
18+
<FileVersion>1.8.0</FileVersion>
1919
<PackageLicenseExpression>MIT</PackageLicenseExpression>
20-
<PackageReleaseNotes>1.7.2-pre1 - Make Dunet attribute internal to prevent clashing in project references.
21-
1.7.1 - Disables implicit conversions when union has a required property.
22-
1.7.0 - Match on specific union variant.
23-
1.6.0 - Support generator cancellation.
24-
1.5.0 - Support async Action match functions.
25-
1.4.2 - Disables implicit conversions when union variant is an interface type.
26-
1.4.1 - Disable CS1591 in generated code.
27-
1.4.0 - Support Action match functions.
28-
1.3.0 - Async match methods.
29-
1.2.0 - Support nested union declarations.
30-
1.1.0 - Add implicit conversions for union variants.
31-
1.0.2 - Support multiple unions with the same name.
32-
1.0.1 - Configure Dunet as development dependency.
33-
1.0.0 - Production release.
34-
0.5.0 - Generate dedicated match method on union records.
35-
0.4.0 - Add support for declaring a union with records.
36-
0.3.0 - Support complex types in union variants.
37-
0.2.2 - Add source generator DLL to package.
38-
0.2.1 - Update readme.
39-
0.2.0 - Generate dedicated match method.
40-
0.1.3 - Add support for declaring unions inside top level programs.
41-
0.1.2 - Simplify generated source.
42-
0.1.1 - Support any number of interfaces.
43-
0.1.0 - Initial release.
44-
</PackageReleaseNotes>
20+
<PackageReleaseNotes>https://github.com/domn1995/dunet/releases</PackageReleaseNotes>
4521
<RepositoryType>git</RepositoryType>
4622
<PackageIcon>favicon.png</PackageIcon>
4723
<SignAssembly>False</SignAssembly>
48-
<Version>1.7.2-pre1</Version>
24+
<Version>1.8.0</Version>
4925
<NeutralLanguage>en</NeutralLanguage>
5026
<DevelopmentDependency>true</DevelopmentDependency>
5127
<NoWarn>$(NoWarn);NU5128</NoWarn>

0 commit comments

Comments
 (0)