Skip to content

Commit

Permalink
Release v1.8.0 (#140)
Browse files Browse the repository at this point in the history
* Add expression calculator with state sample.
* Rev to v1.8.0
* Add v1.8.0 features to readme.
  • Loading branch information
domn1995 committed May 16, 2023
1 parent a221f7f commit 5170b29
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 29 deletions.
7 changes: 7 additions & 0 deletions Dunet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PokemonClient", "samples\Po
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExpressionCalculator", "samples\ExpressionCalculator\ExpressionCalculator.csproj", "{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionCalculatorWithState", "samples\ExpressionCalculatorWithState\ExpressionCalculatorWithState.csproj", "{943A33D0-FAC8-44B2-9D20-205CA415F940}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -59,6 +61,10 @@ Global
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9}.Release|Any CPU.Build.0 = Release|Any CPU
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Debug|Any CPU.Build.0 = Debug|Any CPU
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Release|Any CPU.ActiveCfg = Release|Any CPU
{943A33D0-FAC8-44B2-9D20-205CA415F940}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -69,6 +75,7 @@ Global
{2D2D1B9E-BF43-496F-9EA1-410B40B0566B} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
{ED68670F-60E0-410F-8427-C83D39A886F8} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
{E48DBF5C-52AA-490C-988A-FF191C8CA4B9} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
{943A33D0-FAC8-44B2-9D20-205CA415F940} = {7A773F5B-F0CA-444E-BD3D-C954653DF638}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {587D0652-52E0-4A29-84A8-DE4C64FE1F02}
Expand Down
44 changes: 43 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ public partial record HttpResponse
{
public partial record Success;
public partial record Error(string Message);

// 1. All variants shall have a status code.
public required int StatusCode { get; init; }
}
Expand Down Expand Up @@ -294,6 +293,48 @@ public static async Task<HttpResponse> CreateUserAsync(
}
```

## Stateful Matching

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:

```cs
using Dunet;
using static Expression;

var environment = new Dictionary<string, int>()
{
["a"] = 1,
["b"] = 2,
["c"] = 3,
};

var expression = new Add(new Variable("a"), new Multiply(new Number(2), new Variable("b")));
var result = Evaluate(environment, expression);

Console.WriteLine(result); // "5"
static int Evaluate(Dictionary<string, int> env, Expression exp) =>
exp.Match(
// 1. Pass your state "container" as the first parameter.
state: env,
// 2. Use static lambdas for each variant's match method.
static (_, number) => number.Value,
// 3. Reference the state as the first argument of each lambda.
static (state, add) => Evaluate(state, add.Left) + Evaluate(state, add.Right),
static (state, mul) => Evaluate(state, mul.Left) * Evaluate(state, mul.Right),
static (state, var) => state[var.Value]
);

[Union]
public partial record Expression
{
public partial record Number(int Value);
public partial record Add(Expression Left, Expression Right);
public partial record Multiply(Expression Left, Expression Right);
public partial record Variable(string Value);
}
```

## Nest Unions

To declare a union nested within a class or record, the class or record must be `partial`. For example:
Expand Down Expand Up @@ -328,3 +369,4 @@ var variant1 = new Parent1.Parent2.Nested.Variant1();
- [Option Monad](./samples/OptionMonad/Program.cs)
- [Web Client](./samples/PokemonClient/PokeClient.cs)
- [Recursive Expressions](./samples/ExpressionCalculator/Program.cs)
- [Recursive Expressions with Stateful Matching](./samples/ExpressionCalculatorWithState/Program.cs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dunet" Version="1.7.2-pre1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
38 changes: 38 additions & 0 deletions samples/ExpressionCalculatorWithState/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Dunet;
using static Expression;

var environment = new Dictionary<string, int>()
{
["a"] = 1,
["b"] = 2,
["c"] = 3,
};

var expression = new Add(new Variable("a"), new Multiply(new Number(2), new Variable("b")));
var result = Evaluate(environment, expression);

Console.WriteLine(result); // "5"

static int Evaluate(Dictionary<string, int> env, Expression exp) =>
exp.Match(
// 1. Pass your state "container" as the first parameter.
state: env,
// 2. Use static lambdas for each variant's match method.
static (_, number) => number.Value,
// 3. Reference the state as the first argument of each lambda.
static (state, add) => Evaluate(state, add.Left) + Evaluate(state, add.Right),
static (state, mul) => Evaluate(state, mul.Left) * Evaluate(state, mul.Right),
static (state, var) => state[var.Value]
);

[Union]
public partial record Expression
{
public partial record Number(int Value);

public partial record Add(Expression Left, Expression Right);

public partial record Multiply(Expression Left, Expression Right);

public partial record Variable(string Value);
}
32 changes: 4 additions & 28 deletions src/Dunet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,14 @@
<PackageReadmeFile>Readme.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/domn1995/dunet</RepositoryUrl>
<PackageTags>source; generator; discriminated; union; functional; tagged;</PackageTags>
<AssemblyVersion>1.7.2</AssemblyVersion>
<FileVersion>1.7.2</FileVersion>
<AssemblyVersion>1.8.0</AssemblyVersion>
<FileVersion>1.8.0</FileVersion>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReleaseNotes>1.7.2-pre1 - Make Dunet attribute internal to prevent clashing in project references.
1.7.1 - Disables implicit conversions when union has a required property.
1.7.0 - Match on specific union variant.
1.6.0 - Support generator cancellation.
1.5.0 - Support async Action match functions.
1.4.2 - Disables implicit conversions when union variant is an interface type.
1.4.1 - Disable CS1591 in generated code.
1.4.0 - Support Action match functions.
1.3.0 - Async match methods.
1.2.0 - Support nested union declarations.
1.1.0 - Add implicit conversions for union variants.
1.0.2 - Support multiple unions with the same name.
1.0.1 - Configure Dunet as development dependency.
1.0.0 - Production release.
0.5.0 - Generate dedicated match method on union records.
0.4.0 - Add support for declaring a union with records.
0.3.0 - Support complex types in union variants.
0.2.2 - Add source generator DLL to package.
0.2.1 - Update readme.
0.2.0 - Generate dedicated match method.
0.1.3 - Add support for declaring unions inside top level programs.
0.1.2 - Simplify generated source.
0.1.1 - Support any number of interfaces.
0.1.0 - Initial release.
</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/domn1995/dunet/releases</PackageReleaseNotes>
<RepositoryType>git</RepositoryType>
<PackageIcon>favicon.png</PackageIcon>
<SignAssembly>False</SignAssembly>
<Version>1.7.2-pre1</Version>
<Version>1.8.0</Version>
<NeutralLanguage>en</NeutralLanguage>
<DevelopmentDependency>true</DevelopmentDependency>
<NoWarn>$(NoWarn);NU5128</NoWarn>
Expand Down

0 comments on commit 5170b29

Please sign in to comment.