digitalmars.D - Flag proposal
- Andrei Alexandrescu (3/3) Jun 10 2011 https://github.com/D-Programming-Language/phobos/pull/94
- Andrej Mitrovic (16/16) Jun 10 2011 I like how your proposal is already a pull request.
- Andrei Alexandrescu (16/33) Jun 10 2011 Yes, getopt should support any enum using bool as its base. std.conv
- Andrej Mitrovic (13/18) Jun 10 2011 Oh, maybe this was already incorporated into format but I didn't
- KennyTM~ (3/25) Jun 10 2011 Try to use the Phobos on git master. I have fixed this already (bug
- Andrej Mitrovic (1/1) Jun 10 2011 *notice
- Robert Clipsham (7/10) Jun 10 2011 I really *really* don't like this. It's ugly and verbose, and a pathetic...
- KennyTM~ (9/18) Jun 10 2011 Well I agree it is ugly, but at least it's better than having the same
- Jonathan M Davis (7/28) Jun 10 2011 And there are places in Phobos which _should_ be using enums like this b...
- Andrei Alexandrescu (8/17) Jun 10 2011 This is not half-baked. It's pretty much it.
- Robert Clipsham (15/33) Jun 10 2011 foo(param: true, otherParam: false);
- Michel Fortin (18/38) Jun 10 2011 I have to say I totally agree with Robert.
- Nick Sabalausky (16/52) Jun 10 2011 I completely agree with Robert and Michel on all the points they've rais...
- David Nadlinger (5/21) Jun 10 2011 That quite accurately summarizes the reason for my short »I'm not reall...
- Andrei Alexandrescu (13/47) Jun 10 2011 I disagree with the "templates are difficult" mantra. It is a meme from
- Michel Fortin (19/50) Jun 10 2011 Neither C macros nor C++ or D templates are very difficult by
- Andrei Alexandrescu (15/62) Jun 10 2011 See, here you're simply wrong. C macros are heinously complicated in
- bearophile (4/7) Jun 10 2011 I didn't understand this well at first. Thank you for explaining again.
- Nick Sabalausky (2/45) Jun 10 2011
- Nick Sabalausky (4/59) Jun 10 2011 Ignore this: I went to reply, hit the wrong key, and it sent before I go...
- Nick Sabalausky (14/56) Jun 10 2011 You're assuming that we're choosing the word "hack" as an attempt to swa...
- Nick Sabalausky (3/5) Jun 10 2011 Erm, I mean "the hiccup with it".
- Michel Fortin (22/34) Jun 10 2011 A hack is something that works even though it's ugly and generally
- Nick Sabalausky (9/19) Jun 10 2011 Excellent point.
- Andrei Alexandrescu (3/19) Jun 10 2011 https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac932...
- Michel Fortin (15/24) Jun 10 2011 It's
- Andrei Alexandrescu (7/28) Jun 10 2011 But the problem is the same today.
- Nick Sabalausky (3/34) Jun 10 2011 Which makes Flag even less of an improvement.
- Andrej Mitrovic (4/4) Jun 10 2011 We should rename Yes and No to Yay and Nay to make them alignable, and
- Alix Pexton (7/9) Jun 11 2011 "Yay" and "Nay" are too similar looking, but luckily, "Yay" is not
- Nick Sabalausky (3/11) Jun 11 2011 Dost thou, verily?
- Alix Pexton (3/16) Jun 11 2011 Aye!
- Andrej Mitrovic (3/12) Jun 11 2011 Oh damn, yay is what teenage girls would say, not old Englishmen. My
- Steven Schveighoffer (8/23) Jun 11 2011 You were phonetically right :) It's yea or nay.
- Alix Pexton (6/30) Jun 12 2011 Nope, its definitely Aye when used for voting, (at least it is round
- Steven Schveighoffer (8/45) Jun 12 2011 I don't deny that aye is used frequently for voting. All I was saying i...
- Andrej Mitrovic (1/1) Jun 12 2011 TBH I've only ever heard it used in Ali G Indahouse, so what do I know.....
- Alix Pexton (5/51) Jun 12 2011 True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea"...
- Paul D. Anderson (4/61) Jun 12 2011 Then you must not have heard the King James Version of the Bible read al...
- Alix Pexton (6/67) Jun 13 2011 Aye, I did mean people using their own words and not someone else's. for...
- Andrei Alexandrescu (5/21) Jun 11 2011 I'm not sure I figure the reasoning. You can't penalize twice for the
- Michel Fortin (13/35) Jun 11 2011 It's
- Nick Sabalausky (7/12) Jun 11 2011 That dang "Send Message" keyboard combo gets me now and then, too. In fa...
- Michel Fortin (8/22) Jun 11 2011 Just after sending this message, I changed the combo in my newsreader
- Daniel Gibson (4/32) Jun 11 2011 When using a newsreader you should be able to retract a message, at
- Michel Fortin (6/9) Jun 11 2011 I know, but Unison doesn't have that option.
- Andrei Alexandrescu (5/35) Jun 10 2011 I agree it's more legible. The crucial question is whether the added
- Torarin (4/51) Jun 10 2011 I agree, introducing a syntax for required named parameters sounds
- Nick Sabalausky (10/40) Jun 10 2011 I really see Flag more as a way to try to rationalize avoiding adding na...
- Nick Sabalausky (8/30) Jun 10 2011 Regarding "the complete inability of Flag to address the problem for
- Jonathan M Davis (22/57) Jun 10 2011 These yes/no enums _aren't_ named arguments. They're an attempt at creat...
- Andrei Alexandrescu (11/44) Jun 10 2011 I don't find it entirely fair to demean the suggestion as a tool to
- Lutger Blijdestijn (9/45) Jun 10 2011 I don't, even though I like named parameters. boolean parameters for bin...
- Andrej Mitrovic (2/3) Jun 10 2011 The flag template suffers from the same issue.
- Andrei Alexandrescu (5/8) Jun 10 2011 Actually, not. The name used with Flag is part of its type. Even in a
- Steven Schveighoffer (13/21) Jun 10 2011 No, it's not the same, which actually can be viewed as a plus for named ...
- Andrej Mitrovic (12/21) Jun 10 2011 I've either misread what Lutger said or I haven't stated my intentions
- Lutger Blijdestijn (6/10) Jun 10 2011 Not strictly, but practically yes. It's also the point of them, exposing...
- Nick Sabalausky (4/14) Jun 10 2011 That's hardly an issue though. Updating callers to use a changed functio...
- Jonathan M Davis (15/33) Jun 10 2011 The problem is that there is no way to provide a deprecation path withou...
- Steven Schveighoffer (9/51) Jun 10 2011 This assumes everyone calls every function with named parameters. In
- KennyTM~ (2/35) Jun 10 2011 Why do you need to rename parameter name of a stable API?
- Nick Sabalausky (6/29) Jun 10 2011 What I don't see is a compelling need to provide a deprecation path when...
- Jonathan M Davis (9/13) Jun 10 2011 Not really. There's a big difference between changing the type name and
- Nick Sabalausky (19/36) Jun 10 2011 I *really* think that whole issue is a complete triviality, but:
- Andrei Alexandrescu (16/27) Jun 10 2011 There are fights that I believe are important and others that I think
- Dmitry Olshansky (10/21) Jun 10 2011 I think this looks not half bad and does not require change in the
- Andrei Alexandrescu (4/27) Jun 10 2011 Ask, and ye shall receive.
- Andrej Mitrovic (9/11) Jun 10 2011 That's much more like it. This whole bikeshedding issue for me was
- Lars T. Kyllingstad (13/41) Jun 10 2011 commit/801ccc96ce56827cd0d0b608895269bdccba4330
- Mafi (4/6) Jun 11 2011 I like this version much more but shouldn't it also be
- Andrei Alexandrescu (3/12) Jun 11 2011 Not sure I understand. How do you mean that?
- Mafi (15/30) Jun 11 2011 I meant something like this:
- Mike Parker (3/31) Jun 11 2011 I was going to add my voice against this proposal until I saw this. Nice...
- Steven Schveighoffer (18/45) Jun 11 2011 This is better. Does the definition of the function still require
- Michel Fortin (13/25) Jun 11 2011 If you need to convert a bool to a Flag!"abc", you can do any of these:
- Andrei Alexandrescu (4/25) Jun 11 2011 Agreed. I'll venture to add that I find the first also more desirable
- Steven Schveighoffer (14/35) Jun 11 2011 We need another struct besides Yes and No that allows creation with
- Andrei Alexandrescu (3/40) Jun 11 2011 I agree that's a drawback. I couldn't find a reasonable workaround.
- KennyTM~ (4/22) Jun 10 2011 Making the compulsory enum name as a feature means
- Jonathan M Davis (13/16) Jun 10 2011 I do have to admit that as much as I hate the idea of named parameters, ...
- KennyTM~ (3/19) Jun 10 2011 The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along
- Jonathan M Davis (10/36) Jun 10 2011 Why would it be? You generally want documentation specific to the enum a...
- KennyTM~ (4/40) Jun 10 2011 Please review the previous discussion of why Flag (was YesOrNo) was
- Jonathan M Davis (22/68) Jun 10 2011 In many cases, I very much think that the documentation should be separa...
- Andrei Alexandrescu (16/23) Jun 10 2011 There is general agreement (which includes myself) that a language
- Nick Sabalausky (13/39) Jun 10 2011 Much
- bearophile (6/14) Jun 10 2011 This use of word "scale" assumes there is a larger and larger group of b...
- Steven Schveighoffer (17/35) Jun 10 2011 Yes.
- Andrei Alexandrescu (5/28) Jun 10 2011 Because you still need to define it separately from use.
- Jonathan M Davis (19/47) Jun 10 2011 What I want to know is what you want to do with such enums where it's ac...
- Andrei Alexandrescu (5/7) Jun 10 2011 I guess if you want such you either define the flag separately or make
- Nick Sabalausky (4/24) Jun 10 2011 I'd support this *as long as* it's existence didn't get used as
- bearophile (5/9) Jun 10 2011 Scala faces this problem:
- Andrei Alexandrescu (4/13) Jun 10 2011 That's good evidence that introducing named parameters would be quite
- bearophile (7/8) Jun 10 2011 It's also good evidence that Martin Odersky, one of the most intelligent...
- Andrei Alexandrescu (19/29) Jun 10 2011 I have all respect for Odersky's competence, but that is beside the
- bearophile (9/16) Jun 10 2011 There are few basic features that are missing that are better as built-i...
- Andrei Alexandrescu (15/43) Jun 10 2011 What I did was to say that Don's and others' point, corroborated with
- bearophile (5/9) Jun 10 2011 If you want to build stable large frameworks and libraries then having a...
- Andrei Alexandrescu (11/27) Jun 10 2011 Don't kid yourself. Every additive change creates more precedent and
- Jonathan M Davis (30/57) Jun 10 2011 The Herb Sutter interview that you recently posted a link to has an
- Andrei Alexandrescu (37/43) Jun 10 2011 Good point. Walter and I agree that there are two categories of language...
- Andrej Mitrovic (3/3) Jun 10 2011 Wait, Walter wants to fix this? IIRC just a few days ago he made a
- Walter Bright (2/5) Jun 10 2011 I did?
- bearophile (4/5) Jun 10 2011 I don't remember you talking about this topic. But I don't want this fea...
- Andrej Mitrovic (3/5) Jun 10 2011 I've found someone that contradicts you:
- Andrei Alexandrescu (3/8) Jun 10 2011 Wow.
- bearophile (4/6) Jun 11 2011 Thank you. That person didn't have enough experience yet, it seems. More...
- Andrei Alexandrescu (5/11) Jun 11 2011 I'm not very familiar with Python's module system. Is it very similar to...
- bearophile (8/10) Jun 11 2011 If you take a look at the Python module system, you copy the first half ...
- Andrej Mitrovic (3/8) Jun 10 2011 Hmm. It might have been a bug in the matrix, and I misplaced you for
- bearophile (4/16) Jun 10 2011 You are allowed to import modules inside functions in Python too (there ...
- David Nadlinger (6/22) Jun 10 2011 At least allowing imports in unittests would be nice though – I
- jdrewsen (2/32) Jun 11 2011 +1
- Walter Bright (4/10) Jun 10 2011 What, there's a Python feature you don't like? :-)
- Andrei Alexandrescu (6/22) Jun 10 2011 Maybe you also care less about what you import.
- Lutger Blijdestijn (13/38) Jun 11 2011 Why would you have to find local imports? It's considered good practice ...
- bearophile (4/5) Jun 11 2011 I agree this turtle idea has some good sides too. But I want to stress t...
- Andrei Alexandrescu (4/13) Jun 11 2011 Again, there are two broad categories of changes: feature additions and
- bearophile (4/6) Jun 11 2011 I understand, but that's not always the best decision in this early stag...
- Timon Gehr (15/32) Jun 13 2011 //void main(){
- bearophile (17/18) Jun 13 2011 Mutually recursive inner functions are not so common, and there is a wor...
- Nick Sabalausky (21/25) Jun 10 2011 That analysis of the situation hinges on the steadfast notion that Flag ...
- Andrei Alexandrescu (17/45) Jun 11 2011 Actually my point there was that we should be coy at this point about
- Michel Fortin (35/44) Jun 11 2011 I'm actually not sure whether I want named arguments or not, but I'm
- Andrei Alexandrescu (50/91) Jun 11 2011 The call entails simple data coupling as documented by Steve McConnell:
- David Nadlinger (16/32) Jun 11 2011 So what? Library code is typically written once, and used often. Also,
- Michel Fortin (38/150) Jun 11 2011 Which is often useful if the value is conditional to a boolean
- Andrei Alexandrescu (18/62) Jun 11 2011 The problem is the definition of "reasonable" is loose. For all I can
- Michel Fortin (10/26) Jun 11 2011 Choosing between "yes" and "no" is not meaningful. I'd rather choose
- Andrei Alexandrescu (48/72) Jun 11 2011 I don't see how "OpenRight.yes" is meaningless and "Openness.right" is
- Michel Fortin (12/18) Jun 11 2011 The funny thing is that named arguments are not that difficult to
- Andrei Alexandrescu (3/17) Jun 11 2011 Love the attitude!! Let's see what Don and Walter think.
- Walter Bright (6/27) Jun 11 2011 I think it's clever and insightful how Michel's solution is implemented....
- Andrei Alexandrescu (6/35) Jun 11 2011 If we all get convinced that named parameters are worth it, I'm
- Nick Sabalausky (17/29) Jun 11 2011 Flag -= 1
- Andrei Alexandrescu (12/37) Jun 11 2011 Not at all. The typo in the original text must have confused you: it
- Jonathan M Davis (34/81) Jun 11 2011 Yes, though there is a distinct difference between having to create a fu...
- Andrei Alexandrescu (4/8) Jun 11 2011 Absolutely. The proposed solution is also much smaller than e.g. lambda
- Nick Sabalausky (4/9) Jun 12 2011 It also creates an awkward inconsistency. Most enums are X.Y, but then
- Nick Sabalausky (9/37) Jun 12 2011 Not that I consider quibbling over small English wording differences a m...
- Andrei Alexandrescu (3/43) Jun 12 2011 Still means I need to jump back and forth in the documentation.
- Nick Sabalausky (3/54) Jun 12 2011 And you don't like the "///ditto" suggestion for handling that?
- Andrei Alexandrescu (4/60) Jun 12 2011 That actually does help, but not for enums used by more than one
- Nick Sabalausky (4/68) Jun 13 2011 I would think that an enum used by more than one function *should* be li...
- Andrei Alexandrescu (5/12) Jun 13 2011 Actually, not necessarily, if the definition is self explanatory. By the...
- Timon Gehr (3/16) Jun 13 2011 What about just not documenting the enum itself? This elegantly resolves...
- so (6/16) Jun 12 2011 Quite contrary i think it is pretty much spot on, if it is not but just ...
- bearophile (6/8) Jun 12 2011 This is an unusual teacher that use functional languages, the blog post ...
- Andrei Alexandrescu (3/21) Jun 12 2011 Never did.
- David Nadlinger (30/36) Jun 11 2011 *And*, at least for me, still count it as an (informal) vote against
- Andrei Alexandrescu (7/28) Jun 11 2011 Of course it does, but the point is there are arguments that might
- Ben Grabham (8/37) Jun 11 2011 Hey,
- Robert Clipsham (34/41) Jun 11 2011 This one is perhaps true. I've never needed named arguments.
- Andrei Alexandrescu (4/44) Jun 11 2011 // Generate document in nook format
- Robert Clipsham (17/26) Jun 11 2011 I'd call this a documentation issue. It's obvious you're passing true to...
-
Robert Clipsham
(10/37)
Jun 11 2011
- bearophile (4/8) Jun 10 2011 version(unittest) was added just to solve this problem, and for me it's ...
- Adam Ruppe (10/10) Jun 10 2011 Function local imports make it easier to reason about the code
- Andrei Alexandrescu (3/13) Jun 10 2011 Yes. Local imports facilitate local reasoning.
- Nick Sabalausky (8/18) Jun 10 2011 I have need to do that sort of thing now and then, too. What I usually d...
- bearophile (3/4) Jun 11 2011 I am starting to think that just putting those issues in bugzilla was no...
- Jonathan M Davis (61/64) Jun 11 2011 Okay. Let's see if I can summarize this. Andrei thinks that have a categ...
- David Nadlinger (7/11) Jun 11 2011 s/fair/tiny/, imho:
- Jonathan M Davis (6/18) Jun 11 2011 It's a fair bit only insomuch as the same code is duplicated in several
- Andrei Alexandrescu (16/34) Jun 11 2011 It's the namespace pollution and the non-self-containedness of the
- Jonathan M Davis (11/52) Jun 11 2011 Honestly, at this point, I think that your proposal is pretty good, but ...
- Jonathan M Davis (4/57) Jun 11 2011 Yikes! How did that get posted three times?! I wonder if my mail client ...
- Andrej Mitrovic (6/8) Jun 11 2011 You seem to be forgetting that there are library writers and then
- so (18/33) Jun 12 2011 (Trying the 3rd time, something wrong with newsreader)
- Nick Sabalausky (7/21) Jun 12 2011 You can't put an enum in a class/struct?
- Andrei Alexandrescu (3/31) Jun 12 2011 I'm not sure, but I think I see a sarcasm in there.
- Nick Sabalausky (4/42) Jun 12 2011 I guess it could be taken that way, but it wasn't really my point to be
- Lars T. Kyllingstad (6/16) Jun 13 2011 Yes, but then you have to qualify it with the name of the class/struct
- Steven Schveighoffer (21/33) Jun 11 2011 A big problem with this (and enums in general), what if your flag functi...
- Andrei Alexandrescu (4/39) Jun 12 2011 Thanks, Steve, this is an excellent point - as are all you made in this
- Timon Gehr (9/21) Jun 11 2011 5. The approach is too sophisticated and does not pull its own weight.
- Andrei Alexandrescu (7/31) Jun 11 2011 I proposed this to Walter some years ago, around the time I was
- Nick Sabalausky (20/59) Jun 12 2011 I like the basic idea, and it's a change that falls into the "removing
- Daniel Murphy (13/18) Jun 12 2011 Wow - I actually really like this! It would provide an even _better_
- so (9/33) Jun 12 2011 This also means you can use it only once. Not knowing the type, you can'...
- Nick Sabalausky (12/34) Jun 12 2011 Not only that, but just simply trying to explain why you sometimes do
- Andrei Alexandrescu (5/9) Jun 11 2011 Those were since replaced with No.enumName and Yes.enumName by Dmitry's
- KennyTM~ (3/14) Jun 11 2011 Yes.X and No.X looks grammatically wrong. In D you usually have
- Dmitry Olshansky (9/29) Jun 12 2011 Well, you can do only as much staying within the language.
- bearophile (4/6) Jun 11 2011 I don't know if Walter will appreciate this, or if this will need improv...
- foobar (8/8) Jun 12 2011 People here already noted most advantages and disadvantages of this prop...
- Andrei Alexandrescu (3/5) Jun 12 2011 I agree that KISS is important and that Flag is failing it.
- Walter Bright (2/7) Jun 12 2011 Set phasers to "vaporize".
- bearophile (9/10) Jun 13 2011 I think this is not going to happen because some people (two?) don't wan...
- Nick Sabalausky (3/14) Jun 13 2011 I like it!
- so (24/28) Jun 13 2011 I think they worth it and it is the right time to talk extensively why
- Ary Manzana (9/39) Jun 13 2011 A different rule can be:
- so (5/33) Jun 13 2011 IMO the main that makes NAs confusing is allowing hybrid calls.
- Nick Sabalausky (3/37) Jun 13 2011 I think Ary's suggestion is very simple and easy to understand. Hybrid c...
- so (12/15) Jun 13 2011 An example to it.
- Ary Manzana (4/12) Jun 13 2011 // error: c assigned twice
- so (3/20) Jun 13 2011 Sorry i don't understand, what should i do?
- Ary Manzana (7/28) Jun 13 2011 You can't only name c. You can name arguments from the end to the beginn...
- Ary Manzana (24/63) Jun 13 2011 Well, that's the way Ruby works :-)
- so (7/31) Jun 13 2011 Tell me this is not true! :)
- Ary Manzana (5/44) Jun 14 2011 Well, in fact I don't know if the community came up with this or if the
- Andrei Alexandrescu (4/9) Jun 14 2011 Ha! My Flag chef d'oeuvre would enjoy appreciation, just in another
- KennyTM~ (10/41) Jun 13 2011 I'd rather have no reordering and allow hybrid call. Named argument is
- so (9/18) Jun 13 2011 fun(bool, bool, bool, bool, bool...)
- so (3/6) Jun 14 2011 In fact, i was wrong on this one, you'd simply call fun(a, c:4).
- KennyTM~ (10/31) Jun 14 2011 By "type" I mean the purpose of an argument, e.g. the first 'int' in
- so (9/46) Jun 14 2011 This is the whole point of NAs, it is not clear, you need to check the
- KennyTM~ (12/61) Jun 14 2011 And yet, with loc.x, myWin.width etc, you don't need to check the
- so (23/36) Jun 14 2011 loc.x on the caller side, it has no idea about function signature, and y...
- KennyTM~ (22/61) Jun 14 2011 If you have no idea about the function signature, you have no idea about...
- so (12/47) Jun 14 2011 I think you are just resisting here, if you write a call once with named...
- KennyTM~ (32/85) Jun 14 2011 I'm just bringing up the fact. Why would you need to check the function
- so (22/66) Jun 15 2011 Waste of time? so is writing docs and comments, so is checking the libra...
- bearophile (5/7) Jun 15 2011 To not waste all the good discussions I suggest to write down a DEP (D E...
- KennyTM~ (2/9) Jun 15 2011 You mean a DIP :)
- Nick Sabalausky (4/39) Jun 19 2011 Because it might be wrong.
- KennyTM~ (4/49) Jun 19 2011 Right, no one suggested named arguments should be mandatory, but @so's
- KennyTM~ (34/40) Jun 14 2011 And if you think it's complicated, you're just thinking in a too
- so (7/47) Jun 14 2011 So complicated because it took you this long to match the parameters wit...
- KennyTM~ (5/63) Jun 14 2011 What you're missing may be that what I'm outlining is how the /compiler/...
- Nick Sabalausky (5/62) Jun 19 2011 Simple rule for combining hybrid and reordering:
- Michel Fortin (19/43) Jun 14 2011 There's much more to named arguments as it first appears. Have you
- KennyTM~ (53/91) Jun 14 2011 partition!(ss:SwapStrategy.stable,
- so (8/17) Jun 14 2011 There is already a syntax for this in the language.
- Nick Sabalausky (9/17) Jun 14 2011 I'd say "yes". But even if you said "no, the winner is whichever matches...
https://github.com/D-Programming-Language/phobos/pull/94 Discuss! Andrei
Jun 10 2011
I like how your proposal is already a pull request. I'm not too fond of this workaround: bool state; getopt( args, "state", &state, ); auto line = getLine(cast(Flag!"KeepTerminator")state); Will getopt know how to use Flags? What about std.conv.to? std.format/write will have to know how to print out a Flag too, or we have to cast: writeln(cast(bool)keepTerminator); If the plan is to replace all boolean arguments in Phobos with Flags, won't this break a lot of code? We'll have to switch to using this template, and then if we finally get named arguments sometime down the road we will have to convert everything back to bools again.
Jun 10 2011
On 6/10/11 11:45 AM, Andrej Mitrovic wrote:I like how your proposal is already a pull request. I'm not too fond of this workaround: bool state; getopt( args, "state",&state, ); auto line = getLine(cast(Flag!"KeepTerminator")state); Will getopt know how to use Flags? What about std.conv.to?Yes, getopt should support any enum using bool as its base. std.conv already supports all enums.std.format/write will have to know how to print out a Flag too, or we have to cast: writeln(cast(bool)keepTerminator);Without the cast, writeln prints "yes" or "no", which may be desirable. If you want to print the bool, you can say writeln(keepTerminator == Flag!"KeepTerminator".yes); or writeln(!!keepTerminator); etc. I find this array of options quite sensible.If the plan is to replace all boolean arguments in Phobos with Flags, won't this break a lot of code?Migration can be done piecemeal with deprecation and all.We'll have to switch to using this template, and then if we finally get named arguments sometime down the road we will have to convert everything back to bools again.If we convert back to bool the problem remains that people still can just pass "true" or whatever without specifying the name of the parameter. True, they could and should specify the name of the parameter, but by that argument they could and should insert a comment right now - and nobody does. Andrei
Jun 10 2011
On 6/10/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Without the cast, writeln prints "yes" or "no", which may be desirable. If you want to print the bool, you can say writeln(keepTerminator == Flag!"KeepTerminator".yes); or writeln(!!keepTerminator);Oh, maybe this was already incorporated into format but I didn't nocie, I just did a blunt copy/paste of the template code so it didn't work for me: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1624): Error: template std.format.formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) matches more than one template declaration, D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(895):formatValue(Writer,T,Char) if (is(T == enum)) and D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1104):formatValue(Writer,T,Char) if (is(T : bool))
Jun 10 2011
On Jun 11, 11 01:41, Andrej Mitrovic wrote:On 6/10/11, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org> wrote:Try to use the Phobos on git master. I have fixed this already (bug 5837) and the patch has been merged on June 3rd.Without the cast, writeln prints "yes" or "no", which may be desirable. If you want to print the bool, you can say writeln(keepTerminator == Flag!"KeepTerminator".yes); or writeln(!!keepTerminator);Oh, maybe this was already incorporated into format but I didn't nocie, I just did a blunt copy/paste of the template code so it didn't work for me: D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1624): Error: template std.format.formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) formatValue(Writer,T,Char) if (is(const(T) == const(void[]))) matches more than one template declaration, D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(895):formatValue(Writer,T,Char) if (is(T == enum)) and D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\format.d(1104):formatValue(Writer,T,Char) if (is(T : bool))
Jun 10 2011
On 10/06/2011 17:15, Andrei Alexandrescu wrote:https://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around. -- Robert http://octarineparrot.com/
Jun 10 2011
On Jun 11, 11 01:42, Robert Clipsham wrote:On 10/06/2011 17:15, Andrei Alexandrescu wrote:Well I agree it is ugly, but at least it's better than having the same enum 7 times in Phobos (std.stdio.KeepTerminator, std.string.CaseSensitive, std.algorithm.OpenRight, std.algorithm.SortOutput, std.datetime.AllowDayOverflow, std.datetime.PopFirst, std.datetime.AutoStart). If named parameter is supported, those Flag!"foo" parameters can be reverted back to bool without breaking the caller as the enum is based on bool.https://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.
Jun 10 2011
On 2011-06-10 10:57, KennyTM~ wrote:On Jun 11, 11 01:42, Robert Clipsham wrote:And there are places in Phobos which _should_ be using enums like this but aren't (e.g. std.file.dirEntries' followSymlinks bool), so the number is only going to go up as such things are fixed, even without adding new code to Phobos. And of course, we're going to be adding new code, so the amount of duplication for this type of enum is only going to go up. - Jonathan M DavisOn 10/06/2011 17:15, Andrei Alexandrescu wrote:Well I agree it is ugly, but at least it's better than having the same enum 7 times in Phobos (std.stdio.KeepTerminator, std.string.CaseSensitive, std.algorithm.OpenRight, std.algorithm.SortOutput, std.datetime.AllowDayOverflow, std.datetime.PopFirst, std.datetime.AutoStart). If named parameter is supported, those Flag!"foo" parameters can be reverted back to bool without breaking the caller as the enum is based on bool.https://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.
Jun 10 2011
On 6/10/11 12:42 PM, Robert Clipsham wrote:On 10/06/2011 17:15, Andrei Alexandrescu wrote:This is not half-baked. It's pretty much it. Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true. The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters. Andreihttps://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.
Jun 10 2011
On 10/06/2011 19:06, Andrei Alexandrescu wrote:On 6/10/11 12:42 PM, Robert Clipsham wrote:My choice of wording was poor, sorry.On 10/06/2011 17:15, Andrei Alexandrescu wrote:This is not half-baked. It's pretty much it.https://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true); Would all be valid.Andrei-- Robert http://octarineparrot.com/
Jun 10 2011
On 2011-06-10 14:52:53 -0400, Robert Clipsham <robert octarineparrot.com> said:On 10/06/2011 19:06, Andrei Alexandrescu wrote:I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation? -- Michel Fortin michel.fortin michelf.com http://michelf.com/The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true);
Jun 10 2011
"Michel Fortin" <michel.fortin michelf.com> wrote in message news:istqjn$2jld$1 digitalmars.com...On 2011-06-10 14:52:53 -0400, Robert Clipsham <robert octarineparrot.com> said:I completely agree with Robert and Michel on all the points they've raised. Flag is admittedly a great example of the power of D's templates. And it's admittedly a very clever hack to get around *some* of the limitations of not having named parameters...*But* it's *still* just that: a hack to get around some of the limitations of not having named parameters. And yes, it is comparatively ugly, as Robert and Michel's examples have very clearly shown. Also:On 10/06/2011 19:06, Andrei Alexandrescu wrote:I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true);If by that, you meant that the caller is allowed to call the function without naming the parameters, I really don't see that as a problem. Yea, *maybe* it would be better if the callee could optionally decide "caller must use named params", but even without that, it's a hell of a lot better than the current state, and it's also a lot better than Flag becase 1. It's *much* cleaner for both the caller and callee, and 2. It works for functions like foo(int, int, int, int), not just bools.The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.
Jun 10 2011
On 6/10/11 9:47 PM, Nick Sabalausky wrote:I completely agree with Robert and Michel on all the points they've raised. Flag is admittedly a great example of the power of D's templates. And it's admittedly a very clever hack to get around *some* of the limitations of not having named parameters...*But* it's *still* just that: a hack to get around some of the limitations of not having named parameters. And yes, it is comparatively ugly, as Robert and Michel's examples have very clearly shown. Also:That quite accurately summarizes the reason for my short »I'm not really sure what to think about this – […] named parameters would be the better solution« comment on the pull request; full ack. DavidIf by that, you meant that the caller is allowed to call the function without naming the parameters, I really don't see that as a problem. Yea, *maybe* it would be better if the callee could optionally decide "caller must use named params", but even without that, it's a hell of a lot better than the current state, and it's also a lot better than Flag becase 1. It's *much* cleaner for both the caller and callee, and 2. It works for functions like foo(int, int, int, int), not just bools.The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.
Jun 10 2011
On 6/10/11 2:12 PM, Michel Fortin wrote:On 2011-06-10 14:52:53 -0400, Robert Clipsham <robert octarineparrot.com> said:I disagree with the "templates are difficult" mantra. It is a meme from C++ much like "macros are evil" are one from C. It's a simple construct, you use it.On 10/06/2011 19:06, Andrei Alexandrescu wrote:I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying. The documentation doesn't need the names anymore; the user would just say: void foo( Flag!"compressed", Flag!"encrypted", Flag!"buffered" = Flag!"buffered".no); Save for the "ehm" default parameter this looks palatable to me. AndreiAnd just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true);
Jun 10 2011
On 2011-06-10 16:10:51 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 6/10/11 2:12 PM, Michel Fortin wrote:Neither C macros nor C++ or D templates are very difficult by themselves. People trying to do unintuitive but clever things with them earned them this reputation. If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.I disagree with the "templates are difficult" mantra. It is a meme from C++ much like "macros are evil" are one from C. It's a simple construct, you use it.I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.The documentation doesn't need the names anymore; the user would just say: void foo( Flag!"compressed", Flag!"encrypted", Flag!"buffered" = Flag!"buffered".no); Save for the "ehm" default parameter this looks palatable to me.Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 10 2011
On 6/10/11 3:34 PM, Michel Fortin wrote:On 2011-06-10 16:10:51 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:See, here you're simply wrong. C macros are heinously complicated in definition, and heinously complicated to implement. C++ templates are very bulky in definition too. It's not worth your time you argue this further.On 6/10/11 2:12 PM, Michel Fortin wrote:Neither C macros nor C++ or D templates are very difficult by themselves. People trying to do unintuitive but clever things with them earned them this reputation.I have to say I totally agree with Robert. I agree with the need for a way to name parameters, but instantiating a pseudo-boolean type from a template for each function parameter is worse than the initial problem. Templates are already a difficult concept to grasp for most people (because they're so abstract), we really don't need to replace every boolean parameter with a template type.I disagree with the "templates are difficult" mantra. It is a meme from C++ much like "macros are evil" are one from C. It's a simple construct, you use it.If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming. I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.No, just version(ddoc) for select functions if you want them to. You have the needed means within the language. AndreiThe documentation doesn't need the names anymore; the user would just say: void foo( Flag!"compressed", Flag!"encrypted", Flag!"buffered" = Flag!"buffered".no); Save for the "ehm" default parameter this looks palatable to me.Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?
Jun 10 2011
Andrei:I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.I didn't understand this well at first. Thank you for explaining again. Bye, bearophile
Jun 10 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isu15s$30as$1 digitalmars.com...On 6/10/11 3:34 PM, Michel Fortin wrote:If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming. I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.No, just version(ddoc) for select functions if you want them to. You have the needed means within the language. AndreiThe documentation doesn't need the names anymore; the user would just say: void foo( Flag!"compressed", Flag!"encrypted", Flag!"buffered" = Flag!"buffered".no); Save for the "ehm" default parameter this looks palatable to me.Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?
Jun 10 2011
Ignore this: I went to reply, hit the wrong key, and it sent before I got to type anything... The *real* reply in another post... "Nick Sabalausky" <a a.a> wrote in message news:isu4gg$5ff$1 digitalmars.com..."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isu15s$30as$1 digitalmars.com...On 6/10/11 3:34 PM, Michel Fortin wrote:If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming. I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.No, just version(ddoc) for select functions if you want them to. You have the needed means within the language. AndreiThe documentation doesn't need the names anymore; the user would just say: void foo( Flag!"compressed", Flag!"encrypted", Flag!"buffered" = Flag!"buffered".no); Save for the "ehm" default parameter this looks palatable to me.Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?
Jun 10 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isu15s$30as$1 digitalmars.com...On 6/10/11 3:34 PM, Michel Fortin wrote:You're assuming that we're choosing the word "hack" as an attempt to sway. Not so. We're calling it a hack because we genuinely see it as such. However, I can see how the accusation that our usage of "hack" was an attempt to sway with wordplay (or any other such resorting to meta-arguments) can be used to frame an argument that supports your viewpoint.If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming.I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.Others *do* want a more universal thing.Now who's digging their heels in and just being stubborn? You *really* don't see the problem with "Flag!"param" param"?I don't think so, but I understand how you can frame that as an argument that supports your viewpoint.I find it funny that you see a hiccup only in the default initializer when the name of all parameter is also duplicated in its type. Shouldn't that be 4 hiccups?And just try to think of the signature for the function above if it was using Flag! void foo(Flag!"param" param, Flag!"otherParam" otherParam, Flag!"thisOneIsntRequired" thisOneIsntRequired = Flag!"thisOneIsntRequired".no); Do we really want to expose that in the documentation?Yes, that's the whole point, though I agree the hiccup in the default initializer is annoying.And with named arguments, you don't even need to bother with that. So, more verbosity (and likely an indentation increase) to support (minimally) "less" verbosity.No, just version(ddoc) for select functions if you want them to. You have the needed means within the language.The documentation doesn't need the names anymore; the user would just say: void foo( Flag!"compressed", Flag!"encrypted", Flag!"buffered" = Flag!"buffered".no); Save for the "ehm" default parameter this looks palatable to me.Does that mean we now need a language feature to tell the documentation generator not to emit attribute names for parameters of type Flag!"" ?
Jun 10 2011
"Nick Sabalausky" <a a.a> wrote in message news:isu5aa$6t0$1 digitalmars.com...Now who's digging their heels in and just being stubborn? You *really* don't see the problem with "Flag!"param" param"?Erm, I mean "the hiccup with it".
Jun 10 2011
On 2011-06-10 17:04:42 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 6/10/11 3:34 PM, Michel Fortin wrote:A hack is something that works even though it's ugly and generally cause people to call for something better. I'm not opposed to using hacks as long as they're well-encapsulated and not too fragile, but in this case I find the encapsulation is leaky since you need to litter your code with Flag!"" everywhere.If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming.I don't want a universal thing, I want to solve a simple problem: there are 7 yes/no enums in Phobos, and probably some more to come. Flag solves that problem in a reasonable way. This is pretty much it.I disagree that Flag is a reasonable solution. It works, but it's ugly and verbose. I understand it's tiresome to create an enum for every parameter, but asking all users to write Flag!"" everywhere is going to be tiresome everywhere else, which is hardly an improvement. I also think you are narrowing the problem a little too much. The problem exists everywhere there is a boolean parameter. This includes phobos, druntime, and potentially any other D library. Should Flag!"" become the recommended way to make boolean parameters in D? And should creating a separate Ddoc version of the function signature become the recommended way to document boolean parameters? If so, I think it'll reflect badly on the language. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 10 2011
"Michel Fortin" <michel.fortin michelf.com> wrote in message news:isu5tk$816$1 digitalmars.com...I understand it's tiresome to create an enum for every parameter, but asking all users to write Flag!"" everywhere is going to be tiresome everywhere else, which is hardly an improvement.Excellent point.I also think you are narrowing the problem a little too much. The problem exists everywhere there is a boolean parameter.And not just bools, either. Graphics libraries typically have the same problem in spades, much more than Phobos. But with numbers, not bools. Even a Flag expanded to allow *any* enum is still insufficient for that. It seems like your design strategy here is (unintentionally, of course) focusing primarily on Phobos's own needs rather than really looking out much beyond Phobos.This includes phobos, druntime, and potentially any other D library. Should Flag!"" become the recommended way to make boolean parameters in D? And should creating a separate Ddoc version of the function signature become the recommended way to document boolean parameters? If so, I think it'll reflect badly on the language.
Jun 10 2011
On 6/10/11 5:25 PM, Michel Fortin wrote:On 2011-06-10 17:04:42 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7 AndreiOn 6/10/11 3:34 PM, Michel Fortin wrote:A hack is something that works even though it's ugly and generally cause people to call for something better. I'm not opposed to using hacks as long as they're well-encapsulated and not too fragile, but in this case I find the encapsulation is leaky since you need to litter your code with Flag!"" everywhere.If you want something to be used everywhere and it is not an implementation detail, make it part of the language. Implementing what sounds should be a language feature through a template hack and putting it the standard library is not going to make people feel good about the language, it'll remind them of what the language is missing.The problem with the "hack" label is that it instantly decreases the level of the conversation. It's the "N" word of programming.
Jun 10 2011
On 2011-06-10 18:57:20 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 6/10/11 5:25 PM, Michel Fortin wrote:It'sA hack is something that works even though it's ugly and generally cause people to call for something better. I'm not opposed to using hacks as long as they're well-encapsulated and not too fragile, but in this case I find the encapsulation is leaky since you need to litter your code with Flag!"" everywhere.https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7still a hack, but I'll agree it makes the encapsulation a little better if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 10 2011
On 6/10/11 8:08 PM, Michel Fortin wrote:On 2011-06-10 18:57:20 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times. AndreiOn 6/10/11 5:25 PM, Michel Fortin wrote:It'sA hack is something that works even though it's ugly and generally cause people to call for something better. I'm not opposed to using hacks as long as they're well-encapsulated and not too fragile, but in this case I find the encapsulation is leaky since you need to litter your code with Flag!"" everywhere.https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7still a hack, but I'll agree it makes the encapsulation a little better if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes.
Jun 10 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isuivh$1a6v$1 digitalmars.com...On 6/10/11 8:08 PM, Michel Fortin wrote:Which makes Flag even less of an improvement.On 2011-06-10 18:57:20 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times.On 6/10/11 5:25 PM, Michel Fortin wrote:It'sA hack is something that works even though it's ugly and generally cause people to call for something better. I'm not opposed to using hacks as long as they're well-encapsulated and not too fragile, but in this case I find the encapsulation is leaky since you need to litter your code with Flag!"" everywhere.https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7still a hack, but I'll agree it makes the encapsulation a little better if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes.
Jun 10 2011
We should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen! Kidding. I do welcome the proposal with the prefixed Yes/No template though, it has my vote.
Jun 10 2011
On 11/06/2011 06:18, Andrej Mitrovic wrote:We should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 11 2011
"Alix Pexton" <alix.DOT.pexton gmail.DOT.com> wrote in message news:isvae3$2o51$1 digitalmars.com...On 11/06/2011 06:18, Andrej Mitrovic wrote:Dost thou, verily?We should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :)
Jun 11 2011
On 11/06/2011 11:56, Nick Sabalausky wrote:"Alix Pexton"<alix.DOT.pexton gmail.DOT.com> wrote in message news:isvae3$2o51$1 digitalmars.com...Aye! A...On 11/06/2011 06:18, Andrej Mitrovic wrote:Dost thou, verily?We should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :)
Jun 11 2011
On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:On 11/06/2011 06:18, Andrej Mitrovic wrote:Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :pWe should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 11 2011
On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -SteveOn 11/06/2011 06:18, Andrej Mitrovic wrote:Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :pWe should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 11 2011
On 12/06/2011 02:40, Steven Schveighoffer wrote:On Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^ A...On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -SteveOn 11/06/2011 06:18, Andrej Mitrovic wrote:Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :pWe should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 12 2011
On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:On 12/06/2011 02:40, Steven Schveighoffer wrote:I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -SteveOn Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -SteveOn 11/06/2011 06:18, Andrej Mitrovic wrote:Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :pWe should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 12 2011
TBH I've only ever heard it used in Ali G Indahouse, so what do I know.. :p
Jun 12 2011
On 12/06/2011 16:11, Steven Schveighoffer wrote:On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" on its own is exceptionally rare (to the point where I doubt ever hearing anyone make such a noise and mean it to indicate the affirmative). A...On 12/06/2011 02:40, Steven Schveighoffer wrote:I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -SteveOn Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -SteveOn 11/06/2011 06:18, Andrej Mitrovic wrote:Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :pWe should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 12 2011
Alix Pexton Wrote:On 12/06/2011 16:11, Steven Schveighoffer wrote:Then you must not have heard the King James Version of the Bible read aloud, or been to a Shakespeare play. Admittedly the KJV and Shakespeare's works don't count as modern English, but I doubt you've never "heard such a noise"! :-) p.s. The word appears 209 times in Shakespeare's plays. There's a website for everything!On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" on its own is exceptionally rare (to the point where I doubt ever hearing anyone make such a noise and mean it to indicate the affirmative). A...On 12/06/2011 02:40, Steven Schveighoffer wrote:I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -SteveOn Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^On 6/11/11, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -SteveOn 11/06/2011 06:18, Andrej Mitrovic wrote:Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :pWe should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 12 2011
On 13/06/2011 02:31, Paul D. Anderson wrote:Alix Pexton Wrote:Aye, I did mean people using their own words and not someone else's. for such a prolific writer, 209 doesn't seem like a lot, and I can't help wondering how many times the bard used "aye". Mind you, he was a southerner! A...On 12/06/2011 16:11, Steven Schveighoffer wrote:Then you must not have heard the King James Version of the Bible read aloud, or been to a Shakespeare play. Admittedly the KJV and Shakespeare's works don't count as modern English, but I doubt you've never "heard such a noise"! :-) p.s. The word appears 209 times in Shakespeare's plays. There's a website for everything!On Sun, 12 Jun 2011 04:36:55 -0400, Alix Pexton <alix.DOT.pexton gmail.dot.com> wrote:True, "yea-or-nay" is quite a common, if old fashioned phrase, but "yea" on its own is exceptionally rare (to the point where I doubt ever hearing anyone make such a noise and mean it to indicate the affirmative). A...On 12/06/2011 02:40, Steven Schveighoffer wrote:I don't deny that aye is used frequently for voting. All I was saying is, the correct expression is yea or nay, not yay or nay. Andrej thought it was actually aye or nay, which I've never heard as an expression. I'm not sure it's used anymore, but it's definitely an expression that was used for voting (see my dictionary reference). -SteveOn Sat, 11 Jun 2011 13:04:47 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Nope, its definitely Aye when used for voting, (at least it is round here) as in "all those in favour, say aye", "ayes to the right" and "the ayes have it". Maybe southerners say this "yea" word of which you speak, we don't hold with their strange customs in these parts ^^On 6/11/11, Alix Pexton<alix.DOT.pexton gmail.dot.com> wrote:You were phonetically right :) It's yea or nay. http://dictionary.cambridge.org/dictionary/british/yea-or-nay My son's most recent birthday (3 years old) was a farm-themed birthday, and we asked people to RSVP yay or neigh :P So I guess there's all kinds of kooky fun you can have with flags... -SteveOn 11/06/2011 06:18, Andrej Mitrovic wrote:Oh damn, yay is what teenage girls would say, not old Englishmen. My bad, it really is "Aye". :pWe should rename Yes and No to Yay and Nay to make them alignable, and even more importantly to make us appear as old Englishmen!"Yay" and "Nay" are too similar looking, but luckily, "Yay" is not actually a old English word :) A more correct alternative would be "Aye" (pronounced the same as "eye"), which (along with "Nay") is still used for some voting actions (such as councillors deciding where to go for lunch). I myself say it al least 20 times a day :) A...
Jun 13 2011
On 6/10/11 11:55 PM, Nick Sabalausky wrote:I'm not sure I figure the reasoning. You can't penalize twice for the same reason. This makes the existing situation less desirable, not Flag less of an improvement over it. AndreiWhich makes Flag even less of an improvement.However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes.But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times.
Jun 11 2011
On 2011-06-10 22:08:31 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 6/10/11 8:08 PM, Michel Fortin wrote:It's stillOn 2011-06-10 18:57:20 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7I actually didn't meant to post the above. I wrote it, then thought I should sleep on it before deciding whether I'd post it or not since I was a little to tired. Then I hit a bad key combo and the message reached the server before I could unplug my network cable. I'm not surprised you could find some inconsistencies in it. -- Michel Fortin michel.fortin michelf.com http://michelf.com/But the problem is the same today. enum Abc : bool { no, yes } void fun(Abc abc = Abc.no); No difference. In the function declaration, the word "abc" occurs three times.a hack, but I'll agree it makes the encapsulation a little better if you use yes!"abc" at the function call point. However, I still think it's a deterioration from the user's point of view compared to the current situation with hand-crafted enums: it still requires a string, and the documentation will say func(Flag!"abc" abc), repeating the parameter's name unless you hand-craft a special Ddoc version of the function declaration. It's better than Flag!"abc".yes, but it's worse than Abc.yes.
Jun 11 2011
"Michel Fortin" <michel.fortin michelf.com> wrote in message news:isvhkr$3s4$1 digitalmars.com...I actually didn't meant to post the above. I wrote it, then thought I should sleep on it before deciding whether I'd post it or not since I was a little to tired. Then I hit a bad key combo and the message reached the server before I could unplug my network cable. I'm not surprised you could find some inconsistencies in it.That dang "Send Message" keyboard combo gets me now and then, too. In fact, last time was just yesterday. I'm all for keyboard accessability for everything, but I'd love to see the keyboard access for "Send Message" be a bit less easy. On my mail client, it's Ctrl-Enter, which of course is just begging for it to be accidentally hit while editing text.
Jun 11 2011
On 2011-06-11 07:01:13 -0400, "Nick Sabalausky" <a a.a> said:"Michel Fortin" <michel.fortin michelf.com> wrote in message news:isvhkr$3s4$1 digitalmars.com...Just after sending this message, I changed the combo in my newsreader from command-option-D to command-option-control-shift-D, like I did for my mail client a while ago. -- Michel Fortin michel.fortin michelf.com http://michelf.com/I actually didn't meant to post the above. I wrote it, then thought I should sleep on it before deciding whether I'd post it or not since I was a little to tired. Then I hit a bad key combo and the message reached the server before I could unplug my network cable. I'm not surprised you could find some inconsistencies in it.That dang "Send Message" keyboard combo gets me now and then, too. In fact, last time was just yesterday. I'm all for keyboard accessability for everything, but I'd love to see the keyboard access for "Send Message" be a bit less easy. On my mail client, it's Ctrl-Enter, which of course is just begging for it to be accidentally hit while editing text.
Jun 11 2011
Am 11.06.2011 13:09, schrieb Michel Fortin:On 2011-06-11 07:01:13 -0400, "Nick Sabalausky" <a a.a> said:When using a newsreader you should be able to retract a message, at least in Thunderbird you can just delete your own message to remove it from the server."Michel Fortin" <michel.fortin michelf.com> wrote in message news:isvhkr$3s4$1 digitalmars.com...Just after sending this message, I changed the combo in my newsreader from command-option-D to command-option-control-shift-D, like I did for my mail client a while ago.I actually didn't meant to post the above. I wrote it, then thought I should sleep on it before deciding whether I'd post it or not since I was a little to tired. Then I hit a bad key combo and the message reached the server before I could unplug my network cable. I'm not surprised you could find some inconsistencies in it.That dang "Send Message" keyboard combo gets me now and then, too. In fact, last time was just yesterday. I'm all for keyboard accessability for everything, but I'd love to see the keyboard access for "Send Message" be a bit less easy. On my mail client, it's Ctrl-Enter, which of course is just begging for it to be accidentally hit while editing text.
Jun 11 2011
On 2011-06-11 07:11:19 -0400, Daniel Gibson <metalcaedes gmail.com> said:When using a newsreader you should be able to retract a message, at least in Thunderbird you can just delete your own message to remove it from the server.I know, but Unison doesn't have that option. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
On 6/10/11 1:52 PM, Robert Clipsham wrote:On 10/06/2011 19:06, Andrei Alexandrescu wrote:I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.On 6/10/11 12:42 PM, Robert Clipsham wrote:My choice of wording was poor, sorry.On 10/06/2011 17:15, Andrei Alexandrescu wrote:This is not half-baked. It's pretty much it.https://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".The second call is problematic because it still allows bad style in calls. AndreiThe problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true); Would all be valid.
Jun 10 2011
2011/6/10 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:On 6/10/11 1:52 PM, Robert Clipsham wrote:I agree, introducing a syntax for required named parameters sounds like it would entail baggage of similar weight. TorarinOn 10/06/2011 19:06, Andrei Alexandrescu wrote:I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.On 6/10/11 12:42 PM, Robert Clipsham wrote:My choice of wording was poor, sorry.On 10/06/2011 17:15, Andrei Alexandrescu wrote:This is not half-baked. It's pretty much it.https://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".The second call is problematic because it still allows bad style in calls. AndreiThe problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters.void foo(bool param, bool otherParam, bool thisOneIsntRequired = false); Call it with or without named parameters, two are required, one is not. foo(otherParam: true, param: false); foo(true, false); foo(otherParam: true, param: false, thisOneIsntRequired: true); Would all be valid.
Jun 10 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isttf6$2oub$1 digitalmars.com...On 6/10/11 1:52 PM, Robert Clipsham wrote:I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.On 10/06/2011 19:06, Andrei Alexandrescu wrote:I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.On 6/10/11 12:42 PM, Robert Clipsham wrote:My choice of wording was poor, sorry.On 10/06/2011 17:15, Andrei Alexandrescu wrote:This is not half-baked. It's pretty much it.https://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".
Jun 10 2011
"Nick Sabalausky" <a a.a> wrote in message news:istv62$2skn$1 digitalmars.com..."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isttf6$2oub$1 digitalmars.com...Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77)); ?On 6/10/11 1:52 PM, Robert Clipsham wrote:I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.
Jun 10 2011
On 2011-06-10 13:36, Nick Sabalausky wrote:"Nick Sabalausky" <a a.a> wrote in message news:istv62$2skn$1 digitalmars.com...These yes/no enums _aren't_ named arguments. They're an attempt at creating new types where the values say what they are. The goal is primarily clarity, which named arguments arguably help with, but it's not quite the same thing. Without typedef (which is on its way out), you can't really do something like that with anything other than bool. Int!"y"(4) has to generate an int (unless you want to be forcing that all of these arguments be structs, which would be hideous), at which point it's purely documentation which the compiler has to optimize out. It's not doing the same thing as Flag at all. Andrei isn't trying to create general named arguments here. He's simply trying to create a cleaner way of generating enums with yes and no values and thus reduce boilerplate code. Having named arguments would create a similar effect, but the goal of this enum has nothing to do with named arguments beyond the fact that they have a similar effect. Its goal is to reduce boilerplate code. The net result of having the enums and Flag _is_ similar to named arguments for bool, but I don't believe that Andrei ever set down this path with the idea of creating named arguments. He effectively wanted a typedef for bool which was self-documenting. So, your suggestions of Int!"height(150) and the like are trying to do something very different (albeit somewhat related) to what Flag is trying to do. - Jonathan M Davis"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isttf6$2oub$1 digitalmars.com...Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77));On 6/10/11 1:52 PM, Robert Clipsham wrote:I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.
Jun 10 2011
On 6/10/11 3:36 PM, Nick Sabalausky wrote:"Nick Sabalausky"<a a.a> wrote in message news:istv62$2skn$1 digitalmars.com...I don't find it entirely fair to demean the suggestion as a tool to sustain your viewpoint. Flag supporting only yes and no is not a "complete inability" - it is its charter. The plan is not to have Flag be a replacement for named arguments, but instead to have it support good practices for Boolean settings and replace a number of awkward enum definitions in Phobos. As I mentioned, in the future it's possible to have Flag (or a related abstraction) support categorical features beyond yes and no, but it is not meant, and does not attempt, to cover named arguments. Andrei"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:isttf6$2oub$1 digitalmars.com...Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77)); ?On 6/10/11 1:52 PM, Robert Clipsham wrote:I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language. And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.
Jun 10 2011
Nick Sabalausky wrote:"Nick Sabalausky" <a a.a> wrote in message news:istv62$2skn$1 digitalmars.com...I don't, even though I like named parameters. boolean parameters for binary options are kind of an exception imho, because they decrease readability at the call site much more often than other types do. Somebody one this newsgroup - maybe it was Don Clugston, also made a good point against named parameters: it introduces inflexibility because now the names of the parameters of a function become part of the public api. Changing a name will now break client code. I'd still probably welcome named parameters though."Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isttf6$2oub$1 digitalmars.com...On 6/10/11 1:52 PM, Robert Clipsham wrote:I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.foo(param: true, otherParam: false); foo(Flag!"param".yes, Flag!"otherParam".no); I don't know about you, but I find the former is far more legible. I'd hate to see my code littered with Flag!"something".I agree it's more legible. The crucial question is whether the added legibility warrants adding a new feature to the language.And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);", combined with the frequency of need for such a thing, and the complete inability of Flag to address the problem for anything but bool, the inability to document it separately (as Jonathan Davis pointed out), is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.Regarding "the complete inability of Flag to address the problem for anything but bool", how are we going to wind up papering over that? Like: box(Int!"x"(3), Int!"y"(4), Int!"width"(100), Int!"height"(150), Int!"depth"(1), UInt!"color"(0xFFAA77)); ?
Jun 10 2011
On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Changing a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
On 6/10/11 4:28 PM, Andrej Mitrovic wrote:On 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com> wrote:Actually, not. The name used with Flag is part of its type. Even in a separate compilation approach, the type names must match, which is not the case for parameter names. AndreiChanging a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
On Fri, 10 Jun 2011 17:34:34 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 6/10/11 4:28 PM, Andrej Mitrovic wrote:No, it's not the same, which actually can be viewed as a plus for named parameters. A named parameter call reduces to a normal call with boolean args, which is binary compatible, even if you change the name of the parameter. A Flag! requires a recompile as well as a source change. For things like fixing typos, the binary compatibility might be good. For example, if you have a typo in the name of a Flag parameter in library version 1, you can never change the name and be backwards compatible with someone who has an old version of the library they are compiling against. The Flag makes it *more* a part of the API than named parameters. -SteveOn 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com> wrote:Actually, not. The name used with Flag is part of its type. Even in a separate compilation approach, the type names must match, which is not the case for parameter names.Changing a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
On 6/10/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 6/10/11 4:28 PM, Andrej Mitrovic wrote:I've either misread what Lutger said or I haven't stated my intentions more clearly. Most probably both.. :) By "breaking code", I'm referring to breaking compilation of existing code, not breaking the runtime semantics. You're doing this now: Flag!"KeepTerminator" keepTerminator You can change the variable name and the client code still compiles. But are you going to keep the name "KeepTerminator" in sync with the new variable name? It sure seems that's how this Flag template is used. If you do, that means client code has to change as well. Named arguments have the same problem. That's what I was referring to.On 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com> wrote:Actually, not. The name used with Flag is part of its type. Even in a separate compilation approach, the type names must match, which is not the case for parameter names. AndreiChanging a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
Andrej Mitrovic wrote:On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.Changing a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
"Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message news:isu365$2ao$1 digitalmars.com...Andrej Mitrovic wrote:That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.Changing a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
On 2011-06-10 14:44, Nick Sabalausky wrote:"Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message news:isu365$2ao$1 digitalmars.com...The problem is that there is no way to provide a deprecation path without renaming functions. When changing the types that a function takes or the number of its parameters, you can overload it. The old version gets scheduled for deprecation, then deprecated, and finally, it's removed. People have time to migrate their code. However, you _can't_ overload on parameter names. So, the only way that you can change a parameter's name without breaking any and all code that used it as a named argument is to create a _new_ function with a _new_ name. So, we'd have to rename entire functions just to be able to rename a single parameter. That's way worse than just having to deal with some parameter type changes or a changes in the number of arguments. Suddenly, you have a whole new function to remember. And currently, you can rename a parameter's name without breaking any code at all. So, named arguments _drastically_ increase the pain of renaming function parameters. - Jonathan M DavisAndrej Mitrovic wrote:That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.Changing a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
On Fri, 10 Jun 2011 17:59:30 -0400, Jonathan M Davis <jmdavisProg gmx.com> wrote:On 2011-06-10 14:44, Nick Sabalausky wrote:This assumes everyone calls every function with named parameters. In reality the number of named parameter calls will be low. There are also possible ways to implement this properly: void foo(bool KeepTerminator) { } void foo(bool OldName); // mark as deprecated? Should be feasible. -Steve"Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message news:isu365$2ao$1 digitalmars.com...The problem is that there is no way to provide a deprecation path without renaming functions. When changing the types that a function takes or the number of its parameters, you can overload it. The old version gets scheduled for deprecation, then deprecated, and finally, it's removed. People have time to migrate their code. However, you _can't_ overload on parameter names. So, the only way that you can change a parameter's name without breaking any and all code that used it as a named argument is to create a _new_ function with a _new_ name. So, we'd have to rename entire functions just to be able to rename a single parameter. That's way worse than just having to deal with some parameter type changes or a changes in the number of arguments. Suddenly, you have a whole new function to remember. And currently, you can rename a parameter's name without breaking any code at all. So, named arguments _drastically_ increase the pain of renaming function parameters.Andrej Mitrovic wrote:exposingOn 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Not strictly, but practically yes. It's also the point of them,Changing a name will now break client code.The flag template suffers from the same issue.this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, includingthosealready written without this dependency issue in mind.That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.
Jun 10 2011
On Jun 11, 11 05:59, Jonathan M Davis wrote:On 2011-06-10 14:44, Nick Sabalausky wrote:Why do you need to rename parameter name of a stable API?"Lutger Blijdestijn"<lutger.blijdestijn gmail.com> wrote in message news:isu365$2ao$1 digitalmars.com...The problem is that there is no way to provide a deprecation path without renaming functions. When changing the types that a function takes or the number of its parameters, you can overload it. The old version gets scheduled for deprecation, then deprecated, and finally, it's removed. People have time to migrate their code. However, you _can't_ overload on parameter names. So, the only way that you can change a parameter's name without breaking any and all code that used it as a named argument is to create a _new_ function with a _new_ name. So, we'd have to rename entire functions just to be able to rename a single parameter. That's way worse than just having to deal with some parameter type changes or a changes in the number of arguments. Suddenly, you have a whole new function to remember. And currently, you can rename a parameter's name without breaking any code at all. So, named arguments _drastically_ increase the pain of renaming function parameters. - Jonathan M DavisAndrej Mitrovic wrote:That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.On 6/10/11, Lutger Blijdestijn<lutger.blijdestijn gmail.com> wrote:Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.Changing a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.793.1307743181.14074.digitalmars-d puremagic.com...On 2011-06-10 14:44, Nick Sabalausky wrote:What I don't see is a compelling need to provide a deprecation path when the names change. What's so hard about "Recompiling...Oh, 'foo' doesn't work and the new name is 'bar', and it's on this file/line? Ok, done." And even that isn't needed much in a stable API anyway."Lutger Blijdestijn" <lutger.blijdestijn gmail.com> wrote in message news:isu365$2ao$1 digitalmars.com...The problem is that there is no way to provide a deprecation path without renaming functions.Andrej Mitrovic wrote:That's hardly an issue though. Updating callers to use a changed function name is trivial. I see no reason why this would be any less trivial.On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Not strictly, but practically yes. It's also the point of them, exposing this name in the api. But its *only* for those parameters, which I understand are right now just 7 functions in the whole of phobos. With named parameters, the issue affects every function, including those already written without this dependency issue in mind.Changing a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
On 2011-06-10 14:28, Andrej Mitrovic wrote:On 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Not really. There's a big difference between changing the type name and changing the parameter name. You can freely change the parameter name without changing the type name. Also, you can overload on type names, allowing you to deprecate the old name and replace it with a new one gradually. You _can't_ overload on parameter names, so you _can't_ have a deprecation path with named arguments without renaming the function itself, which is _way_ worse. The difference between the two isn't even comparable. - Jonathan M DavisChanging a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.791.1307742081.14074.digitalmars-d puremagic.com...On 2011-06-10 14:28, Andrej Mitrovic wrote:I *really* think that whole issue is a complete triviality, but: 1. Maybe you *could* allow overloading on name, forcing at least that particular param to be named: void foo(int oldName); void foo(int newName); foo(oldName:7); // Ok foo(newName:7); // Ok foo(7); // Error void bar(int num); bar(num:7); // Ok bar(7); // Ok 2. This: void foo(int newName); deprecated void foo(int oldName); foo(oldName:7); // Error: Deprecated foo(newName:7); // Ok foo(7); // OkOn 6/10/11, Lutger Blijdestijn <lutger.blijdestijn gmail.com> wrote:Not really. There's a big difference between changing the type name and changing the parameter name. You can freely change the parameter name without changing the type name. Also, you can overload on type names, allowing you to deprecate the old name and replace it with a new one gradually. You _can't_ overload on parameter names, so you _can't_ have a deprecation path with named arguments without renaming the function itself, which is _way_ worse. The difference between the two isn't even comparable. - Jonathan M DavisChanging a name will now break client code.The flag template suffers from the same issue.
Jun 10 2011
On 6/10/11 3:30 PM, Nick Sabalausky wrote:I really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);",Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam"); See https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7combined with the frequency of need for such a thing,People have found 7 uses of the yes/no enum pattern in Phobos plus a couple others where it should - in 135KLoC.and the complete inability of Flag to address the problem for anything but bool,Flag can be made to incorporate arbitrary categorical types, I just haven't done that yet so as to not complicate implementation too early.the inability to document it separately (as Jonathan Davis pointed out),This is an issue shared by named parameters, and for such stuff the current enums work just fine. Now who is rationalizing? :o)is all definitely much much more than enough to warrant adding a tried-and-proven feature that's become standard in damn near every other modern language.I'm actually less convinced than before having read your arguments. Andrei
Jun 10 2011
On 11.06.2011 0:58, Andrei Alexandrescu wrote:On 6/10/11 3:30 PM, Nick Sabalausky wrote:I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStart -- Dmitry OlshanskyI really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);",Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");
Jun 10 2011
On 6/10/11 6:03 PM, Dmitry Olshansky wrote:On 11.06.2011 0:58, Andrei Alexandrescu wrote:Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 AndreiOn 6/10/11 3:30 PM, Nick Sabalausky wrote:I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStartI really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);",Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");
Jun 10 2011
On 6/11/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330That's much more like it. This whole bikeshedding issue for me was avoiding the nasty bang quote string unquote shenanigans that look ugly in code. Keeping No and Yes at the beginning kind of goes in hand with the not operator. Now that I mention it, you can't negate a Flag variable: Flag!"KeepTerminator" state; auto line = getLine(!state); But maybe that's a good thing?
Jun 10 2011
On Fri, 10 Jun 2011 18:16:14 -0500, Andrei Alexandrescu wrote:On 6/10/11 6:03 PM, Dmitry Olshansky wrote:commit/801ccc96ce56827cd0d0b608895269bdccba4330 I'm sold. :) To add my 2 cents to the "named arguments" debate, I can't believe people are still asking for this. At this point in D's development, adding such would be a major language change, and there really shouldn't be any more of those. I mean, D2 supposedly went stable almost a year ago! If/when work starts on D3, we can get back to it. In the mean time, I think Flag!"param" with the new Yes/No types nicely solves a common case of code duplication in Phobos. It is not, nor do I think Andrei intended it to be, a general attempt to emulate named parameters. -LarsOn 11.06.2011 0:58, Andrei Alexandrescu wrote:Ask, and ye shall receive. https://github.com/andralex/phobos/On 6/10/11 3:30 PM, Nick Sabalausky wrote:I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStartI really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);",Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");
Jun 10 2011
Am 11.06.2011 01:16, schrieb Andrei Alexandrescu:Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330I like this version much more but shouldn't it also be flag.KeepTerminator for consistency? Mafi
Jun 11 2011
On 6/11/11 4:58 AM, Mafi wrote:Am 11.06.2011 01:16, schrieb Andrei Alexandrescu:Not sure I understand. How do you mean that? AndreiAsk, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330I like this version much more but shouldn't it also be flag.KeepTerminator for consistency? Mafi
Jun 11 2011
Am 11.06.2011 14:07, schrieb Andrei Alexandrescu:On 6/11/11 4:58 AM, Mafi wrote:I meant something like this: template FlagImpl(string name) { enum FlagImpl : bool { yes = true, no = false } } //usage Flag.xy as alias for FlagImpl!"xy" //to be consistent with yes.xy and no.xy struct Flag { template opDispatch(string name) { alias FlagImpl!name opDispatch; } } Now, opDispatch cannot currently be a type, can it.Am 11.06.2011 01:16, schrieb Andrei Alexandrescu:Not sure I understand. How do you mean that? AndreiAsk, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330I like this version much more but shouldn't it also be flag.KeepTerminator for consistency? Mafi
Jun 11 2011
On 6/11/2011 8:16 AM, Andrei Alexandrescu wrote:On 6/10/11 6:03 PM, Dmitry Olshansky wrote:I was going to add my voice against this proposal until I saw this. Nice one!On 11.06.2011 0:58, Andrei Alexandrescu wrote:Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 AndreiOn 6/10/11 3:30 PM, Nick Sabalausky wrote:I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStartI really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);",Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");
Jun 11 2011
On Fri, 10 Jun 2011 19:16:14 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 6/10/11 6:03 PM, Dmitry Olshansky wrote:This is better. Does the definition of the function still require repetition? i.e. getLine(Flag!"KeepTerminator" keepTerminator = Yes.KeepTerminator). I suppose we can live with that. Still reads weird to me with the value coming before the category, but I suppose the names can be adjusted accordingly. As far as the negation, I think we need one more layer of type: struct FlagParam(string pname) { Flag!pname value; alias value this; this(Flag!pname x) { this.value = x } FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); } } BTW, is there a way to hook "!"? Maybe this won't work... The idea is to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes). -SteveOn 11.06.2011 0:58, Andrei Alexandrescu wrote:Ask, and ye shall receive. https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330On 6/10/11 3:30 PM, Nick Sabalausky wrote:I think this looks not half bad and does not require change in the language. Still yes.param and no.param might be easier on the eyes, though IMO it should look more like just param and no.param. e.g. StopWatch(autoStart); StopWatch(no!autoStart); // or no.autoStartI really see Flag more as a way to try to rationalize avoiding adding named parameters to the language.There are fights that I believe are important and others that I think are less so. I find name parameters nice to have but more in the second category. There's just so much stuff that's more important.And yes, the legibility of "foo(Flag!"param".yes, Flag!"otherParam".no);",Fair point. I figured this should be easier: foo(yes!"param", no!"otherParam");
Jun 11 2011
On 2011-06-11 09:05:52 -0400, "Steven Schveighoffer" <schveiguy yahoo.com> said:As far as the negation, I think we need one more layer of type: struct FlagParam(string pname) { Flag!pname value; alias value this; this(Flag!pname x) { this.value = x } FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); } } BTW, is there a way to hook "!"? Maybe this won't work... The idea is to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
On 6/11/11 8:25 AM, Michel Fortin wrote:On 2011-06-11 09:05:52 -0400, "Steven Schveighoffer" <schveiguy yahoo.com> said:Agreed. I'll venture to add that I find the first also more desirable than an implicit conversion from func(expression). AndreiAs far as the negation, I think we need one more layer of type: struct FlagParam(string pname) { Flag!pname value; alias value this; this(Flag!pname x) { this.value = x } FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); } } BTW, is there a way to hook "!"? Maybe this won't work... The idea is to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable.
Jun 11 2011
On Sat, 11 Jun 2011 09:25:19 -0400, Michel Fortin <michel.fortin michelf.com> wrote:On 2011-06-11 09:05:52 -0400, "Steven Schveighoffer" <schveiguy yahoo.com> said:We need another struct besides Yes and No that allows creation with another opDispatch: Foo.abc(expression); The best name for Foo is Flag, but that's taken... But still, is there a way to override the type returned by !flag? I think there isn't... That's kind of sucky. Flipping of a flag is a very common feature, I would expect to be able to do it easily. Hm... what if opCast!bool() returns something other than bool? does that actually work? That *would* be a hack :) We could also possibly use unary - to denote flipping a flag. That's very hacky too, but I think it would work. -SteveAs far as the negation, I think we need one more layer of type: struct FlagParam(string pname) { Flag!pname value; alias value this; this(Flag!pname x) { this.value = x } FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); } } BTW, is there a way to hook "!"? Maybe this won't work... The idea is to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable.
Jun 11 2011
On 6/11/11 9:30 AM, Steven Schveighoffer wrote:On Sat, 11 Jun 2011 09:25:19 -0400, Michel Fortin <michel.fortin michelf.com> wrote:I agree that's a drawback. I couldn't find a reasonable workaround. AndreiOn 2011-06-11 09:05:52 -0400, "Steven Schveighoffer" <schveiguy yahoo.com> said:We need another struct besides Yes and No that allows creation with another opDispatch: Foo.abc(expression); The best name for Foo is Flag, but that's taken... But still, is there a way to override the type returned by !flag? I think there isn't... That's kind of sucky. Flipping of a flag is a very common feature, I would expect to be able to do it easily.As far as the negation, I think we need one more layer of type: struct FlagParam(string pname) { Flag!pname value; alias value this; this(Flag!pname x) { this.value = x } FlagParam op???() const { return FlagParam(cast(Flag!pname)!value); } } BTW, is there a way to hook "!"? Maybe this won't work... The idea is to have Yes.abc return FlagParam!"abc"(Flag!"abc".yes).If you need to convert a bool to a Flag!"abc", you can do any of these: func(expression ? Yes.abc : No.abc); or func(cast(Flag!"abc")expression); or, with your proposal: func(FlagParam!"abc"(expression)); None of this is very appealing, but I find the first is the most readable.
Jun 11 2011
On Jun 11, 11 02:06, Andrei Alexandrescu wrote:On 6/10/11 12:42 PM, Robert Clipsham wrote:Making the compulsory enum name as a feature means http://www.digitalmars.com/d/archives/digitalmars/D/8524.html will never be addressed, I suppose.On 10/06/2011 17:15, Andrei Alexandrescu wrote:This is not half-baked. It's pretty much it. Ugly is in the eye of the beholder, but I fail to see how the added punctuation makes Flag!"param".yes significantly more verbose than param : true. The problem that named parameters are still optional remains. Or we need to add one extra language feature to specify required named parameters. Andreihttps://github.com/D-Programming-Language/phobos/pull/94 Discuss! AndreiI really *really* don't like this. It's ugly and verbose, and a pathetic work around for the lack of named parameters. Either support named parameters or not, don't have an ugly half-baked work-around.
Jun 10 2011
On 2011-06-10 09:15, Andrei Alexandrescu wrote:https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis
Jun 10 2011
On Jun 11, 11 03:30, Jonathan M Davis wrote:On 2011-06-10 09:15, Andrei Alexandrescu wrote:The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis
Jun 10 2011
On 2011-06-10 12:33, KennyTM~ wrote:On Jun 11, 11 03:30, Jonathan M Davis wrote:Why would it be? You generally want documentation specific to the enum anyway, so that isn't exactly boilerplate. You'd just stick the documentation above the mixin. And if you don't want to do that but want it in the documentation for the function that uses it (particularly if there's only one - though that's often not the case), then just put the documentation in the function's documentation. Andrei's current solution does nothing for documentation, and arguably makes it worse, because there's no place to put documentation on the enum directly if you need to. - Jonathan M DavisOn 2011-06-10 09:15, Andrei Alexandrescu wrote:The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis
Jun 10 2011
On Jun 11, 11 03:40, Jonathan M Davis wrote:On 2011-06-10 12:33, KennyTM~ wrote:Please review the previous discussion of why Flag (was YesOrNo) was proposed. http://www.digitalmars.com/d/archives/digitalmars/D/YesOrNo_useful_idiom_helper_or_wanking_134392.htmlOn Jun 11, 11 03:30, Jonathan M Davis wrote:Why would it be? You generally want documentation specific to the enum anyway, so that isn't exactly boilerplate. You'd just stick the documentation above the mixin. And if you don't want to do that but want it in the documentation for the function that uses it (particularly if there's only one - though that's often not the case), then just put the documentation in the function's documentation. Andrei's current solution does nothing for documentation, and arguably makes it worse, because there's no place to put documentation on the enum directly if you need to. - Jonathan M DavisOn 2011-06-10 09:15, Andrei Alexandrescu wrote:The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis
Jun 10 2011
On 2011-06-10 12:47, KennyTM~ wrote:On Jun 11, 11 03:40, Jonathan M Davis wrote:In many cases, I very much think that the documentation should be separate. A prime example would be std.datetime.AllowDayOverflow. It's use in several places in std.datetime, and having one place to read up on it is definitely beneficial. Not having a place where the enum is defined separately would definitely be worse in that case. The area where it's more debatable is when there's only _one_ function which uses the enum. Then Andrei's proposed solution is more reasonable. But worse comes to worst, you can _still_ put the documentation with the function in the current solution. Andrei's solution adds _nothing_ to that. It just makes it so that there isn't actually a separate enum somewhere which can be documented. It removes the possibility of documenting it. I'd rather have the one line mixin which you can either document directly or skip documenting and put its documentation with the function that uses it rather than one where you _can't_ document it separately. std.datetime will _not_ switch to this even if it gets checked in simply because it will make the documentation worse. And I'm not sure that we want to have some enums using this solution and some not, since that would be inconsistent. I'm not entirely against Andrei's solution (it does reduce boilerplate code), but I think that a string mixin solution makes more sense. It's less verbose, and you can choose where to put its documentation. - Jonathan M DavisOn 2011-06-10 12:33, KennyTM~ wrote:Please review the previous discussion of why Flag (was YesOrNo) was proposed. http://www.digitalmars.com/d/archives/digitalmars/D/YesOrNo_useful_idiom_he lper_or_wanking_134392.htmlOn Jun 11, 11 03:30, Jonathan M Davis wrote:Why would it be? You generally want documentation specific to the enum anyway, so that isn't exactly boilerplate. You'd just stick the documentation above the mixin. And if you don't want to do that but want it in the documentation for the function that uses it (particularly if there's only one - though that's often not the case), then just put the documentation in the function's documentation. Andrei's current solution does nothing for documentation, and arguably makes it worse, because there's no place to put documentation on the enum directly if you need to. - Jonathan M DavisOn 2011-06-10 09:15, Andrei Alexandrescu wrote:The problem is the 'YesNoEnum!"KeepTerminator"' will not be shown along with the DDoc of 'getLine'.https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly. - Jonathan M Davis
Jun 10 2011
On 6/10/11 2:30 PM, Jonathan M Davis wrote:On 2011-06-10 09:15, Andrei Alexandrescu wrote:There is general agreement (which includes myself) that a language feature is nicer than Flag, and that Flag is nicer than the current state of affairs. This is no surprise because a specialized language feature will _always_ be better than one built from tools offered within the language. It's like God vs. human. So the crucial question is whether a language change is warranted. We should be much more restrained than this discussion suggests. Any and all programming languages have limitations. This, coupled with the former point, leads to the fact that at some point you MUST look into doing within the language something that could be done nicer if you got to play God. Doing the latter does not scale. So, does Flag work around a limitation in the language? Sure. Would a language-changing solution work better? Absolutely. Is the necessity of changing the language a foregone conclusion? I don't think so. Andreihttps://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes.
Jun 10 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:istulq$2rjc$1 digitalmars.com...On 6/10/11 2:30 PM, Jonathan M Davis wrote:MuchOn 2011-06-10 09:15, Andrei Alexandrescu wrote:There is general agreement (which includes myself) that a language feature is nicer than Flag,https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes.and that Flag is nicer than the current state of affairs.Only *barely*.This is no surprise because a specialized language feature will _always_ be better than one built from tools offered within the language. It's like God vs. human. So the crucial question is whether a language change is warranted. We should be much more restrained than this discussion suggests. Any and all programming languages have limitations. This, coupled with the former point, leads to the fact that at some point you MUST look into doing within the language something that could be done nicer if you got to play God. Doing the latter does not scale. So, does Flag work around a limitation in the language? Sure. Would a language-changing solution work better? Absolutely. Is the necessity of changing the language a foregone conclusion? I don't think so.In general, I would agree with this. I completely understand the desire, and even the need, to avoid extra language features when reasonable to do so. I really do. But the idea of using Flag over named parameters just stretches it to a rediculous extreme. This seriously reminds me of Sun's infamous whitepaper that desperately tried to rationalize Java's lack of delegates/anon-funcs ("But you can use functors!!!" Fuck functors.) Is adding the feature of named parameters worthwhile in light of Flag? *YES*, *ABSOLUTELY*, *CLEARLY*, *DEFINITELY*, *YES*, *YES*, *YES*.
Jun 10 2011
Andrei:We should be much more restrained than this discussion suggests. Any and all programming languages have limitations. This, coupled with the former point, leads to the fact that at some point you MUST look into doing within the language something that could be done nicer if you got to play God. Doing the latter does not scale.This use of word "scale" assumes there is a larger and larger group of basic features that we'll desire in the language. But I have experience both of "normal" languages and of languages with macros as Scheme, and I don't think this is true. In the next few years we will not want to add a large and growing number of basic features to D2/D3. And currently in D there are features much less generally useful than named arguments or tuple unpacking syntax sugar, as Delimited Strings, Lazy Variadic Functions and more.So, does Flag work around a limitation in the language? Sure. Would a language-changing solution work better? Absolutely. Is the necessity of changing the language a foregone conclusion? I don't think so.Named arguments offer a more general solution than Flags, useful for all kinds of arguments, with a more readable syntax. I don't think you need a sub-feature to _require_ the argument name at the call point (on the other hand you may desire a sub-feature Scala has, to support deprecation of argument names. This helps solve a problem Don too has with named arguments). Bye, bearophile
Jun 10 2011
On Fri, 10 Jun 2011 16:21:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 6/10/11 2:30 PM, Jonathan M Davis wrote:Yes.On 2011-06-10 09:15, Andrei Alexandrescu wrote:There is general agreement (which includes myself) that a language feature is nicer than Flag,https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes.and that Flag is nicer than the current state of affairs.No. Flag!"KeepTerminator".yes is much worse than KeepTerminator.yes. And Flag!"KeepTerminator" keepTerminator is just, horrendous, in documentation *or* source. If the rote creation of boolean enums is a problem, why not a mixin? template Flag(string name) { mixin("enum " ~ name ~ " : bool { no = false, yes = true }"); } mixin Flag!"KeepTerminator";This is no surprise because a specialized language feature will _always_ be better than one built from tools offered within the language. It's like God vs. human.I think the debate is more about how this solution is a step in the wrong direction more than it's not as good as a real solution.So the crucial question is whether a language change is warranted.If the options are Flag or a language solution, the answer is yes. I'd much rather keep things as they are than have Flag!string. -Steve
Jun 10 2011
On 6/10/11 5:14 PM, Steven Schveighoffer wrote:On Fri, 10 Jun 2011 16:21:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e744ab8e7There is general agreement (which includes myself) that a language feature is nicer than Flag,Yes.and that Flag is nicer than the current state of affairs.No. Flag!"KeepTerminator".yes is much worse than KeepTerminator.yes. And Flag!"KeepTerminator" keepTerminator is just, horrendous, in documentation *or* source.If the rote creation of boolean enums is a problem, why not a mixin? template Flag(string name) { mixin("enum " ~ name ~ " : bool { no = false, yes = true }"); } mixin Flag!"KeepTerminator";Because you still need to define it separately from use.Keeping things as they are fosters awkward duplication or coupling. AndreiThis is no surprise because a specialized language feature will _always_ be better than one built from tools offered within the language. It's like God vs. human.I think the debate is more about how this solution is a step in the wrong direction more than it's not as good as a real solution.So the crucial question is whether a language change is warranted.If the options are Flag or a language solution, the answer is yes. I'd much rather keep things as they are than have Flag!string.
Jun 10 2011
On 2011-06-10 15:54, Andrei Alexandrescu wrote:On 6/10/11 5:14 PM, Steven Schveighoffer wrote:What I want to know is what you want to do with such enums where it's actually _desirable_ that they be defined separately from use. A prime example of this is std.datetime's AllowDayOverflow. It's used by several functions, and by having it explicitly defined separately, it can be appropriately documented in one place rather than having to explain it for every function that uses it. I really think that it _should_ be defined separately. But if it is defined separately, then I don't see how it could work with the Flag template. Even if we go with the improved yes and no templates that you just added (which are definitely an improvement over naked Flag), they don't work with a yes/no enum which is defined separately. This means that you'll have AllowDayOverflow.yes and AllowDayOverflow.no instead of yes!"AllowDayOverflow" and no!"AllowDayOverflow". That's not necessarily a bad thing, since the enum _is_ defined differently, but if the common idiom is to use yes!"enumName" and no!"enumName", then the yes/no enums which are actually defined separately won't match. Is that acceptable, or is there actually a reasonable way to make the yes and no templates work with non-Flag enums (perhaps by having it first check whether enumName.yes compiles before trying Flag!"enumName")? - Jonathan M DavisOn Fri, 10 Jun 2011 16:21:59 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:https://github.com/andralex/phobos/commit/84c75336a4ef04b4c3b1924d7ac9329e7 44ab8e7There is general agreement (which includes myself) that a language feature is nicer than Flag,Yes.and that Flag is nicer than the current state of affairs.No. Flag!"KeepTerminator".yes is much worse than KeepTerminator.yes. And Flag!"KeepTerminator" keepTerminator is just, horrendous, in documentation *or* source.If the rote creation of boolean enums is a problem, why not a mixin? template Flag(string name) { mixin("enum " ~ name ~ " : bool { no = false, yes = true }"); } mixin Flag!"KeepTerminator";Because you still need to define it separately from use.
Jun 10 2011
On 6/10/11 7:09 PM, Jonathan M Davis wrote:What I want to know is what you want to do with such enums where it's actually _desirable_ that they be defined separately from use.I guess if you want such you either define the flag separately or make it an alias and document the alias. I mean there's nothing new here just because Flag came about. Andrei
Jun 10 2011
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.781.1307734245.14074.digitalmars-d puremagic.com...On 2011-06-10 09:15, Andrei Alexandrescu wrote:I'd support this *as long as* it's existence didn't get used as rationalization for avoiding the inclusion of named arguments.https://github.com/D-Programming-Language/phobos/pull/94 Discuss!I do have to admit that as much as I hate the idea of named parameters, this particular proposal certainly seems to be an argument in favor of adding them, which would tend to argue against making these changes. After thinking about it, I'd argue that it would be better to create a string mixin which created the enums for you instead of using the template as part of the arguments. e.g. mixin(YesNoEnum!"KeepTerminator")); Then all of the rest of the code is the same. You'd still use KeepTerminator.yes and KeepTerminator.no, but we avoided having to create duplicate enums by hand every time that we want this kind of variable. So, you still reduce the boilerplate code, but the usage is much less ugly.
Jun 10 2011
Lutger Blijdestijn:Somebody one this newsgroup - maybe it was Don Clugston, also made a good point against named parameters: it introduces inflexibility because now the names of the parameters of a function become part of the public api. Changing a name will now break client code.Scala faces this problem: http://www.digitalmars.com/d/archives/digitalmars/D/Deprecated_argument_names_131514.html Bye, bearophile
Jun 10 2011
On 6/10/11 5:53 PM, bearophile wrote:Lutger Blijdestijn:That's good evidence that introducing named parameters would be quite involved. AndreiSomebody one this newsgroup - maybe it was Don Clugston, also made a good point against named parameters: it introduces inflexibility because now the names of the parameters of a function become part of the public api. Changing a name will now break client code.Scala faces this problem: http://www.digitalmars.com/d/archives/digitalmars/D/Deprecated_argument_names_131514.html Bye, bearophile
Jun 10 2011
Andrei:That's good evidence that introducing named parameters would be quite involved.It's also good evidence that Martin Odersky, one of the most intelligent language designers alive today, is willing to do a lot to support named arguments in his language :-) Probably implementing tuple unpacking syntax sugar too needs some not small changes, but they are well worth it (of those two features I think tuple unpacking syntax sugar is more important than named arguments). Anyway, in Scala this sub-feature isn't a custom language feature, it uses a general feature, annotations, that's used for several other purposes too. Bye, bearophile
Jun 10 2011
On 6/10/11 6:26 PM, bearophile wrote:Andrei:I have all respect for Odersky's competence, but that is beside the point. Design decisions are always taken in a context, and it's not impossible he would've had decided otherwise in a different context. D is a rich, powerful language _now_. It has classic features present in many languages, and a few features that are not present in many. Their full combination is not present in any other language, and creates a unique context. We've been historically trigger happy about discussing adding features in this group. This is not unique to D - all languages underwent the same process. But at this point it is a necessity that we start migrating our mindset from an endless wishlist - towards finding ingenious solutions within the language. Again, this is the case for every single language there is. Combining existing features towards new ends is in some ways more difficult than language design because you play within a confined ground, and I am a bit disappointed that a few posters have shown only contempt for such an effort.That's good evidence that introducing named parameters would be quite involved.It's also good evidence that Martin Odersky, one of the most intelligent language designers alive today, is willing to do a lot to support named arguments in his language :-)Probably implementing tuple unpacking syntax sugar too needs some not small changes, but they are well worth it (of those two features I think tuple unpacking syntax sugar is more important than named arguments).What's wrong with myTuple.expand? Andrei
Jun 10 2011
Andrei:Design decisions are always taken in a context,Right. But wasn't your comment about Scala named arguments complexity too out of context?But at this point it is a necessity that we start migrating our mindset from an endless wishlist - towards finding ingenious solutions within the language.There are few basic features that are missing that are better as built-ins, even now. Tuple unpacking syntax sugar, named arguments, computed gotos, and few other smaller things. Do you want to freeze D language to D2 and not take a look at ideas for D3?and I am a bit disappointed that a few posters have shown only contempt for such an effort.You need to take a better look at the kind of people that are in this forum. People here are walking away from C++, Java (and even Python), looking for a feature-rich language that avoids some of the syntax kludges their former languages force them to use in their programs. So it's not so strange that people in this forum have on average a significantly lower tolerance to tricks like your Flag proposal. In a C++ forum your Flag idea probably is much more welcome, because compared to D programmers probably C++ programmers accept a higher level of noise and ugliness in their code :-)What's wrong with myTuple.expand?It does nothing of what I need? Haven't we had this discussion already? I am having a huge deja-vu :-) I have discussed this topic several times already. Didn't you agree about the need of unpacking syntax sugar for tuples? I am confused now.................................. Bye, bearophile
Jun 10 2011
On 6/10/11 7:04 PM, bearophile wrote:Andrei:What I did was to say that Don's and others' point, corroborated with the fact that Scala found it necessary to add that feature to the language, suggests that we need to worry about that.Design decisions are always taken in a context,Right. But wasn't your comment about Scala named arguments complexity too out of context?Falling for either extreme would be a mistake.But at this point it is a necessity that we start migrating our mindset from an endless wishlist - towards finding ingenious solutions within the language.There are few basic features that are missing that are better as built-ins, even now. Tuple unpacking syntax sugar, named arguments, computed gotos, and few other smaller things. Do you want to freeze D language to D2 and not take a look at ideas for D3?I'd love to see more evidence to this claim.and I am a bit disappointed that a few posters have shown only contempt for such an effort.You need to take a better look at the kind of people that are in this forum. People here are walking away from C++, Java (and even Python), looking for a feature-rich language that avoids some of the syntax kludges their former languages force them to use in their programs.So it's not so strange that people in this forum have on average a significantly lower tolerance to tricks like your Flag proposal. In a C++ forum your Flag idea probably is much more welcome, because compared to D programmers probably C++ programmers accept a higher level of noise and ugliness in their code :-)I don't think that's the reason. You should have seen the C++ forums up until about 1997. They were brimming with enthusiastic proposals for language changes. Interesting work became possible after it became clear to everyone that the language is now given, so it's time to use what's there. D, too, is receiving an increasing amount of real work from the community since TDPL's publication.I must be the one confused, but at best we shouldn't spread ourselves too thin. AndreiWhat's wrong with myTuple.expand?It does nothing of what I need? Haven't we had this discussion already? I am having a huge deja-vu :-) I have discussed this topic several times already. Didn't you agree about the need of unpacking syntax sugar for tuples? I am confused now..................................
Jun 10 2011
Andrei:I'd love to see more evidence to this claim.Right :-)Interesting work became possible after it became clear to everyone that the language is now given, so it's time to use what's there.If you want to build stable large frameworks and libraries then having a "stable" (backwards compatible) language helps. But in this thread we are only several years. Python is just out of a design hiatus meant to help other Python implementations catch up, and now new design ideas are discussed again. In D syntax sugar for tuple unpacking is useful for library programmers too. Bye, bearophile
Jun 10 2011
On 6/10/11 8:31 PM, bearophile wrote:Andrei:Don't kid yourself. Every additive change creates more precedent and more reason to refuse thinking creatively within the language. It also means the language and its fostered idioms are a moving target.I'd love to see more evidence to this claim.Right :-)Interesting work became possible after it became clear to everyone that the language is now given, so it's time to use what's there.If you want to build stable large frameworks and libraries then having a "stable" (backwards compatible) language helps. But in this thread we are only talking about additive changes.things), and the same has happened to Python too, since several years. Python is just out of a design hiatus meant to help other Python implementations catch up, and now new design ideas are discussed again. In D syntax sugar for tuple unpacking is useful for library programmers too.I think these languages are at a different point in their evolution than D. We still don't have a strong answer to "what are the largest apps written in D" and this is because many people with an interest in the language are paralyzed in analysis. I know the phenomenon: after you spend a lot discussing designs, it is downright frightening to commit to one. Andrei
Jun 10 2011
On 2011-06-10 16:46, Andrei Alexandrescu wrote:On 6/10/11 6:26 PM, bearophile wrote:The Herb Sutter interview that you recently posted a link to has an interesting point of view on that. One of the reasons that lambdas were added to C++0x was because Boost had shown how close you could get there using the language as it was and that it just wasn't good enough. Lambdas were added to the language precisely because they couldn't be done reasonably without additional language supported. On the other hand, other stuff that they added which Boost had tried to do - such as shared_ptr - were added as library solutions, because they worked as library solutions. As you've said, we've reached the point that D is powerful enough and complicated enough that we should be first trying to see how well we can solve problems using the language itself rather than adding new features to it. As we do that, we should be able to see what is reasonably feasible within the language as it is and what just doesn't work. As we find things that just don't work but which we really want to be able to do, we can look at adding features to the language to deal with them, but we should definitely be looking at using the language as it is first. In this particular case, while named arguments might arguably be nice, they're "nice to have," not a necessity. The question is how close we can get to having reasonable yes/no enums like we've been trying to do but without excessive boilerplate code. We may decide to add named arguments later, but D is really at the point that its current features need to be completely ironed out before we look at adding additional features that we don't really need. I think that there _are_ features that we need to look at adding in some form or other (such as conditional attributes) in order to solve current problems in the language (such as the inability to use many attributes - such as pure and safe - with templates without excessive duplication of code). But if a feature does not solve a pressing problem and/or can be reasonably solved by improving Phobos, then we should be improving Phobos. - Jonathan M DavisAndrei:I have all respect for Odersky's competence, but that is beside the point. Design decisions are always taken in a context, and it's not impossible he would've had decided otherwise in a different context. D is a rich, powerful language _now_. It has classic features present in many languages, and a few features that are not present in many. Their full combination is not present in any other language, and creates a unique context. We've been historically trigger happy about discussing adding features in this group. This is not unique to D - all languages underwent the same process. But at this point it is a necessity that we start migrating our mindset from an endless wishlist - towards finding ingenious solutions within the language. Again, this is the case for every single language there is. Combining existing features towards new ends is in some ways more difficult than language design because you play within a confined ground, and I am a bit disappointed that a few posters have shown only contempt for such an effort.That's good evidence that introducing named parameters would be quite involved.It's also good evidence that Martin Odersky, one of the most intelligent language designers alive today, is willing to do a lot to support named arguments in his language :-)
Jun 10 2011
On 6/10/11 7:09 PM, Jonathan M Davis wrote:I think that there _are_ features that we need to look at adding in some form or other (such as conditional attributes) in order to solve current problems in the language (such as the inability to use many attributes - such as pure and safe - with templates without excessive duplication of code). But if a feature does not solve a pressing problem and/or can be reasonably solved by improving Phobos, then we should be improving Phobos.Good point. Walter and I agree that there are two categories of language change: adding new features, and removing undue limitations. At this point, we're planning on a lot more of the latter than the former kind. As an example, consider: module my_module; void fun() { import std.random; return uniform(0, 100); } int gun() { import std.stdio; writeln(fun()); } This module won't compile in today's D, but not for a matter of principles; it's just a random limitation of the language. (It does work if you import from within a class or struct.) You can insert most declarations in a scope, so the ones you can't insert are just awkward exceptions, unless there's a good reason to actively disable them. Any code should work if you just wrap another scope around it. Walter and I call the above a "turtle feature", in allusion to the "turtles all the way down" meme. Walter wants to fix this, and similar limitations that act "unturtly". Imports inside a scope won't be visible outside that scope, and importing the same module from several different functions will come at no cost in compilation time. This may as well lead to a different approach to defining good D modules, in which many imports don't come at the top unless they are of very general use. Functions that have special needs can always embed their own imports modularly without the symbols spilling out in everyone else's sight. As a perk - remember Adam Ruppe's trick to build the examples on the site? Some have top-level code so they don't compile as they are. With this change, code should work if the website simply adds a unittest { ... } around the code. Andrei
Jun 10 2011
Wait, Walter wants to fix this? IIRC just a few days ago he made a post on how this would be a bad feature because it hides imports in arbitrary places. I guess he changed his mind..
Jun 10 2011
On 6/10/2011 6:15 PM, Andrej Mitrovic wrote:Wait, Walter wants to fix this? IIRC just a few days ago he made a post on how this would be a bad feature because it hides imports in arbitrary places.I did?
Jun 10 2011
Walter:I did?I don't remember you talking about this topic. But I don't want this feature, overall I think it will not improve the code. An amoeba is often free to move in every direction in 2D or more, while an insect has a rigid exoskeleton that constricts it to move only in few ways. But such limits allow the insect to run fast :-) Bye, bearophile
Jun 10 2011
On 6/11/11, bearophile <bearophileHUGS lycos.com> wrote:But I don't want this feature, overall I think it will not improve the code.I've found someone that contradicts you: http://www.digitalmars.com/d/archives/digitalmars/D/Function-local_imports_109317.html
Jun 10 2011
On 6/10/11 8:51 PM, Andrej Mitrovic wrote:On 6/11/11, bearophile<bearophileHUGS lycos.com> wrote:Wow. AndreiBut I don't want this feature, overall I think it will not improve the code.I've found someone that contradicts you: http://www.digitalmars.com/d/archives/digitalmars/D/Function-local_imports_109317.html
Jun 10 2011
Andrej Mitrovic:I've found someone that contradicts you: http://www.digitalmars.com/d/archives/digitalmars/D/Function-local_imports_109317.htmlThank you. That person didn't have enough experience yet, it seems. More experienced Python programmers use local imports only in very uncommon situations, you see it from the lot of Python code in the standard library. So I despite its little advantage of local reasoning improvements I think it's far from the top of the list of the important things to desire, I think that currently design improvement efforts are better spent toward more generally useful features instead :-) Bye, bearophile
Jun 11 2011
On 6/11/11 4:38 AM, bearophile wrote:Andrej Mitrovic:I'm not very familiar with Python's module system. Is it very similar to D's? Thanks, AndreiI've found someone that contradicts you: http://www.digitalmars.com/d/archives/digitalmars/D/Function-local_imports_109317.htmlThank you. That person didn't have enough experience yet, it seems. More experienced Python programmers use local imports only in very uncommon situations, you see it from the lot of Python code in the standard library. So I despite its little advantage of local reasoning improvements I think it's far from the top of the list of the important things to desire, I think that currently design improvement efforts are better spent toward more generally useful features instead :-) Bye, bearophile
Jun 11 2011
Andrei:I'm not very familiar with Python's module system. Is it very similar to D's?If you take a look at the Python module system, you copy the first half of it, its more evident characteristics, ignoring its care for details and corner cases, and you remove its dynamic characteristics, you produce a kind of D module system :-) Python doesn't have the anti-hijacking feature, and it's more dynamic. Its package system is more refined than the primitive D package system (and it seems it's not easy to design right, because even the last versions of Python have modified a the its semantics of packages). In Python when you do "import foo" you import only the name "foo". This is probably one of the first things I've asked in D, and I am for it still, but most D programmers have not appreciated this idea, so I have stopped asking for it since lot of time. (S)ML language has a WAY more complex module system, but despite its advantages, I think D/Python module system is good enough and it's easy to learn to use. In the end on the surface if you know the Python module system it's easy to learn to use the D one, and the opposite too is true. I think the D package system needs to be improved, using more brain. This is another example of why D design development can't be stopped yet. Bye, bearophile
Jun 11 2011
On 6/11/11, Walter Bright <newshound2 digitalmars.com> wrote:On 6/10/2011 6:15 PM, Andrej Mitrovic wrote:Hmm. It might have been a bug in the matrix, and I misplaced you for someone else. :]Wait, Walter wants to fix this? IIRC just a few days ago he made a post on how this would be a bad feature because it hides imports in arbitrary places.I did?
Jun 10 2011
Andrei:This module won't compile in today's D, but not for a matter of principles; it's just a random limitation of the language. (It does work if you import from within a class or struct.) You can insert most declarations in a scope, so the ones you can't insert are just awkward exceptions, unless there's a good reason to actively disable them. Any code should work if you just wrap another scope around it. Walter and I call the above a "turtle feature", in allusion to the "turtles all the way down" meme. Walter wants to fix this, and similar limitations that act "unturtly". Imports inside a scope won't be visible outside that scope, and importing the same module from several different functions will come at no cost in compilation time.You are allowed to import modules inside functions in Python too (there is a just a minor restriction), but I have never asked for this feature in D because this feature has a cost too. Putting all imports at the top of the module is more tidy, it allows the person that reads the code to find all the used imports very quickly. If they are spread in the module they become less easy to find, you need to use your editor/IDE to search for them. Bye, bearophile
Jun 10 2011
On 6/11/11 3:21 AM, bearophile wrote:Andrei:At least allowing imports in unittests would be nice though – I frequently find myself writing »version (unittest) {}« blocks before the actual unit tests just to import some modules not needed during regular builds (yeah, I suppose I'm somewhat pedantic about that). DavidThis module won't compile in today's D, but not for a matter of principles; it's just a random limitation of the language. (It does work if you import from within a class or struct.) You can insert most declarations in a scope, so the ones you can't insert are just awkward exceptions, unless there's a good reason to actively disable them. Any code should work if you just wrap another scope around it. Walter and I call the above a "turtle feature", in allusion to the "turtles all the way down" meme. Walter wants to fix this, and similar limitations that act "unturtly". Imports inside a scope won't be visible outside that scope, and importing the same module from several different functions will come at no cost in compilation time.You are allowed to import modules inside functions in Python too (there is a just a minor restriction), but I have never asked for this feature in D because this feature has a cost too. Putting all imports at the top of the module is more tidy, it allows the person that reads the code to find all the used imports very quickly. If they are spread in the module they become less easy to find, you need to use your editor/IDE to search for them. Bye, bearophile
Jun 10 2011
Den 11-06-2011 03:26, David Nadlinger skrev:On 6/11/11 3:21 AM, bearophile wrote:+1Andrei:At least allowing imports in unittests would be nice though – I frequently find myself writing »version (unittest) {}« blocks before the actual unit tests just to import some modules not needed during regular builds (yeah, I suppose I'm somewhat pedantic about that).This module won't compile in today's D, but not for a matter of principles; it's just a random limitation of the language. (It does work if you import from within a class or struct.) You can insert most declarations in a scope, so the ones you can't insert are just awkward exceptions, unless there's a good reason to actively disable them. Any code should work if you just wrap another scope around it. Walter and I call the above a "turtle feature", in allusion to the "turtles all the way down" meme. Walter wants to fix this, and similar limitations that act "unturtly". Imports inside a scope won't be visible outside that scope, and importing the same module from several different functions will come at no cost in compilation time.You are allowed to import modules inside functions in Python too (there is a just a minor restriction), but I have never asked for this feature in D because this feature has a cost too. Putting all imports at the top of the module is more tidy, it allows the person that reads the code to find all the used imports very quickly. If they are spread in the module they become less easy to find, you need to use your editor/IDE to search for them. Bye, bearophile
Jun 11 2011
On 6/10/2011 6:21 PM, bearophile wrote:You are allowed to import modules inside functions in Python too (there is a just a minor restriction), but I have never asked for this feature in D because this feature has a cost too. Putting all imports at the top of the module is more tidy, it allows the person that reads the code to find all the used imports very quickly. If they are spread in the module they become less easy to find, you need to use your editor/IDE to search for them.What, there's a Python feature you don't like? :-) I suspect that way of thinking may go the way of the old C style of putting all your declarations at the top.
Jun 10 2011
On 6/10/11 8:21 PM, bearophile wrote:Andrei:Maybe you also care less about what you import. Similar arguments have been made for placing all variable declarations at the top of the function etc. It's unclear at this point how far local imports would go, but I see good advantages. AndreiThis module won't compile in today's D, but not for a matter of principles; it's just a random limitation of the language. (It does work if you import from within a class or struct.) You can insert most declarations in a scope, so the ones you can't insert are just awkward exceptions, unless there's a good reason to actively disable them. Any code should work if you just wrap another scope around it. Walter and I call the above a "turtle feature", in allusion to the "turtles all the way down" meme. Walter wants to fix this, and similar limitations that act "unturtly". Imports inside a scope won't be visible outside that scope, and importing the same module from several different functions will come at no cost in compilation time.You are allowed to import modules inside functions in Python too (there is a just a minor restriction), but I have never asked for this feature in D because this feature has a cost too. Putting all imports at the top of the module is more tidy, it allows the person that reads the code to find all the used imports very quickly. If they are spread in the module they become less easy to find, you need to use your editor/IDE to search for them. Bye, bearophile
Jun 10 2011
bearophile wrote:Andrei:Why would you have to find local imports? It's considered good practice to narrow scope of variables and put declarations as close as possible to point of use, yet you don't hunt for local variable declarations all the time. If an import is local, it is simply (supposedly) only of concern to that scope and relevant when doing work concerning whatever is in that scope. In effect this could as well lead to reducing to need to look for imports! Python is a bit different because there's an awful lot more going on when importing, with increased chances of bugs when not careful. Simply importing something more than once can introduce errors. Hopefully, that is less so with D. The only really tricky thing are module constructors (circular imports). But at this level, it's probably easier to use facilities of dmd to tell you what imports what.This module won't compile in today's D, but not for a matter of principles; it's just a random limitation of the language. (It does work if you import from within a class or struct.) You can insert most declarations in a scope, so the ones you can't insert are just awkward exceptions, unless there's a good reason to actively disable them. Any code should work if you just wrap another scope around it. Walter and I call the above a "turtle feature", in allusion to the "turtles all the way down" meme. Walter wants to fix this, and similar limitations that act "unturtly". Imports inside a scope won't be visible outside that scope, and importing the same module from several different functions will come at no cost in compilation time.You are allowed to import modules inside functions in Python too (there is a just a minor restriction), but I have never asked for this feature in D because this feature has a cost too. Putting all imports at the top of the module is more tidy, it allows the person that reads the code to find all the used imports very quickly. If they are spread in the module they become less easy to find, you need to use your editor/IDE to search for them. Bye, bearophile
Jun 11 2011
Lutger Blijdestijn:It's considered good practice to narrow scope of variables and put declarations as close as possible to point of use, yet you don't hunt for local variable declarations all the time.<I agree this turtle idea has some good sides too. But I want to stress that it's not among the first five things I think D has to change/improve. More important are tuple unpacking syntax sugar, named arguments, conditional attributes, better vector operations, etc. Bye, bearophile
Jun 11 2011
On 6/11/11 7:20 AM, bearophile wrote:Lutger Blijdestijn:Again, there are two broad categories of changes: feature additions and removal of undue limitations. We favor doing the latter. AndreiIt's considered good practice to narrow scope of variables and put declarations as close as possible to point of use, yet you don't hunt for local variable declarations all the time.<I agree this turtle idea has some good sides too. But I want to stress that it's not among the first five things I think D has to change/improve. More important are tuple unpacking syntax sugar, named arguments, conditional attributes, better vector operations, etc.
Jun 11 2011
Andrei:Again, there are two broad categories of changes: feature additions and removal of undue limitations. We favor doing the latter.I understand, but that's not always the best decision in this early stage of D life. There are also few little feature changes I have put in Bugzilla since lot of time. The more time passes, the less easy they are to apply. Bye, bearophile
Jun 11 2011
Andrei Alexandrescu wrote:module my_module; void fun() { import std.random; return uniform(0, 100); } int gun() { import std.stdio; writeln(fun()); } This module won't compile in today's D, but not for a matter of principles; it's just a random limitation of the language. (It does work if you import from within a class or struct.) You can insert most declarations in a scope, so the ones you can't insert are just awkward exceptions, unless there's a good reason to actively disable them. Any code should work if you just wrap another scope around it.//void main(){ immutable a = b; immutable b = 1; int foo(int n){ if(n==1) return 1; return 1+bar(n); } int bar(int n){ if(n&1) return foo(3*n+1); return foo(n/2); } //} Will this be fixed too? Timon
Jun 13 2011
Timon Gehr:Will this be fixed too?Mutually recursive inner functions are not so common, and there is a workaround, making one of them a delegate defined before. But what about this? auto foo()() out(result) { } body { return 0; } void main() { foo(); } test.d(1): Error: function test.foo!().foo post conditions are not supported if the return type is inferred test.d(7): Error: template instance test.foo!() error instantiating test.d(7): Error: forward reference to inferred return type of function call foo This is a common problem for my code, is it possible to fix (support) this? (In functional-style code auto return values are sometimes almost necessary). Bye, bearophile
Jun 13 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:isualt$hf2$1 digitalmars.com...Combining existing features towards new ends is in some ways more difficult than language design because you play within a confined ground, and I am a bit disappointed that a few posters have shown only contempt for such an effort.That analysis of the situation hinges on the steadfast notion that Flag is a great thing. I absolutely appreciate doing things in library instead of language when reasonable to do so. You don't see me asking for map/reduce or ranges to be built into the language, do you? What a lot of people *don't* like is this seemingly frequent pattern: 1. Andrei comes up with something he feels is a great idea (And you do have a lot of genuinely great ideas, don't get me wrong. Probably more than most of us, certainly including me.) 2. The idea is posted to the NG ostensibly for discussion. 3. Andrei shoots down every objection as being wrong, failing to understand the idea's greatness, or some meta-argument trump card like "X is the N-word of the programming world" is pulled out. 4. The proposed idea can't possibly have any significant flaws, so everyone else on the board is obviously in contempt of something more fundamental, in this case, the strategy of preferring library solutions over language additions. Just because some of us feel this one particular thing doesn't work well in library, does *not* imply we think new features are generally preferable as language additions. So please stop leaping to that conclusion.
Jun 10 2011
On 6/11/11 12:36 AM, Nick Sabalausky wrote:"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:isualt$hf2$1 digitalmars.com...Actually my point there was that we should be coy at this point about changing the language. Flag doesn't have much to do with it. It is clear to me that a language change would obviate Flag and would have additional advantages. The point is it would also have disadvantages.Combining existing features towards new ends is in some ways more difficult than language design because you play within a confined ground, and I am a bit disappointed that a few posters have shown only contempt for such an effort.That analysis of the situation hinges on the steadfast notion that Flag is a great thing.I absolutely appreciate doing things in library instead of language when reasonable to do so. You don't see me asking for map/reduce or ranges to be built into the language, do you? What a lot of people *don't* like is this seemingly frequent pattern: 1. Andrei comes up with something he feels is a great idea (And you do have a lot of genuinely great ideas, don't get me wrong. Probably more than most of us, certainly including me.) 2. The idea is posted to the NG ostensibly for discussion. 3. Andrei shoots down every objection as being wrong, failing to understand the idea's greatness, or some meta-argument trump card like "X is the N-word of the programming world" is pulled out. 4. The proposed idea can't possibly have any significant flaws, so everyone else on the board is obviously in contempt of something more fundamental, in this case, the strategy of preferring library solutions over language additions.I thought what I was doing was to rationally discuss the proposal. Clearly I am in favor of it since I'm proposing it. But that doesn't mean I need to resort to eliciting emotional response, demeaning the counter-arguments, or discussing the competence or ulterior motives of the opponents.Just because some of us feel this one particular thing doesn't work well in library, does *not* imply we think new features are generally preferable as language additions. So please stop leaping to that conclusion.Consider two statements: 1. "I dislike Flag. It looks ugly to me." 2. "I dislike Flag. Instead I want named arguments." There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language. Andrei
Jun 11 2011
On 2011-06-11 07:54:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Consider two statements: 1. "I dislike Flag. It looks ugly to me." 2. "I dislike Flag. Instead I want named arguments." There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language.I'm actually not sure whether I want named arguments or not, but I'm quite sure I don't want to use Flag!"" in my code. I'd actually prefer a simple bool parameter to Flag!"". Currently, it looks like we have these possibilities: // definition // call with a constant void func(bool abc); -> func(true); enum Abc { no, yes } void func(Abc abc); -> func(Abc.yes); void func(Flag!"Abc" abc); -> func(Flag!"Abc".yes); -> func(yes!"Abc"); -> func(Yes.Abc); which then becomes this if you're using a boolean expression instead of a constant: // definition // call with an expression void func(bool abc); -> func(expression); enum Abc { no, yes } void func(Abc abc); -> func(expression ? Abc.yes : Abc.no); -> func(cast(Abc)expression); void func(Flag!"Abc" abc); -> func(expression ? Flag!"Abc".yes : Flag!"Abc".no); -> func(expression ? yes!"Abc" : no!"Abc"); -> func(expression ? Yes.Abc : No.Abc); -> func(cast(Flag!"Abc")expression); My take on this is that we shouldn't try to reinvent the boolean in the standard library. If you want to replace a bool with a two-option enum at some places for clarity, that's fine. But I wouldn't elevate that to a pattern meant to be used everywhere. And personally, I don't like the proliferation of yes/no enums: if you use an enum, value names should be more meaningful than a simple yes/no. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
On 6/11/11 8:16 AM, Michel Fortin wrote:On 2011-06-11 07:54:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:The call entails simple data coupling as documented by Steve McConnell: you can pass any unstructured Boolean for any meaning of abc.Consider two statements: 1. "I dislike Flag. It looks ugly to me." 2. "I dislike Flag. Instead I want named arguments." There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language.I'm actually not sure whether I want named arguments or not, but I'm quite sure I don't want to use Flag!"" in my code. I'd actually prefer a simple bool parameter to Flag!"". Currently, it looks like we have these possibilities: // definition // call with a constant void func(bool abc); -> func(true);enum Abc { no, yes } void func(Abc abc); -> func(Abc.yes);To add the documentation effort: /** This is an argument for func. Refer to func below. */ enum Abc { no, /// you don't want func to do Abc yes /// you do want func to do Abc } /** This is func. Mind Abc defined above. */ void func(Abc abc); I think we agree this is rather awkward (I know because I wrote a fair amount of such). So we have the advantage of a nice call syntax and the disadvantage of verbose definition and documentation.void func(Flag!"Abc" abc); -> func(Flag!"Abc".yes); -> func(yes!"Abc"); -> func(Yes.Abc); which then becomes this if you're using a boolean expression instead of a constant:Aha! This reasoning is flawed as I'll explain below.// definition // call with an expression void func(bool abc); -> func(expression); enum Abc { no, yes } void func(Abc abc); -> func(expression ? Abc.yes : Abc.no); -> func(cast(Abc)expression); void func(Flag!"Abc" abc); -> func(expression ? Flag!"Abc".yes : Flag!"Abc".no); -> func(expression ? yes!"Abc" : no!"Abc"); -> func(expression ? Yes.Abc : No.Abc); -> func(cast(Flag!"Abc")expression); My take on this is that we shouldn't try to reinvent the boolean in the standard library.I think this characterization is wrong. Let me replace the meaningless Abc with an actual example, e.g. OpenRight in std.algorithm. OpenRight is not a Boolean. Its *representation* is Boolean. It is categorical data with two categories. You can represent it with an unstructured Boolean the same way you can represent an automaton state with an unstructured integer or temperature with an unstructured double, but then you'd have the disadvantages that dimensional analysis libraries are solving. For representing categorical data with small sets, programming languages use enumerated types. This is because in a small set you can actually give name each element. That way you have a separate type for the categorical data so you can enjoy good type checking. The mistake I believe you are making is the conflation of a categorical data with two categories with an unstructured Boolean. By making that conflation you lose the advantages of good typechecking in one fell swoop. (But not all categorical data is a small set, and consequently enumerated types are insufficient. Consider e.g. the notion of a user id. People routinely use integers for that, and suffer endless consequences because of bugs caused by unstructured integers posing as user IDs. I have seen instances of such bugs in several codebases in different languages.) As a direct consequence, it is *wrong* to desire to pass an unstructured Boolean expression in lieu of OpenRight. So it is *good* that you can't. What you *should* be doing is to define an OpenRight value in the first place and use it, or construct it in place with "expr ? OpenRight.yes : OpenRight.no", with the advantage that the conversion intent is explicit and visible.If you want to replace a bool with a two-option enum at some places for clarity, that's fine. But I wouldn't elevate that to a pattern meant to be used everywhere. And personally, I don't like the proliferation of yes/no enums: if you use an enum, value names should be more meaningful than a simple yes/no.I think you'd be entirely wrong to make this distinction. There's zero, one, and many. Not zero, one, two, and many. Andrei
Jun 11 2011
On 6/11/11 3:56 PM, Andrei Alexandrescu wrote:To add the documentation effort: /** This is an argument for func. Refer to func below. */ enum Abc { no, /// you don't want func to do Abc yes /// you do want func to do Abc } /** This is func. Mind Abc defined above. */ void func(Abc abc); I think we agree this is rather awkward (I know because I wrote a fair amount of such). So we have the advantage of a nice call syntax and the disadvantage of verbose definition and documentation.So what? Library code is typically written once, and used often. Also, what's wrong with the followig (maybe there is really an issue with it, didn't run it through DDoc): --- /** * This is func. * * Params: * abc = Abc.yes to destroy the world, Abc.no to leave it intact. */ void func(Abc abc) {} /// Ditto. enum Abc : bool { no, yes } --- David
Jun 11 2011
On 2011-06-11 09:56:28 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 6/11/11 8:16 AM, Michel Fortin wrote:Which is often useful if the value is conditional to a boolean expression. The only lacking thing is the parameter name which would make things clear to the reader. Structured data is useful only if you pass it around; if you use it only once as a function parameter and nowhere else, then it just gets in the way. If your argument was that structured data is always preferred to unstructured data, I disagree.On 2011-06-11 07:54:58 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:The call entails simple data coupling as documented by Steve McConnell: you can pass any unstructured Boolean for any meaning of abc.Consider two statements: 1. "I dislike Flag. It looks ugly to me." 2. "I dislike Flag. Instead I want named arguments." There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language.I'm actually not sure whether I want named arguments or not, but I'm quite sure I don't want to use Flag!"" in my code. I'd actually prefer a simple bool parameter to Flag!"". Currently, it looks like we have these possibilities: // definition // call with a constant void func(bool abc); -> func(true);Yes, and I think most of the time this should be a bool. Or to be precise: if it's not worth documenting separately, especially if it's used just once as a flag to a specific function, and if you don't expect it to extend to more than yes/no, then it should be a bool.enum Abc { no, yes } void func(Abc abc); -> func(Abc.yes);To add the documentation effort: /** This is an argument for func. Refer to func below. */ enum Abc { no, /// you don't want func to do Abc yes /// you do want func to do Abc } /** This is func. Mind Abc defined above. */ void func(Abc abc); I think we agree this is rather awkward (I know because I wrote a fair amount of such). So we have the advantage of a nice call syntax and the disadvantage of verbose definition and documentation.I think you're misinterpreting. I don't like yes/no enums because I don't find the value names meaningful, but I'm perfectly fine with two-element enums if they are properly named.void func(Flag!"Abc" abc); -> func(Flag!"Abc".yes); -> func(yes!"Abc"); -> func(Yes.Abc); which then becomes this if you're using a boolean expression instead of a constant:Aha! This reasoning is flawed as I'll explain below.// definition // call with an expression void func(bool abc); -> func(expression); enum Abc { no, yes } void func(Abc abc); -> func(expression ? Abc.yes : Abc.no); -> func(cast(Abc)expression); void func(Flag!"Abc" abc); -> func(expression ? Flag!"Abc".yes : Flag!"Abc".no); -> func(expression ? yes!"Abc" : no!"Abc"); -> func(expression ? Yes.Abc : No.Abc); -> func(cast(Flag!"Abc")expression); My take on this is that we shouldn't try to reinvent the boolean in the standard library.I think this characterization is wrong. Let me replace the meaningless Abc with an actual example, e.g. OpenRight in std.algorithm. OpenRight is not a Boolean. Its *representation* is Boolean. It is categorical data with two categories. You can represent it with an unstructured Boolean the same way you can represent an automaton state with an unstructured integer or temperature with an unstructured double, but then you'd have the disadvantages that dimensional analysis libraries are solving. For representing categorical data with small sets, programming languages use enumerated types. This is because in a small set you can actually give name each element. That way you have a separate type for the categorical data so you can enjoy good type checking. The mistake I believe you are making is the conflation of a categorical data with two categories with an unstructured Boolean. By making that conflation you lose the advantages of good typechecking in one fell swoop.(But not all categorical data is a small set, and consequently enumerated types are insufficient. Consider e.g. the notion of a user id. People routinely use integers for that, and suffer endless consequences because of bugs caused by unstructured integers posing as user IDs. I have seen instances of such bugs in several codebases in different languages.)I totally agree with making specific types to avoid mixing unrelated things, as long as it's reasonable. You wouldn't argue for a UserId type if values of this type weren't passed around.As a direct consequence, it is *wrong* to desire to pass an unstructured Boolean expression in lieu of OpenRight. So it is *good* that you can't. What you *should* be doing is to define an OpenRight value in the first place and use it, or construct it in place with "expr ? OpenRight.yes : OpenRight.no", with the advantage that the conversion intent is explicit and visible.But boundaries can be open or closed on the right, but also on the left. Unfortunately, because you choose to call the enum OpenRight, it can only be used on the right, and nowhere else. What you're doing with OpenRight, and more generally with Flag!"", is narrowing excessively the category to the point where it can be used at one place and one place only: as a specific parameter to a specific function. If you had another parameter for the left side, you'd create an OpenLeft enum with exactly the same choices. I doubt this kind of categorization has any advantage. Actually, I think the advantage you seek has nothing to do with categorization and much more to do with a desire to see those parameter names appear at the call site. You're actually using over-categorization to achieve that, and with Flag!"" you're going to make this systematic. Sorry, I can't approve.No idea what you mean there. -- Michel Fortin michel.fortin michelf.com http://michelf.com/If you want to replace a bool with a two-option enum at some places for clarity, that's fine. But I wouldn't elevate that to a pattern meant to be used everywhere. And personally, I don't like the proliferation of yes/no enums: if you use an enum, value names should be more meaningful than a simple yes/no.I think you'd be entirely wrong to make this distinction. There's zero, one, and many. Not zero, one, two, and many.
Jun 11 2011
On 6/11/11 10:40 AM, Michel Fortin wrote:On 2011-06-11 09:56:28 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:What is meaningless about OpenRight.yes?For representing categorical data with small sets, programming languages use enumerated types. This is because in a small set you can actually give name each element. That way you have a separate type for the categorical data so you can enjoy good type checking. The mistake I believe you are making is the conflation of a categorical data with two categories with an unstructured Boolean. By making that conflation you lose the advantages of good typechecking in one fell swoop.I think you're misinterpreting. I don't like yes/no enums because I don't find the value names meaningful, but I'm perfectly fine with two-element enums if they are properly named.The problem is the definition of "reasonable" is loose. For all I can tell we agree, it's just we have different notions of what's reasonable.(But not all categorical data is a small set, and consequently enumerated types are insufficient. Consider e.g. the notion of a user id. People routinely use integers for that, and suffer endless consequences because of bugs caused by unstructured integers posing as user IDs. I have seen instances of such bugs in several codebases in different languages.)I totally agree with making specific types to avoid mixing unrelated things, as long as it's reasonable. You wouldn't argue for a UserId type if values of this type weren't passed around.But boundaries can be open or closed on the right, but also on the left. Unfortunately, because you choose to call the enum OpenRight, it can only be used on the right, and nowhere else.But this is intentional. If I wanted something more general, I would have used something more general! What are you saying here?What you're doing with OpenRight, and more generally with Flag!"", is narrowing excessively the category to the point where it can be used at one place and one place only: as a specific parameter to a specific function. If you had another parameter for the left side, you'd create an OpenLeft enum with exactly the same choices. I doubt this kind of categorization has any advantage.In fact, no. The same Flag instantiation can be used with distinct functions. Its advantage is that you don't need to go out of your way and define it. It's a sort of a lambda, a literal for a categorical value.Actually, I think the advantage you seek has nothing to do with categorization and much more to do with a desire to see those parameter names appear at the call site. You're actually using over-categorization to achieve that, and with Flag!"" you're going to make this systematic. Sorry, I can't approve.I think it's best to discuss the pros and cons of the proposal than the proposer's desires. Yes, clarifying the intent at the call site is a good thing. And yes, systematization can be good. Named parameters would be one way to go about it, and categorization would be another. If you characterize the approach as *over* categorization, I'm interested in your justification of that qualification.Sets with zero and one elements have distinctive properties compared to sets of more than one element. Sets with two elements don't. AndreiNo idea what you mean there.If you want to replace a bool with a two-option enum at some places for clarity, that's fine. But I wouldn't elevate that to a pattern meant to be used everywhere. And personally, I don't like the proliferation of yes/no enums: if you use an enum, value names should be more meaningful than a simple yes/no.I think you'd be entirely wrong to make this distinction. There's zero, one, and many. Not zero, one, two, and many.
Jun 11 2011
On 2011-06-11 12:01:33 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:On 6/11/11 10:40 AM, Michel Fortin wrote:Choosing between "yes" and "no" is not meaningful. I'd rather choose between "open" and "closed". Of course you'd have to pick a more fitting name for the enum, preferably one that could work for all bounds, not just the right one to make the category more useful. -- Michel Fortin michel.fortin michelf.com http://michelf.com/On 2011-06-11 09:56:28 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:What is meaningless about OpenRight.yes?For representing categorical data with small sets, programming languages use enumerated types. This is because in a small set you can actually give name each element. That way you have a separate type for the categorical data so you can enjoy good type checking. The mistake I believe you are making is the conflation of a categorical data with two categories with an unstructured Boolean. By making that conflation you lose the advantages of good typechecking in one fell swoop.I think you're misinterpreting. I don't like yes/no enums because I don't find the value names meaningful, but I'm perfectly fine with two-element enums if they are properly named.
Jun 11 2011
On 6/11/11 11:56 AM, Michel Fortin wrote:On 2011-06-11 12:01:33 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:I don't see how "OpenRight.yes" is meaningless and "Openness.right" is meaningful.On 6/11/11 10:40 AM, Michel Fortin wrote:Choosing between "yes" and "no" is not meaningful. I'd rather choose between "open" and "closed".On 2011-06-11 09:56:28 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:What is meaningless about OpenRight.yes?For representing categorical data with small sets, programming languages use enumerated types. This is because in a small set you can actually give name each element. That way you have a separate type for the categorical data so you can enjoy good type checking. The mistake I believe you are making is the conflation of a categorical data with two categories with an unstructured Boolean. By making that conflation you lose the advantages of good typechecking in one fell swoop.I think you're misinterpreting. I don't like yes/no enums because I don't find the value names meaningful, but I'm perfectly fine with two-element enums if they are properly named.Of course you'd have to pick a more fitting name for the enum,Name one.preferably one that could work for all bounds, not just the right one to make the category more useful.Again, the charter of that particular category is only "open to the right". Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree. Alright, so we have void topNIndex( alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range, RangeIndex)(Range r, RangeIndex index, SortOutput sorted = SortOutput.no); With Flag in tow, you'd delete SortOutput and you'd replace the definition with: void topNIndex( alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range, RangeIndex)(Range r, RangeIndex index, Flag!"sortOutput" sorted = No.sortOutput); Call: auto a = [ 1, 2, 3 ]; topNIndex(a, Yes.sortOutput); I understand you find the above meaningless and would advocate using a bool, which means: topNIndex(a, true); which would have even me running to the manual, and I wrote the darn thing. With named parameters, we'd have something along the lines of: topNIndex(a, sortOutput : true); which is nice, but not present in the language (and I can tell after talking to Walter it won't be anytime soon). With your choice of meaningful/less, you'd have something like: enum HowToOutput { unsorted, sorted } topNIndex(a, HowToOutput.sorted); which is pretty much the same thing as yes/no, just more convoluted and less systematic. I mean you can't impose to yourself to choose any names except "yes" and "no" on account of them being meaningless. Andrei
Jun 11 2011
On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:With named parameters, we'd have something along the lines of: topNIndex(a, sortOutput : true); which is nice, but not present in the language (and I can tell after talking to Walter it won't be anytime soon).The funny thing is that named arguments are not that difficult to implement as long as you don't allow reordering. Much easier than const(Object)ref actually. <https://github.com/michelf/dmd/commit/673bae4982ff18a3d216bc1578f50d40f4d26d7a> Took me less time than what I took arguing about Flag!"". -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 11 2011
On 6/11/11 1:59 PM, Michel Fortin wrote:On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Love the attitude!! Let's see what Don and Walter think. AndreiWith named parameters, we'd have something along the lines of: topNIndex(a, sortOutput : true); which is nice, but not present in the language (and I can tell after talking to Walter it won't be anytime soon).The funny thing is that named arguments are not that difficult to implement as long as you don't allow reordering. Much easier than const(Object)ref actually. <https://github.com/michelf/dmd/commit/673bae4982ff18a3d216bc1578f50d40f4d26d7a> Took me less time than what I took arguing about Flag!"".
Jun 11 2011
On 6/11/2011 12:58 PM, Andrei Alexandrescu wrote:On 6/11/11 1:59 PM, Michel Fortin wrote:I think it's clever and insightful how Michel's solution is implemented. It does not allow, however, for named arguments to be not in the same positions as unnamed ones. In other words, unlike struct field initializations, named arguments cannot appear in any order. I think people will find it an odd difference.On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Love the attitude!! Let's see what Don and Walter think.With named parameters, we'd have something along the lines of: topNIndex(a, sortOutput : true); which is nice, but not present in the language (and I can tell after talking to Walter it won't be anytime soon).The funny thing is that named arguments are not that difficult to implement as long as you don't allow reordering. Much easier than const(Object)ref actually. <https://github.com/michelf/dmd/commit/673bae4982ff18a3d216bc1578f50d40f4d26d7a> Took me less time than what I took arguing about Flag!"".
Jun 11 2011
On 06/11/2011 10:05 PM, Walter Bright wrote:On 6/11/2011 12:58 PM, Andrei Alexandrescu wrote:If we all get convinced that named parameters are worth it, I'm convinced Michel would be sufficiently motivated to address this limitation. I personally am lukewarm regarding the feature but I think many people would find it quite convenient. AndreiOn 6/11/11 1:59 PM, Michel Fortin wrote:I think it's clever and insightful how Michel's solution is implemented. It does not allow, however, for named arguments to be not in the same positions as unnamed ones. In other words, unlike struct field initializations, named arguments cannot appear in any order. I think people will find it an odd difference.On 2011-06-11 13:08:48 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Love the attitude!! Let's see what Don and Walter think.With named parameters, we'd have something along the lines of: topNIndex(a, sortOutput : true); which is nice, but not present in the language (and I can tell after talking to Walter it won't be anytime soon).The funny thing is that named arguments are not that difficult to implement as long as you don't allow reordering. Much easier than const(Object)ref actually. <https://github.com/michelf/dmd/commit/673bae4982ff18a3d216bc1578f50d40f4d26d7a> Took me less time than what I took arguing about Flag!"".
Jun 11 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear. Also, since you're in favor of Flag, I think you'd agree with me that the doc comments on the "no" and "yes" values are unnecessary and can be ditched. Which makes the whole idiom this: enum SortOutput { no, yes } I hadn't noticed this before, but now that I'm actually looking directly at that, I don't see how that can be considered "boilerplate", or at least enough boilerplate to be worth having a utility template, adding Flag!"..." to function signatures in the code and documentation, and the inconsistency in changing the user's syntax away from how people expect to use an enum. And not only that, but all for the sake of a scenario that you've already argued is only rarely encountered. It's a clever use of templates, sure, but it's a little too clever for it's own good.
Jun 11 2011
On 06/11/2011 03:52 PM, Nick Sabalausky wrote:"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Not at all. The typo in the original text must have confused you: it should be "certain algorithms" because SortOutput is used in four distinct algorithms (one of which has two overloads). Grep std/algorithm.d. Flag += 2Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear.Also, since you're in favor of Flag, I think you'd agree with me that the doc comments on the "no" and "yes" values are unnecessary and can be ditched. Which makes the whole idiom this: enum SortOutput { no, yes }This exact kind of argument has been made in 1995 in favor of STL algorithms that require defining a struct outside the current context. The cost of adding one extra symbol turned out to be a fair amount more unpleasant than it was initially though. Assessing that the boilerplate in this case is one line would be missing that important aspect. Andrei
Jun 11 2011
On 2011-06-11 20:27, Andrei Alexandrescu wrote:On 06/11/2011 03:52 PM, Nick Sabalausky wrote:Yes, though there is a distinct difference between having to create a functor elswhere to just to call an STL function and creating an extra enum next to your function definition for one of its parameters. The parameter issue is far smaller IMHO. It only comes up when defining functions, and particularly if we created a mixin for creating such an enum, the overhead would be fairly minimal - certainly far less than creating a functor for every call to an STL algorithm function (which pratically destroys the usefulness of the STL's algorithms for most people). So, I don't think that the cost involved is altogether comparable. However, you do bring up a very valid point. Flag definitely lowers the bar for the usage of such enums. Ultimately, my main concern with using Flag like this is the error messages. Given the templates involved, I'd expect them to be pretty bad. D's template error messages are certainly better than C++'s (primarily thanks to template constraints), but they're still pretty bad - especially for newbies - and this particular use case effectively is simplifying the library developer's life slightly at the cost of nastier error messages for everyone who mistypes one of these enums. So, we save pain in one area and move it over to another which arguably has a higher impact. And I'm just not sure whether that's worth it or not. The fact that you've gotten to Yes.EnumName and eliminated all of the obvious template stuff from the user's perspective makes the code much cleaner, and it's fine as long as they don't have any typos, but the difference between EnumName.yes and Yes.EnumName for the user is pretty much nonexistant except for the fact that Yes.EnumName will have worse error messages. So, from the user's perspective, the situation is worse. I don't know. I think that this proposal has reached the point where it might be reasonable to include it, but I just don't know if the gain in development is worth the pain for everyone who uses the functions which have Flag enums. If the error messages weren't worse, then it wouldn't be a problem, but as soon as you include templates, the error messages are pretty much always significantly worse. If there were a significant gain from this proposal, then I'd say that it would be worth it, but the gain seems pretty minor to me. So, I just don't know. - Jonathan M Davis"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Not at all. The typo in the original text must have confused you: it should be "certain algorithms" because SortOutput is used in four distinct algorithms (one of which has two overloads). Grep std/algorithm.d. Flag += 2Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear.Also, since you're in favor of Flag, I think you'd agree with me that the doc comments on the "no" and "yes" values are unnecessary and can be ditched. Which makes the whole idiom this: enum SortOutput { no, yes }This exact kind of argument has been made in 1995 in favor of STL algorithms that require defining a struct outside the current context. The cost of adding one extra symbol turned out to be a fair amount more unpleasant than it was initially though. Assessing that the boilerplate in this case is one line would be missing that important aspect.
Jun 11 2011
On 06/11/2011 10:45 PM, Jonathan M Davis wrote:Yes, though there is a distinct difference between having to create a functor elswhere to just to call an STL function and creating an extra enum next to your function definition for one of its parameters. The parameter issue is far smaller IMHO.Absolutely. The proposed solution is also much smaller than e.g. lambda libraries and ultimately the language feature. Andrei
Jun 11 2011
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.841.1307850316.14074.digitalmars-d puremagic.com...but the difference between EnumName.yes and Yes.EnumName for the user is pretty much nonexistant except for the fact that Yes.EnumName will have worse error messages.It also creates an awkward inconsistency. Most enums are X.Y, but then callint certain functions it's Y.X
Jun 12 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it1c0f$1uup$1 digitalmars.com...On 06/11/2011 03:52 PM, Nick Sabalausky wrote:Not that I consider quibbling over small English wording differences a major thing, but I fail to see how: "Specifies whether the output of an algorithm is desired in sorted format." is significantly different from: "Specifies whether the output of certain algorithms are desired in sorted format." In either case, I don't see anything problematically imprecise."Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Not at all. The typo in the original text must have confused you: it should be "certain algorithms" because SortOutput is used in four distinct algorithms (one of which has two overloads). Grep std/algorithm.d. Flag += 2Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear.
Jun 12 2011
On 6/12/11 1:45 PM, Nick Sabalausky wrote:"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it1c0f$1uup$1 digitalmars.com...Still means I need to jump back and forth in the documentation. AndreiOn 06/11/2011 03:52 PM, Nick Sabalausky wrote:Not that I consider quibbling over small English wording differences a major thing, but I fail to see how: "Specifies whether the output of an algorithm is desired in sorted format." is significantly different from: "Specifies whether the output of certain algorithms are desired in sorted format." In either case, I don't see anything problematically imprecise."Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Not at all. The typo in the original text must have confused you: it should be "certain algorithms" because SortOutput is used in four distinct algorithms (one of which has two overloads). Grep std/algorithm.d. Flag += 2Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear.
Jun 12 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it32j8$2gfq$1 digitalmars.com...On 6/12/11 1:45 PM, Nick Sabalausky wrote:And you don't like the "///ditto" suggestion for handling that?"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it1c0f$1uup$1 digitalmars.com...Still means I need to jump back and forth in the documentation.On 06/11/2011 03:52 PM, Nick Sabalausky wrote:Not that I consider quibbling over small English wording differences a major thing, but I fail to see how: "Specifies whether the output of an algorithm is desired in sorted format." is significantly different from: "Specifies whether the output of certain algorithms are desired in sorted format." In either case, I don't see anything problematically imprecise."Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Not at all. The typo in the original text must have confused you: it should be "certain algorithms" because SortOutput is used in four distinct algorithms (one of which has two overloads). Grep std/algorithm.d. Flag += 2Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear.
Jun 12 2011
On 6/12/11 2:19 PM, Nick Sabalausky wrote:"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it32j8$2gfq$1 digitalmars.com...That actually does help, but not for enums used by more than one function. The other issues remain too. AndreiOn 6/12/11 1:45 PM, Nick Sabalausky wrote:And you don't like the "///ditto" suggestion for handling that?"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it1c0f$1uup$1 digitalmars.com...Still means I need to jump back and forth in the documentation.On 06/11/2011 03:52 PM, Nick Sabalausky wrote:Not that I consider quibbling over small English wording differences a major thing, but I fail to see how: "Specifies whether the output of an algorithm is desired in sorted format." is significantly different from: "Specifies whether the output of certain algorithms are desired in sorted format." In either case, I don't see anything problematically imprecise."Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Not at all. The typo in the original text must have confused you: it should be "certain algorithms" because SortOutput is used in four distinct algorithms (one of which has two overloads). Grep std/algorithm.d. Flag += 2Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear.
Jun 12 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it3ne2$1g2f$1 digitalmars.com...On 6/12/11 2:19 PM, Nick Sabalausky wrote:I would think that an enum used by more than one function *should* be listed separately."Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it32j8$2gfq$1 digitalmars.com...That actually does help, but not for enums used by more than one function. The other issues remain too.On 6/12/11 1:45 PM, Nick Sabalausky wrote:And you don't like the "///ditto" suggestion for handling that?"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it1c0f$1uup$1 digitalmars.com...Still means I need to jump back and forth in the documentation.On 06/11/2011 03:52 PM, Nick Sabalausky wrote:Not that I consider quibbling over small English wording differences a major thing, but I fail to see how: "Specifies whether the output of an algorithm is desired in sorted format." is significantly different from: "Specifies whether the output of certain algorithms are desired in sorted format." In either case, I don't see anything problematically imprecise."Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it07ni$1pvj$1 digitalmars.com...Not at all. The typo in the original text must have confused you: it should be "certain algorithms" because SortOutput is used in four distinct algorithms (one of which has two overloads). Grep std/algorithm.d. Flag += 2Anyway, that was the first thing "grep yes std/*" found. Let's see the next one: /** Specifies whether the output of certain algorithm is desired in sorted format. */ enum SortOutput { no, /// Don't sort output yes, /// Sort output } This already is very unpleasant because "certain" is as imprecise as it gets. Plus one for Flag, I hope you agree.Flag -= 1 s/output of certain algorithm/output of an algorithm/ += 1 That one-word doc change makes it all perfectly clear.
Jun 13 2011
On 6/13/11 4:02 PM, Nick Sabalausky wrote:"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it3ne2$1g2f$1 digitalmars.com...Actually, not necessarily, if the definition is self explanatory. By the same argument a named argument with the same name and meaning in several functions doesn't necessarily have to be defined separately. AndreiThat actually does help, but not for enums used by more than one function. The other issues remain too.I would think that an enum used by more than one function *should* be listed separately.
Jun 13 2011
On 6/13/11 4:02 PM, Nick Sabalausky wrote:What about just not documenting the enum itself? This elegantly resolves the 'certain' vs. 'an' debate too :o). Timon"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it3ne2$1g2f$1 digitalmars.com...Actually, not necessarily, if the definition is self explanatory. By the same argument a named argument with the same name and meaning in several functions doesn't necessarily have to be defined separately. AndreiThat actually does help, but not for enums used by more than one function. The other issues remain too.I would think that an enum used by more than one function *should* be listed separately.
Jun 13 2011
Quite contrary i think it is pretty much spot on, if it is not but just its representation is boolean so is every other usage of boolean. The only reason we use an enum instead of simple bool is self documentation "fun(OpenRight.yes)". You simply can't deny the named arguments solve not only this particular issue but the entire area nicely "fun(openRight:true, width:4, height:3, depth:5)".My take on this is that we shouldn't try to reinvent the boolean in the standard library.I think this characterization is wrong. Let me replace the meaningless Abc with an actual example, e.g. OpenRight in std.algorithm. OpenRight is not a Boolean. Its *representation* is Boolean. It is categorical data with two categories. You can represent it with an unstructured Boolean the same way you can represent an automaton state with an unstructured integer or temperature with an unstructured double, but then you'd have the disadvantages that dimensional analysis libraries are solving.
Jun 12 2011
so:Quite contrary i think it is pretty much spot on, if it is not but just its representation is boolean so is every other usage of boolean.This is an unusual teacher that use functional languages, the blog post is about booleans and related matters: http://existentialtype.wordpress.com/2011/03/15/boolean-blindness/ (Often I don't agree with this author, but I try to read some of his posts.) Bye, bearophile
Jun 12 2011
On 6/12/11 7:26 AM, so wrote:Never did. AndreiQuite contrary i think it is pretty much spot on, if it is not but just its representation is boolean so is every other usage of boolean. The only reason we use an enum instead of simple bool is self documentation "fun(OpenRight.yes)". You simply can't deny the named arguments solve not only this particular issue but the entire area nicely "fun(openRight:true, width:4, height:3, depth:5)".My take on this is that we shouldn't try to reinvent the boolean in the standard library.I think this characterization is wrong. Let me replace the meaningless Abc with an actual example, e.g. OpenRight in std.algorithm. OpenRight is not a Boolean. Its *representation* is Boolean. It is categorical data with two categories. You can represent it with an unstructured Boolean the same way you can represent an automaton state with an unstructured integer or temperature with an unstructured double, but then you'd have the disadvantages that dimensional analysis libraries are solving.
Jun 12 2011
On 6/11/11 1:54 PM, Andrei Alexandrescu wrote:Consider two statements: 1. "I dislike Flag. It looks ugly to me." 2. "I dislike Flag. Instead I want named arguments." There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language.*And*, at least for me, still count it as an (informal) vote against Flag. You wrote about »The point is it [named arguments] would also have disadvantages«, but at the same time, you seem to ignore that using a non-obvious construct all over the standard library adds to perceived the »language complexity« (from the user's perspective) just as well, even more so if opDispatch or other »hacks« are used to beautify the implementation. Yes, I do think named parameters would be a step forward and we should definitely look into adding them to D. But independently, I don't think that reinventing bool in Phobos is a good idea. How would you explain somebody new to D that, while usually it's »Something.property«, you have to write »Yes.foo« instead of »Foo.yes«? Also, there is the issue of error messages: --- void foo(Flag!"bar" flag) {} void main() { foo(No.baz); } --- leads to --- Error: function foo (Flag flag) is not callable using argument types (Flag) Error: cannot implicitly convert expression (opDispatch()) of type Flag to Flag --- I don't know about you, but I think this is not quite an acceptable error message for mistyping a single character while trying to pass a boolean parameter to some standard library function. David
Jun 11 2011
On 6/11/11 9:08 AM, David Nadlinger wrote:On 6/11/11 1:54 PM, Andrei Alexandrescu wrote:Of course it does, but the point is there are arguments that might convince the person.Consider two statements: 1. "I dislike Flag. It looks ugly to me." 2. "I dislike Flag. Instead I want named arguments." There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language.*And*, at least for me, still count it as an (informal) vote against Flag.You wrote about »The point is it [named arguments] would also have disadvantages«, but at the same time, you seem to ignore that using a non-obvious construct all over the standard library adds to perceived the »language complexity« (from the user's perspective) just as well, even more so if opDispatch or other »hacks« are used to beautify the implementation.I agree that implementation complexity has a cost. That would be justified if the idiom becomes commonly used outside the library.Yes, I do think named parameters would be a step forward and we should definitely look into adding them to D. But independently, I don't think that reinventing bool in Phobos is a good idea.You may want to refer to my answer to Michel. Andrei
Jun 11 2011
On 11/06/11 15:28, Andrei Alexandrescu wrote:On 6/11/11 9:08 AM, David Nadlinger wrote:Hey, Don't know whether I can vote but I looked through it and I prefer using booleans over this. This just doesn't look very nice to me and if you *really* wanted to use this in a program, you could just use an enum but I don't see why flags is good (even after reading through all your counter-arguments). NebsterOn 6/11/11 1:54 PM, Andrei Alexandrescu wrote:Of course it does, but the point is there are arguments that might convince the person.Consider two statements: 1. "I dislike Flag. It looks ugly to me." 2. "I dislike Flag. Instead I want named arguments." There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language.*And*, at least for me, still count it as an (informal) vote against Flag.You wrote about »The point is it [named arguments] would also have disadvantages«, but at the same time, you seem to ignore that using a non-obvious construct all over the standard library adds to perceived the »language complexity« (from the user's perspective) just as well, even more so if opDispatch or other »hacks« are used to beautify the implementation.I agree that implementation complexity has a cost. That would be justified if the idiom becomes commonly used outside the library.Yes, I do think named parameters would be a step forward and we should definitely look into adding them to D. But independently, I don't think that reinventing bool in Phobos is a good idea.You may want to refer to my answer to Michel. Andrei
Jun 11 2011
On 11/06/2011 12:54, Andrei Alexandrescu wrote:Consider two statements: 1. "I dislike Flag. It looks ugly to me."This statement holds true for me.2. "I dislike Flag. Instead I want named arguments."This one is perhaps true. I've never needed named arguments.There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language. AndreiSo I had an idea. ---- struct Flag { static bool opDispatch(string n)() { static if (n[0..2] == "no") { return false; } else { return true; } } } void myFunc(bool foo, bool bar) { } void main() { myFunc(Flag.foo, Flag.noBar); } ---- * No ugly templates * Self documenting * No overhead (dmd can inline it to myFunc(true, false)) * Caller decides if they want it -- Robert http://octarineparrot.com/
Jun 11 2011
On 6/11/11 2:12 PM, Robert Clipsham wrote:On 11/06/2011 12:54, Andrei Alexandrescu wrote:// Generate document in nook format generatePdf("doc.pdf", Flag.nook); AndreiConsider two statements: 1. "I dislike Flag. It looks ugly to me."This statement holds true for me.2. "I dislike Flag. Instead I want named arguments."This one is perhaps true. I've never needed named arguments.There is little retort to (1) - it simply counts as a vote against. For (2) the course of action is to point out the liabilities of changing the language. AndreiSo I had an idea. ---- struct Flag { static bool opDispatch(string n)() { static if (n[0..2] == "no") { return false; } else { return true; } } } void myFunc(bool foo, bool bar) { } void main() { myFunc(Flag.foo, Flag.noBar); } ---- * No ugly templates * Self documenting * No overhead (dmd can inline it to myFunc(true, false)) * Caller decides if they want it
Jun 11 2011
On 11/06/2011 20:59, Andrei Alexandrescu wrote:On 6/11/11 2:12 PM, Robert Clipsham wrote:I'd call this a documentation issue. It's obvious you're passing true to the function. Of course, if you want to mitigate this somewhat, something like this could work: struct FuncFlag(alias func) { // See code from above, but use typeof(&func).stringof to get // a list of parameter names and make sure the passed name is valid // of course, you can't check position, but the only way to get // around that is named parameters or some sort of compiler support } alias FuncFlag!generatePdf PdfFlag; // This now fails to compile generatePdf("doc.pdf", PdfFlag.nook); -- Robert http://octarineparrot.com/.... * No ugly templates * Self documenting * No overhead (dmd can inline it to myFunc(true, false)) * Caller decides if they want it// Generate document in nook format generatePdf("doc.pdf", Flag.nook); Andrei
Jun 11 2011
On 11/06/2011 21:31, Robert Clipsham wrote:On 11/06/2011 20:59, Andrei Alexandrescu wrote:<idea> You can actually check the order! Add in a counter to FuncFlag, and each time opDispatch is called increment it. You can use this to check the position. The obvious downside is optional parameters, where the counter will be incorrect unless you reset it. </idea> -- Robert http://octarineparrot.com/On 6/11/11 2:12 PM, Robert Clipsham wrote:I'd call this a documentation issue. It's obvious you're passing true to the function. Of course, if you want to mitigate this somewhat, something like this could work: struct FuncFlag(alias func) { // See code from above, but use typeof(&func).stringof to get // a list of parameter names and make sure the passed name is valid // of course, you can't check position, but the only way to get // around that is named parameters or some sort of compiler support } alias FuncFlag!generatePdf PdfFlag; // This now fails to compile generatePdf("doc.pdf", PdfFlag.nook);.... * No ugly templates * Self documenting * No overhead (dmd can inline it to myFunc(true, false)) * Caller decides if they want it// Generate document in nook format generatePdf("doc.pdf", Flag.nook); Andrei
Jun 11 2011
David Nadlinger:At least allowing imports in unittests would be nice though – I frequently find myself writing »version (unittest) {}« blocks before the actual unit tests just to import some modules not needed during regular builds (yeah, I suppose I'm somewhat pedantic about that).version(unittest) was added just to solve this problem, and for me it's a good solution. So imports in unittests is an anti-justification for the turtle-import feature. Bye, bearophile
Jun 10 2011
Function local imports make it easier to reason about the code which is of slight importance. The big thing I'd like though is using it with mixins. In my cgi.d, there's a mixin main that depends on std.string being available inside the mixed in function. Currently, I use a public import of std.string. Alternatively, the other module could import it too, but that is pretty opaque. But a scoped import would be cleaner: I could ensure it's always available in that function without making the mixin user wonder WTF the error messages are about and without polluting his namespace.
Jun 10 2011
On 6/10/11 8:44 PM, Adam Ruppe wrote:Function local imports make it easier to reason about the code which is of slight importance. The big thing I'd like though is using it with mixins. In my cgi.d, there's a mixin main that depends on std.string being available inside the mixed in function. Currently, I use a public import of std.string. Alternatively, the other module could import it too, but that is pretty opaque. But a scoped import would be cleaner: I could ensure it's always available in that function without making the mixin user wonder WTF the error messages are about and without polluting his namespace.Yes. Local imports facilitate local reasoning. Andrei
Jun 10 2011
"Adam Ruppe" <destructionator gmail.com> wrote in message news:isuhab$17hb$1 digitalmars.com...Function local imports make it easier to reason about the code which is of slight importance. The big thing I'd like though is using it with mixins. In my cgi.d, there's a mixin main that depends on std.string being available inside the mixed in function. Currently, I use a public import of std.string. Alternatively, the other module could import it too, but that is pretty opaque.I have need to do that sort of thing now and then, too. What I usually do is include it in my module as a public renamed import, renamed with some special prefix, like "_myModuleName_theOriginalName". Then I use that super-ugly name inside the code that's intended to be mixed in. It's an ugly hack, but at least it's semi-hygenic and works. Scoped imports would probably be far better.But a scoped import would be cleaner: I could ensure it's always available in that function without making the mixin user wonder WTF the error messages are about and without polluting his namespace.
Jun 10 2011
There are also few little feature changes I have put in Bugzilla since lot of time.I am starting to think that just putting those issues in bugzilla was not enough, they seem to get mostly ignored. More periodic drumming in this newsgroup was needed... :-( Bye, bearophile
Jun 11 2011
On 2011-06-10 09:15, Andrei Alexandrescu wrote:https://github.com/D-Programming-Language/phobos/pull/94 Discuss!Okay. Let's see if I can summarize this. Andrei thinks that have a categorized boolean type which is explicit about what it's used for is valuable. So, for instance, std.algorithm.until takes OpenRight.yes and OpenRight.no rather than bool so that it's explicit to the caller what the boolean value indicates and so that you don't accidentally pass a bool which means something else entirely to until. This currently requires declaring a separate enum with yes and no values for every function that does this with the occasional function which can reuse such an enum from another function, because it needs a boolean value for exactly the same thing. Andrei therefore have 2 problems with the status quo: 1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value. 2. The documentation for these yes/no enums generally really should be with the function that they're using but ends up on the enum itself or in both places. Ideally, it would just go with the function. So, Andrei created the Flag template in an attempt to do 3 things: 1. Be able to create the yes/no enum just by declaring the type of the function parameter - you eliminate boilerplate code. 2. The documentation is then clearly with the function that the yes/no enum goes with (it has nowhere else to go). 3. It promotes the yes/no idiom in a manner than seeing Flag!"enumName" as the type makes it immediately clear what the type in question is trying to do, and no one feels the need to go looking for the documentation for the enum because the use of the Flag idiom makes it clear what the type is. The complaints about this generally seem to be one of these: 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag does it, it's a problem, because it's promoting an idiom that the poster dislikes in the first place. 2. Flag!"enumName".yes and Flag!"enumName".no are ugly. 3. The use of a template such as Flag results in ugly error messages when it's mistyped. EnumName.yes gets _much_ better errors when mistyped than Flag!"enumName".yes. 4. Flag is seen as a narrow attempt at named arguments which would be far better served by actually implementing named arguments. Andrei's response to each of these in turn is: 1. He argues for the yes/no enum idiom, citing issues with naked bool values and lack of clarity in code - how it saves you from having to look at the documentation to figure out what a particular boolean value means. It's essentially the same arguments he's made for the idiom ever since it was introduced into Phobos. 2. He proposed a template wrapper which would allow you to type yes!"enumName" and no!"enumName" instead of the full Flag!"enumName".yes and think that it's still quite ugly. 3. He essentially says that the compiler's error messages for templates need to be improved. It's an inherent problem with templates. 4. He's not trying to solve anything with named arguments. He's trying to solve a much narrower problem of naked bool values being relatively meaningless for many function arguments and error-prone when you pass a boolean value which meant something else entirely. yes/no enums solve that specific problem. Named arguments would be a change to the language at a time when we should be looking at doing as much with the language as possible rather than looking to add new features to it. Features which solve restrictions and intrinsic problems in the language need to be looked at, but those which could be solved by using the existing language and creating a library-based solution should be first explored as library solutions. Would you say that this is a fair summary of this debate so far? - Jonathan M Davis
Jun 11 2011
On 6/11/11 11:20 PM, Jonathan M Davis wrote:1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value.s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } --- David
Jun 11 2011
On 2011-06-11 14:32, David Nadlinger wrote:On 6/11/11 11:20 PM, Jonathan M Davis wrote:It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value.s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---
Jun 11 2011
On 06/11/2011 04:42 PM, Jonathan M Davis wrote:On 2011-06-11 14:32, David Nadlinger wrote:It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there. What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response. This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere." "Gaaaaaaaaaaaaaa!!!" AndreiOn 6/11/11 11:20 PM, Jonathan M Davis wrote:It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value.s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---
Jun 11 2011
On 2011-06-11 20:44, Andrei Alexandrescu wrote:On 06/11/2011 04:42 PM, Jonathan M Davis wrote:Honestly, at this point, I think that your proposal is pretty good, but I'm not sure that it's worth the degradation in error messages that the added templatization causes. But for a lot of people, I think that it's simply a combination of them not liking the yes/no enum idiom in the first place and/or feeling like what they really want is named parameters and that this really should be solved by named parameters. So, they don't like it. Personally, I'm a bit ambivalent towards yes/no enums, but I'm fine with having them. At this point, I'm just concerned about the worse error messages that the use of Flag will create and whether that pain is worth the added benefit that Flag brings. - Jonathan M DavisOn 2011-06-11 14:32, David Nadlinger wrote:It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there. What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response. This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere." "Gaaaaaaaaaaaaaa!!!"On 6/11/11 11:20 PM, Jonathan M Davis wrote:It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value.s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---
Jun 11 2011
On 2011-06-11 20:50, Jonathan M Davis wrote:On 2011-06-11 20:44, Andrei Alexandrescu wrote:Yikes! How did that get posted three times?! I wonder if my mail client is on the fritz... - Jonathan M DavisOn 06/11/2011 04:42 PM, Jonathan M Davis wrote:Honestly, at this point, I think that your proposal is pretty good, but I'm not sure that it's worth the degradation in error messages that the added templatization causes. But for a lot of people, I think that it's simply a combination of them not liking the yes/no enum idiom in the first place and/or feeling like what they really want is named parameters and that this really should be solved by named parameters. So, they don't like it. Personally, I'm a bit ambivalent towards yes/no enums, but I'm fine with having them. At this point, I'm just concerned about the worse error messages that the use of Flag will create and whether that pain is worth the added benefit that Flag brings.On 2011-06-11 14:32, David Nadlinger wrote:It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there. What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response. This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere." "Gaaaaaaaaaaaaaa!!!"On 6/11/11 11:20 PM, Jonathan M Davis wrote:It's a fair bit only insomuch as the same code is duplicated in several places. The code itself in each instance is small. But if you do that enough times, it adds up. Whether it's enough to matter is debatable, but there is definitely boilerplate code there which could be reduced. - Jonathan M Davis1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value.s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---
Jun 11 2011
On 6/12/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Funny thing is, the change is tiny.You seem to be forgetting that there are library writers and then there are library *users*. :) Seeing Flag!"foo".yes in the calling code scared people. So naturally people wanted to nuke it from orbit. If the proposal was yes.foo from the beginning things would much quieter around here, methinks.
Jun 11 2011
It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there. What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response. This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere." "Gaaaaaaaaaaaaaa!!!" Andrei(Trying the 3rd time, something wrong with newsreader) As you might know i prefer library solutions to language changes any day even the change is additive, yet this one i don't like. Library solutions, especially those affect user must be IMO both elegant and generic, this one is not. I think we are agree on this. There might be 7 in only std.algorithm but it is after all belongs to the std library, with the importance of phobos we can't change anything that is not accepted by majority. These are i think pretty strong arguments, though i believe it is you that needs to come up with strong arguments and i can't see any from you either :) Introducing an idiom to phobos means it is the D way, there should be many other frameworks that would use such a solution much more frequently. They will either dismiss this solution (most likely) or populate it. The former means the failure of the change, the latter is ugly code (again, when it is used more frequently). Named arguments both clean and generic. On one drawback (?) that variable names being part of library definition, i don't see how it is a drawback.
Jun 12 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it1cvf$21d4$1 digitalmars.com...It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there.You can't put an enum in a class/struct?What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response.Correction: Andrei's staunch dismissal of all counterarguments has not stood in the way of a strong emotional response.This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere."Correction: "Here, there's a way to solve a barely-existant problem by botching up syntax (and error messages) for the user.""Gaaaaaaaaaaaaaa!!!"
Jun 12 2011
On 6/12/11 1:59 PM, Nick Sabalausky wrote:"Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it1cvf$21d4$1 digitalmars.com...I'm not sure, but I think I see a sarcasm in there. AndreiIt's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there.You can't put an enum in a class/struct?What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response.Correction: Andrei's staunch dismissal of all counterarguments has not stood in the way of a strong emotional response.This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere."Correction: "Here, there's a way to solve a barely-existant problem by botching up syntax (and error messages) for the user.""Gaaaaaaaaaaaaaa!!!"
Jun 12 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it32kq$2gfq$2 digitalmars.com...On 6/12/11 1:59 PM, Nick Sabalausky wrote:I guess it could be taken that way, but it wasn't really my point to be sarcastic. My intent was just to summarize the way I see the situation."Andrei Alexandrescu"<SeeWebsiteForEmail erdani.org> wrote in message news:it1cvf$21d4$1 digitalmars.com...I'm not sure, but I think I see a sarcasm in there.It's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there.You can't put an enum in a class/struct?What I find most interesting is that the lack of strong counterarguments has not stood in the way of a strong emotional response.Correction: Andrei's staunch dismissal of all counterarguments has not stood in the way of a strong emotional response.This mood has made it difficult for exchange of rational arguments. Funny thing is, the change is tiny. "Here, I'll add a handful of yes/no enums here and there in the standard library, just to help some algorithms. More to come." "Yeah, sure, whatevs." "Here, there's a way to define them once so we don't need to define them everywhere."Correction: "Here, there's a way to solve a barely-existant problem by botching up syntax (and error messages) for the user.""Gaaaaaaaaaaaaaa!!!"
Jun 12 2011
On Sun, 12 Jun 2011 14:59:57 -0400, Nick Sabalausky wrote:"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it1cvf$21d4$1 digitalmars.com...Yes, but then you have to qualify it with the name of the class/struct when using it. See Steve's post: http://www.digitalmars.com/webnews/newsgroups.php? art_group=digitalmars.D&article_id=138281 -LarsIt's the namespace pollution and the non-self-containedness of the function that's most troublesome. Also see Steve's point about methods. It's just untenable - to use the idiom with a class/struct method, you need to go all the way _outside_ of it an plant a symbol there.You can't put an enum in a class/struct?
Jun 13 2011
On Sat, 11 Jun 2011 17:32:56 -0400, David Nadlinger <see klickverbot.at> wrote:On 6/11/11 11:20 PM, Jonathan M Davis wrote:A big problem with this (and enums in general), what if your flag function is defined inside a struct or class? struct MyStruct { /// This function ROCKS! void someKickAssFunction(MoreBitchin moreBitchin) {} /// ditto enum MoreBitchin { yes, no } } // the call, not so much. s.someKickAssFunction(MyStruct.MoreBitchin.yes); In other words, in order for your doc trick to work, member functions have to require an additional namespace to the enum. IMO, however, we need a better way to access the enum values without specifying the entire namespace. The difficult part is to do it in a way which doesn't conflict with normal symbols. Of course, such an improvement would pull the rug from this Flag proposal... -Steve1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value.s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---
Jun 11 2011
On 6/11/11 8:49 PM, Steven Schveighoffer wrote:On Sat, 11 Jun 2011 17:32:56 -0400, David Nadlinger <see klickverbot.at> wrote:Thanks, Steve, this is an excellent point - as are all you made in this discussion (pro and con)! AndreiOn 6/11/11 11:20 PM, Jonathan M Davis wrote:A big problem with this (and enums in general), what if your flag function is defined inside a struct or class? struct MyStruct { /// This function ROCKS! void someKickAssFunction(MoreBitchin moreBitchin) {} /// ditto enum MoreBitchin { yes, no } } // the call, not so much. s.someKickAssFunction(MyStruct.MoreBitchin.yes); In other words, in order for your doc trick to work, member functions have to require an additional namespace to the enum. IMO, however, we need a better way to access the enum values without specifying the entire namespace. The difficult part is to do it in a way which doesn't conflict with normal symbols. Of course, such an improvement would pull the rug from this Flag proposal... -Steve1. Programmers following this idiom (including the Phobos devs) end up creating enums with yes and no values and are effectively identical to other enums except for their names. So, we end up with a fair bit of boilerplate code just to pass a strict boolean value.s/fair/tiny/, imho: --- /// ditto. enum SomeFlag { enable, disable } ---
Jun 12 2011
Jonathan M Davis wrote:... The complaints about this generally seem to be one of these: 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag does it, it's a problem, because it's promoting an idiom that the poster dislikes in the first place. 2. Flag!"enumName".yes and Flag!"enumName".no are ugly. 3. The use of a template such as Flag results in ugly error messages when it's mistyped. EnumName.yes gets _much_ better errors when mistyped than Flag!"enumName".yes. 4. Flag is seen as a narrow attempt at named arguments which would be far better served by actually implementing named arguments. [snip.]5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off! What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted); Timon
Jun 11 2011
On 06/11/2011 04:58 PM, Timon Gehr wrote:Jonathan M Davis wrote:I proposed this to Walter some years ago, around the time I was anticipating the nascent yes/no enum proliferation. The problem with this is it defines a type in a function parameter specification, which is unprecedented and therefore surprising. There's a closely related slide in our D 2007 conference talk. Andrei... The complaints about this generally seem to be one of these: 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag does it, it's a problem, because it's promoting an idiom that the poster dislikes in the first place. 2. Flag!"enumName".yes and Flag!"enumName".no are ugly. 3. The use of a template such as Flag results in ugly error messages when it's mistyped. EnumName.yes gets _much_ better errors when mistyped than Flag!"enumName".yes. 4. Flag is seen as a narrow attempt at named arguments which would be far better served by actually implementing named arguments. [snip.]5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off! What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);
Jun 11 2011
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message news:it1cd7$1vv2$1 digitalmars.com...On 06/11/2011 04:58 PM, Timon Gehr wrote:I like the basic idea, and it's a change that falls into the "removing restrictions" category. But the issue "so" brought up with this about not being able to pass in a variable would need to be solved for the general case. It's trivial in the case of two options: bool useSorted = ...; someAlgorithm(..., useSorted? sorted : unsorted); Although, really, that just shifts the boilerplate from the callee to the caller, so it's really a net loss. You could maybe do: T someAlgorithm(..., enum Sorted {yes, no} sortOutput); Which would be equivalent to: enum Sorted {yes, no} T someAlgorithm(..., Sorted sortOutput); But I don't now if Andrei would like that (it makes the func signature kinda verbose, too).Jonathan M Davis wrote:... The complaints about this generally seem to be one of these: 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag does it, it's a problem, because it's promoting an idiom that the poster dislikes in the first place. 2. Flag!"enumName".yes and Flag!"enumName".no are ugly. 3. The use of a template such as Flag results in ugly error messages when it's mistyped. EnumName.yes gets _much_ better errors when mistyped than Flag!"enumName".yes. 4. Flag is seen as a narrow attempt at named arguments which would be far better served by actually implementing named arguments. [snip.]5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off! What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);I proposed this to Walter some years ago, around the time I was anticipating the nascent yes/no enum proliferation. The problem with this is it defines a type in a function parameter specification, which is unprecedented and therefore surprising.Your Flag idiom essentially defines a type in a function parameter specification.
Jun 12 2011
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:it0oee$ehu$1 digitalmars.com...What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);Wow - I actually really like this! It would provide an even _better_ solution than named arguments for this type of thing! The best part is that it could degrade to the enum's base type when taking a function pointer, mangling the function's name and even inside the function's body! void myfunction(enum : int { option1, option2, option3 } options) { static assert(is(typeof(options) == int)); } static assert(is(typeof(&myfunction) == void function(int)); myfunction(option2);
Jun 12 2011
On Sun, 12 Jun 2011 15:33:00 +0300, Daniel Murphy <yebblies nospamgmail.com> wrote:"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:it0oee$ehu$1 digitalmars.com...This also means you can use it only once. Not knowing the type, you can't pass as a variable either. The loss is too big compared to the gain. fun_step_one(enum whatever) fun_step_two(enum?) enum type? val fun(val)What about allowing anonymous enums in parameter lists? Unfortunately that would be a language feature. :) T someAlgorithm(..., enum {unsorted, sorted} sortOutput); To call: someAlgorithm(..., sorted); / someAlgorithm(..., unsorted);Wow - I actually really like this! It would provide an even _better_ solution than named arguments for this type of thing! The best part is that it could degrade to the enum's base type when taking a function pointer, mangling the function's name and even inside the function's body! void myfunction(enum : int { option1, option2, option3 } options) { static assert(is(typeof(options) == int)); } static assert(is(typeof(&myfunction) == void function(int)); myfunction(option2);
Jun 12 2011
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:it0oee$ehu$1 digitalmars.com...Jonathan M Davis wrote:Not only that, but just simply trying to explain why you sometimes do "enumName.value" and sometimes do "value.enumName". It introduces a big inconsistency for callers, just for the sake of a trivial decrease in boilerplate for the callee. Also, one thing I'm unclear on: If you do: void foo(Flag!"bar" a) {} Can the caller do something like this?: bar barValue = yes.bar; foo(barValue);... The complaints about this generally seem to be one of these: 1. Dislike of the yes/no enum idiom in the first place. Regardless of how Flag does it, it's a problem, because it's promoting an idiom that the poster dislikes in the first place. 2. Flag!"enumName".yes and Flag!"enumName".no are ugly. 3. The use of a template such as Flag results in ugly error messages when it's mistyped. EnumName.yes gets _much_ better errors when mistyped than Flag!"enumName".yes. 4. Flag is seen as a narrow attempt at named arguments which would be far better served by actually implementing named arguments. [snip.]5. The approach is too sophisticated and does not pull its own weight. Imagine what you would have to explain to somebody new to the language who wondered how Yes.sortOutput works... instant turn-off!
Jun 12 2011
On 06/11/2011 04:20 PM, Jonathan M Davis wrote:2. He proposed a template wrapper which would allow you to type yes!"enumName" and no!"enumName" instead of the full Flag!"enumName".yes and think that it's still quite ugly.Those were since replaced with No.enumName and Yes.enumName by Dmitry's idea: https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 Andrei
Jun 11 2011
On Jun 12, 11 11:18, Andrei Alexandrescu wrote:On 06/11/2011 04:20 PM, Jonathan M Davis wrote:Yes.X and No.X looks grammatically wrong. In D you usually have 'Aggregate.member', not 'Member.aggregate'.2. He proposed a template wrapper which would allow you to type yes!"enumName" and no!"enumName" instead of the full Flag!"enumName".yes and Others think that it's still quite ugly.Those were since replaced with No.enumName and Yes.enumName by Dmitry's idea: https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0b608895269bdccba4330 Andrei
Jun 11 2011
On 12.06.2011 10:31, KennyTM~ wrote:On Jun 12, 11 11:18, Andrei Alexandrescu wrote:Well, you can do only as much staying within the language. Personally, I think the biggest stumbling block is error messages, maybe we can do something about them. Like make Flag struct with alias this and provide this(Flag!s) constructor, opAssign etc. that static assert something sensible on mismatch. -- Dmitry OlshanskyOn 06/11/2011 04:20 PM, Jonathan M Davis wrote:Yes.X and No.X looks grammatically wrong. In D you usually have 'Aggregate.member', not 'Member.aggregate'.2. He proposed a template wrapper which would allow you to type yes!"enumName" and no!"enumName" instead of the full Flag!"enumName".yes and Others think that it's still quite ugly.Those were since replaced with No.enumName and Yes.enumName by Dmitry's idea: https://github.com/andralex/phobos/commit/801ccc96ce56827cd0d0 608895269bdccba4330 Andrei
Jun 12 2011
Michel Fortin:<https://github.com/michelf/dmd/commit/673bae4982ff18a3d216bc1578f50d40f4d26d7a> Took me less time than what I took arguing about Flag!"".I don't know if Walter will appreciate this, or if this will need improvements, but you have done something better than my posts where I just talk :-) Bye, bearophile
Jun 11 2011
People here already noted most advantages and disadvantages of this proposal so I'll just add one more: KISS. I too am against this proposal since it's very unKISS. I think, that either you really need a separate enum type to document the different values and hence use *should* define the enum or you don't really need it and hence KISS it with a plain boolean. I see zero benefit from adding so much complexity here. Are we trying to kill a fly with a hammer (and by that i mean the vehicle)? I see no benefit in adding redundant "Yes" / "No" values. Regarding named arguments, I don't like this "feature" and believe that it's more trouble than its worth. For example, Ruby managed to live without it and Rails uses AAs instead. And finally, Andrei's complain about scrolling up and down because of this so called boilerplate (7 lines of code in all of phobos): Even though D has a far superior module system compared to c++ (which has no such system whatsoever) you still chose to implement library-in-a-file. You even went so far as to add "groups" to DDoc. Is there some sort of weird metric at Facebook that gives you a bigger bonus if you manage to cram more code per file? Are you getting deducted per the amount of files you've added?
Jun 12 2011
On 06/12/2011 03:55 PM, foobar wrote:People here already noted most advantages and disadvantages of this proposal so I'll just add one more: KISS. I too am against this proposal since it's very unKISS.I agree that KISS is important and that Flag is failing it. Andrei
Jun 12 2011
On 6/12/2011 1:54 PM, Andrei Alexandrescu wrote:On 06/12/2011 03:55 PM, foobar wrote:Set phasers to "vaporize".People here already noted most advantages and disadvantages of this proposal so I'll just add one more: KISS. I too am against this proposal since it's very unKISS.I agree that KISS is important and that Flag is failing it.
Jun 12 2011
Andrei:If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature. I am for it, if it's well implemented. The reordering is one important part of this feature. An optional sub-feature is a way to deprecate argument names. Thankfully in D there is already the deprecated keyword; a first idea: void foo(int deprecated(y) x) {} Or: void foo(int deprecated{y} x) {} Bye, bearophile
Jun 13 2011
"bearophile" < bearophileHUGS lycos.com> wrote in message news:it5gqj$a1g$1 digitalmars.com...Andrei:I like it!If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature. I am for it, if it's well implemented. The reordering is one important part of this feature. An optional sub-feature is a way to deprecate argument names. Thankfully in D there is already the deprecated keyword; a first idea: void foo(int deprecated(y) x) {} Or: void foo(int deprecated{y} x) {}
Jun 13 2011
On Mon, 13 Jun 2011 20:19:15 +0300, bearophile < <bearophileHUGS lycos.com> wrote:Andrei:I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion. fun(int a, int b, int c=3) fun(1, 2, 3) // fine - current fun(1, 2) // fine - current fun(a:1, b:3, c:5) // fine fun(a:1, b:3) // fine fun(b:1, c:3, a:5) // fine fun(b:1, a:3) // fine fun(b:1) // error fun(c:1) // error fun(2, b:1) // error fun(2, c:1) // error fun(2, c:2, 3) // error Thanks.If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature.
Jun 13 2011
On 6/14/11 8:36 AM, so wrote:On Mon, 13 Jun 2011 20:19:15 +0300, bearophile < <bearophileHUGS lycos.com> wrote:A different rule can be: - Named arguments come last. - Any previous arguments match the order.Andrei:I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature.fun(int a, int b, int c=3) fun(1, 2, 3) // fine - current fun(1, 2) // fine - current fun(a:1, b:3, c:5) // fine fun(a:1, b:3) // fine fun(b:1, c:3, a:5) // fine fun(b:1, a:3) // fine fun(b:1) // error// error: missing afun(c:1) // error// error: missing a and bfun(2, b:1) // error// ok, a is 2, b is 1, c is 3fun(2, c:1) // error// error: missing bfun(2, c:2, 3) // error// error, 3 after named arguments
Jun 13 2011
On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana <ary esperanto.org.ar> wrote:On 6/14/11 8:36 AM, so wrote:IMO the main that makes NAs confusing is allowing hybrid calls. I don't think allowing reordering then introducing two new rules on ordering is a good idea.On Mon, 13 Jun 2011 20:19:15 +0300, bearophile < <bearophileHUGS lycos.com> wrote:A different rule can be: - Named arguments come last. - Any previous arguments match the order.Andrei:I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature.
Jun 13 2011
"so" <so so.so> wrote in message news:op.vw1msqy0mpw3zg so-pc...On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana <ary esperanto.org.ar> wrote:I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.On 6/14/11 8:36 AM, so wrote:IMO the main that makes NAs confusing is allowing hybrid calls. I don't think allowing reordering then introducing two new rules on ordering is a good idea.On Mon, 13 Jun 2011 20:19:15 +0300, bearophile < <bearophileHUGS lycos.com> wrote:A different rule can be: - Named arguments come last. - Any previous arguments match the order.Andrei:I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature.
Jun 13 2011
On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5) Ary's rules and function signature in mind, after you glance the call you'd do some calculations and eventually find out the caller meant: fun(a:2, b:3, d:1, c:5) This is only 4 parameters and i named only one. Now NAs supposed to ease to process of self-documenting, not complicate it even further. I'm in favor of keeping it as simple as possible without creating any confusion.
Jun 13 2011
On 6/14/11 12:58 PM, so wrote:On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:// error: c assigned twice Remember, the third argument is positional so it's assigned to c. Then you are trying to assign c again. It's an error.I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5)
Jun 13 2011
On Tue, 14 Jun 2011 09:33:54 +0300, Ary Manzana <ary esperanto.org.ar> wrote:On 6/14/11 12:58 PM, so wrote:Sorry i don't understand, what should i do?On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:// error: c assigned twice Remember, the third argument is positional so it's assigned to c. Then you are trying to assign c again. It's an error.I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5)
Jun 13 2011
On 6/14/11 1:38 PM, so wrote:On Tue, 14 Jun 2011 09:33:54 +0300, Ary Manzana <ary esperanto.org.ar> wrote:You can't only name c. You can name arguments from the end to the beginning: fun(2, 3, 1, d: 99) fun(2, 3, c: 98, d:99) fun(2, 3, d: 98, c:99) fun(2, c: 97, b: 98, d:99) etc.On 6/14/11 12:58 PM, so wrote:Sorry i don't understand, what should i do?On Tue, 14 Jun 2011 08:32:59 +0300, Nick Sabalausky <a a.a> wrote:// error: c assigned twice Remember, the third argument is positional so it's assigned to c. Then you are trying to assign c again. It's an error.I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.An example to it. fun(int a, int b, int c, int d) Say we want to name only c: fun(2, 3, 1, c:5)
Jun 13 2011
On 6/14/11 12:32 PM, Nick Sabalausky wrote:"so"<so so.so> wrote in message news:op.vw1msqy0mpw3zg so-pc...Well, that's the way Ruby works :-) In fact, in Ruby there are no named arguments. So people came up with this idea. def some_function(param_a, param_b, options = {}) param_c = options['param_c'] || default_for_c param_d = options['param_d'] || default_for_d end The last argument is a hash (a dictionary) with a default value of an empty hash. So you can call it: some_function(1, 2) some_function(1, 2, {'param_c' => 3}) some_function(1, 2, {'param_c' => 3, 'param_d' => 4}) But in Ruby there's a rule: you can skip parenthesis. And you can skip the brackets for a hash if it's the last argument. And instead of strings symbols are much nicer and efficient. So... some_function 1, 2 some_function 1, 2, :param_c => 3 some_function 1, 3, :param_c => 3, :param_d => 4 Of course this won't work in D because passing hashes all the time would be very inneficcient. But I think positional arguments first, named arguments last is a simple rule that's easy to follow and probably implement (maybe when I'll go back to my country I'll try to implement it).On Tue, 14 Jun 2011 04:46:54 +0300, Ary Manzana<ary esperanto.org.ar> wrote:I think Ary's suggestion is very simple and easy to understand. Hybrid calls are *only* confusing when an unnamed parameter comes after a named one.On 6/14/11 8:36 AM, so wrote:IMO the main that makes NAs confusing is allowing hybrid calls. I don't think allowing reordering then introducing two new rules on ordering is a good idea.On Mon, 13 Jun 2011 20:19:15 +0300, bearophile< <bearophileHUGS lycos.com> wrote:A different rule can be: - Named arguments come last. - Any previous arguments match the order.Andrei:I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion.If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature.
Jun 13 2011
On Tue, 14 Jun 2011 09:48:14 +0300, Ary Manzana <ary esperanto.org.ar> wrote:Well, that's the way Ruby works :-) In fact, in Ruby there are no named arguments. So people came up with this idea. def some_function(param_a, param_b, options = {}) param_c = options['param_c'] || default_for_c param_d = options['param_d'] || default_for_d end The last argument is a hash (a dictionary) with a default value of an empty hash. So you can call it: some_function(1, 2) some_function(1, 2, {'param_c' => 3}) some_function(1, 2, {'param_c' => 3, 'param_d' => 4}) But in Ruby there's a rule: you can skip parenthesis. And you can skip the brackets for a hash if it's the last argument. And instead of strings symbols are much nicer and efficient. So... some_function 1, 2 some_function 1, 2, :param_c => 3 some_function 1, 3, :param_c => 3, :param_d => 4 Of course this won't work in D because passing hashes all the time would be very inneficcient. But I think positional arguments first, named arguments last is a simple rule that's easy to follow and probably implement (maybe when I'll go back to my country I'll try to implement it).Tell me this is not true! :) So ruby don't have named arguments and the community came up with a solution which is by the look of it heavily influenced by language capabilities. No offense and please no kicking butts but... This is madness!!!
Jun 13 2011
On 6/14/11 1:58 PM, so wrote:On Tue, 14 Jun 2011 09:48:14 +0300, Ary Manzana <ary esperanto.org.ar> wrote::-PWell, that's the way Ruby works :-) In fact, in Ruby there are no named arguments. So people came up with this idea. def some_function(param_a, param_b, options = {}) param_c = options['param_c'] || default_for_c param_d = options['param_d'] || default_for_d end The last argument is a hash (a dictionary) with a default value of an empty hash. So you can call it: some_function(1, 2) some_function(1, 2, {'param_c' => 3}) some_function(1, 2, {'param_c' => 3, 'param_d' => 4}) But in Ruby there's a rule: you can skip parenthesis. And you can skip the brackets for a hash if it's the last argument. And instead of strings symbols are much nicer and efficient. So... some_function 1, 2 some_function 1, 2, :param_c => 3 some_function 1, 3, :param_c => 3, :param_d => 4 Of course this won't work in D because passing hashes all the time would be very inneficcient. But I think positional arguments first, named arguments last is a simple rule that's easy to follow and probably implement (maybe when I'll go back to my country I'll try to implement it).Tell me this is not true! :)So ruby don't have named arguments and the community came up with a solution which is by the look of it heavily influenced by language capabilities. No offense and please no kicking butts but... This is madness!!!Well, in fact I don't know if the community came up with this or if the creators came up with this. But I'm sure at some point they agreed on this because it's supported on the syntax level.
Jun 14 2011
On 6/14/11 1:58 AM, so wrote:Tell me this is not true! :) So ruby don't have named arguments and the community came up with a solution which is by the look of it heavily influenced by language capabilities. No offense and please no kicking butts but... This is madness!!!Ha! My Flag chef d'oeuvre would enjoy appreciation, just in another language. Andrei
Jun 14 2011
On Jun 14, 11 09:36, so wrote:On Mon, 13 Jun 2011 20:19:15 +0300, bearophile < <bearophileHUGS lycos.com> wrote:I'd rather have no reordering and allow hybrid call. Named argument is useful for specifying the nature of an argument. If the type is clear for all but one argument, the rest is just noisy redundant info. e.g. MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); is no worse than MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);Andrei:I think they worth it and it is the right time to talk extensively why people think they don't. And reasoning should not be about its failure or success in another language, we better have our own rules. IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion. fun(int a, int b, int c=3) fun(1, 2, 3) // fine - current fun(1, 2) // fine - current fun(a:1, b:3, c:5) // fine fun(a:1, b:3) // fine fun(b:1, c:3, a:5) // fine fun(b:1, a:3) // fine fun(b:1) // error fun(c:1) // error fun(2, b:1) // error fun(2, c:1) // error fun(2, c:2, 3) // error Thanks.If we all get convinced that named parameters are worth it,I think this is not going to happen because some people (two?) don't want this feature.
Jun 13 2011
On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:I'd rather have no reordering and allow hybrid call. Named argument is useful for specifying the nature of an argument. If the type is clear for all but one argument, the rest is just noisy redundant info.fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?e.g. MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); is no worse than MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do? Named arguments isn't something to save typing. Also the first version of the MoveWindow indeed worse than the second, which again i think requires no explanation.
Jun 13 2011
Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do?In fact, i was wrong on this one, you'd simply call fun(a, c:4). Reordering is nice because if you remove hybrid calls you no longer need an order, you are free to change priority.
Jun 14 2011
On Jun 14, 11 14:46, so wrote:On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:By "type" I mean the purpose of an argument, e.g. the first 'int' in MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry I don't know of a better term. When what one argument does is clear for the caller, forcing NA on it just annoys the programmer.I'd rather have no reordering and allow hybrid call. Named argument is useful for specifying the nature of an argument. If the type is clear for all but one argument, the rest is just noisy redundant info.fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?That's skipping, not really reordering. 'a' still precedes 'c'. Also, I'm not against reordering, but I'm against using reordering as a reason to abandon hybrid.e.g. MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); is no worse than MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do?Named arguments isn't something to save typing. Also the first version of the MoveWindow indeed worse than the second, which again i think requires no explanation.No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy, when the respective arguments already show what they are?'
Jun 14 2011
On Tue, 14 Jun 2011 11:23:12 +0300, KennyTM~ <kennytm gmail.com> wrote:On Jun 14, 11 14:46, so wrote:This is the whole point of NAs, it is not clear, you need to check the function definition whenever you read the call.On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:By "type" I mean the purpose of an argument, e.g. the first 'int' in MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry I don't know of a better term. When what one argument does is clear for the caller, forcing NA on it just annoys the programmer.I'd rather have no reordering and allow hybrid call. Named argument is useful for specifying the nature of an argument. If the type is clear for all but one argument, the rest is just noisy redundant info.fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?It is not a reason to abandon hybrid, it is a consequence of abandoning it.That's skipping, not really reordering. 'a' still precedes 'c'. Also, I'm not against reordering, but I'm against using reordering as a reason to abandon hybrid.e.g. MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); is no worse than MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do?Matching, with fun(x:x, y:y) or fun(y:y, x:x) you are done, you don't ever need to check function definition again. With your reasoning you don't need named arguments at all. enum bRepaint=true; MoveWindow(... bRepaint)Named arguments isn't something to save typing. Also the first version of the MoveWindow indeed worse than the second, which again i think requires no explanation.No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy, when the respective arguments already show what they are?'
Jun 14 2011
On Jun 14, 11 16:39, so wrote:On Tue, 14 Jun 2011 11:23:12 +0300, KennyTM~ <kennytm gmail.com> wrote:And yet, with loc.x, myWin.width etc, you don't need to check the definition to know those should be coordinates and widths.On Jun 14, 11 14:46, so wrote:This is the whole point of NAs, it is not clear, you need to check the function definition whenever you read the call.On Tue, 14 Jun 2011 09:18:42 +0300, KennyTM~ <kennytm gmail.com> wrote:By "type" I mean the purpose of an argument, e.g. the first 'int' in MoveWindow is an x-coordinate, the second is a y-coordinate, etc. Sorry I don't know of a better term. When what one argument does is clear for the caller, forcing NA on it just annoys the programmer.I'd rather have no reordering and allow hybrid call. Named argument is useful for specifying the nature of an argument. If the type is clear for all but one argument, the rest is just noisy redundant info.fun(bool, bool, bool, bool, bool...) Isn't the type clear for every argument here?You don't need to abandon hybrid to enable reordering. Ary's suggestion, for example, allows positional and named arguments to coexist.It is not a reason to abandon hybrid, it is a consequence of abandoning it.That's skipping, not really reordering. 'a' still precedes 'c'. Also, I'm not against reordering, but I'm against using reordering as a reason to abandon hybrid.e.g. MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); is no worse than MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true);Reordering is important an example: fun(int a, int b=2, int c=3) If you want to name c but not b what are you going to do?Why do you need to check the function definition when you see 'moveTo(x, y)'?Matching, with fun(x:x, y:y) or fun(y:y, x:x) you are done, you don't ever need to check function definition again. With your reasoning you don't need named arguments at all.Named arguments isn't something to save typing. Also the first version of the MoveWindow indeed worse than the second, which again i think requires no explanation.No, please explain. What does the extra hWnd, X, Y, nWidth, nHeight buy, when the respective arguments already show what they are?'enum bRepaint=true; MoveWindow(... bRepaint)Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed to be variables you got from elsewhere. The names of these variables already provide the semantics to the readers, making NA for those arguments redundant. If they were constants it's nothing wrong with MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);
Jun 14 2011
On Tue, 14 Jun 2011 12:58:30 +0300, KennyTM~ <kennytm gmail.com> wrote:And yet, with loc.x, myWin.width etc, you don't need to check the definition to know those should be coordinates and widths.loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // sameYou don't need to abandon hybrid to enable reordering. Ary's suggestion, for example, allows positional and named arguments to coexist.Allows reordering by introducing two new order restrictions which i still had trouble understanding, sorry Ary :)Why do you need to check the function definition when you see 'moveTo(x, y)'?Same question, why do you need named arguments?Again, they are variables you get on the caller side, they got no idea about function signature. Also i don't understand why some think allowing hybrid calls has any merit. Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception. Allowing unnamed arguments and named arguments in one call doesn't make any sense to me, it is almost opposite to the reasons named arguments designed for, you don't even need to talk about its drawbacks like the complications and confusions.enum bRepaint=true; MoveWindow(... bRepaint)Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed to be variables you got from elsewhere. The names of these variables already provide the semantics to the readers, making NA for those arguments redundant. If they were constants it's nothing wrong with MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);
Jun 14 2011
On Jun 14, 11 19:11, so wrote:On Tue, 14 Jun 2011 12:58:30 +0300, KennyTM~ <kennytm gmail.com> wrote:If you have no idea about the function signature, you have no idea about the parameter names either.And yet, with loc.x, myWin.width etc, you don't need to check the definition to know those should be coordinates and widths.loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // sameYou see the difference between variables and generic constants? RECT bounds; GetWindowRect(hWnd, &bounds); writeln("Please enter the coordinates."); auto x = readln().chomp().to!int(); auto y = readln().chomp().to!int(); auto width = bounds.right - bounds.left; auto height = bounds.bottom - bounds.top; MoveWindow(hWnd, x, y, width, height, bRepaint:true); vs. writeln("Resetting window dimensions"); ... MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true); Named arguments provides clarification when the argument itself (e.g. 0, false, true) is meaningless. But with a variable which itself provides a meaning, forcing named argument on _every_argument_passed_ is just annoying.You don't need to abandon hybrid to enable reordering. Ary's suggestion, for example, allows positional and named arguments to coexist.Allows reordering by introducing two new order restrictions which i still had trouble understanding, sorry Ary :)Why do you need to check the function definition when you see 'moveTo(x, y)'?Same question, why do you need named arguments?See above.Again, they are variables you get on the caller side, they got no idea about function signature.enum bRepaint=true; MoveWindow(... bRepaint)Non sequitur. In my MoveWindow example hWnd, loc and myWin are assumed to be variables you got from elsewhere. The names of these variables already provide the semantics to the readers, making NA for those arguments redundant. If they were constants it's nothing wrong with MoveWindow(hWnd, X:0, Y:0, nWidth:200, nHeight:200, bRepaint:true);Also i don't understand why some think allowing hybrid calls has any merit. Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception. Allowing unnamed arguments and named arguments in one call doesn't make any sense to me, it is almost opposite to the reasons named arguments designed for, you don't even need to talk about its drawbacks like the complications and confusions.Yet all well-known languages that support named arguments that support
Jun 14 2011
On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~ <kennytm gmail.com> wrote:I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // sameIf you have no idea about the function signature, you have no idea about the parameter names either.You see the difference between variables and generic constants? RECT bounds; GetWindowRect(hWnd, &bounds); writeln("Please enter the coordinates."); auto x = readln().chomp().to!int(); auto y = readln().chomp().to!int(); auto width = bounds.right - bounds.left; auto height = bounds.bottom - bounds.top; MoveWindow(hWnd, x, y, width, height, bRepaint:true); vs. writeln("Resetting window dimensions"); ... MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true); Named arguments provides clarification when the argument itself (e.g. 0, false, true) is meaningless. But with a variable which itself provides a meaning, forcing named argument on _every_argument_passed_ is just annoying.Looks like i am just repeating myself but i don't understand how is pssing constants meaningless and variables, and why do you even need named arguments for those? enum x=... enum y=... ... fun(x, y)Yet all well-known languages that support named arguments that supportThis is not an argument.
Jun 14 2011
On Jun 15, 11 00:45, so wrote:On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~ <kennytm gmail.com> wrote:I'm just bringing up the fact. Why would you need to check the function signature when reading MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); ? It's clear what each argument does. If you feel the need of duplicating the same information, fine, write MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true); in your code. But don't make it mandatory, it's a waste of time and space when the writer just wants to clarify that 'true' is a bRepaint.I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // sameIf you have no idea about the function signature, you have no idea about the parameter names either.If you want to disregard named argument, why go the complicated route and define enums? You could do as well fun(/*x*/0, /*y*/0); (and yes I'm currently using it.) But the point is it's ugly. Heck why do we need to defend NA. My point is only "hybrid should be allowed if I want to".You see the difference between variables and generic constants? RECT bounds; GetWindowRect(hWnd, &bounds); writeln("Please enter the coordinates."); auto x = readln().chomp().to!int(); auto y = readln().chomp().to!int(); auto width = bounds.right - bounds.left; auto height = bounds.bottom - bounds.top; MoveWindow(hWnd, x, y, width, height, bRepaint:true); vs. writeln("Resetting window dimensions"); ... MoveWindow(hWnd, X:0, Y:0, nWidth:800, nHeight:600, bRepaint:true); Named arguments provides clarification when the argument itself (e.g. 0, false, true) is meaningless. But with a variable which itself provides a meaning, forcing named argument on _every_argument_passed_ is just annoying.Looks like i am just repeating myself but i don't understand how is pssing constants meaningless and variables, and why do you even need named arguments for those? enum x=... enum y=... ... fun(x, y)Neither is 'Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception.' Maybe another argument: D's static struct initializer already supports hybrid and reordering. Extending that to function arguments is natural. ------------------------------------ struct S { int x; int y; } void main() { S s0 = {4, 5}; S s1 = {x:4, 5}; S s2 = {4, y:5}; S s3 = {x:4, y:5}; // S s4 = {y:4, 5}; // error S s5 = {y:5, x:4}; } ------------------------------------Yet all well-known languages that support named arguments that supportThis is not an argument.
Jun 14 2011
I'm just bringing up the fact. Why would you need to check the function signature when reading MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); ? It's clear what each argument does. If you feel the need of duplicating the same information, fine, write MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true); in your code. But don't make it mandatory, it's a waste of time and space when the writer just wants to clarify that 'true' is a bRepaint.Waste of time? so is writing docs and comments, so is checking the library everytime you have trouble understanding a call. It is designed to ease understanding your own or others code. I have no idea how you can think about writing a few chars more as if something bad. In programming we waste our times not when we are actually writing but while doing everything else!No, you are the one suggesting that, in your example you called MoveWindow(hwnd) and said it was all you need, then i gave this example to prove if all you need is that, you don't need NAs anyways since it is just so easy to treat other things as "hwnd".Looks like i am just repeating myself but i don't understand how is pssing constants meaningless and variables, and why do you even need named arguments for those? enum x=... enum y=... ... fun(x, y)If you want to disregard named argument, why go the complicated route and define enums? You could do as well fun(/*x*/0, /*y*/0);(and yes I'm currently using it.) But the point is it's ugly. Heck why do we need to defend NA. My point is only "hybrid should be allowed if I want to".It is ugly but it is not heck, it does nothing, it gives you no guaranties, compiler does no matching. It is no better than fun(0, 0). We came this far but we still don't think the NAs same way, and i am starting to lose my hope explaining myself.Why not? first thing you would encounter is its prototype, its best usage that makes most sense, i told it because you seem to give its primary function no value at all.Neither is 'Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception.'Yet all well-known languages that support named arguments that supportThis is not an argument.Maybe another argument: D's static struct initializer already supports hybrid and reordering. Extending that to function arguments is natural. ------------------------------------ struct S { int x; int y; } void main() { S s0 = {4, 5}; S s1 = {x:4, 5}; S s2 = {4, y:5}; S s3 = {x:4, y:5}; // S s4 = {y:4, 5}; // error S s5 = {y:5, x:4}; } ------------------------------------I didn't know they work this way, i agree it is a good argument (finally we agree on something!) Though i have to say it looks quite confusing and verbose (rules). Then again, it looks like i am alone on this one, quite possibly i am wrong :)
Jun 15 2011
so:I didn't know they work this way, i agree it is a good argument (finally we agree on something!)To not waste all the good discussions I suggest to write down a DEP (D Enhancement Proposal), that tries to list what to do in all corner cases, even just a "?" where you don't know what to do (and including my Scala-style deprecated(oldArgName) idea). Even writing a pre-DEP will be a good starting point. Even if in the end named arguments don't get added to D, having this DEP will be good to avoid further future discussions, or as starting point for a future desire to try adding them again. Bye, bearophile
Jun 15 2011
On Jun 16, 11 00:43, bearophile wrote:so:You mean a DIP :)I didn't know they work this way, i agree it is a good argument (finally we agree on something!)To not waste all the good discussions I suggest to write down a DEP (D Enhancement Proposal), that tries to list what to do in all corner cases, even just a "?" where you don't know what to do (and including my Scala-style deprecated(oldArgName) idea). Even writing a pre-DEP will be a good starting point. Even if in the end named arguments don't get added to D, having this DEP will be good to avoid further future discussions, or as starting point for a future desire to try adding them again. Bye, bearophile
Jun 15 2011
"KennyTM~" <kennytm gmail.com> wrote in message news:it8f4s$1gve$1 digitalmars.com...On Jun 15, 11 00:45, so wrote:Because it might be wrong.On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~ <kennytm gmail.com> wrote:I'm just bringing up the fact. Why would you need to check the function signature when reading MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); ? It's clear what each argument does.I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // sameIf you have no idea about the function signature, you have no idea about the parameter names either.If you feel the need of duplicating the same information, fine, write MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true); in your code. But don't make it mandatory, it's a waste of time and space when the writer just wants to clarify that 'true' is a bRepaint.I don't think anyone suggested named arguments should be manditory.
Jun 19 2011
On Jun 20, 11 03:03, Nick Sabalausky wrote:"KennyTM~"<kennytm gmail.com> wrote in message news:it8f4s$1gve$1 digitalmars.com...Right, no one suggested named arguments should be mandatory, but so's original suggestion is either "all on" or "all off", which makes this example pretty much mandatory because of a 'bRepaint: true'.On Jun 15, 11 00:45, so wrote:Because it might be wrong.On Tue, 14 Jun 2011 15:18:09 +0300, KennyTM~<kennytm gmail.com> wrote:I'm just bringing up the fact. Why would you need to check the function signature when reading MoveWindow(hWnd, loc.x, loc.y, myWin.width, myWin.height, bRepaint:true); ? It's clear what each argument does.I think you are just resisting here, if you write a call once with named arguments, you documented it in place, the next time you visit this call all you need to see is in the call site.loc.x on the caller side, it has no idea about function signature, and you don't know if it was 10th or 2nd argument in function. // definition fun(int x, int y) { } // call fun(x, y) // you need to check the definition if you think something wrong with parameters the second time you come here fun(y, x) // same fun(x:x, y:y) // you know there is nothing wrong with parameters fun(y:y, x:x) // sameIf you have no idea about the function signature, you have no idea about the parameter names either.If you feel the need of duplicating the same information, fine, write MoveWindow(hWnd:hWnd, X:loc.x, Y:loc.y, nWidth:myWin.width, nHeight:myWin.height, bRepaint:true); in your code. But don't make it mandatory, it's a waste of time and space when the writer just wants to clarify that 'true' is a bRepaint.I don't think anyone suggested named arguments should be manditory.
Jun 19 2011
On Jun 14, 11 19:11, so wrote: [snip]Also i don't understand why some think allowing hybrid calls has any merit. Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception. Allowing unnamed arguments and named arguments in one call doesn't make any sense to me, it is almost opposite to the reasons named arguments designed for, you don't even need to talk about its drawbacks like the complications and confusions.And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).
Jun 14 2011
On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~ <kennytm gmail.com> wrote:On Jun 14, 11 19:11, so wrote: [snip]So complicated because it took you this long to match the parameters with the variables, you still need to check function definition because you have parameters that have no match. These are the very things named arguments needs to solve or am i missing something? You could just drop it and go read the function signature everytime, it'd save you time :PAlso i don't understand why some think allowing hybrid calls has any merit. Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception. Allowing unnamed arguments and named arguments in one call doesn't make any sense to me, it is almost opposite to the reasons named arguments designed for, you don't even need to talk about its drawbacks like the complications and confusions.And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).
Jun 14 2011
On Jun 15, 11 01:18, so wrote:On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~ <kennytm gmail.com> wrote:What you're missing may be that what I'm outlining is how the /compiler/ matches the parameters. The /compiler/ of course needs to check the function definition every time, otherwise how could it emit errors when you give a wrong name? :)On Jun 14, 11 19:11, so wrote: [snip]So complicated because it took you this long to match the parameters with the variables, you still need to check function definition because you have parameters that have no match. These are the very things named arguments needs to solve or am i missing something? You could just drop it and go read the function signature everytime, it'd save you time :PAlso i don't understand why some think allowing hybrid calls has any merit. Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception. Allowing unnamed arguments and named arguments in one call doesn't make any sense to me, it is almost opposite to the reasons named arguments designed for, you don't even need to talk about its drawbacks like the complications and confusions.And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).
Jun 14 2011
"so" <so so.so> wrote in message news:op.vw2s1b19mpw3zg tan-pc...On Tue, 14 Jun 2011 16:01:20 +0300, KennyTM~ <kennytm gmail.com> wrote:Simple rule for combining hybrid and reordering: Look at the caller's args one at a time: as soon as one is reordered, the rest of the args must be named (otherwise you wouldn't know which param it's supposed to be).On Jun 14, 11 19:11, so wrote: [snip]So complicated because it took you this long to match the parameters with the variables, you still need to check function definition because you have parameters that have no match. These are the very things named arguments needs to solve or am i missing something?Also i don't understand why some think allowing hybrid calls has any merit. Just search "named arguments" and first thing you'd see is calls with all arguments named, no exception. Allowing unnamed arguments and named arguments in one call doesn't make any sense to me, it is almost opposite to the reasons named arguments designed for, you don't even need to talk about its drawbacks like the complications and confusions.And if you think it's complicated, you're just thinking in a too complicated way. The rule is simple. Say there is a function pure nothrow S parseString(S=const(char)[], C) (ref C[] input, out ConversionResult result, char quote='"', bool recognizePrefix=true) if (...); and you call it as string s = `"hello"`; ConversionResult detailResult; auto parsed = parseString(s, recognizePrefix:false, result:detailResult); The first step is identify all positional arguments ('s' here), and fill them in in-order. input <- s result <- ... quote <- ... recognizePrefix <- ... next, we match the named args input <- s result <- detailResult quote <- ... recognizePrefix <- false finally we fill in the optional parameters input <- s result <- detailResult quote <- '"' recognizePrefix <- false what's so complicated? Actually, reordering creates more complication than hybrid (e.g. ambiguity in selecting an overload).
Jun 19 2011
On 2011-06-13 21:36:01 -0400, so <so so.so> said:IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion. fun(int a, int b, int c=3) fun(1, 2, 3) // fine - current fun(1, 2) // fine - current fun(a:1, b:3, c:5) // fine fun(a:1, b:3) // fine fun(b:1, c:3, a:5) // fine fun(b:1, a:3) // fine fun(b:1) // error fun(c:1) // error fun(2, b:1) // error fun(2, c:1) // error fun(2, c:2, 3) // errorThere's much more to named arguments as it first appears. Have you thought about: 1. variadic arguments? 2. named template arguments? 3. template variadic arguments (tuples) and how they expand as function parameters? Also, with reordering, if you have two overloaded functions of this form: void fun(int a, string b) {} void fun(string b, int a) {} which one does this calls: fun(a: 1, b: "hello"); ? Does the call become ambiguous when using named arguments? It with this? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 14 2011
On Jun 14, 11 20:34, Michel Fortin wrote:On 2011-06-13 21:36:01 -0400, so <so so.so> said:partition!(ss:SwapStrategy.stable, predicate:"a>0") (r:[1,2,3,4]);IMO named arguments in D at least should do: - Reordering (since we got default parameters, even better) - It is enabled only if we have access to the function declaration. - In a function call we either use named arguments for all the non-default arguments or call it with the usual syntax. No hybrid stuff, no confusion. fun(int a, int b, int c=3) fun(1, 2, 3) // fine - current fun(1, 2) // fine - current fun(a:1, b:3, c:5) // fine fun(a:1, b:3) // fine fun(b:1, c:3, a:5) // fine fun(b:1, a:3) // fine fun(b:1) // error fun(c:1) // error fun(2, b:1) // error fun(2, c:1) // error fun(2, c:2, 3) // errorThere's much more to named arguments as it first appears. Have you thought about: 1. variadic arguments? 2. named template arguments?3. template variadic arguments (tuples) and how they expand as function parameters? Also, with reordering, if you have two overloaded functions of this form: void fun(int a, string b) {} void fun(string b, int a) {} which one does this calls: fun(a: 1, b: "hello"); ? Does the call become ambiguous when using named arguments? It wouldn'tLooks like the last one get the precedence. At least for Mono (see http://ideone.com/REXC0). MSDN says ============================================ Use of named and optional arguments affects overload resolution in the following ways: - A method, indexer, or constructor is a candidate for execution if each of its parameters either is optional or corresponds, by name or by position, to a single argument in the calling statement, and that argument can be converted to the type of the parameter. - If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Omitted arguments for optional parameters are ignored. - If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters. ============================================ It doesn't cover your case. Of course this is bad. But this isn't much different from another solved problem... ---------------------------------------- void f(float s){} void f(double s){} void main() { f(3); } ---------------------------------------- x.d(5): Error: function x.f called with argument types: ((int)) matches both: x.f(float s) and: x.f(double s) ---------------------------------------- We could do the same for named arguments. ---------------------------------------- void fun(int a, string b) {} void fun(string b, int a) {} void main() { fun(a: 1, b: "hello"); } ---------------------------------------- x.d(5): Error: function x.fun called with argument names and types: ((int a, string b)) matches both: x.f(int a, string b) and: x.f(string b, int a) ----------------------------------------
Jun 14 2011
On Tue, 14 Jun 2011 15:34:53 +0300, Michel Fortin <michel.fortin michelf.com> wrote:There's much more to named arguments as it first appears. Have you thought about: 1. variadic arguments?There is already a syntax for this in the language. fun(a:1, var:{3,5,7})2. named template arguments?Do we need this?3. template variadic arguments (tuples) and how they expand as function parameters?This one is a bit tricky but wouldn't 1 also apply here?Also, with reordering, if you have two overloaded functions of this form: void fun(int a, string b) {} void fun(string b, int a) {}Only solution i can think of to this would be changing argument names, otherwise an error.
Jun 14 2011
"Michel Fortin" <michel.fortin michelf.com> wrote in message news:it7kq2$26ha$1 digitalmars.com...Also, with reordering, if you have two overloaded functions of this form: void fun(int a, string b) {} void fun(string b, int a) {} which one does this calls: fun(a: 1, b: "hello"); ? Does the call become ambiguous when using named arguments?I'd say "yes". But even if you said "no, the winner is whichever matches the order given, if there is a perfect match", that would be fine too. I'd further argue that either way it's not a significant problem, because it seems that situation would be extremely rare. And the only realistic case I can think of where it would might occur is if the callee wants to allow re-ordered params. But that would already solved by re-orderable names arguments anyway.with this?
Jun 14 2011