Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 01:30:47 UTC, Jack Stouffer wrote: It almost happened with Toyota. The auto industry has a C coding convention for safety called MISRA C, and it was brought up in court as to why Toyota's acceleration problems were entirely their fault. You can bet this will be brought up again. 1. Changing language won't change this, for that you need something that is formally proven (and even that assumes that the requirements spec is correct). I found this book from 2012 on industry use of formal methods which seems to be available on Google Books: https://books.google.no/books?id=E5sdDs00MuwC 2. What good does it do you to have your source code proven formally correct if your compiler can contain bugs? To get around that you need a formally verified compiler: http://compcert.inria.fr/ So... We are back to C again.
Re: DIP 1003 Formal Review
On Saturday, 13 May 2017 at 10:46:51 UTC, Jonathan M Davis wrote: be DOA. And not having them definitely simplifies lexing and parsing D code, so it's quite understandable that Walter is against them. I don't see how it complicates the lexer? "body" would be a valid identifier, so it would be lexed as such. All the parser has to do is to check the content of the identifer-token.
Re: Fixing opEquals and opCmp
On Saturday, 13 May 2017 at 18:52:48 UTC, Timon Gehr wrote: I can't seem to find the post you are referring to but IIRC it was immediately destroyed completely. It was probably in this thread: http://forum.dlang.org/post/dhrtitehdkcgnlmuk...@forum.dlang.org And as one can see generic support for comparison relations is non-trivial.
Re: DIP 1007 Preliminary Review Round 1
On Thursday, 11 May 2017 at 17:35:31 UTC, Nick Sabalausky (Abscissa) wrote: It is already addressed in the DIP. FQNs only help if they are used and current idiomatic D code tends to rely on unqualified imports/names. I didn't see that. Certainly not in the "Existing solutions" section. It needs to be there. It is mostly discussed in "Comparison with other languages" section - it is not a solution for the DIP problem, it is one of problems the DIP tries to solve. You put it kind of backwards in my opinion. Only if you consider "after compiler/library upgrade your project doesn't work anymore" a sufficient "informing" which we definitely don't. I definitely do. But even if you don't, see my "@new_func" alternate suggestion. This suggestion seems considerably more complex - it requires either additional tools to specify "yes, I truly want to use that new function" or forcing developer to always use FQN to do it. Required compiler changes are likely to be more convoluted too because same symbols would have to be interpreted as regular of "fake" ones depending on the context. Most importantly, I don't see motivation behind it. For conservatively maintained libraries defining no-op stub one version before introducing actual implementation is hardly a problem. Everyone else won't bother about it at all and just add new symbols in a regular manner. Trivial compilation error fixup that takes 5 minutes to address in a single project takes up to one month to propagate across all our libraries in projects per my experience. Actually fixing code is hardly a problem with breaking changes, ever. It is synchronization between developers and projects that makes it so painful. This needs to go in the DIP. No, it does not. That paragraph is a generic rationale why _any_ breaking changes without deprecation paths are so painful. I have no interest in trying to convince anyone who doesn't get it by now. And in override case, there is no backwards compatible solution available at all (see Steven comment). This needs to be made explicit in the DIP. Currently, I see nothing in the DIP clarifying that FQNs cannot address the override case. Yeah, will do.
Re: DIP 1007 Preliminary Review Round 1
https://github.com/dlang/DIPs/pull/63
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 00:05:56 UTC, Dibyendu Majumdar wrote: On Saturday, 6 May 2017 at 06:26:29 UTC, Joakim wrote: Walter: I believe memory safety will kill C. Hi, I think that comparing languages like D to C is not appropriate. C is a high level assembler and has different design goals. A useful document to refer to is: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1250.pdf In particular: (although note the addition of facet f, which echoes the sentiment that security is important) Keep the spirit of C. The Committee kept as a major goal to preserve the traditional spirit of C. There are many facets of the spirit of C, but the essence is a community sentiment of the underlying principles upon which the C language is based. For the Cx1 revision there is consensus to add a new facet f to the original list of facets. The new spirit of C can be summarized in phrases like: (a) Trust the programmer. (b) Don't prevent the programmer from doing what needs to be done. (c) Keep the language small and simple. (d) Provide only one way to do an operation. (e) Make it fast, even if it is not guaranteed to be portable. (f) Make support for safety and security demonstrable. Proverb e needs a little explanation. The potential for efficient code generation is one of the most important strengths of C. To help ensure that no code explosion occurs for what appears to be a very simple operation, many operations are defined to be how the target machine's hardware does it rather than by a general abstract rule. An example of this willingness to live with what the machine does can be seen in the rules that govern the widening of char objects for use in expressions: whether the values of char objects widen to signed or unsigned quantities typically depends on which byte operation is more efficient on the target machine. If only the gcc and clang designers followed that rule. These consider that undefined behaviour allows to break the code in any way they fancy (the nasal demon thing). While pragmaticists interpret it as do the thing that is the simplest to implement on that hardware. The most ridiculous example being the undefined behaviour of signed integer overflow. Signed integer overflow is undefined in C because some obscure platforms may not use 2 complements for the representation of integers. So INT_MAX+1 does not necessarily result in INT_MIN. But completely removing the code when one encounters for example: if(val+1 == INT_MIN) is simply nuts.
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 02:11:36 UTC, bachmeier wrote: On Sunday, 14 May 2017 at 00:05:56 UTC, Dibyendu Majumdar wrote: (a) Trust the programmer. I don't understand this point. C doesn't offer the programmer much to work with. If you trust the programmer, shouldn't that mean you provide a large set of tools and let them decide which parts to use? C is pretty much "here are some pointers, go have fun". Hi - I think this point really is saying that the type system in C is for convenience only - ultimately if you as a programmer want to manipulate memory in a certain way then C assumes you know what you are doing and why. As I said C is really a high level assembler. Regards
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 02:11:36 UTC, bachmeier wrote: On Sunday, 14 May 2017 at 00:05:56 UTC, Dibyendu Majumdar wrote: (a) Trust the programmer. I don't understand this point. C doesn't offer the programmer much to work with. If you trust the programmer, shouldn't that mean you provide a large set of tools and let them decide which parts to use? C is pretty much "here are some pointers, go have fun". The C99 Rationale also says: "The Committee is content to let C++ be the big and ambitious language. While some features of C++ may well be embraced, it is not the Committee’s intention that C become C++." I read that as: C is mostly in preservation and fossilization mode. If you want new features look elsewhere. We will not rock the boat. That is probably a good thing. C has its niche and it is comfortable there. If you want to beat C, it will not fight back. The only problem is to convince the C programmers to move.
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 01:30:47 UTC, Jack Stouffer wrote: On Sunday, 14 May 2017 at 00:05:56 UTC, Dibyendu Majumdar wrote: (a) Trust the programmer. That's the first and most deadly mistake. Buffer overflows and null pointers alone have caused hundreds of millions of dollars of damages. I think we can say that this trust is misplaced. I should have added that the C11 charter also says: 12. Trust the programmer, as a goal, is outdated in respect to the security and safety programming communities. While it should not be totally disregarded as a facet of the spirit of C, the C11 version of the C Standard should take into account that programmers need the ability to check their work. In real terms though tools like ASAN and Valgrind if used from the start usually allow you to catch most of the issues. Most likely even better tools for C will come about in time. But I don't see how languages like D or Rust can replace C for certain types of use cases. Maybe you can argue for the use of C in embedded systems and in OS's, although I see no reason why Rust can't eventually overtake C there. I think Rust is a promising language but I don't know enough about it to comment. My impression about Rust is that: a) Rust has a steep learning curve as a language. b) If you want to do things that C allows you to do, then Rust is no more safer than C. Regards
Re: Fantastic exchange from DConf
On Wednesday, 10 May 2017 at 12:18:40 UTC, Patrick Schluter wrote: On Wednesday, 10 May 2017 at 11:16:57 UTC, Atila Neves wrote: [...] The likelihood of a randomly picked C/C++ programmer not even knowing what a profiler is, much less having used one, is extremely high in my experience. I worked with a lot of embedded C programmers with several years of experience who knew nothing but embedded C. We're talking dozens of people here. Not one of them had ever used a profiler. I've worked 10 years in embedded (industry, time acquisition and network gears) and I can say that there is a good reason to that. It's nearly impossible to profile in an embedded system (nowadays it's often possible because of the generalization of Linux and gnu tools but at that time it wasn't). The tools don't exist or if they do, the instrumentation breaks the constraints of the controller. This was also one of the reason we chose our embedded CPU's very carefully. We always chose processors for which there existed mainstream desktop versions so that we could at least use the confortable tooling to test some parts of the code on a nice environment. We used Z80 (CP/M), 80186 (MS-C on DOS) and then 68030 (Pure-C on Atari TT). TL;DR profiling for embedded is order of magnitudes harder than for nice OS environments. IMO it's just different. The thing is, the tools you can use don't need to be marketed as "profilers". People will always find excuses if they lack time, will or knowledge. In practice, there's always a way to profile and debug, even if you don't have dedicated tools for it. It's also a lot easier to reason about performance on small chips with no caches, ILP, etc. and with fixed instruction timing, than it is on modern complex CPUs with hundreds of tasks competing for resources. One universal tool is oscilloscope, for sure you have one on your colleague's desk if you really do embedded stuff. A common way to profile on home computers from the '80s such as Atari XE (6502), was simply to change screen colors. That way you always knew the time taken by the measured code with 1-cycle precision. 13.5 scanlines are white? That's 1539 cycles! The time it took to execute a tight loop could even be computed accurately with pen and paper by just looking at the assembly. It's also a lot easier to implement a cycle-exact emulator for such simple chips, and then you can measure everything without observer effect.
Re: Fantastic exchange from DConf
On 14.05.2017 11:42, Patrick Schluter wrote: ... (a) Trust the programmer. (b) Don't prevent the programmer from doing what needs to be done. (c) Keep the language small and simple. (d) Provide only one way to do an operation. (e) Make it fast, even if it is not guaranteed to be portable. (f) Make support for safety and security demonstrable. Proverb e needs a little explanation. The potential for efficient code generation is one of the most important strengths of C. To help ensure that no code explosion occurs for what appears to be a very simple operation, many operations are defined to be how the target machine's hardware does it rather than by a general abstract rule. An example of this willingness to live with what the machine does can be seen in the rules that govern the widening of char objects for use in expressions: whether the values of char objects widen to signed or unsigned quantities typically depends on which byte operation is more efficient on the target machine. If only the gcc and clang designers followed that rule. It's precisely what they do. You are blaming the wrong people. These consider that undefined behaviour allows to break the code in any way they fancy (the nasal demon thing). While pragmaticists interpret it as do the thing that is the simplest to implement on that hardware. Those "pragmaticists" cannot be trusted, therefore they are not programmers. Why do they matter? The most ridiculous example being the undefined behaviour of signed integer overflow. Signed integer overflow is undefined in C because some obscure platforms may not use 2 complements for the representation of integers. So INT_MAX+1 does not necessarily result in INT_MIN. It's _undefined_, not implementation-defined or unspecified. Excerpt from the C standard: 3.4.1 1 implementation-defined behavior unspecified behavior where each implementation documents how the choice is made ... 3.4.3 1 undefined behavior behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements ... 3.4.4 1 unspecified behavior use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance ... What is it about "no requirements" that "pragmaticists" fail to understand? Not inventing artificial additional requirements is among the most pragmatic things to do. But completely removing the code when one encounters for example: if(val+1 == INT_MIN) is simply nuts. Why? This is simple dead code elimination. The programmer clearly must have known that it is dead code and the compiler trusts the programmer. The programmer would _never_ break that trust and make a program evaluate INT_MAX+1 ! The corollary to 'trust the programmer' is 'blame the programmer'. Don't use C if you want to blame the compiler.
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 09:56:18 UTC, Dibyendu Majumdar wrote: On Sunday, 14 May 2017 at 02:11:36 UTC, bachmeier wrote: On Sunday, 14 May 2017 at 00:05:56 UTC, Dibyendu Majumdar wrote: (a) Trust the programmer. I don't understand this point. C doesn't offer the programmer much to work with. If you trust the programmer, shouldn't that mean you provide a large set of tools and let them decide which parts to use? C is pretty much "here are some pointers, go have fun". Hi - I think this point really is saying that the type system in C is for convenience only - ultimately if you as a programmer want to manipulate memory in a certain way then C assumes you know what you are doing and why. As I said C is really a high level assembler. Regards I guess my point is that C only trusts programmers in one direction. You can go as low-level as you want, but it doesn't trust you to use more productive features when that is better (but it certainly gives you the tools to roll your own buggy, hard-to-share version of those features). D, C++, and Rust really do trust the programmer.
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 09:42:05 UTC, Patrick Schluter wrote: But completely removing the code when one encounters for example: if(val+1 == INT_MIN) is simply nuts. Removing such code is precisely what dmd does: https://issues.dlang.org/show_bug.cgi?id=16268
Re: DIP 1003 Formal Review
On 5/13/17 6:07 PM, Petar Kirov [ZombineDev] wrote: On Saturday, 13 May 2017 at 18:07:57 UTC, Timon Gehr wrote: On 13.05.2017 16:30, Petar Kirov [ZombineDev] wrote: On Saturday, 13 May 2017 at 10:27:25 UTC, Timon Gehr wrote: On 12.05.2017 18:17, Mike Parker wrote: The first stage of the formal review for DIP 1003 [1], "Remove body as a Keyword", is now underway. From now until 11:59 PM ET on May 26 (3:59 AM GMT on May 27), the community has the opportunity to provide last-minute feedback. If you missed the preliminary review [2], this is your chance to provide input. At the end of the feedback period, I will submit the DIP to Walter and Andrei for their final decision. Thanks in advance to those of you who participate. [1] https://github.com/dlang/DIPs/blob/fbb797f61ac92300eda1d63202157cd2a30ba555/DIPs/DIP1003.md [2] http://forum.dlang.org/thread/qgxvrbxrvkxtimzvn...@forum.dlang.org Option 1 is good: There is nothing wrong with the current syntax. [1] Option 2 is bad: It's the function body, not the function. Option 3 is ugly: There is no precedent for '...{}{}' belonging to the same declaration or statement. Hmm, I guess it depends on how you format your code. No, it does not. This was a point about the grammar. How would you feel about: if(condition){ then(); } { otherwise(); } I don't see any problem, in fact this is valid code even today - both in C++ and D. And my case still stands - if you were to format the code like this: if (condition) { then(); } { otherwise(); } then the intent would be more obvious. At least in C++ using a plain scope { } is common idiom used to explicitly limit the lifetime of RAII objects declared within it. There is a huge difference. if() {} else {} is semantically completely different than if() {} {} Currently, we already allow omitting body when in/out aren't present: void foo() { } is equivalent to void foo() body { } I think really, option 1 is both the easiest and least disruptive. I'm OK with option 3, but it sure seems like an unnecessary breakage. -Steve
Re: DIP 1003 Formal Review
On Sunday, 14 May 2017 at 13:04:12 UTC, Steven Schveighoffer wrote: On 5/13/17 6:07 PM, Petar Kirov [ZombineDev] wrote: On Saturday, 13 May 2017 at 18:07:57 UTC, Timon Gehr wrote: On 13.05.2017 16:30, Petar Kirov [ZombineDev] wrote: On Saturday, 13 May 2017 at 10:27:25 UTC, Timon Gehr wrote: [...] Hmm, I guess it depends on how you format your code. No, it does not. This was a point about the grammar. How would you feel about: if(condition){ then(); } { otherwise(); } I don't see any problem, in fact this is valid code even today - both in C++ and D. And my case still stands - if you were to format the code like this: if (condition) { then(); } { otherwise(); } then the intent would be more obvious. At least in C++ using a plain scope { } is common idiom used to explicitly limit the lifetime of RAII objects declared within it. There is a huge difference. if() {} else {} is semantically completely different than if() {} {} Obviously. I was just referring to the fact 'if (expr) {} {}' is already valid today and I don't think it confuses anyone with 'if (expr) {} else {}', *if code is formatted and/or commented properly*. Currently, we already allow omitting body when in/out aren't present: void foo() { } is equivalent to void foo() body { } I think really, option 1 is both the easiest and least disruptive. I'm OK with option 3, but it sure seems like an unnecessary breakage. -Steve By making body optional and a contextual keyword there should be no breaking changes (except for obscure code like `static assert (!__traits(compiles, { mixin ("int body;"); }))` :D).
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 12:07:40 UTC, Timon Gehr wrote: On 14.05.2017 11:42, Patrick Schluter wrote: But completely removing the code when one encounters for example: if(val+1 == INT_MIN) is simply nuts. Why? This is simple dead code elimination. The programmer clearly must have known that it is dead code and the compiler trusts the programmer. The programmer would _never_ break that trust and make a program evaluate INT_MAX+1 ! Well, actually, it makes sense to issue a warning in C. But in C++ it makes less sense since meta-programming easily can generate such code without breaking the semantics of the program. The corollary to 'trust the programmer' is 'blame the programmer'. Don't use C if you want to blame the compiler. Oh well, there are lots of different checkers for C, so I guess it would be more like "don't blame the compiler, blame the verifier".
Re: DIP 1003 Formal Review
On Sunday, 14 May 2017 at 01:30:19 UTC, Timon Gehr wrote: On 14.05.2017 00:07, Petar Kirov [ZombineDev] wrote: How would you feel about: if(condition){ then(); } { otherwise(); } I don't see any problem, ... The intention is that in this _hypothetical_ (hence "would") grammar (which is somewhat analogous to what is proposed in 3), the second block would bind to the if-statement as the 'else' case, but I see how that is confusing. And my case still stands - if you were to format the code like this: Again, this is not about formatting. Reformat the code as you wish. With your reformatting, it would actually be even less obvious. I now see what you meant, but the two ideas are not equivalent. Making 'else' optional is not possible, because it can change the meaning of existing code, while making 'body' optional would not. Edit: I may be wrong. Here's a case that's on the edge of ambiguity: void main() { void inner(int x) in { } { writeln("WAT"); } } If 'body' was optional, what would be the output of the program? It turns out that the output would be empty, because function bodies are required for functions with 'in' or 'out' contracts, making the block bind to the 'inner' function, instead of 'main'.
Re: DIP 1003 Formal Review
On 5/14/17 9:24 AM, Petar Kirov [ZombineDev] wrote: By making body optional and a contextual keyword there should be no breaking changes (except for obscure code like `static assert (!__traits(compiles, { mixin ("int body;"); }))` :D). It doesn't even need to be optional. It can be required as it is now (when in/out are specified), just not a keyword. I believe that this is what is specified in Option 1 of the DIP. -Steve
Re: DIP 1003 Formal Review
On Sunday, 14 May 2017 at 13:55:44 UTC, Steven Schveighoffer wrote: On 5/14/17 9:24 AM, Petar Kirov [ZombineDev] wrote: By making body optional and a contextual keyword there should be no breaking changes (except for obscure code like `static assert (!__traits(compiles, { mixin ("int body;"); }))` :D). It doesn't even need to be optional. It can be required as it is now (when in/out are specified), just not a keyword. I believe that this is what is specified in Option 1 of the DIP. -Steve Yeah, I'm OK with Option 1. I would just prefer not typing 'body' when writing functions with contracts.
Re: DIP 1003 Formal Review
On 5/14/17 9:53 AM, Petar Kirov [ZombineDev] wrote: Edit: I may be wrong. Here's a case that's on the edge of ambiguity: void main() { void inner(int x) in { } { writeln("WAT"); } } If 'body' was optional, what would be the output of the program? It turns out that the output would be empty, because function bodies are required for functions with 'in' or 'out' contracts, making the block bind to the 'inner' function, instead of 'main'. I don't think this is ambiguous or controversial. We are used to a block that follows a function declaration being that function's body without a special keyword. Look at it this way: void inner(int x) // in {} { writeln("Yeah, this is normal"); } If you uncomment the in clause, it's still pretty normal looking. Not that I'm particularly arguing for making body always optional, I'm fine with continuing to require it. But it's also fine to make it optional IMO. -Steve
Re: DIP 1003 Formal Review
On Saturday, 13 May 2017 at 10:27:25 UTC, Timon Gehr wrote: [1] Also, here is a list of existing contextual keywords: exit success failure C C++ D Windows Pascal System Objective-C They are not used alone. They are used in a **statement** and surrounded by parens. It's important because statements start with keywords, which, in a way, makes the contextual keyword less important. "body" as contextual keyword would be only comparable if 1/ "in" and "out" would also be contextual keywords. For example "exit", "success" and "failure" are **all** contextual keywords. 2/ used in a statement, for example "contract": void foo() contract(in){}contract(out){} contract(body){} (i don't say that this is the way to follow, it's more theoretical)
Re: DIP 1003 Formal Review
On 5/12/2017 9:17 AM, Mike Parker wrote: The first stage of the formal review for DIP 1003 [1], "Remove body as a Keyword", is now underway. A combination of Options 1 and 2: 1. Introduce 'function' as an alternative to 'body'. 2. Turn 'body' into a contextual keyword. 3. Deprecate 'body' as a contextual keyword. 4. Eventually remove 'body' as a contextual keyword. The advantages of this are: 1. 'body' can immediately be used as a regular identifier. 2. Existing code is not immediately broken. 3. Can have a decent deprecation period for users using 'body'. 4. No long term problems with contextual keywords.
Re: D is really cool
On Saturday, 13 May 2017 at 13:55:17 UTC, Russel Winder wrote: anecdotal, there is no statistically significant data. But then Reddit is mostly opinion and advocacy research. In my experience /r/programming has rather poor quality, but /r/cpp and other more specific groups tend to be much better. The only reason to read /r/programming is to get a feeling for trends... I guess.
Re: DIP 1003 Formal Review
On Friday, 12 May 2017 at 16:17:03 UTC, Mike Parker wrote: [1] https://github.com/dlang/DIPs/blob/fbb797f61ac92300eda1d63202157cd2a30ba555/DIPs/DIP1003.md Currently function declarations with contracts don't require semicolon at the end. This conflicts with options 1 and 3 and is not addressed in the DIP.
Re: DIP 1003 Formal Review
On Friday, 12 May 2017 at 18:03:43 UTC, H. S. Teoh wrote: I disagree that `function` is not overloaded: it *will* be overloaded if option 2 is chosen, because `function` currently means function *pointer*, not the function body itself. For this reason, I oppose Option 2. Function literal includes function body.
Re: Fantastic exchange from DConf
What does that snippet do ? What should it do? int caca(void) { for(int i=0x; i!=0x8000; i++) printf("coucou"); }
Re: weird empty string
On Saturday, 13 May 2017 at 03:41:29 UTC, mogu wrote: Thanks very much. This is a little bit confusing. There was a lot of discussion about it: https://issues.dlang.org/show_bug.cgi?id=4733, https://forum.dlang.org/thread/rrrtkfosfnfuybble...@forum.dlang.org
Re: "I made a game using Rust"
Am Fri, 12 May 2017 05:42:58 + schrieb Lewis : > Ah okay. If I understand correctly, the "game" itself is just the > two .d files in the Scripts folder, which get compiled then > linked with the prebuilt .lib for the engine. If so, a 10-12s > compile just for those two files still sounds really long to me. > Either I'm misunderstanding, or there's something bizarre going > on that's causing those build times. You can't tell how long a compile takes from looking at the size of the modules you pass to the linker. Unlike C++, Dlang lacks header files that could short-circuit import chains. What this means is that all the imports in a module (except inside templates) are analyzed recursively. In the game at hand this only means parsing the entire engine code base in addition to the two modules, but projected onto LibreOffice or other big projects it would parse the code of so many libraries that compilation times would sky-rocket. (I told this story here once or twice before, but haven't actively done anything to improve the situation.) Things you can do today: - If an import is only used in templates, copy it inside of them. This works today and stops the import from being analyzed unless the template is instantiated during the compilation. Multiple instances wont pessimize compile times. - Move imports from top-level into the functions that use them. There is no other way to say "This import not needed by our public interface". - Don't turn everything and the dog into a template. Nested templates stretching over several modules require analysis of all those modules along the way, while a regular function may stop right there. - Following all the above, generate .di files for your library's exported modules. All the imports inside non-template functions will be removed and only what's needed by the public interface (i.e. argument types and return types) is kept. Several ideas spread in the past. From the top of my head: - Walter had the idea to make imports evaluate lazily, and improve the situation without resorting to .di files. - Some issued with the .di file generation stop it from being widely used for example by dub when installing libraries. - The "export" keyword could be narrowed down to be the only visibility level that goes into the .di files created for a library. (Removing public and package visibility symbols and imports pulled in by them in turn.) Last not least, with single-file-compilation like in C++ you may still shoot yourself in the foot in Dlang, because when you update a template and forget to recompile all modules that instantiate it, it is left in the old state there and cause conflicts at link time or runtime errors. Disclaimer: If you find mistakes in the above or something simply isn't true any more please give an update on the current situation. -- Marco
Re: DIP 1003 Formal Review
On Sunday, 14 May 2017 at 16:35:32 UTC, Kagamin wrote: On Friday, 12 May 2017 at 16:17:03 UTC, Mike Parker wrote: [1] https://github.com/dlang/DIPs/blob/fbb797f61ac92300eda1d63202157cd2a30ba555/DIPs/DIP1003.md Currently function declarations with contracts don't require semicolon at the end. This conflicts with options 1 and 3 and is not addressed in the DIP. I'm confused as to how this conflicts with option 1. Can you explain?
Re: DIP 1003 Formal Review
On 14.05.2017 18:36, Kagamin wrote: On Friday, 12 May 2017 at 18:03:43 UTC, H. S. Teoh wrote: I disagree that `function` is not overloaded: it *will* be overloaded if option 2 is chosen, because `function` currently means function *pointer*, not the function body itself. For this reason, I oppose Option 2. Function literal includes function body. auto add = function int(int a,int b)in{ assert(0<=a && 0 <=b && a<=int.max-b); }body{ return a+b; };
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 16:44:10 UTC, Patrick Schluter wrote: What does that snippet do ? What should it do? int caca(void) { for(int i=0x; i!=0x8000; i++) printf("coucou"); } Implicit coercion is a design bug in both C and D... :-P
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 19:10:05 UTC, Ola Fosheim Grøstad wrote: On Sunday, 14 May 2017 at 16:44:10 UTC, Patrick Schluter wrote: What does that snippet do ? What should it do? int caca(void) { for(int i=0x; i!=0x8000; i++) printf("coucou"); } Implicit coercion is a design bug in both C and D... :-P Of course the annoying part is that C allows 2s-complement notation for integer literals, so with warnings on: int i = 0x; // passes without warning. int i = 0xUL; // warning is issued.
DUB: Multiprocess?
When I build C++ projects using make, I can specify how many processes I want to use (-j). This keeps the processors full and happy and greatly reduces the overall build time. Does DUB have a similar way of compiling each file in it's own process or thread?
Re: DUB: Multiprocess?
On Sunday, 14 May 2017 at 20:23:17 UTC, Ivan Trombley wrote: When I build C++ projects using make, I can specify how many processes I want to use (-j). This keeps the processors full and happy and greatly reduces the overall build time. Does DUB have a similar way of compiling each file in it's own process or thread? There's the "--parallel" switch for that. Example dub build --build=release --parallel It's in the documentation.
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 10:10:41 UTC, Dibyendu Majumdar wrote: In real terms though tools like ASAN and Valgrind if used from the start usually allow you to catch most of the issues. Most likely even better tools for C will come about in time. See Walter's comment earlier in this thread and my reply. I think Rust is a promising language but I don't know enough about it to comment. My impression about Rust is that: a) Rust has a steep learning curve as a language. So does C, if you're doing C "correctly". b) If you want to do things that C allows you to do, then Rust is no more safer than C. That's the entire bloody point isn't it? Maybe you shouldn't be doing a lot of the things that C allows you to do.
Re: Fantastic exchange from DConf
On Sunday, 14 May 2017 at 21:01:40 UTC, Jack Stouffer wrote: On Sunday, 14 May 2017 at 10:10:41 UTC, Dibyendu Majumdar wrote: b) If you want to do things that C allows you to do, then Rust is no more safer than C. That's the entire bloody point isn't it? Maybe you shouldn't be doing a lot of the things that C allows you to do. Like building a graph? Sure, Rust is perfect if you can model your world like a tree, but that is usually not what you want if you are looking for performance. You could replace pointers with integer-ids, but that is just emulating pointers with a construct that may be harder to check for in an automated fashion. So that is not a good solution either.
Re: DIP 1003 Formal Review
On 14.05.2017 17:39, Walter Bright wrote: On 5/12/2017 9:17 AM, Mike Parker wrote: The first stage of the formal review for DIP 1003 [1], "Remove body as a Keyword", is now underway. A combination of Options 1 and 2: 1. Introduce 'function' as an alternative to 'body'. 2. Turn 'body' into a contextual keyword. 3. Deprecate 'body' as a contextual keyword. 4. Eventually remove 'body' as a contextual keyword. The advantages of this are: 1. 'body' can immediately be used as a regular identifier. 2. Existing code is not immediately broken. 3. Can have a decent deprecation period for users using 'body'. 4. No long term problems with contextual keywords. The drawback is that option 2 is not a good option.
Re: DUB: Multiprocess?
On Sunday, 14 May 2017 at 21:01:37 UTC, Basile B. wrote: On Sunday, 14 May 2017 at 20:23:17 UTC, Ivan Trombley wrote: When I build C++ projects using make, I can specify how many processes I want to use (-j). This keeps the processors full and happy and greatly reduces the overall build time. Does DUB have a similar way of compiling each file in it's own process or thread? There's the "--parallel" switch for that. Example dub build --build=release --parallel It's in the documentation. I tried that and only one processor is used. The rest are idle.
Re: DUB: Multiprocess?
On Sunday, 14 May 2017 at 21:41:58 UTC, Ivan Trombley wrote: On Sunday, 14 May 2017 at 21:01:37 UTC, Basile B. wrote: On Sunday, 14 May 2017 at 20:23:17 UTC, Ivan Trombley wrote: When I build C++ projects using make, I can specify how many processes I want to use (-j). This keeps the processors full and happy and greatly reduces the overall build time. Does DUB have a similar way of compiling each file in it's own process or thread? There's the "--parallel" switch for that. Example dub build --build=release --parallel It's in the documentation. I tried that and only one processor is used. The rest are idle. It currently is only implemented for "--build-mode singleFile", but this build mode is usually a lot slower than building each package at once. Implementing it for the latter mode is planned as well, but it should be noted that depending on the project this will require a lot of RAM.
Re: DIP 1003 Formal Review
On Sunday, May 14, 2017 08:39:12 Walter Bright via Digitalmars-d wrote: > On 5/12/2017 9:17 AM, Mike Parker wrote: > > The first stage of the formal review for DIP 1003 [1], "Remove body as a > > Keyword", is now underway. > > A combination of Options 1 and 2: > > 1. Introduce 'function' as an alternative to 'body'. > 2. Turn 'body' into a contextual keyword. > 3. Deprecate 'body' as a contextual keyword. > 4. Eventually remove 'body' as a contextual keyword. > > The advantages of this are: > > 1. 'body' can immediately be used as a regular identifier. > 2. Existing code is not immediately broken. > 3. Can have a decent deprecation period for users using 'body'. > 4. No long term problems with contextual keywords. Why would we want to introduce function as an alternative to body? Personally, I've always found the need to use body to be very odd and annoying. It doesn't need to be there when you don't have in or out contracts, and it just makes contracts that much more verbose. It's not even like you can put in our out contracts after the function body, so body is needed to indicate which block the function body is - the contracts have to go first. So, as far as I can tell, body serves no useful function. It just makes the code longer, and the amount of extra code required around in/out contracts is part of why I almost never use them. In most cases, it just makes more sense to put the assertions in the function body and not have all of that extra plumbing right after the function signature. So, while I do like the idea of getting the word body back as an identifier, what really appeals to me here is getting rid of the need for it with contracts. And using function instead of body doesn't help that at all. If we need a keyword there, then I agree that function is a good fit, but I don't understand why having a keyword there is even beneficial. As far as I can tell, it doesn't solve any ambiguity; it's inconsistent with function declarations that don't have contracts; and it's just making an already annoyingly verbose construct that much more verbose. I like the idea of doing the deprecation in a way that avoids having contextual keywords in the long run, and having the ability to use body as identifier immediately would be nice - so in that sense, your proposal seems good - but I'd _really_ like to see it be the case ultimately that no keyword is needed for function bodies even when in/out contracts are used. - Jonathan M Davis
Re: DIP 1003 Formal Review
On Monday, 15 May 2017 at 01:18:02 UTC, Jonathan M Davis wrote: Why would we want to introduce function as an alternative to body? Personally, I've always found the need to use body to be very odd and annoying. It doesn't need to be there when you don't have in or out contracts, and it just makes contracts that much more verbose. It's not even like you can put in our out contracts after the function body, so body is needed to indicate which block the function body is - the contracts have to go first. So, as far as I can tell, body serves no useful function. It just makes the code longer, and the amount of extra code required around in/out contracts is part of why I almost never use them. In most cases, it just makes more sense to put the assertions in the function body and not have all of that extra plumbing right after the function signature. Not that a whole new way of doing things is called for... but I think a better design would have been to allow 'in' and 'out' statements in the function itself, with no need for brackets if you only have one line's worth of contract, e.g., int fun(int a) { in assert(...); out(x) assert(...); // do stuff }
Re: DIP 1003 Formal Review
On Monday, 15 May 2017 at 01:39:34 UTC, MysticZach wrote: Not that a whole new way of doing things is called for... but I think a better design would have been to allow 'in' and 'out' statements in the function itself, with no need for brackets if you only have one line's worth of contract, e.g., int fun(int a) { in assert(...); out(x) assert(...); // do stuff } You could even accumulate in statement if you want to save on brackets and indentation: int fun() { in assert(...); in assert2(...); // etc. }
Re: DIP 1003 Formal Review
On Monday, 15 May 2017 at 01:39:34 UTC, MysticZach wrote: Not that a whole new way of doing things is called for... but I think a better design would have been to allow 'in' and 'out' statements in the function itself, with no need for brackets if you only have one line's worth of contract, e.g., int fun(int a) { in assert(...); out(x) assert(...); // do stuff } It's nice, i like it but it cant work as simply. You're forgetting that interface member functions can have contracts. With this syntax interfaces member functions would always have a body BUT the current semantic is that interface member functions with bodies are final methods. Boom. Interfaces don't work anymore because there's no easy way to make the difference between an interface member function that's final and an interface member function that's not pre-implemented (so overridable) but has contracts.