-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
FR: Improve functional programming for Motoko #3321
Comments
Yes, something like this would be nice but note that:
This FR is related to #2537, which proposes adding something akin to C# extension methods (a.k.a F# augmentations) to let you invoke a static function using the dot notation, passing the receiver as the first argument. |
It's a little easier to understand your original code if you break it up using a let.
This is actually more efficient than using any higher-order combinator (in the current implementation) since we don't inline those yet and the all the calls will wind up being direct calls. But yes, having to name the intermediate results is less concise. https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=3719590015 |
Many |
To throw in my two rappens: could we add a syntax for anonymous function arguments, like in Scala? E.g., I would love to be able to write _.principal == caller instead of func p = p.principal == caller when the type of the lambda-expression can be inferred unambiguously. |
In many cases function types containing type parameters behave differently that without: > ((func (c : Char, t : Text) : (Int, Int) = (1,2)) : ((Char, Text)) -> ((Int, Int)));
<func> : ((Char, Text)) -> ((Int, Int)) By annotating a monomorphic multi-arg/return function to be single (compound) arg/return one can change the calling modalities. But as soon as a type parameter comes into play, this is not possible, as type parameters are unary, consider: > (func <T>(v : T) : (Int, Int) = (1,2))<(Char, Text)>('H',"ello");
(1, 2) : (Int, Int) Here an instantiation can be added for a call, but we cannot annotate the function to be multi-arg: > ((func <T>(v : T) : (Int, Int) = (1,2)) : (Char, Text) -> (Int, Int))('H',"ello");
stdin:5.3-5.39: type error [M0096], expression of type
<T>T -> (Int, Int)
cannot produce expected type
(Char, Text) -> (Int, Int) even if we annotate it as unary: > ((func <T>(v : T) : (Int, Int) = (1,2)) : ((Char, Text)) -> (Int, Int))('H',"ello");
stdin:6.3-6.39: type error [M0096], expression of type
<T>T -> (Int, Int)
cannot produce expected type
((Char, Text)) -> (Int, Int) Even arity-changing on the monomorphic return-side is disallowed: > ((func <T>(v : T) : (Int, Int) = (1,2)) : <T>T -> ((Int, Int)))('H',"ello");
stdin:7.3-7.39: type error [M0096], expression of type
<T>T -> (Int, Int)
cannot produce expected type
<T>T -> ((Int, Int)) But when building IR functions "by hand" (e.g. For the record, here is the simplest annotation that does go wrong (but shouldn't) > (func <T>(v : T) : () = ()) : <U>U -> (());
stdin:18.2-18.27: type error [M0096], expression of type
<T>T -> ()
cannot produce expected type
<U>U -> (()) the relevant AST diff being - (FuncT Local (U (PrimT Any)) (PathT (IdH U)) (TupT))
+ (FuncT Local (U (PrimT Any)) (PathT (IdH U)) (ParT (TupT))) as the second argument of The big difference between the two modi comes from | FuncE (_, shared_pat, [], pat, typ_opt, _sugar, exp), T.Func (s, c, [], ts1, ts2) -> as we can see only parameterless functions are checked, otherwise the I am trying to flesh this out in #4620. |
Problem
Working with collections is verbose and difficult. For example, I want to filter blog posts and return the ids:
The example is difficult to understand, write, and debug.
Solution 1: Operator piping
We can use something like a pipe operator from F# to improve readability with Swift-style anonymous functions:
I think this example is much easier to read and understand.
Solution 2: Class-level higher-order functions
If a pipe operator is too much to ask, we can at least make higher-order functions a part of the class for chaining
The text was updated successfully, but these errors were encountered: