Frostware.Pipe
1.0.0
dotnet add package Frostware.Pipe --version 1.0.0
NuGet\Install-Package Frostware.Pipe -Version 1.0.0
<PackageReference Include="Frostware.Pipe" Version="1.0.0" />
paket add Frostware.Pipe --version 1.0.0
#r "nuget: Frostware.Pipe, 1.0.0"
// Install Frostware.Pipe as a Cake Addin #addin nuget:?package=Frostware.Pipe&version=1.0.0 // Install Frostware.Pipe as a Cake Tool #tool nuget:?package=Frostware.Pipe&version=1.0.0
Frostware.Pipe
A lightweight piping library for C#
Table of contents
Why Piping?
In computer programming, a pipe is a technique for passing information from one program process to another. A pipe passes a parameter such as the output of one process to another process which accepts it as input. The system temporarily holds the piped information until it is read by the receiving process.
This is useful because it allows us to write more readable code that requires less temporary variables.
Consider this example:
//prints "2" to the console
Console.WriteLine(MathF.Round(1.7f));
Here we are rounding 1.7, then printing the result to the console. Which is fine, but there are 2 main problems with this.
- The order of operations is the opposite of how it is read.
- Once this gets more complicated, it get's harder to keep track of what is going on. To combat this, it is common to cache intermediate states in order to maintain readability
Instead, we could use a pipe:
1.7f
.Pipe(MathF.Round) // returns 2f
.Pipe(Console.WriteLine); //Prints "2" in the console
Now, the operations are executed the way they are read and the logic is easier to follow and there is no longer a need to cache values for readability's sake.
Basics
Frostware.Pipe extends all objects with the Pipe method whether it be a string, an int or a class. Everything can be piped.
"Hello".Pipe()
2.Pipe()
new Foo().Pipe()
The simplest form of pipe is the lambda pipe.
var result = "Hello"
.Pipe(hello => hello + " World"); // returns "Hello World"
var result = 2
.Pipe(two => two + 2); // returns 4
Pipes can be chained any amount of times, the result of the first being piped into the input of the next.
var result = 3f
.Pipe(x => x / 2) // returns 1.5f
//x here is 1.5f
.Pipe(x => MathF.Round(x)); // returns 2f
Which is pretty cool, but this can be simplified.
Since the Pipe methods take in an Action or a Func, that means we can pass in methods that match the function signature. In the case above, the second pipe takes in a float, so we can pass any 1 parameter method that takes in a float.
MathF.Round has an overload that takes in 1 float, which means we can do this:
var result = 3f
.Pipe(x => x / 2) // returns 1.5f
//the pipe will pass 1.5f into MathF.Round implicitly
.Pipe(MathF.Round); // returns 2f
Console.WriteLine() also takes in a float, so we can take the result of our rounding and print it to the console.
3f
.Pipe(x => x / 2f) // returns 1.5f
.Pipe(MathF.Round) // returns 2f
.Pipe(Console.WriteLine); //Prints "2" in the console
Multi pipes
Multi pipes allow you to use a tuple to pipe multiple arguments at the same time.
//the tuples are mapped to the arguments in order
var result = (x: 1.75f, digits: 1)
//this is equivalent to MathF.Round(x: 1.15f, digits: 1)
.Pipe2(MathF.Round); // returns 2f
var result = (value: 1.75f, min: 0f, max: 1f)
// this is equivalent to Math.Clamp(value: 1.75f, min: 0f, max: 1f)
.Pipe3(Math.Clamp); // returns 1f
CurriedPipes
Curried functions are also supported
Func<float, Func<float, Func<float, float>>> Clamp;
6f
.Pipe(Clamp)(0)(5)
.Pipe(x => Console.WriteLine($"clamp: {x}")); // prints 5 to the console
Thanks to Curryfy, none curried functions may also be passed
Func<float, float, float, float> Clamp = Math.Clamp;
6f
.Pipe(Clamp)(0)(5)
.Pipe(x => Console.WriteLine($"clamp: {x}")); // prints 5 to the console
In these cases the function will be curried as part of the pipe.
It is important to note that due to implicit casting limitations, methods cannot be passed implicitly. you will have to do one of the following:
//explicitly cast
6f
.Pipe((Func<float, float, float, float>)Math.Clamp)(0)(5)
.Pipe(x => Console.WriteLine($"clamp: {x}"));
//convert the method to a function
Func<float, float, float, float> Clamp = Math.Clamp;
Dependencies
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Curryfy (>= 3.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 337 | 4/24/2021 |