-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding forward pipe operator |>
#113
Comments
So that's supposed to mean this?
I'm not sure how valuable this is... but if I were going to do this operator, I think I'd use a syntax like this, using
Edit: I see YaakovDavis had the same idea. |
By the way, when you used
It's funny because I just added that exact method to Loyc.Essentials in the release yesterday. |
Yeah I have such Over the years I am more and more thinking in the pipiline / fluent flow style. So I am mildly extending the number of pipe operations in my own libs https://github.com/dadhi/ImTools/blob/master/src/ImTools/ImTools.cs#L61 The reason is similar to why you have introduced the A most important drawback of using the extension method (except the one with multiple argument methods) is the performance. It is too easy to complain about lambda cast to dismiss the feature. So using the macro for this is ideal!
Yes, for instance using both GetUserId()::id |> GetUserDetails(#, extended: true) |> Display(id, #.Name); UpdateUsing with null-coalescing
|
@qwertie ...and while we are at it, your glorious postfix Thoughts unfold :) seq {
ReadFile(f)::lines \
Log($"{f.Name} has {lines.Count} lines") \
par { lines.Batch(100) |> CountWords(#) } |> Sum(#)::wordCount
Log($"{f.Name} has {wordCount} words") \
Return(lines, wordCount)
}::program;
program.Debug(TestInterpreter);
program.Run(AsyncInterpreter) |> WriteLine(#); The link for example inspiration https://github.com/dadhi/SharpIO/blob/e1a7f900de409dae4d841e4abe79925991ea2a53/FreeIO/FreeIO.cs#L42 |
I guess you mean I'm willing to add at least syntax for a |
Yes, that's what I mean. For now please ignore the rest - sorry for the bloat :< From this noise I would've only peek the if (A()::@a != null) B(a); converted to var a = await A();
if (a != null) B(a); |
I don't think it's worth a new operator when you can just write |
The await _powerUsersMongoRepo.GetAllUnderpoweredUsersByIds(blahhhhhhhh).ToList(); Here is the error - I cannot simply call So may be we don't need the whole _powerUsersMongoRepo.GetAllUnderpoweredUsersByIds(blahhhhhhhh)@.ToList(); |
How about this. Define the following macro:
(The parentheses are requires around And then you can write
|
Will try it out! |
Yes, you can. And, fun fact, I made another example to show you... and was horrified that it didn't work: define operator/($x * $y, $z) { MulDiv($x, $y, $z); }
var x = a * 7 / c; // warning: 1 macro(s) saw the input and declined to process it "Is there some major bug in the // Input
define operator/(($x * $y), $z) { MulDiv($x, $y, $z); }
var x = a * 7 / c;
// Output
var x = MulDiv(a, 7, c); Add the [Passive]
define operator/(($x * $y), $z) { MulDiv($x, $y, $z); }
var x = 1.0 / y; |
Here is more foundation and discussions for the thing: |
While I added You can kind of hack an implementation as follows:
This does work: // Generated from Untitled.ecs by LeMP 2.8.3.0.
void examples()
{
Console.WriteLine("SHA1: {0}", BitConverter.ToString(SHA1.Create().ComputeHash(File.ReadAllBytes(Console.ReadLine))));
var src1 = new Random();
Console.WriteLine(src1.Next(6) + src1.Next(6));
} But |
@qwertie Anyway, this is cool and something I can start using (even if to learn more about complex lemp stuff). Also, means that the tool is mature enough to provide (even if not ideal) the custom solution for the custom need. Simplifying the macros writing should help people with the fun and crazy (useful) ideas. |
In the latest commit, you can define macros in C# code using a new ["Change first argument to HELLO if it's not an identifier", Passive]
macro StupidDemoMacro($(arg0 && !arg0.IsId), $(..rest))
{
return node.WithArgChanged(0, quote(HELLO));
}
StupidDemoMacro(1 + 1, 2 + 2);
StupidDemoMacro(goodbye, 2 + 2);
// Generated from Untitled.ecs by LeMP 2.9.0.0.
StupidDemoMacro(HELLO, 2 + 2);
StupidDemoMacro(goodbye, 2 + 2); Note: C# 9 has a new |
@qwertie Cool, man! Will be checking it out. |
Okay, I still haven't actually released v29, but I will soon, and The same algorithm could be used to provide red squiggly underlines in Visual Studio, mapping errors from the ".out.cs" file back to the ".ecs" file, but doing so would basically involve writing a brand new Visual Studio extension and when it comes to doing that, I don't really know where to begin. But of course, if we can map errors back to the original ecs code, perhaps it is also possible to map IntelliSense back to the original ecs code... if I could figure out how to use the VS APIs properly, it seems like it should be possible, when you type "." or "(" in an ecs file, to run LeMP and then ask Roslyn for code completions, thus providing support for (slow) IntelliSense in ecs files. But of course, I don't have anyone to tell me how to use those darn APIs. And of course I've wanted to support VS Code, but that will involve a completely different set of APIs. |
This is a big step. Did you think about writing the Language Service extension for VS Code? |
Let me put it this way: I'm not even sure what those words mean. I would like to support it, it's just a matter of figuring out all those APIs. Not only the APIs for writing a language service but also the APIs for consuming the existing C# language service - assuming it's even practical for one language service to use a different one. It's especially hard for me because I don't even know how VS Code behaves in C# projects as a user. I mean, VS Code is folder-based, you open a folder and start working. But I'm used to the Visual Studio model of opening a solution, and I've never used VS Code for C# and don't really understand how it behaves. So I'd have to figure that out too. Btw I have two projects in each folder in this repo, a .NET 4.5/4.7 version and a .NET Standard 2.0 version... no idea how VS Code will act in the face of such madness. Right now I'm just planning to investigate how to write printers more efficiently before the official 2.9 release. In the meantime, here's a prerelease. Merry Xmas. If you'd like to discuss more things unrelated to a |
Sorry for the flood, will use the discussions. |
It's not you, it's me - I should have just started a discussion and @atted you. |
Okay, so, in total I've added four operators, I'm preparing a release today. It won't have semantics for these operators, but I decided to try implementing them quickly with some macros. Here's what I came up with (I see GitHub is having some trouble with the syntax highlighting ... they're picking up on the fact it's not the original C#!) #ecs;
using System.Linq;
define operator|=>($A, $B) { $B = $A; }
define operator?=>($A, $B) { $A::temp# == null ? null : $B = temp#; }
macro operator|>($A, $B)
{
int counter = B.DescendantsAndSelf().Count(n => n.IsIdNamed("#"));
if (counter == 0)
return quote($B($A));
else if (counter == 1)
return B.ReplaceRecursive(n => n.IsIdNamed("#") ? A : null);
else {
LNode temp = LNode.Id("temp" + #context.IncrementTempCounter());
LNode B' = B.ReplaceRecursive(n => n.IsIdNamed("#") ? temp : null);
return quote(#runSequence(var $temp = $A, $B'));
}
}
macro operator?>($A, $B)
{
int counter = B.DescendantsAndSelf().Count(n => n.IsIdNamed("#"));
LNode temp = LNode.Id("temp" + #context.IncrementTempCounter());
if (counter == 0) {
return quote($A::$temp == null ? null : $B($temp));
} else {
LNode B' = B.ReplaceRecursive(n => n.IsIdNamed("#") ? temp : null);
return quote($A::$temp == null ? null : $B');
}
}
void Example()
{
DoThing(x) |> DoOtherThing(#, #) ?> IfPreviousThingWasn'tNull ?=> Result;
} Generated result: void Example()
{
var temp12 = DoThing(x);
var temp11 = DoOtherThing(temp12, temp12);
var temp10 = temp11 == null ? null : IfPreviousThingWasn_apostNull(temp11);
temp10 == null ? null : Result = temp10; // not sure why but this concats to previous line
} Unfortunately, MS C# rejects the last line. Looks like something special will have to be done with the |
dotnet/csharplang#74 (comment)
The text was updated successfully, but these errors were encountered: