digitalmars.D.learn - how to define infix function
- greatsam4sure (5/5) Jun 02 2018 Sorry for the typo
- =?UTF-8?Q?Ali_=c3=87ehreli?= (16/19) Jun 02 2018 This is called universal function call syntax (UFCS) in D. The idea is
- greatsam4sure (11/31) Jun 02 2018 Thanks for your reply to my question.
- KnightMare (35/41) Apr 11 2019 UFCS is not same as infix functions.
- KnightMare (5/6) Apr 11 2019 UPD
- Neia Neutuladh (28/33) Jun 02 2018 This is a horrible abuse of D's operator overloading discovered
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (33/70) Jun 02 2018 And of course, this can be generalized:
- Meta (3/77) Jun 03 2018 That is interesting. I don't know yet whether it's good or bad,
- Andrea Fontana (5/11) Jun 04 2018 Why not:
- greatsam4sure (2/32) Jun 03 2018 thanks
Sorry for the typo is it possible to define infix function in D 3.min(5)// 3: where min is a function, works in D 3 min 5 // does not work. thanks in advance
Jun 02 2018
On 06/02/2018 02:44 PM, greatsam4sure wrote:is it possible to define infix function in D 3.min(5)// 3: where min is a function, works in D 3 min 5 // does not work.This is called universal function call syntax (UFCS) in D. The idea is simple: You can pull the first argument out as if the function is a member function of that argument. So, in your case it already works because there is already a min() function that works with two (actually, many) parameters: import std.algorithm; void main() { assert(min(3, 5) == 3); assert(3.min(5) == 3); } However, many people don't like overusing it; it works well only in cases where the first parameter is arguably the "main character" in the operation. For example, min doesn't look good because all parameters have equal roles in that function. Ali
Jun 02 2018
On Saturday, 2 June 2018 at 22:01:02 UTC, Ali Çehreli wrote:On 06/02/2018 02:44 PM, greatsam4sure wrote:Thanks for your reply to my question. Your book: programming in D is real a great help learning D. I will appreciate it if your can expand the book to advance use of D. That is, dealing with D advance use Case. I discover that the D language is very advance but I am lock in the elementary yet don't know the way out. This is because D is the most Higher programming language that I ever use. Better still you can direct me to more materials about D. I am already familiar will all D books. thanksis it possible to define infix function in D 3.min(5)// 3: where min is a function, works in D 3 min 5 // does not work.This is called universal function call syntax (UFCS) in D. The idea is simple: You can pull the first argument out as if the function is a member function of that argument. So, in your case it already works because there is already a min() function that works with two (actually, many) parameters: import std.algorithm; void main() { assert(min(3, 5) == 3); assert(3.min(5) == 3); } However, many people don't like overusing it; it works well only in cases where the first parameter is arguably the "main character" in the operation. For example, min doesn't look good because all parameters have equal roles in that function. Ali
Jun 02 2018
On Saturday, 2 June 2018 at 22:01:02 UTC, Ali Çehreli wrote:On 06/02/2018 02:44 PM, greatsam4sure wrote:UFCS is not same as infix functions. infix allow to u write code like: 1)for (i in 0 to 10 step 2) // `in`(can be keyword too), `to` and `step` can be some functions that change range or something 2) auto shiftedRes = someVar shr 13; // `shr` is infix function too u can use infix function with 1arg without any parentheses. why this need? how it can be useful? look at Kotlin lang. pure functional programming. it can be useful for code looks like LINQ(.NET): DB, UI... and I think UFCS should be improved too: function with 1arg can be written without parenthesis too. for example some declarations: class Task<T> { .. }; Task<Buffer> asyncRead( File file ) { .. } T await!(T)( Task<T> task ) { .. } we can use await like: auto buf = asyncRead( file ).await(); or auto buf = await( asyncRead( file )); // I like spaces between fn-names and args but more clear IMO: auto buf = await asyncRead( file ); // less parenthesis more improvements: 1) see Kotlin passing lambda as last parameter https://kotlinlang.org/docs/reference/lambdas.html#passing-a-lambda-to-the-last-parameter 2) Kotlin/when with pattern matching. dont need change current `switch` instruction. and we can make `when` as expression (look Kotlin samples) 3) scope functions https://kotlinlang.org/docs/reference/scope-functions.html with(button) { text = "hello"; background = Colors.Yellow; } text & background are props of some Button class for instance button. {} is a lambda as last argis it possible to define infix function in D 3.min(5)// 3: where min is a function, works in D 3 min 5 // does not work.This is called universal function call syntax (UFCS) in D. Ali
Apr 11 2019
u can use infix function with 1arg without any parentheses.UPD with 2args arg1 `infix func` arg2 latter I told about UFCS with 1arg `UFCS func` arg1
Apr 11 2019
On Saturday, 2 June 2018 at 21:44:39 UTC, greatsam4sure wrote:Sorry for the typo is it possible to define infix function in D 3.min(5)// 3: where min is a function, works in D 3 min 5 // does not work. thanks in advanceThis is a horrible abuse of D's operator overloading discovered by FeepingCreature in the distant past. You have to delimit your custom infix operator with slashes; you can't make `3 min 5` work, but you can make `3 /min/ 5` work. Observe: struct Min { MinIntermediate!T opBinaryRight(string op, T)(T value) if (op == "/") { return MinIntermediate!T(value); } } struct MinIntermediate(T) { T value; T opBinary(string op, T)(T value2) if (op == "/") { if (value < value2) return value; return value2; } } Min min; void main() { writeln(1 /min/ 2); }
Jun 02 2018
On Saturday, 2 June 2018 at 22:09:49 UTC, Neia Neutuladh wrote:On Saturday, 2 June 2018 at 21:44:39 UTC, greatsam4sure wrote:And of course, this can be generalized: struct Operator(alias fn, string operator = "/") { static auto opBinaryRight(string op : operator, T...)(T value1) { struct Result { auto opBinary(string op : operator, U...)(U value2) if (__traits(compiles, fn(value1, value2))) { return fn(value1, value2); } } Result result; return result; } } unittest { import std.algorithm.comparison; alias min = Operator!(std.algorithm.comparison.min); assert(1 /min/ 3 == 1); } Note also the use of static opBinaryRight, allowing one to eschew the 'min' variable. All of this said, I would suggest not using this in prod - it's a neat trick that shows off some of D's power, but I don't see a case where this would be easier to understand than a straightforward function call. -- SimenSorry for the typo is it possible to define infix function in D 3.min(5)// 3: where min is a function, works in D 3 min 5 // does not work. thanks in advanceThis is a horrible abuse of D's operator overloading discovered by FeepingCreature in the distant past. You have to delimit your custom infix operator with slashes; you can't make `3 min 5` work, but you can make `3 /min/ 5` work. Observe: struct Min { MinIntermediate!T opBinaryRight(string op, T)(T value) if (op == "/") { return MinIntermediate!T(value); } } struct MinIntermediate(T) { T value; T opBinary(string op, T)(T value2) if (op == "/") { if (value < value2) return value; return value2; } } Min min; void main() { writeln(1 /min/ 2); }
Jun 02 2018
On Saturday, 2 June 2018 at 23:17:48 UTC, Simen Kjærås wrote:On Saturday, 2 June 2018 at 22:09:49 UTC, Neia Neutuladh wrote:That is interesting. I don't know yet whether it's good or bad, but certainly, it's interesting.On Saturday, 2 June 2018 at 21:44:39 UTC, greatsam4sure wrote:And of course, this can be generalized: struct Operator(alias fn, string operator = "/") { static auto opBinaryRight(string op : operator, T...)(T value1) { struct Result { auto opBinary(string op : operator, U...)(U value2) if (__traits(compiles, fn(value1, value2))) { return fn(value1, value2); } } Result result; return result; } } unittest { import std.algorithm.comparison; alias min = Operator!(std.algorithm.comparison.min); assert(1 /min/ 3 == 1); } Note also the use of static opBinaryRight, allowing one to eschew the 'min' variable. All of this said, I would suggest not using this in prod - it's a neat trick that shows off some of D's power, but I don't see a case where this would be easier to understand than a straightforward function call. -- SimenSorry for the typo is it possible to define infix function in D 3.min(5)// 3: where min is a function, works in D 3 min 5 // does not work. thanks in advanceThis is a horrible abuse of D's operator overloading discovered by FeepingCreature in the distant past. You have to delimit your custom infix operator with slashes; you can't make `3 min 5` work, but you can make `3 /min/ 5` work. Observe: struct Min { MinIntermediate!T opBinaryRight(string op, T)(T value) if (op == "/") { return MinIntermediate!T(value); } } struct MinIntermediate(T) { T value; T opBinary(string op, T)(T value2) if (op == "/") { if (value < value2) return value; return value2; } } Min min; void main() { writeln(1 /min/ 2); }
Jun 03 2018
On Saturday, 2 June 2018 at 23:17:48 UTC, Simen Kjærås wrote:unittest { import std.algorithm.comparison; alias min = Operator!(std.algorithm.comparison.min); assert(1 /min/ 3 == 1); }Why not: alias Δ = Operator!(std.algorithm.comparison.min); assert(1 /Δ/ 3 == 1); To improve readibility :)
Jun 04 2018
On Saturday, 2 June 2018 at 22:09:49 UTC, Neia Neutuladh wrote:On Saturday, 2 June 2018 at 21:44:39 UTC, greatsam4sure wrote:thanks[...]This is a horrible abuse of D's operator overloading discovered by FeepingCreature in the distant past. You have to delimit your custom infix operator with slashes; you can't make `3 min 5` work, but you can make `3 /min/ 5` work. Observe: struct Min { MinIntermediate!T opBinaryRight(string op, T)(T value) if (op == "/") { return MinIntermediate!T(value); } } struct MinIntermediate(T) { T value; T opBinary(string op, T)(T value2) if (op == "/") { if (value < value2) return value; return value2; } } Min min; void main() { writeln(1 /min/ 2); }
Jun 03 2018