digitalmars.D - std.bind documentation sucks hard
- Georg Wrede (43/43) Feb 22 2009 At first sight I thought I had become stupid. Reading the page once
- Andrei Alexandrescu (12/20) Feb 22 2009 Yah, I agree, std.bind is terribly outdated. Recent progress of D makes
- Tom S (13/23) Feb 22 2009 Well, I'll be that smarta** then. I've mostly implemented Bind for fun
- downs (7/7) Feb 22 2009 Let me say first that I don't use std.bind myself, but tools.base:fix fi...
- grauzone (3/3) Feb 23 2009 A great example of how to get rid of weird, obfuscating template hacks
- Jason House (3/16) Feb 23 2009 I look at bind as the difference between by reference and by value seman...
- Lars Kyllingstad (7/26) Feb 24 2009 I've always thought currying was the main point of std.bind. If I'm not
- Yigal Chripun (7/43) Feb 24 2009 you don't need bind for currying, it's even possible to do this in C:
- downs (5/24) Feb 24 2009 Just for comparison' sake:
- bearophile (4/7) Feb 24 2009 I like none of those :-) (but the 2.0 literal is a bit better).
- Yigal Chripun (4/27) Feb 24 2009 auto dg = foo(_, somevar);
- Lars Kyllingstad (13/43) Feb 24 2009 I for one like it, and would very much like to see such a syntax in D2.
- Yigal Chripun (11/56) Feb 24 2009 no such restriction was intended. but that's good that you made this
- Lars Kyllingstad (18/84) Feb 24 2009 I'm on thin ice here, I know, but consider the following simple example:
- Lars Kyllingstad (6/12) Feb 24 2009 Correction: bar shouldn't be marked as pure here, or I guess it wouldn't...
- Daniel Keep (22/48) Feb 24 2009 There was a proposal made by Walter (or possibly Andrei) involving
- bearophile (4/6) Feb 24 2009 ...or by me :-)
- Daniel Keep (7/25) Feb 24 2009 auto a = b(_, c(_, x), _);
- Lars Kyllingstad (5/35) Feb 24 2009 Good point. How about this alternative syntax, then:
- Daniel Keep (10/49) Feb 24 2009 This doesn't address the problem of what, exactly, the context of the
- Yigal Chripun (31/56) Feb 24 2009 given the following functions:
- Andrei Alexandrescu (23/27) Feb 24 2009 I'd agree that generally there's a strong bias in this group for adding
- Ary Borenszweig (2/34) Feb 24 2009 How do you curry on the second argument?
- Andrei Alexandrescu (5/40) Feb 24 2009 That's not currying, it's binding.
- Yigal Chripun (3/31) Feb 24 2009 I disagree with this notion. there are requests to add new *useful* feat...
- Andrei Alexandrescu (7/16) Feb 24 2009 There's a much stronger bias to add than remove, and IMHO adding to the
- bearophile (9/10) Feb 24 2009 Yes, unfortunately with time most (or all) languages tend to grow, and t...
- Lars Kyllingstad (3/37) Feb 25 2009 I like the syntax, and I agree that this belongs in std.functional.
- Jason House (3/37) Feb 25 2009 I've done the whole boost::bind thing before and it sucks. When boost::l...
- Andrei Alexandrescu (30/56) Feb 25 2009 So let's see. If what you have is a function int fun(int, int) and you
- Denis Koroskin (27/80) Feb 25 2009 I don't want to offend anyone, but this syntax sucks badly.
- Andrei Alexandrescu (21/63) Feb 25 2009 Of course it is shorter. You seldom need makeDelegate. And the more
- Georg Wrede (12/17) Feb 25 2009 then it is possible that the post did not gather the impact and readers
- Michel Fortin (9/16) Feb 25 2009 I pretty much agree with this. What's great about this is that you just
- Jason House (5/71) Feb 25 2009 The first follow-up to your reply captured the kind of messiness bind ca...
- Walter Bright (13/14) Feb 25 2009 You do caps, quotes, special characters, correct grammar with your thumb...
- Jarrett Billingsley (3/6) Feb 25 2009 There are cell phones with QWERTY keypads (or touchscreens) now, you kno...
-
Walter Bright
(3/4)
Feb 25 2009
I am soo obsolete
! My cell phone has a number pad on it. When I even... - Christopher Wright (4/23) Feb 25 2009 Playstation 3 (and possibly Playstation 2) has USB ports and USB HID
- Daniel Keep (10/34) Feb 25 2009 The XBox 360 supports keyboards as well, although not mice (I understand
- Jason House (8/15) Feb 25 2009 Who says I don't have a full keyboard? Ok, well, it's a tiny keyboard o...
- Andrei Alexandrescu (10/14) Feb 25 2009 I see. The only problem is that very few people seem to use std.bind;
- Bill Baxter (8/21) Feb 25 2009 I think simple is fine here.
- Jason House (16/30) Feb 25 2009 I was one of those people using bind when I was using D1, and I didn't
- Don (3/21) Feb 26 2009 Yes. I think that the smaller Phobos can be, the better. Make sure that
- Denis Koroskin (5/36) Feb 24 2009 void foo(int x, int y) { ... }
At first sight I thought I had become stupid. Reading the page once through left me with absolutely no notion on how or to what one should or could use bind. (And that coming from someone who actually has studied the STL hard (albeit 10 years ago)). I can only imagine how much the average D-newcomer gets out of the page. First of all, the function bind itself is impossible to find simply by scanning the page. It also isn't in the Jump List at the top. Turns out it is hidden behind a scary line starting with typeof(new BoundFunc...)... stuff. (Yes, I understand it has to be there, but the word bind itself *has* to be "findable" by eyeballing the page down from the top. So put the word bind, e.g. in a mini-heading or whatever right before that line!) There are no examples. Yes, there are commands in example-style boxes, but they aren't examples, since all we have is the bare command invocation. An example (heh, even this post has one) of what I mean: - bind(&foo, _0, _1) // will yield a delegate accepting two parameters - bind(&foo, _1, _0) // will yield a delegate accepting two parameters - bind(&bar, _0, _1, _2, _0) // will yield a delegate accepting three parameters What does this tell the _new_ reader?? Another example is "const DynArg!(2) _2;" What do I use it for, and where. And how do I use it? One would also expect that at the start of the page there is some text explaining the concept itself, where one should use bind, and for what benefit. The fact that nobody has yet pointed out the blatant typo in the "long" "example" that I pasted above, only serves to show that most readers try to read and understand the page, and give up. And the page has been there for over 2 years. It is not impossible to write good D doc pages, for example std.signals does a much better job. Or std.getopt. And before any smarta** says well, georg, why don't you fix it, I have to remind that currently I hardly have the time to read these NGs. But even then, for every few hours of reading, I at least try to give a meaningful contribution in exchange. Another smarta** might say that "it says References: boost" so read that. Well, one could say this about every single doc page on the site. Anyhow, if Tomasz Stachowiak (whom I'm not attacking with this post!) is unavailable, then I wish somebody who actually uses bind, could submit a better version. Even a little improvement would be most welcome. PS: with the newest developments in D2, bind is suddenly becoming an essential part of the new kind of D programming that is currently becoming possible!
Feb 22 2009
Georg Wrede wrote:At first sight I thought I had become stupid. Reading the page once through left me with absolutely no notion on how or to what one should or could use bind. (And that coming from someone who actually has studied the STL hard (albeit 10 years ago)). I can only imagine how much the average D-newcomer gets out of the page.[snip]PS: with the newest developments in D2, bind is suddenly becoming an essential part of the new kind of D programming that is currently becoming possible!Yah, I agree, std.bind is terribly outdated. Recent progress of D makes std.bind look like a curious silex tool. It's due for a complete rewrite. I don't have much time for that at the moment, but let's reframe this as an opportunity. Several people offered to tender their help to Phobos. Are there any takers for a new std.bind design? To avoid wasting work, let's discuss an interface first before doing any implementation. I have something in mind, but I don't want to bias anyone. So, I'm renaming this thread and launching a design contest for the new std.bind. First step: how should the interface look like? Andrei
Feb 22 2009
Georg Wrede wrote:Another smarta** might say that "it says References: boost" so read that. Well, one could say this about every single doc page on the site.Well, I'll be that smarta** then. I've mostly implemented Bind for fun and I hate writing docs. I'm not sure if I actually use it in more than two(?) places in all of my projects and there was very little interest in it except the Phobos inclusion. Thus spending a few days writing docs that are already there (see the smarta** reference) was the last thing I wanted to do.Anyhow, if Tomasz Stachowiak (whom I'm not attacking with this post!) is unavailable, then I wish somebody who actually uses bind, could submit a better version. Even a little improvement would be most welcome. PS: with the newest developments in D2, bind is suddenly becoming an essential part of the new kind of D programming that is currently becoming possible!I'm not even sure what kind of improvements it needs except the docs since I don't really use it myself and I'm stuck with D1 anyway... -- Tomasz Stachowiak http://h3.team0xf.com/ h3/h3r3tic on #D freenode
Feb 22 2009
Let me say first that I don't use std.bind myself, but tools.base:fix fills essentially the same need - creating full closures from dynamic ones. Say you have a function that takes a number and returns a delegate that does something with that number. void delegate() test(int i) { return { return i + 2; }; } In 2.0 this will ...................... Oh. Nevermind. I don't know what to use bind for after all :) In fact, I suspect it's essentially useless in 2.0. Creating full closures was my only use case :)
Feb 22 2009
A great example of how to get rid of weird, obfuscating template hacks by introducing simple and powerful language features. I'm not sure if this makes it worth to switch to D2.0, though.
Feb 23 2009
downs Wrote:Let me say first that I don't use std.bind myself, but tools.base:fix fills essentially the same need - creating full closures from dynamic ones. Say you have a function that takes a number and returns a delegate that does something with that number. void delegate() test(int i) { return { return i + 2; }; } In 2.0 this will ...................... Oh. Nevermind. I don't know what to use bind for after all :) In fact, I suspect it's essentially useless in 2.0. Creating full closures was my only use case :)I look at bind as the difference between by reference and by value semantics. When using scope delegates (or delegates that could be scope delegates), this difference rarely matters. When passing data between threads, the need to pass by value becomes more important. "By value" may even require a deep copy. Even though I can see uses for some kind of bind functionality in D2, I need to see where all this "shared" object stuff goes before I know what/if a D2 bind library should do.
Feb 23 2009
Jason House wrote:downs Wrote:I've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -LarsLet me say first that I don't use std.bind myself, but tools.base:fix fills essentially the same need - creating full closures from dynamic ones. Say you have a function that takes a number and returns a delegate that does something with that number. void delegate() test(int i) { return { return i + 2; }; } In 2.0 this will ...................... Oh. Nevermind. I don't know what to use bind for after all :) In fact, I suspect it's essentially useless in 2.0. Creating full closures was my only use case :)I look at bind as the difference between by reference and by value semantics. When using scope delegates (or delegates that could be scope delegates), this difference rarely matters. When passing data between threads, the need to pass by value becomes more important. "By value" may even require a deep copy. Even though I can see uses for some kind of bind functionality in D2, I need to see where all this "shared" object stuff goes before I know what/if a D2 bind library should do.
Feb 24 2009
Lars Kyllingstad wrote:Jason House wrote:you don't need bind for currying, it's even possible to do this in C: int foo(int a, int b) { ... } int bar(int a) { return foo(a, _value); } // curry with some _value Other languages provide useful syntax sugar for currying: auto bar2 = foo(_, 500); bar2 here will be a delegate that will do the the same as the above bar.downs Wrote:I've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -LarsLet me say first that I don't use std.bind myself, but tools.base:fix fills essentially the same need - creating full closures from dynamic ones. Say you have a function that takes a number and returns a delegate that does something with that number. void delegate() test(int i) { return { return i + 2; }; } In 2.0 this will ...................... Oh. Nevermind. I don't know what to use bind for after all :) In fact, I suspect it's essentially useless in 2.0. Creating full closures was my only use case :)I look at bind as the difference between by reference and by value semantics. When using scope delegates (or delegates that could be scope delegates), this difference rarely matters. When passing data between threads, the need to pass by value becomes more important. "By value" may even require a deep copy. Even though I can see uses for some kind of bind functionality in D2, I need to see where all this "shared" object stuff goes before I know what/if a D2 bind library should do.
Feb 24 2009
Yigal Chripun wrote:Lars Kyllingstad wrote:Just for comparison' sake: auto dg = &foo /rfix/ somevar; // 1.0, tools auto dg = _bind(&foo, _1, somevar); // 1.0, std.bind auto dg = (int a) { return foo(a, somevar); }; // 2.0, literalI've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -Larsyou don't need bind for currying, it's even possible to do this in C: int foo(int a, int b) { ... } int bar(int a) { return foo(a, _value); } // curry with some _value Other languages provide useful syntax sugar for currying: auto bar2 = foo(_, 500); bar2 here will be a delegate that will do the the same as the above bar.
Feb 24 2009
downs:auto dg = &foo /rfix/ somevar; // 1.0, tools auto dg = _bind(&foo, _1, somevar); // 1.0, std.bind auto dg = (int a) { return foo(a, somevar); }; // 2.0, literalI like none of those :-) (but the 2.0 literal is a bit better). Bye, bearophile
Feb 24 2009
downs wrote:Yigal Chripun wrote:auto dg = foo(_, somevar); So does that mean you like the above suggestion? after all, it's shorter and clearer than all the other alternatives.. ;)Lars Kyllingstad wrote:Just for comparison' sake: auto dg =&foo /rfix/ somevar; // 1.0, tools auto dg = _bind(&foo, _1, somevar); // 1.0, std.bind auto dg = (int a) { return foo(a, somevar); }; // 2.0, literalI've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -Larsyou don't need bind for currying, it's even possible to do this in C: int foo(int a, int b) { ... } int bar(int a) { return foo(a, _value); } // curry with some _value Other languages provide useful syntax sugar for currying: auto bar2 = foo(_, 500); bar2 here will be a delegate that will do the the same as the above bar.
Feb 24 2009
Yigal Chripun wrote:downs wrote:I for one like it, and would very much like to see such a syntax in D2. Also, I'd have it work with either of a function's arguments, not only the leading or trailing ones: int foo(int a, int b, int c, int d) {...} auto bar1 = foo(_, b, c, d); auto bar2 = foo(a, b, c, _); auto bar3 = foo(_, b, _, d); assert (is (typeof(bar3) == int delegate(int, int))); In its simplest form, it would just be syntactic sugar for the delegate literal. But I'm curious: If foo is a pure function, couldn't the compiler perform some extra optimization here? -LarsYigal Chripun wrote:auto dg = foo(_, somevar); So does that mean you like the above suggestion? after all, it's shorter and clearer than all the other alternatives.. ;)Lars Kyllingstad wrote:Just for comparison' sake: auto dg =&foo /rfix/ somevar; // 1.0, tools auto dg = _bind(&foo, _1, somevar); // 1.0, std.bind auto dg = (int a) { return foo(a, somevar); }; // 2.0, literalI've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -Larsyou don't need bind for currying, it's even possible to do this in C: int foo(int a, int b) { ... } int bar(int a) { return foo(a, _value); } // curry with some _value Other languages provide useful syntax sugar for currying: auto bar2 = foo(_, 500); bar2 here will be a delegate that will do the the same as the above bar.
Feb 24 2009
Lars Kyllingstad wrote:Yigal Chripun wrote:downs wrote:I for one like it, and would very much like to see such a syntax in D2. Also, I'd have it work with either of a function's arguments, not only the leading or trailing ones:Yigal Chripun wrote:auto dg = foo(_, somevar); So does that mean you like the above suggestion? after all, it's shorter and clearer than all the other alternatives.. ;)Lars Kyllingstad wrote:Just for comparison' sake: auto dg =&foo /rfix/ somevar; // 1.0, tools auto dg = _bind(&foo, _1, somevar); // 1.0, std.bind auto dg = (int a) { return foo(a, somevar); }; // 2.0, literalI've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -Larsyou don't need bind for currying, it's even possible to do this in C: int foo(int a, int b) { ... } int bar(int a) { return foo(a, _value); } // curry with some _value Other languages provide useful syntax sugar for currying: auto bar2 = foo(_, 500); bar2 here will be a delegate that will do the the same as the above bar.int foo(int a, int b, int c, int d) {...} auto bar1 = foo(_, b, c, d); auto bar2 = foo(a, b, c, _); auto bar3 = foo(_, b, _, d); assert (is (typeof(bar3) == int delegate(int, int)));no such restriction was intended. but that's good that you made this clear. the only restriction here is re-ordering: bar3(A, C) will always call foo(A, b, C, d) but since it's just syntax sugar and will be expanded by the language to the delegate literal this is not a big deal - the user can always re-order arguments by using the delegate literal syntax directly: auto reordered_bar3 = (int C, int A) { return foo(A, b, C, d); };In its simplest form, it would just be syntactic sugar for the delegate literal. But I'm curious: If foo is a pure function, couldn't the compiler perform some extra optimization here? -Larswhat kind of optimizations you had in mind? b & d in bar3 above can be specified at run-time so you can't avoid the intermidiate delegate, I think.
Feb 24 2009
Yigal Chripun wrote:Lars Kyllingstad wrote:I'm on thin ice here, I know, but consider the following simple example: pure real foo(real a, real b, real c) { auto tmp = sqrt(b + c); return tmp + a; } auto bar = foo(_, x, y); Since bar now carries with it the last two arguments, it should in principle only have to calculate the square root once, i.e. the last line above would be equivalent to something like struct Bar { auto tmp; pure real bar(real a) { return tmp + a; } } auto bar = &Bar(sqrt(x+y)).bar; -LarsYigal Chripun wrote:downs wrote:I for one like it, and would very much like to see such a syntax in D2. Also, I'd have it work with either of a function's arguments, not only the leading or trailing ones:Yigal Chripun wrote:auto dg = foo(_, somevar); So does that mean you like the above suggestion? after all, it's shorter and clearer than all the other alternatives.. ;)Lars Kyllingstad wrote:Just for comparison' sake: auto dg =&foo /rfix/ somevar; // 1.0, tools auto dg = _bind(&foo, _1, somevar); // 1.0, std.bind auto dg = (int a) { return foo(a, somevar); }; // 2.0, literalI've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -Larsyou don't need bind for currying, it's even possible to do this in C: int foo(int a, int b) { ... } int bar(int a) { return foo(a, _value); } // curry with some _value Other languages provide useful syntax sugar for currying: auto bar2 = foo(_, 500); bar2 here will be a delegate that will do the the same as the above bar.int foo(int a, int b, int c, int d) {...} auto bar1 = foo(_, b, c, d); auto bar2 = foo(a, b, c, _); auto bar3 = foo(_, b, _, d); assert (is (typeof(bar3) == int delegate(int, int)));no such restriction was intended. but that's good that you made this clear. the only restriction here is re-ordering: bar3(A, C) will always call foo(A, b, C, d) but since it's just syntax sugar and will be expanded by the language to the delegate literal this is not a big deal - the user can always re-order arguments by using the delegate literal syntax directly: auto reordered_bar3 = (int C, int A) { return foo(A, b, C, d); };In its simplest form, it would just be syntactic sugar for the delegate literal. But I'm curious: If foo is a pure function, couldn't the compiler perform some extra optimization here? -Larswhat kind of optimizations you had in mind? b & d in bar3 above can be specified at run-time so you can't avoid the intermidiate delegate, I think.
Feb 24 2009
Lars Kyllingstad wrote:struct Bar { auto tmp; pure real bar(real a) { return tmp + a; } }Correction: bar shouldn't be marked as pure here, or I guess it wouldn't have access to tmp. But you get my point: It should be possible to factor out the calculations that only involve the curryed arguments, and only perform them once. -Lars
Feb 24 2009
Lars Kyllingstad wrote:I'm on thin ice here, I know, but consider the following simple example: pure real foo(real a, real b, real c) { auto tmp = sqrt(b + c); return tmp + a; } auto bar = foo(_, x, y); Since bar now carries with it the last two arguments, it should in principle only have to calculate the square root once, i.e. the last line above would be equivalent to something like struct Bar { auto tmp; pure real bar(real a) { return tmp + a; } } auto bar = &Bar(sqrt(x+y)).bar; -LarsThere was a proposal made by Walter (or possibly Andrei) involving partial specialisation. pure real foo(real a, static real b, static real c) { return a + sqrt(b + c); } void main() { auto x = foo(1, 2, 3); } Would automagically become: pure real foo_2_3(real a) { return a + (value of sqrt(b+c), assuming sqrt was CTFE-enabled); } void main() { auto x = foo_2_3(1); } Still waiting for it, though :) -- Daniel
Feb 24 2009
Daniel Keep:There was a proposal made by Walter (or possibly Andrei) involving partial specialisation....or by me :-) Bye, bearophile
Feb 24 2009
Lars Kyllingstad wrote:[snip] I for one like it, and would very much like to see such a syntax in D2. Also, I'd have it work with either of a function's arguments, not only the leading or trailing ones: int foo(int a, int b, int c, int d) {...} auto bar1 = foo(_, b, c, d); auto bar2 = foo(a, b, c, _); auto bar3 = foo(_, b, _, d); assert (is (typeof(bar3) == int delegate(int, int))); In its simplest form, it would just be syntactic sugar for the delegate literal. But I'm curious: If foo is a pure function, couldn't the compiler perform some extra optimization here? -Larsauto a = b(_, c(_, x), _); What are the types of a, b and c? What if b has multiple overloads or is templated? Context-dependant grammar (let alone context-dependant single character symbols): just say "no". -- Daniel
Feb 24 2009
Daniel Keep wrote:Lars Kyllingstad wrote:Good point. How about this alternative syntax, then: auto bar3 = foo(int, b, int, d); Will this also cause problems? -Lars[snip] I for one like it, and would very much like to see such a syntax in D2. Also, I'd have it work with either of a function's arguments, not only the leading or trailing ones: int foo(int a, int b, int c, int d) {...} auto bar1 = foo(_, b, c, d); auto bar2 = foo(a, b, c, _); auto bar3 = foo(_, b, _, d); assert (is (typeof(bar3) == int delegate(int, int))); In its simplest form, it would just be syntactic sugar for the delegate literal. But I'm curious: If foo is a pure function, couldn't the compiler perform some extra optimization here? -Larsauto a = b(_, c(_, x), _); What are the types of a, b and c? What if b has multiple overloads or is templated? Context-dependant grammar (let alone context-dependant single character symbols): just say "no". -- Daniel
Feb 24 2009
Lars Kyllingstad wrote:Daniel Keep wrote:This doesn't address the problem of what, exactly, the context of the curried arguments is. What's more, you're putting a type where an expression is expected; I don't see how you get "currying" from "repeating an argument type." The problem I have with these suggestions are that you're basically arguing for an incredibly inflexible, context-dependant, completely unintuitive syntax for something you already have working syntax for. I just don't see the point. -- DanielLars Kyllingstad wrote:Good point. How about this alternative syntax, then: auto bar3 = foo(int, b, int, d); Will this also cause problems? -Lars[snip] I for one like it, and would very much like to see such a syntax in D2. Also, I'd have it work with either of a function's arguments, not only the leading or trailing ones: int foo(int a, int b, int c, int d) {...} auto bar1 = foo(_, b, c, d); auto bar2 = foo(a, b, c, _); auto bar3 = foo(_, b, _, d); assert (is (typeof(bar3) == int delegate(int, int))); In its simplest form, it would just be syntactic sugar for the delegate literal. But I'm curious: If foo is a pure function, couldn't the compiler perform some extra optimization here? -Larsauto a = b(_, c(_, x), _); What are the types of a, b and c? What if b has multiple overloads or is templated? Context-dependant grammar (let alone context-dependant single character symbols): just say "no". -- Daniel
Feb 24 2009
Daniel Keep wrote:given the following functions: int foo(int a, int b) {..} int bar(int x, int delegate(int) dg, int z) {..} here's the example you gave above in current D2: (not tested) auto temp = int(int a) { return foo(a, somevar); }; auto dg = int(int a, int c) { return bar(a, temp, c); }; or you can do it in one go: auto dg = int(int a, int c) { return bar(a, (int x){ return foo(x, somevar); }, c); }; surely using instead the following is much clearer: auto dg = bar(_, foo(_, somevar), _); all it does is generate the delegates for you. what do you mean by "the context of the curried arguments"? regarding your point on context-dependency: that is a good point indeed and can be solved by either using Lars' alternative syntax or by making ambiguities compile time errors. given the following functions: void foo(int x, int y) { ... } void foo(float x, int y) { ... } here's what happens: auto dg = foo(_, 0); // compile time error - ambiguity void delegate(int) dg = foo(_, 0); // select first overload void delegate(float) dg = foo(_, 0); // select second overload this is similar to &foo only that if there are overloads of foo: auto dg = &foo; // this IMHO shouldn't compile IIRC, the current behavior is to use the first foo. with your example, the compiler knows the signature of bar and can choose the correct overload of foo based on its type. if there's more than one overload of bar than the programmer needs to specify the type of bar to disambiguate.This doesn't address the problem of what, exactly, the context of the curried arguments is. What's more, you're putting a type where an expression is expected; I don't see how you get "currying" from "repeating an argument type." The problem I have with these suggestions are that you're basically arguing for an incredibly inflexible, context-dependant, completely unintuitive syntax for something you already have working syntax for. I just don't see the point. -- Danielauto a = b(_, c(_, x), _); What are the types of a, b and c? What if b has multiple overloads or is templated? Context-dependant grammar (let alone context-dependant single character symbols): just say "no". -- DanielGood point. How about this alternative syntax, then: auto bar3 = foo(int, b, int, d); Will this also cause problems? -Lars
Feb 24 2009
Daniel Keep wrote:The problem I have with these suggestions are that you're basically arguing for an incredibly inflexible, context-dependant, completely unintuitive syntax for something you already have working syntax for. I just don't see the point.I'd agree that generally there's a strong bias in this group for adding to the language. Every itsy-bitsy issue comes around, there are a dozen cute syntaxes invented for it right on the spot. And then once every few months, there's the inevitable huge thread "Where did my simple language go???" :o) Currying/binding can be done easily with a library, and the implementation is so simple there's no need for a separate file dedicated to it. The one interesting case is currying a function passed by alias. In that case there's no indirect call, just a little struct created that contains the curried state: int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think? Andrei
Feb 24 2009
Andrei Alexandrescu wrote:Daniel Keep wrote:How do you curry on the second argument?The problem I have with these suggestions are that you're basically arguing for an incredibly inflexible, context-dependant, completely unintuitive syntax for something you already have working syntax for. I just don't see the point.I'd agree that generally there's a strong bias in this group for adding to the language. Every itsy-bitsy issue comes around, there are a dozen cute syntaxes invented for it right on the spot. And then once every few months, there's the inevitable huge thread "Where did my simple language go???" :o) Currying/binding can be done easily with a library, and the implementation is so simple there's no need for a separate file dedicated to it. The one interesting case is currying a function passed by alias. In that case there's no indirect call, just a little struct created that contains the curried state: int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think?
Feb 24 2009
Ary Borenszweig wrote:Andrei Alexandrescu wrote:That's not currying, it's binding. auto plus5rhs = bind!(plus, 2)(5); etc. AndreiDaniel Keep wrote:How do you curry on the second argument?The problem I have with these suggestions are that you're basically arguing for an incredibly inflexible, context-dependant, completely unintuitive syntax for something you already have working syntax for. I just don't see the point.I'd agree that generally there's a strong bias in this group for adding to the language. Every itsy-bitsy issue comes around, there are a dozen cute syntaxes invented for it right on the spot. And then once every few months, there's the inevitable huge thread "Where did my simple language go???" :o) Currying/binding can be done easily with a library, and the implementation is so simple there's no need for a separate file dedicated to it. The one interesting case is currying a function passed by alias. In that case there's no indirect call, just a little struct created that contains the curried state: int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think?
Feb 24 2009
Andrei Alexandrescu Wrote:I'd agree that generally there's a strong bias in this group for adding to the language. Every itsy-bitsy issue comes around, there are a dozen cute syntaxes invented for it right on the spot. And then once every few months, there's the inevitable huge thread "Where did my simple language go???" :o)I disagree with this notion. there are requests to add new *useful* features but there are also requests to remove unneeded features, latest was the discussion of the implicit concatenation of string literals. There was a thread not long ago listing the features most people want to remove - foreach_reverse comes to mind. that how evolution works - you add new useful stuff and remove old unneeded baggage. both are equally important.Currying/binding can be done easily with a library, and the implementation is so simple there's no need for a separate file dedicated to it. The one interesting case is currying a function passed by alias. In that case there's no indirect call, just a little struct created that contains the curried state: int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think? Andrei
Feb 24 2009
Yigal Chripun wrote:Andrei Alexandrescu Wrote:There's a much stronger bias to add than remove, and IMHO adding to the language for currying is just unnecessary. I'll venture the thought that for those who don't use the language often enough it's not easy to envision how something could be implemented within it, and inventing a new specialized feature for the problem at hand comes very easily. AndreiI'd agree that generally there's a strong bias in this group for adding to the language. Every itsy-bitsy issue comes around, there are a dozen cute syntaxes invented for it right on the spot. And then once every few months, there's the inevitable huge thread "Where did my simple language go???" :o)I disagree with this notion. there are requests to add new *useful* features but there are also requests to remove unneeded features, latest was the discussion of the implicit concatenation of string literals. There was a thread not long ago listing the features most people want to remove - foreach_reverse comes to mind. that how evolution works - you add new useful stuff and remove old unneeded baggage. both are equally important.
Feb 24 2009
Andrei Alexandrescu:There's a much stronger bias to add than remove,Yes, unfortunately with time most (or all) languages tend to grow, and to become more complex and hairy. And often there's no way to fix this problem, the complexity keeps growing, until people want to create a better new language that finds better ways to do most of those things with less complexity. Even in language communities that value language simplicity and clarity above almost everything else like the Python community, where they are even willing to break the high-valued backward compatibility, they have created Python3 that removes as many warts and duplicated features as possible, yet, Python3 is more complex than Python 2.5 still. One of the big intrinsic disadvantages of the C++ and D languages is that they have a lot of near-duplicated features, one feature from C and one new way to do essentially the same thing. This of course has some advantages (C compatibility first of all, but also the old C features are often the more efficient ones, when you really need max performance). Regarding binding and currying and other functional features, you/we have to decide the future taste of D2. If people want to make D2 more functional-tasting, then some functional features may be better as built-ins. Regardless your choice, I suggest all D designers to often look at the Scala far from perfect, and in some regards may already be too much complex, but it shows interesting ways to mix OOP, mutation, actor-based multiprocessing, and strong functional features with a type system much more refined than the current one used in D2. So it partly shows how D2 or D3 may look. To be more precise, I now think D2 doesn't need much the pattern matching (because it's useful but it also adds a significant amount of complexity to the language), but it may enjoy to gain Algebraic Data Types (http://en.wikipedia.org/wiki/Algebraic_data_type ), more than AST macros. ADTs too add complexity and require a more complex type system, but they allow a to express several things in a quite compact way, add power to the language, etc :-) Bye, bearophile
Feb 24 2009
Andrei Alexandrescu wrote:Daniel Keep wrote:I like the syntax, and I agree that this belongs in std.functional. -LarsThe problem I have with these suggestions are that you're basically arguing for an incredibly inflexible, context-dependant, completely unintuitive syntax for something you already have working syntax for. I just don't see the point.I'd agree that generally there's a strong bias in this group for adding to the language. Every itsy-bitsy issue comes around, there are a dozen cute syntaxes invented for it right on the spot. And then once every few months, there's the inevitable huge thread "Where did my simple language go???" :o) Currying/binding can be done easily with a library, and the implementation is so simple there's no need for a separate file dedicated to it. The one interesting case is currying a function passed by alias. In that case there's no indirect call, just a little struct created that contains the curried state: int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think? Andrei
Feb 25 2009
Andrei Alexandrescu Wrote:Daniel Keep wrote:I've done the whole boost::bind thing before and it sucks. When boost::lambda came out, that was way better. Anonymous delegates are even better. Learning a separate functional syntax will always be a sub par solution to me. I'll go even further. If D had only what you've proposed for ranges and std.functional but lacked opApply and anonymous delegates, I never would have become a D user. Simple, clean syntax is that important to me... Please don't recreate boost and STL in D. They're great libraries, but we can do way better than that!The problem I have with these suggestions are that you're basically arguing for an incredibly inflexible, context-dependant, completely unintuitive syntax for something you already have working syntax for. I just don't see the point.I'd agree that generally there's a strong bias in this group for adding to the language. Every itsy-bitsy issue comes around, there are a dozen cute syntaxes invented for it right on the spot. And then once every few months, there's the inevitable huge thread "Where did my simple language go???" :o) Currying/binding can be done easily with a library, and the implementation is so simple there's no need for a separate file dedicated to it. The one interesting case is currying a function passed by alias. In that case there's no indirect call, just a little struct created that contains the curried state: int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think? Andrei
Feb 25 2009
Jason House wrote:Andrei Alexandrescu Wrote:So let's see. If what you have is a function int fun(int, int) and you want to fix its first parameter to a specific value, you can write: (int x) { return fun(42, x); } That would be a function literal. To give it a name, you can say: int gun(int x) { return fun(42, x); } If you want to pass that thing around, you take &gun (or &(literal)) and transform it into a delegate. One minor issue with the above is that the syntax is rather verbose and that the relationship between the function, the parameter, and the outcome is not conceptualized. Yes, the constructs can curry any function, but you have no *notion* of currying a function. So I thought of defining such a simple notion that would allow you to write: curry!(fun)(42) instead of the literals above. In your code you are of course free to use either form as you find fit, just as you can write x * x * x or cube(x) or pow(x, 3). So I'm not sure where the sub par thing comes.int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think? AndreiI've done the whole boost::bind thing before and it sucks. When boost::lambda came out, that was way better. Anonymous delegates are even better. Learning a separate functional syntax will always be a sub par solution to me.I'll go even further. If D had only what you've proposed for ranges and std.functional but lacked opApply and anonymous delegates, I never would have become a D user. Simple, clean syntax is that important to me... Please don't recreate boost and STL in D. They're great libraries, but we can do way better than that!This is the Usenet equivalent of a pie in the face. Wait, what? I _thought_ I'm far beyond recreating boost and STL and also that in the process I am using the full power of the language (and sometimes even more, as shown by the stream of bug reports and enhancement requests that I had to post recently). All range, functional, and algorithms do hinge on anonymous delegates (function literals in fact, which are considerably better); they don't compete with them at all, so I fail to see how one could be thought of in separation from the other. Anyhow, if you have some ideas on how we can do way better than the current trend I'm all ears. My perception, if you allow me to venture a thought, is that you are a bit confused. To paraphrase SICP, you are happy with x * x * x and are afraid that the option of writing cube(x) makes things worse. Andrei
Feb 25 2009
On Wed, 25 Feb 2009 17:19:30 +0300, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Jason House wrote:I don't want to offend anyone, but this syntax sucks badly. Just compare: auto x = (int x) { return fun(42, x); }; auto x = makeDelegate(curry!(fun)(42)); And you say that your solution is /shorter/? You must be kidding! Delegate is THE way to pass closures in D, not some functional object that has opCall(). Besides, I want my methods to be virtual and I can't afford myself a template method that accepts functional objects of any type. bind is way *way* WAY more capable that what you propose as a replacement. It allows parameter reordering, duplication etc with a simple, uniform syntax: auto x = bind(&fun, 42, _0); auto y = bind(&fun, _0, 42); auto z = bind(&fun, _1, _0); But it's not very intuitive and easy to read: auto q = bind(&fun, _1, bind(&fun, bind(&fun, _0, 42), _1)); Besides, it is often ambiguous: void foo(int x, int y); void foo(float x, int y); auto x = makeDelegate(bind(&foo, _0, 42)); // error With built-in D delegate syntax, there is no ambiguity and mistake: auto x = (int x) { foo(x, 42); }; That's *the best* syntax I can think of. Just keep it and let the std.bind go. Don't waste your precious time of fixing something that isn't broken (err.. std.bind IS broken, but that's not what I was talking about :p)Andrei Alexandrescu Wrote:So let's see. If what you have is a function int fun(int, int) and you want to fix its first parameter to a specific value, you can write: (int x) { return fun(42, x); } That would be a function literal. To give it a name, you can say: int gun(int x) { return fun(42, x); } If you want to pass that thing around, you take &gun (or &(literal)) and transform it into a delegate. One minor issue with the above is that the syntax is rather verbose and that the relationship between the function, the parameter, and the outcome is not conceptualized. Yes, the constructs can curry any function, but you have no *notion* of currying a function. So I thought of defining such a simple notion that would allow you to write: curry!(fun)(42) instead of the literals above.int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think? AndreiI've done the whole boost::bind thing before and it sucks. When boost::lambda came out, that was way better. Anonymous delegates are even better. Learning a separate functional syntax will always be a sub par solution to me.In your code you are of course free to use either form as you find fit, just as you can write x * x * x or cube(x) or pow(x, 3). So I'm not sure where the sub par thing comes.I'll go even further. If D had only what you've proposed for ranges and std.functional but lacked opApply and anonymous delegates, I never would have become a D user. Simple, clean syntax is that important to me... Please don't recreate boost and STL in D. They're great libraries, but we can do way better than that!This is the Usenet equivalent of a pie in the face. Wait, what? I _thought_ I'm far beyond recreating boost and STL and also that in the process I am using the full power of the language (and sometimes even more, as shown by the stream of bug reports and enhancement requests that I had to post recently). All range, functional, and algorithms do hinge on anonymous delegates (function literals in fact, which are considerably better); they don't compete with them at all, so I fail to see how one could be thought of in separation from the other. Anyhow, if you have some ideas on how we can do way better than the current trend I'm all ears. My perception, if you allow me to venture a thought, is that you are a bit confused. To paraphrase SICP, you are happy with x * x * x and are afraid that the option of writing cube(x) makes things worse. Andrei
Feb 25 2009
Denis Koroskin wrote:On Wed, 25 Feb 2009 17:19:30 +0300, Andrei AlexandrescuOf course it is shorter. You seldom need makeDelegate. And the more parameters you add to the mix, the shorter it becomes.curry!(fun)(42) instead of the literals above.I don't want to offend anyone, but this syntax sucks badly. Just compare: auto x = (int x) { return fun(42, x); }; auto x = makeDelegate(curry!(fun)(42)); And you say that your solution is /shorter/? You must be kidding!Delegate is THE way to pass closures in D, not some functional object that has opCall().Who told you that lied.Besides, I want my methods to be virtual and I can't afford myself a template method that accepts functional objects of any type.Sure. Make a delegate out of it when you so need. Notice that *I* don't want to be shoehorned into making only virtual calls.bind is way *way* WAY more capable that what you propose as a replacement. It allows parameter reordering, duplication etc with a simple, uniform syntax: auto x = bind(&fun, 42, _0); auto y = bind(&fun, _0, 42); auto z = bind(&fun, _1, _0);I'm not sure how you can say that because you don't know about the replacement I want to propose. Even I don't fully know. I tried to launch a thread asking people for designs, met with a thundering silence (in contrast, ironically, there's been a lot of interest in creating ad-hoc syntax). Anyway, I was thinking of: auto x = bind!(fun, 0)(42); auto y = bind!(fun, 1)(42); Rewiring arguments would be the charter of a different functional.But it's not very intuitive and easy to read: auto q = bind(&fun, _1, bind(&fun, bind(&fun, _0, 42), _1));I agree :o). I wanted to come up with an equivalent, but couldn't actually figure what yours does. For example, where does the first parameter of the outer bind go? Did you mean _0 instead of the first _1?Besides, it is often ambiguous: void foo(int x, int y); void foo(float x, int y); auto x = makeDelegate(bind(&foo, _0, 42)); // error With built-in D delegate syntax, there is no ambiguity and mistake: auto x = (int x) { foo(x, 42); }; That's *the best* syntax I can think of. Just keep it and let the std.bind go. Don't waste your precious time of fixing something that isn't broken (err.. std.bind IS broken, but that's not what I was talking about :p)Well no matter how the conversation went, I'm hugely drawn to a conclusion that has me do less work :o). Andrei
Feb 25 2009
Andrei Alexandrescu wrote:I tried to launch a thread asking people for designs, met with a thundering silence (in contrast, ironically, there's been a lot of interest in creating ad-hoc syntax).If you're referring to your post earlier in this thread, where you wrote:So, I'm renaming this thread and launching a design contest for the new std.bind. First step: how should the interface look like?then it is possible that the post did not gather the impact and readers that you expected. Most of us are pressed for time, so a boring thread on "std.bind documentation sucks hard" is not what we choose to open first. A mere leaf in such a tree risks lack of exposure. Also, a leaf-level post lacks implicit urgency and prestige. Another thing is of course, a design contest needs several days at least to produce any results. And many took the post as soliciting for programming of such a bind library, as opposed to merely posting one's wishes of usage syntax.
Feb 25 2009
On 2009-02-25 14:36:43 -0500, "Denis Koroskin" <2korden gmail.com> said:With built-in D delegate syntax, there is no ambiguity and mistake: auto x = (int x) { foo(x, 42); }; That's *the best* syntax I can think of. Just keep it and let the std.bind go. Don't waste your precious time of fixing something that isn't broken (err.. std.bind IS broken, but that's not what I was talking about :p)I pretty much agree with this. What's great about this is that you just reuse your knowleadge of functions instead of having to learn something new. The mental load is thus smaller; this is much more important than saving a few characters. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 25 2009
Andrei Alexandrescu Wrote:Jason House wrote:Sorry about that. I'm sleep deprived and working extra long hours at work lately.Andrei Alexandrescu Wrote:So let's see. If what you have is a function int fun(int, int) and you want to fix its first parameter to a specific value, you can write: (int x) { return fun(42, x); } That would be a function literal. To give it a name, you can say: int gun(int x) { return fun(42, x); } If you want to pass that thing around, you take &gun (or &(literal)) and transform it into a delegate. One minor issue with the above is that the syntax is rather verbose and that the relationship between the function, the parameter, and the outcome is not conceptualized. Yes, the constructs can curry any function, but you have no *notion* of currying a function. So I thought of defining such a simple notion that would allow you to write: curry!(fun)(42) instead of the literals above. In your code you are of course free to use either form as you find fit, just as you can write x * x * x or cube(x) or pow(x, 3). So I'm not sure where the sub par thing comes.int plus(int x, int y} { return x + y; } auto plus5 = curry!(plus)(5); assert(plus5(10) == 15); typeof(plus5) will be a little struct that may be cumbersome to pass around, in which case you do want to take the toll of the indirect call by writing: auto plus5 = makeDelegate(curry!(plus)(5)); assert(is(typeof(plus5) == int delegate(int)); assert(plus5(10) == 15); This stuff belongs to std.functional. I plan to eliminate std.bind and put currying and binding in std.functional. What do people think? AndreiI've done the whole boost::bind thing before and it sucks. When boost::lambda came out, that was way better. Anonymous delegates are even better. Learning a separate functional syntax will always be a sub par solution to me.I'll go even further. If D had only what you've proposed for ranges and std.functional but lacked opApply and anonymous delegates, I never would have become a D user. Simple, clean syntax is that important to me... Please don't recreate boost and STL in D. They're great libraries, but we can do way better than that!This is the Usenet equivalent of a pie in the face.Wait, what? I _thought_ I'm far beyond recreating boost and STL and also that in the process I am using the full power of the language (and sometimes even more, as shown by the stream of bug reports and enhancement requests that I had to post recently). All range, functional, and algorithms do hinge on anonymous delegates (function literals in fact, which are considerably better); they don't compete with them at all, so I fail to see how one could be thought of in separation from the other. Anyhow, if you have some ideas on how we can do way better than the current trend I'm all ears. My perception, if you allow me to venture a thought, is that you are a bit confused. To paraphrase SICP, you are happy with x * x * x and are afraid that the option of writing cube(x) makes things worse.The first follow-up to your reply captured the kind of messiness bind can bring in C++. So far, all your examples are trivial (lack argument reordering, function composition, etc...). It's true that your examples look clean, but the devil will be in the details. I'd give better examples/details if I wasn't typing this with my thumb into a cell phone... I'm normally a man of few words, but that makes me give less detail than I otherwise would.Andrei
Feb 25 2009
Jason House wrote:I'd give better examples/details if I wasn't typing this with my thumb into a cell phone...You do caps, quotes, special characters, correct grammar with your thumb on a cell phone?! I'm impressed! I can't bother with that without a full keyboard. Doing text on a phone keypad is agony for me. <rant> I have several devices, like a dvd recorder, game box, etc., that need text entry. Each has their own kludge-o-matic way of doing it with the remote. They're all horrible and agonizingly slow. Can't any of them put a gawd-dammed USB port on so I can plug in a keyboard? Or a PS/2 keyboard port? Or even, dare I say it, a morse key? http://www.freepatentsonline.com/6418323.html </rant>
Feb 25 2009
On Wed, Feb 25, 2009 at 5:50 PM, Walter Bright <newshound1 digitalmars.com> wrote:You do caps, quotes, special characters, correct grammar with your thumb on a cell phone?! I'm impressed! I can't bother with that without a full keyboard. Doing text on a phone keypad is agony for me.There are cell phones with QWERTY keypads (or touchscreens) now, you know ;)
Feb 25 2009
Jarrett Billingsley wrote:There are cell phones with QWERTY keypads (or touchscreens) now, you know ;)I am soo obsolete <g>! My cell phone has a number pad on it. When I even bother to put a charge on it.
Feb 25 2009
Walter Bright wrote:Jason House wrote:Playstation 3 (and possibly Playstation 2) has USB ports and USB HID support. I've hooked up an IBM Model M to one (using a ps/2 -> usb adapter). Playstation 3 is also a reasonably-priced bluray player.I'd give better examples/details if I wasn't typing this with my thumb into a cell phone...You do caps, quotes, special characters, correct grammar with your thumb on a cell phone?! I'm impressed! I can't bother with that without a full keyboard. Doing text on a phone keypad is agony for me. <rant> I have several devices, like a dvd recorder, game box, etc., that need text entry. Each has their own kludge-o-matic way of doing it with the remote. They're all horrible and agonizingly slow. Can't any of them put a gawd-dammed USB port on so I can plug in a keyboard? Or a PS/2 keyboard port? Or even, dare I say it, a morse key? http://www.freepatentsonline.com/6418323.html </rant>
Feb 25 2009
Christopher Wright wrote:Walter Bright wrote:The XBox 360 supports keyboards as well, although not mice (I understand the PS3 does support mice in some games.) This sucks as it makes the machine useless for first person shooters. :P The Wii also has support for keyboards, although I'm only aware of it actually working in the web browser. As an interesting side note, the 360 is the only current-gen console that can't browse the web. You'd think MS would have jumped at the chance to put IE on yet another platform... -- DanielJason House wrote:Playstation 3 (and possibly Playstation 2) has USB ports and USB HID support. I've hooked up an IBM Model M to one (using a ps/2 -> usb adapter). Playstation 3 is also a reasonably-priced bluray player.I'd give better examples/details if I wasn't typing this with my thumb into a cell phone...You do caps, quotes, special characters, correct grammar with your thumb on a cell phone?! I'm impressed! I can't bother with that without a full keyboard. Doing text on a phone keypad is agony for me. <rant> I have several devices, like a dvd recorder, game box, etc., that need text entry. Each has their own kludge-o-matic way of doing it with the remote. They're all horrible and agonizingly slow. Can't any of them put a gawd-dammed USB port on so I can plug in a keyboard? Or a PS/2 keyboard port? Or even, dare I say it, a morse key? http://www.freepatentsonline.com/6418323.html </rant>
Feb 25 2009
Walter Bright wrote:Jason House wrote:Who says I don't have a full keyboard? Ok, well, it's a tiny keyboard on a touch screen. The iPhone interface is one of the nicest I've used. I've always had the bad habit of trying to write properly even when I had a keypad. K9 was a godsend, but a "normal" keyboard is even better. PS: This post was with a real computer. It's a rare luxury with a little baby in the house that is usually spent working on my D code instead of doing newsgroup stuff :)I'd give better examples/details if I wasn't typing this with my thumb into a cell phone...You do caps, quotes, special characters, correct grammar with your thumb on a cell phone?! I'm impressed! I can't bother with that without a full keyboard. Doing text on a phone keypad is agony for me.
Feb 25 2009
Jason House wrote:The first follow-up to your reply captured the kind of messiness bind can bring in C++. So far, all your examples are trivial (lack argument reordering, function composition, etc...). It's true that your examples look clean, but the devil will be in the details.I see. The only problem is that very few people seem to use std.bind; there are few interesting examples of arbitrary partial argument binding that need formalization. The one good example I know of is those float vector permutations, but nobody in their right mind would use a delegate for that! That all makes it even more appealing to stick with a five-liner in std.functional that gets currying into the bag (which is a useful and low-hanging fruit) and call std.bind history. Makes sense? Andrei
Feb 25 2009
On Thu, Feb 26, 2009 at 9:21 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Jason House wrote:I think simple is fine here. About the only places I've used boost::bind in C++ are things that I would never use a bind library to do in D, since in D we have nested functions and delegates. Those things knock about 80% of the wind out of a bind library in my opinion. --bbThe first follow-up to your reply captured the kind of messiness bind can bring in C++. So far, all your examples are trivial (lack argument reordering, function composition, etc...). It's true that your examples look clean, but the devil will be in the details.I see. The only problem is that very few people seem to use std.bind; there are few interesting examples of arbitrary partial argument binding that need formalization. The one good example I know of is those float vector permutations, but nobody in their right mind would use a delegate for that! That all makes it even more appealing to stick with a five-liner in std.functional that gets currying into the bag (which is a useful and low-hanging fruit) and call std.bind history. Makes sense?
Feb 25 2009
Andrei Alexandrescu wrote:Jason House wrote:I was one of those people using bind when I was using D1, and I didn't actually use std.bind... I think what is really needed before a design contest is to know what the use cases are. If there's only one use case, I'd argue that completely generic terms such as curry are not appropriate.The first follow-up to your reply captured the kind of messiness bind can bring in C++. So far, all your examples are trivial (lack argument reordering, function composition, etc...). It's true that your examples look clean, but the devil will be in the details.I see. The only problem is that very few people seem to use std.bind; there are few interesting examples of arbitrary partial argument binding that need formalization. The one good example I know of is those float vector permutations, but nobody in their right mind would use a delegate for that!That all makes it even more appealing to stick with a five-liner in std.functional that gets currying into the bag (which is a useful and low-hanging fruit) and call std.bind history. Makes sense?The few lines of code for a single case does make sense. I can't yet figure out what you're thinking the final product should be or what it should do. When talking about bind, I think of boost::bind (or std::bind). When thinking of that, I envision all the ugly combinations that can arise. I usually think of delegates as solving those cases better. I also would have assumed that when you talked about small structs that you'd be using the opCall trick (or similar). Of course, we all know you don't like adding parenthesis at the end, so maybe a function name would be better ;) ... so no, it doesn't make sense.
Feb 25 2009
Andrei Alexandrescu wrote:Jason House wrote:Yes. I think that the smaller Phobos can be, the better. Make sure that everything in it is actually useful, and ditch the rest.The first follow-up to your reply captured the kind of messiness bind can bring in C++. So far, all your examples are trivial (lack argument reordering, function composition, etc...). It's true that your examples look clean, but the devil will be in the details.I see. The only problem is that very few people seem to use std.bind; there are few interesting examples of arbitrary partial argument binding that need formalization. The one good example I know of is those float vector permutations, but nobody in their right mind would use a delegate for that! That all makes it even more appealing to stick with a five-liner in std.functional that gets currying into the bag (which is a useful and low-hanging fruit) and call std.bind history. Makes sense? Andrei
Feb 26 2009
On Tue, 24 Feb 2009 15:58:18 +0300, Yigal Chripun <yigal100 gmail.com> wrote:downs wrote:void foo(int x, int y) { ... } void foo(float x, int y) { ... } auto dg = foo(_, 0); // which one is picked?Yigal Chripun wrote:auto dg = foo(_, somevar); So does that mean you like the above suggestion? after all, it's shorter and clearer than all the other alternatives.. ;)Lars Kyllingstad wrote:Just for comparison' sake: auto dg =&foo /rfix/ somevar; // 1.0, tools auto dg = _bind(&foo, _1, somevar); // 1.0, std.bind auto dg = (int a) { return foo(a, somevar); }; // 2.0, literalI've always thought currying was the main point of std.bind. If I'm not mistaken, currying is commonly a built-in feature of functional programming languages, so if anything, std.bind could become more useful/important in D2 than in D1. I agree that the std.bind API could and should be improved. -Larsyou don't need bind for currying, it's even possible to do this in C: int foo(int a, int b) { ... } int bar(int a) { return foo(a, _value); } // curry with some _value Other languages provide useful syntax sugar for currying: auto bar2 = foo(_, 500); bar2 here will be a delegate that will do the the same as the above bar.
Feb 24 2009